mirror of
https://github.com/openssl/openssl.git
synced 2025-04-06 20:20:50 +08:00
Move Certificate Verify construction and processing into statem_lib.c
Reviewed-by: Rich Salz <rsalz@openssl.org> (Merged from https://github.com/openssl/openssl/pull/2157)
This commit is contained in:
parent
3f305a80e9
commit
d8bc139978
@ -2232,6 +2232,7 @@ int ERR_load_SSL_strings(void);
|
||||
# define SSL_F_TLS_CONSTRUCT_CERTIFICATE_REQUEST 372
|
||||
# define SSL_F_TLS_CONSTRUCT_CERT_STATUS 429
|
||||
# define SSL_F_TLS_CONSTRUCT_CERT_STATUS_BODY 494
|
||||
# define SSL_F_TLS_CONSTRUCT_CERT_VERIFY 496
|
||||
# define SSL_F_TLS_CONSTRUCT_CHANGE_CIPHER_SPEC 427
|
||||
# define SSL_F_TLS_CONSTRUCT_CKE_DHE 404
|
||||
# define SSL_F_TLS_CONSTRUCT_CKE_ECDHE 405
|
||||
|
@ -262,6 +262,7 @@ static ERR_STRING_DATA SSL_str_functs[] = {
|
||||
{ERR_FUNC(SSL_F_TLS_CONSTRUCT_CERT_STATUS), "tls_construct_cert_status"},
|
||||
{ERR_FUNC(SSL_F_TLS_CONSTRUCT_CERT_STATUS_BODY),
|
||||
"tls_construct_cert_status_body"},
|
||||
{ERR_FUNC(SSL_F_TLS_CONSTRUCT_CERT_VERIFY), "tls_construct_cert_verify"},
|
||||
{ERR_FUNC(SSL_F_TLS_CONSTRUCT_CHANGE_CIPHER_SPEC),
|
||||
"tls_construct_change_cipher_spec"},
|
||||
{ERR_FUNC(SSL_F_TLS_CONSTRUCT_CKE_DHE), "tls_construct_cke_dhe"},
|
||||
|
@ -689,7 +689,7 @@ int ossl_statem_client_construct_message(SSL *s, WPACKET *pkt,
|
||||
break;
|
||||
|
||||
case TLS_ST_CW_CERT_VRFY:
|
||||
*confunc = tls_construct_client_verify;
|
||||
*confunc = tls_construct_cert_verify;
|
||||
*mt = SSL3_MT_CERTIFICATE_VERIFY;
|
||||
break;
|
||||
|
||||
@ -2840,80 +2840,6 @@ int tls_client_key_exchange_post_work(SSL *s)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tls_construct_client_verify(SSL *s, WPACKET *pkt)
|
||||
{
|
||||
EVP_PKEY *pkey;
|
||||
const EVP_MD *md = s->s3->tmp.md[s->cert->key - s->cert->pkeys];
|
||||
EVP_MD_CTX *mctx = NULL;
|
||||
unsigned u = 0;
|
||||
long hdatalen = 0;
|
||||
void *hdata;
|
||||
unsigned char *sig = NULL;
|
||||
|
||||
mctx = EVP_MD_CTX_new();
|
||||
if (mctx == NULL) {
|
||||
SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
pkey = s->cert->key->privatekey;
|
||||
|
||||
hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata);
|
||||
if (hdatalen <= 0) {
|
||||
SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY, ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (SSL_USE_SIGALGS(s)&& !tls12_get_sigandhash(pkt, pkey, md)) {
|
||||
SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY, ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
#ifdef SSL_DEBUG
|
||||
fprintf(stderr, "Using client alg %s\n", EVP_MD_name(md));
|
||||
#endif
|
||||
sig = OPENSSL_malloc(EVP_PKEY_size(pkey));
|
||||
if (sig == NULL) {
|
||||
SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
if (!EVP_SignInit_ex(mctx, md, NULL)
|
||||
|| !EVP_SignUpdate(mctx, hdata, hdatalen)
|
||||
|| (s->version == SSL3_VERSION
|
||||
&& !EVP_MD_CTX_ctrl(mctx, EVP_CTRL_SSL3_MASTER_SECRET,
|
||||
(int)s->session->master_key_length,
|
||||
s->session->master_key))
|
||||
|| !EVP_SignFinal(mctx, sig, &u, pkey)) {
|
||||
SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY, ERR_R_EVP_LIB);
|
||||
goto err;
|
||||
}
|
||||
#ifndef OPENSSL_NO_GOST
|
||||
{
|
||||
int pktype = EVP_PKEY_id(pkey);
|
||||
if (pktype == NID_id_GostR3410_2001
|
||||
|| pktype == NID_id_GostR3410_2012_256
|
||||
|| pktype == NID_id_GostR3410_2012_512)
|
||||
BUF_reverse(sig, NULL, u);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!WPACKET_sub_memcpy_u16(pkt, sig, u)) {
|
||||
SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY, ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Digest cached records and discard handshake buffer */
|
||||
if (!ssl3_digest_cached_records(s, 0))
|
||||
goto err;
|
||||
|
||||
OPENSSL_free(sig);
|
||||
EVP_MD_CTX_free(mctx);
|
||||
return 1;
|
||||
err:
|
||||
OPENSSL_free(sig);
|
||||
EVP_MD_CTX_free(mctx);
|
||||
ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check a certificate can be used for client authentication. Currently check
|
||||
* cert exists, if we have a suitable digest for TLS 1.2 if static DH client
|
||||
|
@ -72,6 +72,237 @@ int tls_close_construct_packet(SSL *s, WPACKET *pkt, int htype)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int tls_construct_cert_verify(SSL *s, WPACKET *pkt)
|
||||
{
|
||||
EVP_PKEY *pkey;
|
||||
const EVP_MD *md = s->s3->tmp.md[s->cert->key - s->cert->pkeys];
|
||||
EVP_MD_CTX *mctx = NULL;
|
||||
unsigned u = 0;
|
||||
long hdatalen = 0;
|
||||
void *hdata;
|
||||
unsigned char *sig = NULL;
|
||||
|
||||
mctx = EVP_MD_CTX_new();
|
||||
if (mctx == NULL) {
|
||||
SSLerr(SSL_F_TLS_CONSTRUCT_CERT_VERIFY, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
pkey = s->cert->key->privatekey;
|
||||
|
||||
hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata);
|
||||
if (hdatalen <= 0) {
|
||||
SSLerr(SSL_F_TLS_CONSTRUCT_CERT_VERIFY, ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (SSL_USE_SIGALGS(s)&& !tls12_get_sigandhash(pkt, pkey, md)) {
|
||||
SSLerr(SSL_F_TLS_CONSTRUCT_CERT_VERIFY, ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
#ifdef SSL_DEBUG
|
||||
fprintf(stderr, "Using client alg %s\n", EVP_MD_name(md));
|
||||
#endif
|
||||
sig = OPENSSL_malloc(EVP_PKEY_size(pkey));
|
||||
if (sig == NULL) {
|
||||
SSLerr(SSL_F_TLS_CONSTRUCT_CERT_VERIFY, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
if (!EVP_SignInit_ex(mctx, md, NULL)
|
||||
|| !EVP_SignUpdate(mctx, hdata, hdatalen)
|
||||
|| (s->version == SSL3_VERSION
|
||||
&& !EVP_MD_CTX_ctrl(mctx, EVP_CTRL_SSL3_MASTER_SECRET,
|
||||
(int)s->session->master_key_length,
|
||||
s->session->master_key))
|
||||
|| !EVP_SignFinal(mctx, sig, &u, pkey)) {
|
||||
SSLerr(SSL_F_TLS_CONSTRUCT_CERT_VERIFY, ERR_R_EVP_LIB);
|
||||
goto err;
|
||||
}
|
||||
#ifndef OPENSSL_NO_GOST
|
||||
{
|
||||
int pktype = EVP_PKEY_id(pkey);
|
||||
if (pktype == NID_id_GostR3410_2001
|
||||
|| pktype == NID_id_GostR3410_2012_256
|
||||
|| pktype == NID_id_GostR3410_2012_512)
|
||||
BUF_reverse(sig, NULL, u);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!WPACKET_sub_memcpy_u16(pkt, sig, u)) {
|
||||
SSLerr(SSL_F_TLS_CONSTRUCT_CERT_VERIFY, ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Digest cached records and discard handshake buffer */
|
||||
if (!ssl3_digest_cached_records(s, 0))
|
||||
goto err;
|
||||
|
||||
OPENSSL_free(sig);
|
||||
EVP_MD_CTX_free(mctx);
|
||||
return 1;
|
||||
err:
|
||||
OPENSSL_free(sig);
|
||||
EVP_MD_CTX_free(mctx);
|
||||
ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt)
|
||||
{
|
||||
EVP_PKEY *pkey = NULL;
|
||||
const unsigned char *sig, *data;
|
||||
#ifndef OPENSSL_NO_GOST
|
||||
unsigned char *gost_data = NULL;
|
||||
#endif
|
||||
int al, ret = MSG_PROCESS_ERROR;
|
||||
int type = 0, j;
|
||||
unsigned int len;
|
||||
X509 *peer;
|
||||
const EVP_MD *md = NULL;
|
||||
long hdatalen = 0;
|
||||
void *hdata;
|
||||
|
||||
EVP_MD_CTX *mctx = EVP_MD_CTX_new();
|
||||
|
||||
if (mctx == NULL) {
|
||||
SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, ERR_R_MALLOC_FAILURE);
|
||||
al = SSL_AD_INTERNAL_ERROR;
|
||||
goto f_err;
|
||||
}
|
||||
|
||||
peer = s->session->peer;
|
||||
pkey = X509_get0_pubkey(peer);
|
||||
type = X509_certificate_type(peer, pkey);
|
||||
|
||||
if (!(type & EVP_PKT_SIGN)) {
|
||||
SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY,
|
||||
SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE);
|
||||
al = SSL_AD_ILLEGAL_PARAMETER;
|
||||
goto f_err;
|
||||
}
|
||||
|
||||
/* Check for broken implementations of GOST ciphersuites */
|
||||
/*
|
||||
* If key is GOST and n is exactly 64, it is bare signature without
|
||||
* length field (CryptoPro implementations at least till CSP 4.0)
|
||||
*/
|
||||
#ifndef OPENSSL_NO_GOST
|
||||
if (PACKET_remaining(pkt) == 64
|
||||
&& EVP_PKEY_id(pkey) == NID_id_GostR3410_2001) {
|
||||
len = 64;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
if (SSL_USE_SIGALGS(s)) {
|
||||
int rv;
|
||||
|
||||
if (!PACKET_get_bytes(pkt, &sig, 2)) {
|
||||
al = SSL_AD_DECODE_ERROR;
|
||||
goto f_err;
|
||||
}
|
||||
rv = tls12_check_peer_sigalg(&md, s, sig, pkey);
|
||||
if (rv == -1) {
|
||||
al = SSL_AD_INTERNAL_ERROR;
|
||||
goto f_err;
|
||||
} else if (rv == 0) {
|
||||
al = SSL_AD_DECODE_ERROR;
|
||||
goto f_err;
|
||||
}
|
||||
#ifdef SSL_DEBUG
|
||||
fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md));
|
||||
#endif
|
||||
} else {
|
||||
/* Use default digest for this key type */
|
||||
int idx = ssl_cert_type(NULL, pkey);
|
||||
if (idx >= 0)
|
||||
md = s->s3->tmp.md[idx];
|
||||
if (md == NULL) {
|
||||
al = SSL_AD_INTERNAL_ERROR;
|
||||
goto f_err;
|
||||
}
|
||||
}
|
||||
|
||||
if (!PACKET_get_net_2(pkt, &len)) {
|
||||
SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, SSL_R_LENGTH_MISMATCH);
|
||||
al = SSL_AD_DECODE_ERROR;
|
||||
goto f_err;
|
||||
}
|
||||
}
|
||||
j = EVP_PKEY_size(pkey);
|
||||
if (((int)len > j) || ((int)PACKET_remaining(pkt) > j)
|
||||
|| (PACKET_remaining(pkt) == 0)) {
|
||||
SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, SSL_R_WRONG_SIGNATURE_SIZE);
|
||||
al = SSL_AD_DECODE_ERROR;
|
||||
goto f_err;
|
||||
}
|
||||
if (!PACKET_get_bytes(pkt, &data, len)) {
|
||||
SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, SSL_R_LENGTH_MISMATCH);
|
||||
al = SSL_AD_DECODE_ERROR;
|
||||
goto f_err;
|
||||
}
|
||||
|
||||
hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata);
|
||||
if (hdatalen <= 0) {
|
||||
SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, ERR_R_INTERNAL_ERROR);
|
||||
al = SSL_AD_INTERNAL_ERROR;
|
||||
goto f_err;
|
||||
}
|
||||
|
||||
#ifdef SSL_DEBUG
|
||||
fprintf(stderr, "Using 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_TLS_PROCESS_CERT_VERIFY, ERR_R_EVP_LIB);
|
||||
al = SSL_AD_INTERNAL_ERROR;
|
||||
goto f_err;
|
||||
}
|
||||
#ifndef OPENSSL_NO_GOST
|
||||
{
|
||||
int pktype = EVP_PKEY_id(pkey);
|
||||
if (pktype == NID_id_GostR3410_2001
|
||||
|| pktype == NID_id_GostR3410_2012_256
|
||||
|| pktype == NID_id_GostR3410_2012_512) {
|
||||
if ((gost_data = OPENSSL_malloc(len)) == NULL) {
|
||||
SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, ERR_R_MALLOC_FAILURE);
|
||||
al = SSL_AD_INTERNAL_ERROR;
|
||||
goto f_err;
|
||||
}
|
||||
BUF_reverse(gost_data, data, len);
|
||||
data = gost_data;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (s->version == SSL3_VERSION
|
||||
&& !EVP_MD_CTX_ctrl(mctx, EVP_CTRL_SSL3_MASTER_SECRET,
|
||||
(int)s->session->master_key_length,
|
||||
s->session->master_key)) {
|
||||
SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, ERR_R_EVP_LIB);
|
||||
al = SSL_AD_INTERNAL_ERROR;
|
||||
goto f_err;
|
||||
}
|
||||
|
||||
if (EVP_VerifyFinal(mctx, data, len, pkey) <= 0) {
|
||||
al = SSL_AD_DECRYPT_ERROR;
|
||||
SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, SSL_R_BAD_SIGNATURE);
|
||||
goto f_err;
|
||||
}
|
||||
|
||||
ret = MSG_PROCESS_CONTINUE_PROCESSING;
|
||||
if (0) {
|
||||
f_err:
|
||||
ssl3_send_alert(s, SSL3_AL_FATAL, al);
|
||||
ossl_statem_set_error(s);
|
||||
}
|
||||
BIO_free(s->s3->handshake_buffer);
|
||||
s->s3->handshake_buffer = NULL;
|
||||
EVP_MD_CTX_free(mctx);
|
||||
#ifndef OPENSSL_NO_GOST
|
||||
OPENSSL_free(gost_data);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
int tls_construct_finished(SSL *s, WPACKET *pkt)
|
||||
{
|
||||
size_t finish_md_len;
|
||||
|
@ -118,7 +118,7 @@ __owur MSG_PROCESS_RETURN tls_process_new_session_ticket(SSL *s, PACKET *pkt);
|
||||
__owur int tls_process_cert_status_body(SSL *s, PACKET *pkt, int *al);
|
||||
__owur MSG_PROCESS_RETURN tls_process_cert_status(SSL *s, PACKET *pkt);
|
||||
__owur MSG_PROCESS_RETURN tls_process_server_done(SSL *s, PACKET *pkt);
|
||||
__owur int tls_construct_client_verify(SSL *s, WPACKET *pkt);
|
||||
__owur int tls_construct_cert_verify(SSL *s, WPACKET *pkt);
|
||||
__owur WORK_STATE tls_prepare_client_certificate(SSL *s, WORK_STATE wst);
|
||||
__owur int tls_construct_client_certificate(SSL *s, WPACKET *pkt);
|
||||
__owur int ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey);
|
||||
|
@ -2974,163 +2974,6 @@ WORK_STATE tls_post_process_client_key_exchange(SSL *s, WORK_STATE wst)
|
||||
return WORK_FINISHED_CONTINUE;
|
||||
}
|
||||
|
||||
MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt)
|
||||
{
|
||||
EVP_PKEY *pkey = NULL;
|
||||
const unsigned char *sig, *data;
|
||||
#ifndef OPENSSL_NO_GOST
|
||||
unsigned char *gost_data = NULL;
|
||||
#endif
|
||||
int al, ret = MSG_PROCESS_ERROR;
|
||||
int type = 0, j;
|
||||
unsigned int len;
|
||||
X509 *peer;
|
||||
const EVP_MD *md = NULL;
|
||||
long hdatalen = 0;
|
||||
void *hdata;
|
||||
|
||||
EVP_MD_CTX *mctx = EVP_MD_CTX_new();
|
||||
|
||||
if (mctx == NULL) {
|
||||
SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, ERR_R_MALLOC_FAILURE);
|
||||
al = SSL_AD_INTERNAL_ERROR;
|
||||
goto f_err;
|
||||
}
|
||||
|
||||
peer = s->session->peer;
|
||||
pkey = X509_get0_pubkey(peer);
|
||||
type = X509_certificate_type(peer, pkey);
|
||||
|
||||
if (!(type & EVP_PKT_SIGN)) {
|
||||
SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY,
|
||||
SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE);
|
||||
al = SSL_AD_ILLEGAL_PARAMETER;
|
||||
goto f_err;
|
||||
}
|
||||
|
||||
/* Check for broken implementations of GOST ciphersuites */
|
||||
/*
|
||||
* If key is GOST and n is exactly 64, it is bare signature without
|
||||
* length field (CryptoPro implementations at least till CSP 4.0)
|
||||
*/
|
||||
#ifndef OPENSSL_NO_GOST
|
||||
if (PACKET_remaining(pkt) == 64
|
||||
&& EVP_PKEY_id(pkey) == NID_id_GostR3410_2001) {
|
||||
len = 64;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
if (SSL_USE_SIGALGS(s)) {
|
||||
int rv;
|
||||
|
||||
if (!PACKET_get_bytes(pkt, &sig, 2)) {
|
||||
al = SSL_AD_DECODE_ERROR;
|
||||
goto f_err;
|
||||
}
|
||||
rv = tls12_check_peer_sigalg(&md, s, sig, pkey);
|
||||
if (rv == -1) {
|
||||
al = SSL_AD_INTERNAL_ERROR;
|
||||
goto f_err;
|
||||
} else if (rv == 0) {
|
||||
al = SSL_AD_DECODE_ERROR;
|
||||
goto f_err;
|
||||
}
|
||||
#ifdef SSL_DEBUG
|
||||
fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md));
|
||||
#endif
|
||||
} else {
|
||||
/* Use default digest for this key type */
|
||||
int idx = ssl_cert_type(NULL, pkey);
|
||||
if (idx >= 0)
|
||||
md = s->s3->tmp.md[idx];
|
||||
if (md == NULL) {
|
||||
al = SSL_AD_INTERNAL_ERROR;
|
||||
goto f_err;
|
||||
}
|
||||
}
|
||||
|
||||
if (!PACKET_get_net_2(pkt, &len)) {
|
||||
SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, SSL_R_LENGTH_MISMATCH);
|
||||
al = SSL_AD_DECODE_ERROR;
|
||||
goto f_err;
|
||||
}
|
||||
}
|
||||
j = EVP_PKEY_size(pkey);
|
||||
if (((int)len > j) || ((int)PACKET_remaining(pkt) > j)
|
||||
|| (PACKET_remaining(pkt) == 0)) {
|
||||
SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, SSL_R_WRONG_SIGNATURE_SIZE);
|
||||
al = SSL_AD_DECODE_ERROR;
|
||||
goto f_err;
|
||||
}
|
||||
if (!PACKET_get_bytes(pkt, &data, len)) {
|
||||
SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, SSL_R_LENGTH_MISMATCH);
|
||||
al = SSL_AD_DECODE_ERROR;
|
||||
goto f_err;
|
||||
}
|
||||
|
||||
hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata);
|
||||
if (hdatalen <= 0) {
|
||||
SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, ERR_R_INTERNAL_ERROR);
|
||||
al = SSL_AD_INTERNAL_ERROR;
|
||||
goto f_err;
|
||||
}
|
||||
|
||||
#ifdef SSL_DEBUG
|
||||
fprintf(stderr, "Using 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_TLS_PROCESS_CERT_VERIFY, ERR_R_EVP_LIB);
|
||||
al = SSL_AD_INTERNAL_ERROR;
|
||||
goto f_err;
|
||||
}
|
||||
#ifndef OPENSSL_NO_GOST
|
||||
{
|
||||
int pktype = EVP_PKEY_id(pkey);
|
||||
if (pktype == NID_id_GostR3410_2001
|
||||
|| pktype == NID_id_GostR3410_2012_256
|
||||
|| pktype == NID_id_GostR3410_2012_512) {
|
||||
if ((gost_data = OPENSSL_malloc(len)) == NULL) {
|
||||
SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, ERR_R_MALLOC_FAILURE);
|
||||
al = SSL_AD_INTERNAL_ERROR;
|
||||
goto f_err;
|
||||
}
|
||||
BUF_reverse(gost_data, data, len);
|
||||
data = gost_data;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (s->version == SSL3_VERSION
|
||||
&& !EVP_MD_CTX_ctrl(mctx, EVP_CTRL_SSL3_MASTER_SECRET,
|
||||
(int)s->session->master_key_length,
|
||||
s->session->master_key)) {
|
||||
SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, ERR_R_EVP_LIB);
|
||||
al = SSL_AD_INTERNAL_ERROR;
|
||||
goto f_err;
|
||||
}
|
||||
|
||||
if (EVP_VerifyFinal(mctx, data, len, pkey) <= 0) {
|
||||
al = SSL_AD_DECRYPT_ERROR;
|
||||
SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, SSL_R_BAD_SIGNATURE);
|
||||
goto f_err;
|
||||
}
|
||||
|
||||
ret = MSG_PROCESS_CONTINUE_PROCESSING;
|
||||
if (0) {
|
||||
f_err:
|
||||
ssl3_send_alert(s, SSL3_AL_FATAL, al);
|
||||
ossl_statem_set_error(s);
|
||||
}
|
||||
BIO_free(s->s3->handshake_buffer);
|
||||
s->s3->handshake_buffer = NULL;
|
||||
EVP_MD_CTX_free(mctx);
|
||||
#ifndef OPENSSL_NO_GOST
|
||||
OPENSSL_free(gost_data);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
MSG_PROCESS_RETURN tls_process_client_certificate(SSL *s, PACKET *pkt)
|
||||
{
|
||||
int i, al = SSL_AD_INTERNAL_ERROR, ret = MSG_PROCESS_ERROR;
|
||||
|
Loading…
x
Reference in New Issue
Block a user