diff options
author | Arne Schwabe <arne@rfc2549.org> | 2014-06-05 18:34:09 +0200 |
---|---|---|
committer | Arne Schwabe <arne@rfc2549.org> | 2014-06-05 18:34:09 +0200 |
commit | 626c2706b1f7abdc6af1216873b7687e59025d1f (patch) | |
tree | 0617ebb1e49364082071482aa9a977dd1da45940 /main/openssl/ssl/s3_srvr.c | |
parent | 614b8790e5fc0bb3864eb2e3dd8c15016333d016 (diff) |
Update OpenSSL to aosp/masterc0.6.13
--HG--
extra : rebase_source : a2f70c1a7529c7fcfc88f8dd1882e66e6ba42167
Diffstat (limited to 'main/openssl/ssl/s3_srvr.c')
-rw-r--r-- | main/openssl/ssl/s3_srvr.c | 540 |
1 files changed, 293 insertions, 247 deletions
diff --git a/main/openssl/ssl/s3_srvr.c b/main/openssl/ssl/s3_srvr.c index 8692f149..0ee781f1 100644 --- a/main/openssl/ssl/s3_srvr.c +++ b/main/openssl/ssl/s3_srvr.c @@ -217,6 +217,7 @@ int ssl3_accept(SSL *s) { BUF_MEM *buf; unsigned long alg_k,Time=(unsigned long)time(NULL); + unsigned long alg_a; void (*cb)(const SSL *ssl,int type,int val)=NULL; int ret= -1; int new_state,state,skip=0; @@ -412,9 +413,11 @@ int ssl3_accept(SSL *s) case SSL3_ST_SW_CERT_A: case SSL3_ST_SW_CERT_B: /* Check if it is anon DH or anon ECDH, */ - /* normal PSK or KRB5 or SRP */ + /* non-RSA PSK or KRB5 or SRP */ if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) - && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK) + /* Among PSK ciphersuites only RSA_PSK uses server certificate */ + && !(s->s3->tmp.new_cipher->algorithm_auth & SSL_aPSK && + !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kRSA)) && !(s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5)) { ret=ssl3_send_server_certificate(s); @@ -443,6 +446,7 @@ int ssl3_accept(SSL *s) case SSL3_ST_SW_KEY_EXCH_A: case SSL3_ST_SW_KEY_EXCH_B: alg_k = s->s3->tmp.new_cipher->algorithm_mkey; + alg_a = s->s3->tmp.new_cipher->algorithm_auth; /* clear this, it may get reset by * send_server_key_exchange */ @@ -472,10 +476,12 @@ int ssl3_accept(SSL *s) * public key for key exchange. */ if (s->s3->tmp.use_rsa_tmp - /* PSK: send ServerKeyExchange if PSK identity - * hint if provided */ + /* PSK: send ServerKeyExchange if either: + * - PSK identity hint is provided, or + * - the key exchange is kEECDH. + */ #ifndef OPENSSL_NO_PSK - || ((alg_k & SSL_kPSK) && s->ctx->psk_identity_hint) + || ((alg_a & SSL_aPSK) && ((alg_k & SSL_kEECDH) || s->session->psk_identity_hint)) #endif #ifndef OPENSSL_NO_SRP /* SRP: send ServerKeyExchange */ @@ -1589,11 +1595,16 @@ int ssl3_send_server_key_exchange(SSL *s) int curve_id = 0; BN_CTX *bn_ctx = NULL; #endif +#ifndef OPENSSL_NO_PSK + const char* psk_identity_hint; + size_t psk_identity_hint_len; +#endif EVP_PKEY *pkey; const EVP_MD *md = NULL; unsigned char *p,*d; int al,i; - unsigned long type; + unsigned long alg_k; + unsigned long alg_a; int n; CERT *cert; BIGNUM *r[4]; @@ -1604,15 +1615,28 @@ int ssl3_send_server_key_exchange(SSL *s) EVP_MD_CTX_init(&md_ctx); if (s->state == SSL3_ST_SW_KEY_EXCH_A) { - type=s->s3->tmp.new_cipher->algorithm_mkey; + alg_k=s->s3->tmp.new_cipher->algorithm_mkey; + alg_a=s->s3->tmp.new_cipher->algorithm_auth; cert=s->cert; buf=s->init_buf; r[0]=r[1]=r[2]=r[3]=NULL; n=0; +#ifndef OPENSSL_NO_PSK + if (alg_a & SSL_aPSK) + { + /* size for PSK identity hint */ + psk_identity_hint = s->session->psk_identity_hint; + if (psk_identity_hint) + psk_identity_hint_len = strlen(psk_identity_hint); + else + psk_identity_hint_len = 0; + n+=2+psk_identity_hint_len; + } +#endif /* !OPENSSL_NO_PSK */ #ifndef OPENSSL_NO_RSA - if (type & SSL_kRSA) + if (alg_k & SSL_kRSA) { rsa=cert->rsa_tmp; if ((rsa == NULL) && (s->cert->rsa_tmp_cb != NULL)) @@ -1639,10 +1663,9 @@ int ssl3_send_server_key_exchange(SSL *s) r[1]=rsa->e; s->s3->tmp.use_rsa_tmp=1; } - else #endif #ifndef OPENSSL_NO_DH - if (type & SSL_kEDH) + else if (alg_k & SSL_kEDH) { dhp=cert->dh_tmp; if ((dhp == NULL) && (s->cert->dh_tmp_cb != NULL)) @@ -1695,10 +1718,9 @@ int ssl3_send_server_key_exchange(SSL *s) r[1]=dh->g; r[2]=dh->pub_key; } - else #endif #ifndef OPENSSL_NO_ECDH - if (type & SSL_kEECDH) + else if (alg_k & SSL_kEECDH) { const EC_GROUP *group; @@ -1811,7 +1833,7 @@ int ssl3_send_server_key_exchange(SSL *s) * to encode the entire ServerECDHParams * structure. */ - n = 4 + encodedlen; + n += 4 + encodedlen; /* We'll generate the serverKeyExchange message * explicitly so we can set these to NULLs @@ -1821,18 +1843,9 @@ int ssl3_send_server_key_exchange(SSL *s) r[2]=NULL; r[3]=NULL; } - else #endif /* !OPENSSL_NO_ECDH */ -#ifndef OPENSSL_NO_PSK - if (type & SSL_kPSK) - { - /* reserve size for record length and PSK identity hint*/ - n+=2+strlen(s->ctx->psk_identity_hint); - } - else -#endif /* !OPENSSL_NO_PSK */ #ifndef OPENSSL_NO_SRP - if (type & SSL_kSRP) + else if (alg_k & SSL_kSRP) { if ((s->srp_ctx.N == NULL) || (s->srp_ctx.g == NULL) || @@ -1847,8 +1860,8 @@ int ssl3_send_server_key_exchange(SSL *s) r[2]=s->srp_ctx.s; r[3]=s->srp_ctx.B; } - else #endif + else if (!(alg_k & SSL_kPSK)) { al=SSL_AD_HANDSHAKE_FAILURE; SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE); @@ -1858,15 +1871,16 @@ int ssl3_send_server_key_exchange(SSL *s) { nr[i]=BN_num_bytes(r[i]); #ifndef OPENSSL_NO_SRP - if ((i == 2) && (type & SSL_kSRP)) + if ((i == 2) && (alg_k & SSL_kSRP)) n+=1+nr[i]; else #endif n+=2+nr[i]; } - if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) - && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) + if (!(alg_a & SSL_aNULL) + /* Among PSK ciphersuites only RSA uses a certificate */ + && !((alg_a & SSL_aPSK) && !(alg_k & SSL_kRSA))) { if ((pkey=ssl_get_sign_pkey(s,s->s3->tmp.new_cipher,&md)) == NULL) @@ -1893,7 +1907,7 @@ int ssl3_send_server_key_exchange(SSL *s) for (i=0; i < 4 && r[i] != NULL; i++) { #ifndef OPENSSL_NO_SRP - if ((i == 2) && (type & SSL_kSRP)) + if ((i == 2) && (alg_k & SSL_kSRP)) { *p = nr[i]; p++; @@ -1905,8 +1919,24 @@ int ssl3_send_server_key_exchange(SSL *s) p+=nr[i]; } +/* Note: ECDHE PSK ciphersuites use SSL_kEECDH and SSL_aPSK. + * When one of them is used, the server key exchange record needs to have both + * the psk_identity_hint and the ServerECDHParams. */ +#ifndef OPENSSL_NO_PSK + if (alg_a & SSL_aPSK) + { + /* copy PSK identity hint (if provided) */ + s2n(psk_identity_hint_len, p); + if (psk_identity_hint_len > 0) + { + memcpy(p, psk_identity_hint, psk_identity_hint_len); + p+=psk_identity_hint_len; + } + } +#endif /* OPENSSL_NO_PSK */ + #ifndef OPENSSL_NO_ECDH - if (type & SSL_kEECDH) + if (alg_k & SSL_kEECDH) { /* XXX: For now, we only support named (not generic) curves. * In this situation, the serverKeyExchange message has: @@ -1929,17 +1959,7 @@ int ssl3_send_server_key_exchange(SSL *s) encodedPoint = NULL; p += encodedlen; } -#endif - -#ifndef OPENSSL_NO_PSK - if (type & SSL_kPSK) - { - /* copy PSK identity hint */ - s2n(strlen(s->ctx->psk_identity_hint), p); - strncpy((char *)p, s->ctx->psk_identity_hint, strlen(s->ctx->psk_identity_hint)); - p+=strlen(s->ctx->psk_identity_hint); - } -#endif +#endif /* OPENSSL_NO_ECDH */ /* not anonymous */ if (pkey != NULL) @@ -1976,7 +1996,7 @@ int ssl3_send_server_key_exchange(SSL *s) n+=u+2; } else -#endif +#endif /* OPENSSL_NO_RSA */ if (md) { /* For TLS1.2 and later send signature @@ -2145,6 +2165,7 @@ int ssl3_get_client_key_exchange(SSL *s) int i,al,ok; long n; unsigned long alg_k; + unsigned long alg_a; unsigned char *p; #ifndef OPENSSL_NO_RSA RSA *rsa=NULL; @@ -2162,7 +2183,11 @@ int ssl3_get_client_key_exchange(SSL *s) EC_KEY *srvr_ecdh = NULL; EVP_PKEY *clnt_pub_pkey = NULL; EC_POINT *clnt_ecpoint = NULL; - BN_CTX *bn_ctx = NULL; + BN_CTX *bn_ctx = NULL; +#ifndef OPENSSL_NO_PSK + unsigned int psk_len = 0; + unsigned char psk[PSK_MAX_PSK_LEN]; +#endif /* OPENSSL_NO_PSK */ #endif n=s->method->ssl_get_message(s, @@ -2176,7 +2201,95 @@ int ssl3_get_client_key_exchange(SSL *s) p=(unsigned char *)s->init_msg; alg_k=s->s3->tmp.new_cipher->algorithm_mkey; + alg_a=s->s3->tmp.new_cipher->algorithm_auth; +#ifndef OPENSSL_NO_PSK + if (alg_a & SSL_aPSK) + { + unsigned char *t = NULL; + unsigned char pre_ms[PSK_MAX_PSK_LEN*2+4]; + unsigned int pre_ms_len = 0; + int psk_err = 1; + char tmp_id[PSK_MAX_IDENTITY_LEN+1]; + + al=SSL_AD_HANDSHAKE_FAILURE; + + n2s(p, i); + if (n != i+2 && !(alg_k & SSL_kEECDH)) + { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_LENGTH_MISMATCH); + goto psk_err; + } + if (i > PSK_MAX_IDENTITY_LEN) + { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_DATA_LENGTH_TOO_LONG); + goto psk_err; + } + if (s->psk_server_callback == NULL) + { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_PSK_NO_SERVER_CB); + goto psk_err; + } + + /* Create guaranteed NUL-terminated identity + * string for the callback */ + memcpy(tmp_id, p, i); + memset(tmp_id+i, 0, PSK_MAX_IDENTITY_LEN+1-i); + psk_len = s->psk_server_callback(s, tmp_id, psk, sizeof(psk)); + + if (psk_len > PSK_MAX_PSK_LEN) + { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto psk_err; + } + else if (psk_len == 0) + { + /* PSK related to the given identity not found */ + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_PSK_IDENTITY_NOT_FOUND); + al=SSL_AD_UNKNOWN_PSK_IDENTITY; + goto psk_err; + } + if (!(alg_k & SSL_kEECDH)) + { + /* Create the shared secret now if we're not using ECDHE-PSK.*/ + pre_ms_len=2+psk_len+2+psk_len; + t = pre_ms; + s2n(psk_len, t); + memset(t, 0, psk_len); + t+=psk_len; + s2n(psk_len, t); + memcpy(t, psk, psk_len); + + s->session->master_key_length= + s->method->ssl3_enc->generate_master_secret(s, + s->session->master_key, pre_ms, pre_ms_len); + } + if (s->session->psk_identity != NULL) + OPENSSL_free(s->session->psk_identity); + s->session->psk_identity = BUF_strdup(tmp_id); + OPENSSL_cleanse(tmp_id, PSK_MAX_IDENTITY_LEN+1); + if (s->session->psk_identity == NULL) + { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + ERR_R_MALLOC_FAILURE); + goto psk_err; + } + + p += i; + n -= (i + 2); + psk_err = 0; + psk_err: + OPENSSL_cleanse(pre_ms, sizeof(pre_ms)); + if (psk_err != 0) + goto f_err; + } +#endif /* OPENSSL_NO_PSK */ + if (0) {} #ifndef OPENSSL_NO_RSA if (alg_k & SSL_kRSA) { @@ -2281,10 +2394,9 @@ int ssl3_get_client_key_exchange(SSL *s) p,i); OPENSSL_cleanse(p,i); } - else #endif #ifndef OPENSSL_NO_DH - if (alg_k & (SSL_kEDH|SSL_kDHr|SSL_kDHd)) + else if (alg_k & (SSL_kEDH|SSL_kDHr|SSL_kDHd)) { n2s(p,i); if (n != i+2) @@ -2345,10 +2457,9 @@ int ssl3_get_client_key_exchange(SSL *s) s->session->master_key,p,i); OPENSSL_cleanse(p,i); } - else #endif #ifndef OPENSSL_NO_KRB5 - if (alg_k & SSL_kKRB5) + else if (alg_k & SSL_kKRB5) { krb5_error_code krb5rc; krb5_data enc_ticket; @@ -2537,17 +2648,20 @@ int ssl3_get_client_key_exchange(SSL *s) ** if (s->kssl_ctx) s->kssl_ctx = NULL; */ } - else #endif /* OPENSSL_NO_KRB5 */ - #ifndef OPENSSL_NO_ECDH - if (alg_k & (SSL_kEECDH|SSL_kECDHr|SSL_kECDHe)) + else if (alg_k & (SSL_kEECDH|SSL_kECDHr|SSL_kECDHe)) { int ret = 1; int field_size = 0; const EC_KEY *tkey; const EC_GROUP *group; const BIGNUM *priv_key; +#ifndef OPENSSL_NO_PSK + unsigned char *pre_ms; + unsigned int pre_ms_len; + unsigned char *t; +#endif /* OPENSSL_NO_PSK */ /* initialize structures for server's ECDH key pair */ if ((srvr_ecdh = EC_KEY_new()) == NULL) @@ -2643,7 +2757,7 @@ int ssl3_get_client_key_exchange(SSL *s) } /* Get encoded point length */ - i = *p; + i = *p; p += 1; if (n != 1 + i) { @@ -2685,223 +2799,155 @@ int ssl3_get_client_key_exchange(SSL *s) EC_KEY_free(srvr_ecdh); BN_CTX_free(bn_ctx); EC_KEY_free(s->s3->tmp.ecdh); - s->s3->tmp.ecdh = NULL; + s->s3->tmp.ecdh = NULL; - /* Compute the master secret */ - s->session->master_key_length = s->method->ssl3_enc-> \ - generate_master_secret(s, s->session->master_key, p, i); - - OPENSSL_cleanse(p, i); - return (ret); - } - else -#endif #ifndef OPENSSL_NO_PSK - if (alg_k & SSL_kPSK) + /* ECDHE PSK ciphersuites from RFC 5489 */ + if ((alg_a & SSL_aPSK) && psk_len != 0) { - unsigned char *t = NULL; - unsigned char psk_or_pre_ms[PSK_MAX_PSK_LEN*2+4]; - unsigned int pre_ms_len = 0, psk_len = 0; - int psk_err = 1; - char tmp_id[PSK_MAX_IDENTITY_LEN+1]; - - al=SSL_AD_HANDSHAKE_FAILURE; - - n2s(p,i); - if (n != i+2) - { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_LENGTH_MISMATCH); - goto psk_err; - } - if (i > PSK_MAX_IDENTITY_LEN) - { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_DATA_LENGTH_TOO_LONG); - goto psk_err; - } - if (s->psk_server_callback == NULL) - { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_PSK_NO_SERVER_CB); - goto psk_err; - } - - /* Create guaranteed NULL-terminated identity - * string for the callback */ - memcpy(tmp_id, p, i); - memset(tmp_id+i, 0, PSK_MAX_IDENTITY_LEN+1-i); - psk_len = s->psk_server_callback(s, tmp_id, - psk_or_pre_ms, sizeof(psk_or_pre_ms)); - OPENSSL_cleanse(tmp_id, PSK_MAX_IDENTITY_LEN+1); - - if (psk_len > PSK_MAX_PSK_LEN) - { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); - goto psk_err; - } - else if (psk_len == 0) - { - /* PSK related to the given identity not found */ - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_PSK_IDENTITY_NOT_FOUND); - al=SSL_AD_UNKNOWN_PSK_IDENTITY; - goto psk_err; - } - - /* create PSK pre_master_secret */ - pre_ms_len=2+psk_len+2+psk_len; - t = psk_or_pre_ms; - memmove(psk_or_pre_ms+psk_len+4, psk_or_pre_ms, psk_len); - s2n(psk_len, t); - memset(t, 0, psk_len); - t+=psk_len; - s2n(psk_len, t); - - if (s->session->psk_identity != NULL) - OPENSSL_free(s->session->psk_identity); - s->session->psk_identity = BUF_strdup((char *)p); - if (s->session->psk_identity == NULL) - { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - ERR_R_MALLOC_FAILURE); - goto psk_err; - } - - if (s->session->psk_identity_hint != NULL) - OPENSSL_free(s->session->psk_identity_hint); - s->session->psk_identity_hint = BUF_strdup(s->ctx->psk_identity_hint); - if (s->ctx->psk_identity_hint != NULL && - s->session->psk_identity_hint == NULL) + pre_ms_len = 2+psk_len+2+i; + pre_ms = OPENSSL_malloc(pre_ms_len); + if (pre_ms == NULL) { SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); - goto psk_err; + goto err; } - - s->session->master_key_length= - s->method->ssl3_enc->generate_master_secret(s, - s->session->master_key, psk_or_pre_ms, pre_ms_len); - psk_err = 0; - psk_err: - OPENSSL_cleanse(psk_or_pre_ms, sizeof(psk_or_pre_ms)); - if (psk_err != 0) - goto f_err; + memset(pre_ms, 0, pre_ms_len); + t = pre_ms; + s2n(psk_len, t); + memcpy(t, psk, psk_len); + t += psk_len; + s2n(i, t); + memcpy(t, p, i); + s->session->master_key_length = s->method->ssl3_enc \ + -> generate_master_secret(s, + s->session->master_key, pre_ms, pre_ms_len); + OPENSSL_cleanse(pre_ms, pre_ms_len); + OPENSSL_free(pre_ms); } - else +#endif /* OPENSSL_NO_PSK */ + if (!(alg_a & SSL_aPSK)) + { + /* Compute the master secret */ + s->session->master_key_length = s->method->ssl3_enc \ + -> generate_master_secret(s, + s->session->master_key, p, i); + } + + OPENSSL_cleanse(p, i); + } #endif #ifndef OPENSSL_NO_SRP - if (alg_k & SSL_kSRP) + else if (alg_k & SSL_kSRP) + { + int param_len; + + n2s(p,i); + param_len=i+2; + if (param_len > n) + { + al=SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_BAD_SRP_A_LENGTH); + goto f_err; + } + if (!(s->srp_ctx.A=BN_bin2bn(p,i,NULL))) { - int param_len; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,ERR_R_BN_LIB); + goto err; + } + if (s->session->srp_username != NULL) + OPENSSL_free(s->session->srp_username); + s->session->srp_username = BUF_strdup(s->srp_ctx.login); + if (s->session->srp_username == NULL) + { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + ERR_R_MALLOC_FAILURE); + goto err; + } - n2s(p,i); - param_len=i+2; - if (param_len > n) - { - al=SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_BAD_SRP_A_LENGTH); - goto f_err; - } - if (!(s->srp_ctx.A=BN_bin2bn(p,i,NULL))) - { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,ERR_R_BN_LIB); - goto err; - } - if (s->session->srp_username != NULL) - OPENSSL_free(s->session->srp_username); - s->session->srp_username = BUF_strdup(s->srp_ctx.login); - if (s->session->srp_username == NULL) - { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - ERR_R_MALLOC_FAILURE); - goto err; - } + if ((s->session->master_key_length = SRP_generate_server_master_secret(s,s->session->master_key))<0) + { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR); + goto err; + } - if ((s->session->master_key_length = SRP_generate_server_master_secret(s,s->session->master_key))<0) - { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR); - goto err; - } + p+=i; + } +#endif /* OPENSSL_NO_SRP */ + else if (alg_k & SSL_kGOST) + { + int ret = 0; + EVP_PKEY_CTX *pkey_ctx; + EVP_PKEY *client_pub_pkey = NULL, *pk = NULL; + unsigned char premaster_secret[32], *start; + size_t outlen=32, inlen; + unsigned long alg_a; + + /* Get our certificate private key*/ + alg_a = s->s3->tmp.new_cipher->algorithm_auth; + if (alg_a & SSL_aGOST94) + pk = s->cert->pkeys[SSL_PKEY_GOST94].privatekey; + else if (alg_a & SSL_aGOST01) + pk = s->cert->pkeys[SSL_PKEY_GOST01].privatekey; - p+=i; + pkey_ctx = EVP_PKEY_CTX_new(pk,NULL); + EVP_PKEY_decrypt_init(pkey_ctx); + /* If client certificate is present and is of the same type, maybe + * use it for key exchange. Don't mind errors from + * EVP_PKEY_derive_set_peer, because it is completely valid to use + * a client certificate for authorization only. */ + client_pub_pkey = X509_get_pubkey(s->session->peer); + if (client_pub_pkey) + { + if (EVP_PKEY_derive_set_peer(pkey_ctx, client_pub_pkey) <= 0) + ERR_clear_error(); + } + /* Decrypt session key */ + if ((*p!=( V_ASN1_SEQUENCE| V_ASN1_CONSTRUCTED))) + { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_DECRYPTION_FAILED); + goto gerr; + } + if (p[1] == 0x81) + { + start = p+3; + inlen = p[2]; + } + else if (p[1] < 0x80) + { + start = p+2; + inlen = p[1]; } else -#endif /* OPENSSL_NO_SRP */ - if (alg_k & SSL_kGOST) { - int ret = 0; - EVP_PKEY_CTX *pkey_ctx; - EVP_PKEY *client_pub_pkey = NULL, *pk = NULL; - unsigned char premaster_secret[32], *start; - size_t outlen=32, inlen; - unsigned long alg_a; - - /* Get our certificate private key*/ - alg_a = s->s3->tmp.new_cipher->algorithm_auth; - if (alg_a & SSL_aGOST94) - pk = s->cert->pkeys[SSL_PKEY_GOST94].privatekey; - else if (alg_a & SSL_aGOST01) - pk = s->cert->pkeys[SSL_PKEY_GOST01].privatekey; - - pkey_ctx = EVP_PKEY_CTX_new(pk,NULL); - EVP_PKEY_decrypt_init(pkey_ctx); - /* If client certificate is present and is of the same type, maybe - * use it for key exchange. Don't mind errors from - * EVP_PKEY_derive_set_peer, because it is completely valid to use - * a client certificate for authorization only. */ - client_pub_pkey = X509_get_pubkey(s->session->peer); - if (client_pub_pkey) - { - if (EVP_PKEY_derive_set_peer(pkey_ctx, client_pub_pkey) <= 0) - ERR_clear_error(); - } - /* Decrypt session key */ - if ((*p!=( V_ASN1_SEQUENCE| V_ASN1_CONSTRUCTED))) - { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_DECRYPTION_FAILED); - goto gerr; - } - if (p[1] == 0x81) - { - start = p+3; - inlen = p[2]; - } - else if (p[1] < 0x80) - { - start = p+2; - inlen = p[1]; - } - else - { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_DECRYPTION_FAILED); - goto gerr; - } - if (EVP_PKEY_decrypt(pkey_ctx,premaster_secret,&outlen,start,inlen) <=0) + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_DECRYPTION_FAILED); + goto gerr; + } + if (EVP_PKEY_decrypt(pkey_ctx,premaster_secret,&outlen,start,inlen) <=0) - { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_DECRYPTION_FAILED); - goto gerr; - } - /* Generate master secret */ - s->session->master_key_length= - s->method->ssl3_enc->generate_master_secret(s, - s->session->master_key,premaster_secret,32); - /* Check if pubkey from client certificate was used */ - if (EVP_PKEY_CTX_ctrl(pkey_ctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 2, NULL) > 0) - ret = 2; - else - ret = 1; - gerr: - EVP_PKEY_free(client_pub_pkey); - EVP_PKEY_CTX_free(pkey_ctx); - if (ret) - return ret; - else - goto err; + { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_DECRYPTION_FAILED); + goto gerr; } + /* Generate master secret */ + s->session->master_key_length= + s->method->ssl3_enc->generate_master_secret(s, + s->session->master_key,premaster_secret,32); + /* Check if pubkey from client certificate was used */ + if (EVP_PKEY_CTX_ctrl(pkey_ctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 2, NULL) > 0) + ret = 2; + else + ret = 1; + gerr: + EVP_PKEY_free(client_pub_pkey); + EVP_PKEY_CTX_free(pkey_ctx); + if (ret) + return ret; else + goto err; + } + else if (!(alg_k & SSL_kPSK)) { al=SSL_AD_HANDSHAKE_FAILURE; SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, |