s->s3->tmp.new_cipher = s->session->cipher;
}
- if (!SSL_USE_SIGALGS(s) || !(s->verify_mode & SSL_VERIFY_PEER)) {
+ if (!(s->verify_mode & SSL_VERIFY_PEER)) {
if (!ssl3_digest_cached_records(s, 0)) {
al = SSL_AD_INTERNAL_ERROR;
goto f_err;
int tls_construct_server_key_exchange(SSL *s)
{
#ifndef OPENSSL_NO_RSA
- unsigned char *q;
- int j, num;
RSA *rsa;
- unsigned char md_buf[MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH];
- unsigned int u;
#endif
#ifndef OPENSSL_NO_DH
DH *dh = NULL, *dhp;
* n is the length of the params, they start at &(d[4]) and p
* points to the space at the end.
*/
-#ifndef OPENSSL_NO_RSA
- if (pkey->type == EVP_PKEY_RSA && !SSL_USE_SIGALGS(s)) {
- q = md_buf;
- j = 0;
- for (num = 2; num > 0; num--) {
- EVP_MD_CTX_set_flags(&md_ctx,
- EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
- EVP_DigestInit_ex(&md_ctx, (num == 2)
- ? s->ctx->md5 : s->ctx->sha1, NULL);
- EVP_DigestUpdate(&md_ctx, &(s->s3->client_random[0]),
- SSL3_RANDOM_SIZE);
- EVP_DigestUpdate(&md_ctx, &(s->s3->server_random[0]),
- SSL3_RANDOM_SIZE);
- EVP_DigestUpdate(&md_ctx, d, n);
- EVP_DigestFinal_ex(&md_ctx, q, (unsigned int *)&i);
- q += i;
- j += i;
- }
- if (RSA_sign(NID_md5_sha1, md_buf, j,
- &(p[2]), &u, pkey->pkey.rsa) <= 0) {
- SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, ERR_LIB_RSA);
- goto err;
- }
- s2n(u, p);
- n += u + 2;
- } else
-#endif
if (md) {
/* send signature algorithm */
if (SSL_USE_SIGALGS(s)) {
#ifdef SSL_DEBUG
fprintf(stderr, "Using hash %s\n", EVP_MD_name(md));
#endif
- EVP_SignInit_ex(&md_ctx, md, NULL);
- EVP_SignUpdate(&md_ctx, &(s->s3->client_random[0]),
- SSL3_RANDOM_SIZE);
- EVP_SignUpdate(&md_ctx, &(s->s3->server_random[0]),
- SSL3_RANDOM_SIZE);
- EVP_SignUpdate(&md_ctx, d, n);
- if (!EVP_SignFinal(&md_ctx, &(p[2]),
- (unsigned int *)&i, pkey)) {
+ if (EVP_SignInit_ex(&md_ctx, md, NULL) <= 0
+ || EVP_SignUpdate(&md_ctx, &(s->s3->client_random[0]),
+ SSL3_RANDOM_SIZE) <= 0
+ || EVP_SignUpdate(&md_ctx, &(s->s3->server_random[0]),
+ SSL3_RANDOM_SIZE) <= 0
+ || EVP_SignUpdate(&md_ctx, d, n) <= 0
+ || EVP_SignFinal(&md_ctx, &(p[2]),
+ (unsigned int *)&i, pkey) <= 0) {
SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, ERR_LIB_EVP);
- goto err;
+ al = SSL_AD_INTERNAL_ERROR;
+ goto f_err;
}
s2n(i, p);
n += i + 2;
/* Get our certificate private key */
alg_a = s->s3->tmp.new_cipher->algorithm_auth;
- if (alg_a & SSL_aGOST01)
+ if (alg_a & SSL_aGOST12) {
+ /*
+ * New GOST ciphersuites have SSL_aGOST01 bit too
+ */
+ pk = s->cert->pkeys[SSL_PKEY_GOST12_512].privatekey;
+ if (pk == NULL) {
+ pk = s->cert->pkeys[SSL_PKEY_GOST12_256].privatekey;
+ }
+ if (pk == NULL) {
+ pk = s->cert->pkeys[SSL_PKEY_GOST01].privatekey;
+ }
+ } else if (alg_a & SSL_aGOST01) {
pk = s->cert->pkeys[SSL_PKEY_GOST01].privatekey;
+ }
pkey_ctx = EVP_PKEY_CTX_new(pk, NULL);
if (pkey_ctx == NULL) {
SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE);
goto f_err;
}
- EVP_PKEY_decrypt_init(pkey_ctx);
+ if (EVP_PKEY_decrypt_init(pkey_ctx) <= 0) {
+ al = SSL_AD_INTERNAL_ERROR;
+ SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
+ goto f_err;
+ }
/*
* If client certificate is present and is of the same type, maybe
* use it for key exchange. Don't mind errors from
if (!PACKET_get_bytes(pkt, &data, sess_key_len)) {
al = SSL_AD_INTERNAL_ERROR;
SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
- goto f_err;
+ goto gerr;
}
if (ASN1_get_object ((const unsigned char **)&data, &Tlen, &Ttag,
&Tclass, sess_key_len) != V_ASN1_CONSTRUCTED
|| Ttag != V_ASN1_SEQUENCE
|| Tclass != V_ASN1_UNIVERSAL) {
+ al = SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE,
SSL_R_DECRYPTION_FAILED);
goto gerr;
inlen = Tlen;
if (EVP_PKEY_decrypt
(pkey_ctx, premaster_secret, &outlen, start, inlen) <= 0) {
+ al = SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE,
SSL_R_DECRYPTION_FAILED);
goto gerr;
sizeof(premaster_secret), 0)) {
al = SSL_AD_INTERNAL_ERROR;
SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
- goto f_err;
+ goto gerr;
}
/* Check if pubkey from client certificate was used */
if (EVP_PKEY_CTX_ctrl
gerr:
EVP_PKEY_free(client_pub_pkey);
EVP_PKEY_CTX_free(pkey_ctx);
- goto err;
+ goto f_err;
} else {
al = SSL_AD_HANDSHAKE_FAILURE;
SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, SSL_R_UNKNOWN_CIPHER_TYPE);
if (s->statem.no_cert_verify) {
/* No certificate verify so we no longer need the handshake_buffer */
BIO_free(s->s3->handshake_buffer);
+ s->s3->handshake_buffer = NULL;
return WORK_FINISHED_CONTINUE;
- } else if (SSL_USE_SIGALGS(s)) {
+ } else {
if (!s->session->peer) {
/* No peer certificate so we no longer need the handshake_buffer */
BIO_free(s->s3->handshake_buffer);
ossl_statem_set_error(s);
return WORK_ERROR;
}
- } else {
- int offset = 0;
- int dgst_num;
-
- /*
- * We need to get hashes here so if there is a client cert,
- * it can be verified FIXME - digest processing for
- * CertificateVerify should be generalized. But it is next
- * step
- */
- if (!ssl3_digest_cached_records(s, 0)) {
- ossl_statem_set_error(s);
- return WORK_ERROR;
- }
- for (dgst_num = 0; dgst_num < SSL_MAX_DIGEST; dgst_num++) {
- if (s->s3->handshake_dgst[dgst_num]) {
- int dgst_size;
-
- s->method->ssl3_enc->cert_verify_mac(s,
- EVP_MD_CTX_type
- (s->
- s3->handshake_dgst
- [dgst_num]),
- &(s->s3->
- tmp.cert_verify_md
- [offset]));
- dgst_size =
- EVP_MD_CTX_size(s->s3->handshake_dgst[dgst_num]);
- if (dgst_size < 0) {
- ossl_statem_set_error(s);
- return WORK_ERROR;
- }
- offset += dgst_size;
- }
- }
}
return WORK_FINISHED_CONTINUE;
EVP_PKEY *pkey = NULL;
unsigned char *sig, *data;
int al, ret = MSG_PROCESS_ERROR;
- int type = 0, i, j;
+ 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_init(&mctx);
/* Check for broken implementations of GOST ciphersuites */
/*
* If key is GOST and n is exactly 64, it is bare signature without
- * length field
+ * length field (CryptoPro implementations at least till CSP 4.0)
*/
if (PACKET_remaining(pkt) == 64 && pkey->type == NID_id_GostR3410_2001) {
len = 64;
#ifdef SSL_DEBUG
fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md));
#endif
+ } else if (pkey->type == EVP_PKEY_RSA) {
+ md = EVP_md5_sha1();
+ } else {
+ md = EVP_sha1();
}
if (!PACKET_get_net_2(pkt, &len)) {
SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, SSL_R_LENGTH_MISMATCH);
goto f_err;
}
- if (SSL_USE_SIGALGS(s)) {
- long hdatalen = 0;
- void *hdata;
- 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;
- }
+ 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 TLS 1.2 with client verify alg %s\n",
- EVP_MD_name(md));
+ 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;
- }
+ 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;
+ }
- 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;
- }
- } else
-#ifndef OPENSSL_NO_RSA
- if (pkey->type == EVP_PKEY_RSA) {
- i = RSA_verify(NID_md5_sha1, s->s3->tmp.cert_verify_md,
- MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH, data, len,
- pkey->pkey.rsa);
- if (i < 0) {
- al = SSL_AD_DECRYPT_ERROR;
- SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, SSL_R_BAD_RSA_DECRYPT);
- goto f_err;
- }
- if (i == 0) {
- al = SSL_AD_DECRYPT_ERROR;
- SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, SSL_R_BAD_RSA_SIGNATURE);
- goto f_err;
- }
- } else
-#endif
-#ifndef OPENSSL_NO_DSA
- if (pkey->type == EVP_PKEY_DSA) {
- j = DSA_verify(pkey->save_type,
- &(s->s3->tmp.cert_verify_md[MD5_DIGEST_LENGTH]),
- SHA_DIGEST_LENGTH, data, len, pkey->pkey.dsa);
- if (j <= 0) {
- /* bad signature */
- al = SSL_AD_DECRYPT_ERROR;
- SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, SSL_R_BAD_DSA_SIGNATURE);
- goto f_err;
+ if (pkey->type == NID_id_GostR3410_2001
+ || pkey->type == NID_id_GostR3410_2012_256
+ || pkey->type == NID_id_GostR3410_2012_512) {
+ unsigned int j1, j2;
+ for (j1 = len - 1, j2 = 0; j2 < len/2; j2++, j1--) {
+ char c = data[j2];
+ data[j2] = data[j1];
+ data[j1] = c;
}
- } else
-#endif
-#ifndef OPENSSL_NO_EC
- if (pkey->type == EVP_PKEY_EC) {
- j = ECDSA_verify(pkey->save_type,
- &(s->s3->tmp.cert_verify_md[MD5_DIGEST_LENGTH]),
- SHA_DIGEST_LENGTH, data, len, pkey->pkey.ec);
- if (j <= 0) {
- /* bad signature */
- al = SSL_AD_DECRYPT_ERROR;
- SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, SSL_R_BAD_ECDSA_SIGNATURE);
- goto f_err;
- }
- } else
-#endif
- if (pkey->type == NID_id_GostR3410_2001) {
- unsigned char signature[64];
- int idx;
- EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new(pkey, NULL);
- if (pctx == NULL) {
- al = SSL_AD_INTERNAL_ERROR;
- SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, ERR_R_MALLOC_FAILURE);
- goto f_err;
- }
- EVP_PKEY_verify_init(pctx);
- if (len != 64) {
- fprintf(stderr, "GOST signature length is %d", len);
- }
- for (idx = 0; idx < 64; idx++) {
- signature[63 - idx] = data[idx];
- }
- j = EVP_PKEY_verify(pctx, signature, 64, s->s3->tmp.cert_verify_md,
- 32);
- EVP_PKEY_CTX_free(pctx);
- if (j <= 0) {
- al = SSL_AD_DECRYPT_ERROR;
- SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, SSL_R_BAD_ECDSA_SIGNATURE);
- goto f_err;
- }
- } else {
- SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, ERR_R_INTERNAL_ERROR);
- al = SSL_AD_UNSUPPORTED_CERTIFICATE;
+ }
+
+ if (s->version == SSL3_VERSION
+ && !EVP_MD_CTX_ctrl(&mctx, EVP_CTRL_SSL3_MASTER_SECRET,
+ 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;
}