mirror of
https://github.com/openssl/openssl.git
synced 2024-11-23 18:13:39 +08:00
PR: 2295
Submitted by: Alexei Khlebnikov <alexei.khlebnikov@opera.com> Reviewed by: steve OOM checking. Leak in OOM fix. Fall-through comment. Duplicate code elimination.
This commit is contained in:
parent
101e6e19f2
commit
f37f20ffd3
3
CHANGES
3
CHANGES
@ -4,6 +4,9 @@
|
||||
|
||||
Changes between 1.0.1 and 1.1.0 [xx XXX xxxx]
|
||||
|
||||
*) Add TLS v1.2 server support for client authentication.
|
||||
[Steve Henson]
|
||||
|
||||
*) Add support for FIPS mode in ssl library: disable SSLv3, non-FIPS ciphers
|
||||
and enable MD5.
|
||||
[Steve Henson]
|
||||
|
13
ssl/s3_enc.c
13
ssl/s3_enc.c
@ -569,12 +569,12 @@ void ssl3_free_digest_list(SSL *s)
|
||||
OPENSSL_free(s->s3->handshake_dgst);
|
||||
s->s3->handshake_dgst=NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void ssl3_finish_mac(SSL *s, const unsigned char *buf, int len)
|
||||
{
|
||||
if (s->s3->handshake_buffer)
|
||||
if (s->s3->handshake_buffer && !(s->s3->flags & TLS1_FLAGS_KEEP_HANDSHAKE))
|
||||
{
|
||||
BIO_write (s->s3->handshake_buffer,(void *)buf,len);
|
||||
}
|
||||
@ -629,9 +629,12 @@ int ssl3_digest_cached_records(SSL *s)
|
||||
s->s3->handshake_dgst[i]=NULL;
|
||||
}
|
||||
}
|
||||
/* Free handshake_buffer BIO */
|
||||
BIO_free(s->s3->handshake_buffer);
|
||||
s->s3->handshake_buffer = NULL;
|
||||
if (!(s->s3->flags & TLS1_FLAGS_KEEP_HANDSHAKE))
|
||||
{
|
||||
/* Free handshake_buffer BIO */
|
||||
BIO_free(s->s3->handshake_buffer);
|
||||
s->s3->handshake_buffer = NULL;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
113
ssl/s3_srvr.c
113
ssl/s3_srvr.c
@ -516,6 +516,9 @@ int ssl3_accept(SSL *s)
|
||||
skip=1;
|
||||
s->s3->tmp.cert_request=0;
|
||||
s->state=SSL3_ST_SW_SRVR_DONE_A;
|
||||
if (s->s3->handshake_buffer)
|
||||
if (!ssl3_digest_cached_records(s))
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -608,6 +611,24 @@ int ssl3_accept(SSL *s)
|
||||
#endif
|
||||
s->init_num = 0;
|
||||
}
|
||||
else if (s->version >= TLS1_2_VERSION)
|
||||
{
|
||||
s->state=SSL3_ST_SR_CERT_VRFY_A;
|
||||
s->init_num=0;
|
||||
if (!s->session->peer)
|
||||
break;
|
||||
/* For TLS v1.2 freeze the handshake buffer
|
||||
* at this point and digest cached records.
|
||||
*/
|
||||
if (!s->s3->handshake_buffer)
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_ACCEPT,ERR_R_INTERNAL_ERROR);
|
||||
return -1;
|
||||
}
|
||||
s->s3->flags |= TLS1_FLAGS_KEEP_HANDSHAKE;
|
||||
if (!ssl3_digest_cached_records(s))
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
int offset=0;
|
||||
@ -1359,8 +1380,11 @@ int ssl3_get_client_hello(SSL *s)
|
||||
s->s3->tmp.new_cipher=s->session->cipher;
|
||||
}
|
||||
|
||||
if (!ssl3_digest_cached_records(s))
|
||||
goto f_err;
|
||||
if (s->version < TLS1_2_VERSION || !(s->verify_mode & SSL_VERIFY_PEER))
|
||||
{
|
||||
if (!ssl3_digest_cached_records(s))
|
||||
goto f_err;
|
||||
}
|
||||
|
||||
/* we now have the following setup.
|
||||
* client_random
|
||||
@ -2007,6 +2031,14 @@ int ssl3_send_certificate_request(SSL *s)
|
||||
p+=n;
|
||||
n++;
|
||||
|
||||
if (s->version >= TLS1_2_VERSION)
|
||||
{
|
||||
nl = tls12_get_req_sig_algs(s, p + 2);
|
||||
s2n(nl, p);
|
||||
p += nl + 2;
|
||||
n += nl + 2;
|
||||
}
|
||||
|
||||
off=n;
|
||||
p+=2;
|
||||
n+=2;
|
||||
@ -2861,6 +2893,9 @@ int ssl3_get_cert_verify(SSL *s)
|
||||
long n;
|
||||
int type=0,i,j;
|
||||
X509 *peer;
|
||||
const EVP_MD *md = NULL;
|
||||
EVP_MD_CTX mctx;
|
||||
EVP_MD_CTX_init(&mctx);
|
||||
|
||||
n=s->method->ssl_get_message(s,
|
||||
SSL3_ST_SR_CERT_VRFY_A,
|
||||
@ -2929,6 +2964,36 @@ int ssl3_get_cert_verify(SSL *s)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (s->version >= TLS1_2_VERSION)
|
||||
{
|
||||
int sigalg = tls12_get_sigid(pkey);
|
||||
/* Should never happen */
|
||||
if (sigalg == -1)
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,ERR_R_INTERNAL_ERROR);
|
||||
al=SSL_AD_INTERNAL_ERROR;
|
||||
goto f_err;
|
||||
}
|
||||
/* Check key type is consistent with signature */
|
||||
if (sigalg != (int)p[1])
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_WRONG_SIGNATURE_TYPE);
|
||||
al=SSL_AD_DECODE_ERROR;
|
||||
goto f_err;
|
||||
}
|
||||
md = tls12_get_hash(p[0]);
|
||||
if (md == NULL)
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_UNKNOWN_DIGEST);
|
||||
al=SSL_AD_DECODE_ERROR;
|
||||
goto f_err;
|
||||
}
|
||||
#ifdef SSL_DEBUG
|
||||
fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md));
|
||||
#endif
|
||||
p += 2;
|
||||
n -= 2;
|
||||
}
|
||||
n2s(p,i);
|
||||
n-=2;
|
||||
if (i > n)
|
||||
@ -2946,6 +3011,37 @@ int ssl3_get_cert_verify(SSL *s)
|
||||
goto f_err;
|
||||
}
|
||||
|
||||
if (s->version >= TLS1_2_VERSION)
|
||||
{
|
||||
long hdatalen = 0;
|
||||
void *hdata;
|
||||
hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata);
|
||||
if (hdatalen <= 0)
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, ERR_R_INTERNAL_ERROR);
|
||||
al=SSL_AD_INTERNAL_ERROR;
|
||||
goto f_err;
|
||||
}
|
||||
#ifdef SSL_DEBUG
|
||||
fprintf(stderr, "Using TLS 1.2 with client verify alg %s\n",
|
||||
EVP_MD_name(md));
|
||||
#endif
|
||||
if (!EVP_VerifyInit_ex(&mctx, md, NULL)
|
||||
|| !EVP_VerifyUpdate(&mctx, hdata, hdatalen))
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, ERR_R_EVP_LIB);
|
||||
al=SSL_AD_INTERNAL_ERROR;
|
||||
goto f_err;
|
||||
}
|
||||
|
||||
if (EVP_VerifyFinal(&mctx, p , i, pkey) <= 0)
|
||||
{
|
||||
al=SSL_AD_DECRYPT_ERROR;
|
||||
SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_BAD_SIGNATURE);
|
||||
goto f_err;
|
||||
}
|
||||
}
|
||||
else
|
||||
#ifndef OPENSSL_NO_RSA
|
||||
if (pkey->type == EVP_PKEY_RSA)
|
||||
{
|
||||
@ -3036,6 +3132,13 @@ f_err:
|
||||
ssl3_send_alert(s,SSL3_AL_FATAL,al);
|
||||
}
|
||||
end:
|
||||
if (s->s3->handshake_buffer)
|
||||
{
|
||||
BIO_free(s->s3->handshake_buffer);
|
||||
s->s3->handshake_buffer = NULL;
|
||||
s->s3->flags &= ~TLS1_FLAGS_KEEP_HANDSHAKE;
|
||||
}
|
||||
EVP_MD_CTX_cleanup(&mctx);
|
||||
EVP_PKEY_free(pkey);
|
||||
return(ret);
|
||||
}
|
||||
@ -3148,6 +3251,12 @@ int ssl3_get_client_certificate(SSL *s)
|
||||
al=SSL_AD_HANDSHAKE_FAILURE;
|
||||
goto f_err;
|
||||
}
|
||||
/* No client certificate so digest cached records */
|
||||
if (s->s3->handshake_buffer && !ssl3_digest_cached_records(s))
|
||||
{
|
||||
al=SSL_AD_INTERNAL_ERROR;
|
||||
goto f_err;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -383,6 +383,7 @@ typedef struct ssl3_buffer_st
|
||||
#define SSL3_FLAGS_POP_BUFFER 0x0004
|
||||
#define TLS1_FLAGS_TLS_PADDING_BUG 0x0008
|
||||
#define TLS1_FLAGS_SKIP_CERT_VERIFY 0x0010
|
||||
#define TLS1_FLAGS_KEEP_HANDSHAKE 0x0020
|
||||
|
||||
#ifndef OPENSSL_NO_SSL_INTERN
|
||||
|
||||
|
@ -1096,4 +1096,5 @@ int ssl_parse_clienthello_renegotiate_ext(SSL *s, unsigned char *d, int len,
|
||||
int *al);
|
||||
long ssl_get_algorithm2(SSL *s);
|
||||
int tls1_process_sigalgs(SSL *s, const unsigned char *data, int dsize);
|
||||
int tls12_get_req_sig_algs(SSL *s, unsigned char *p);
|
||||
#endif
|
||||
|
@ -315,7 +315,12 @@ static unsigned char tls12_sigalgs[] = {
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
int tls12_get_req_sig_algs(SSL *s, unsigned char *p)
|
||||
{
|
||||
if (p)
|
||||
memcpy(p, tls12_sigalgs, sizeof(tls12_sigalgs));
|
||||
return (int)sizeof(tls12_sigalgs);
|
||||
}
|
||||
|
||||
unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user