diff --git a/include/openssl/ssl3.h b/include/openssl/ssl3.h index 4edb6dfbe..665f2c633 100644 --- a/include/openssl/ssl3.h +++ b/include/openssl/ssl3.h @@ -341,7 +341,6 @@ typedef struct ssl3_buffer_st #define SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS 0x0001 #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 /* TODO(davidben): This flag can probably be merged into s3->change_cipher_spec * to something tri-state. (Normal / Expect CCS / Between CCS and Finished). */ diff --git a/ssl/d1_clnt.c b/ssl/d1_clnt.c index 51fd1440b..99cfefd28 100644 --- a/ssl/d1_clnt.c +++ b/ssl/d1_clnt.c @@ -375,9 +375,6 @@ int dtls1_connect(SSL *s) dtls1_start_timer(s); ret=ssl3_send_client_key_exchange(s); if (ret <= 0) goto end; - - /* EAY EAY EAY need to check for DH fix cert - * sent back */ /* For TLS, cert_req is set to 2, so a cert chain * of nothing is sent, but no verify packet is sent */ if (s->s3->tmp.cert_req == 1) diff --git a/ssl/d1_srvr.c b/ssl/d1_srvr.c index 33cd349eb..fd5bc11d7 100644 --- a/ssl/d1_srvr.c +++ b/ssl/d1_srvr.c @@ -492,22 +492,9 @@ int dtls1_accept(SSL *s) case SSL3_ST_SR_KEY_EXCH_A: case SSL3_ST_SR_KEY_EXCH_B: ret=ssl3_get_client_key_exchange(s); - if (ret <= 0) goto end; - - s->state=SSL3_ST_SR_CERT_VRFY_A; - s->init_num=0; - - if (ret == 2) - { - /* For the ECDH ciphersuites when - * the client sends its ECDH pub key in - * a certificate, the CertificateVerify - * message is not sent. - */ - s->state=SSL3_ST_SR_FINISHED_A; - s->init_num = 0; - } - else if (SSL_USE_SIGALGS(s)) + if (ret <= 0) + goto end; + if (SSL_USE_SIGALGS(s)) { s->state=SSL3_ST_SR_CERT_VRFY_A; s->init_num=0; diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c index cba98a772..253cf8149 100644 --- a/ssl/s3_clnt.c +++ b/ssl/s3_clnt.c @@ -362,17 +362,8 @@ int ssl3_connect(SSL *s) case SSL3_ST_CW_KEY_EXCH_B: ret=ssl3_send_client_key_exchange(s); if (ret <= 0) goto end; - /* EAY EAY EAY need to check for DH fix cert - * sent back */ /* For TLS, cert_req is set to 2, so a cert chain * of nothing is sent, but no verify packet is sent */ - /* XXX: For now, we do not support client - * authentication in ECDH cipher suites with - * ECDH (rather than ECDSA) certificates. - * We need to skip the certificate verify - * message when client's ECDH public key is sent - * inside the client certificate. - */ if (s->s3->tmp.cert_req == 1) { s->state=SSL3_ST_CW_CERT_VRFY_A; @@ -382,11 +373,6 @@ int ssl3_connect(SSL *s) s->state=SSL3_ST_CW_CHANGE_A; s->s3->change_cipher_spec=0; } - if (s->s3->flags & TLS1_FLAGS_SKIP_CERT_VERIFY) - { - s->state=SSL3_ST_CW_CHANGE_A; - s->s3->change_cipher_spec=0; - } s->init_num=0; break; @@ -2122,33 +2108,17 @@ int ssl3_send_client_key_exchange(SSL *s) goto err; } } - if (s->s3->flags & TLS1_FLAGS_SKIP_CERT_VERIFY) + /* generate a new random key */ + if ((dh_clnt=DHparams_dup(dh_srvr)) == NULL) { - /* Use client certificate key */ - EVP_PKEY *clkey = s->cert->key->privatekey; - dh_clnt = NULL; - if (clkey) - dh_clnt = EVP_PKEY_get1_DH(clkey); - if (dh_clnt == NULL) - { - OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_INTERNAL_ERROR); - goto err; - } + OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_DH_LIB); + goto err; } - else + if (!DH_generate_key(dh_clnt)) { - /* generate a new random key */ - if ((dh_clnt=DHparams_dup(dh_srvr)) == NULL) - { - OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_DH_LIB); - goto err; - } - if (!DH_generate_key(dh_clnt)) - { - OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_DH_LIB); - DH_free(dh_clnt); - goto err; - } + OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_DH_LIB); + DH_free(dh_clnt); + goto err; } /* use the 'p' output buffer for the DH key, but @@ -2172,16 +2142,11 @@ int ssl3_send_client_key_exchange(SSL *s) /* clean up */ memset(p,0,n); - if (s->s3->flags & TLS1_FLAGS_SKIP_CERT_VERIFY) - n = 0; - else - { - /* send off the data */ - n=BN_num_bytes(dh_clnt->pub_key); - s2n(n,p); - BN_bn2bin(dh_clnt->pub_key,p); - n+=2; - } + /* send off the data */ + n=BN_num_bytes(dh_clnt->pub_key); + s2n(n,p); + BN_bn2bin(dh_clnt->pub_key,p); + n+=2; DH_free(dh_clnt); @@ -2194,7 +2159,6 @@ int ssl3_send_client_key_exchange(SSL *s) { const EC_GROUP *srvr_group = NULL; EC_KEY *tkey; - int ecdh_clnt_cert = 0; int field_size = 0; unsigned char *pre_ms; unsigned char *t; @@ -2208,34 +2172,6 @@ int ssl3_send_client_key_exchange(SSL *s) goto err; } - /* Did we send out the client's - * ECDH share for use in premaster - * computation as part of client certificate? - * If so, set ecdh_clnt_cert to 1. - */ - if ((alg_k & (SSL_kECDHr|SSL_kECDHe)) && (s->cert != NULL)) - { - /* XXX: For now, we do not support client - * authentication using ECDH certificates. - * To add such support, one needs to add - * code that checks for appropriate - * conditions and sets ecdh_clnt_cert to 1. - * For example, the cert have an ECC - * key on the same curve as the server's - * and the key should be authorized for - * key agreement. - * - * One also needs to add code in ssl3_connect - * to skip sending the certificate verify - * message. - * - * if ((s->cert->key->privatekey != NULL) && - * (s->cert->key->privatekey->type == - * EVP_PKEY_EC) && ...) - * ecdh_clnt_cert = 1; - */ - } - if (s->session->sess_cert->peer_ecdh_tmp != NULL) { tkey = s->session->sess_cert->peer_ecdh_tmp; @@ -2276,34 +2212,11 @@ int ssl3_send_client_key_exchange(SSL *s) OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_EC_LIB); goto err; } - if (ecdh_clnt_cert) - { - /* Reuse key info from our certificate - * We only need our private key to perform - * the ECDH computation. - */ - const BIGNUM *priv_key; - tkey = s->cert->key->privatekey->pkey.ec; - priv_key = EC_KEY_get0_private_key(tkey); - if (priv_key == NULL) - { - OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_MALLOC_FAILURE); - goto err; - } - if (!EC_KEY_set_private_key(clnt_ecdh, priv_key)) - { - OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_EC_LIB); - goto err; - } - } - else + /* Generate a new ECDH key pair */ + if (!(EC_KEY_generate_key(clnt_ecdh))) { - /* Generate a new ECDH key pair */ - if (!(EC_KEY_generate_key(clnt_ecdh))) - { - OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_ECDH_LIB); - goto err; - } + OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_ECDH_LIB); + goto err; } /* use the 'p' output buffer for the ECDH key, but @@ -2355,59 +2268,51 @@ int ssl3_send_client_key_exchange(SSL *s) } memset(p, 0, n); /* clean up */ - if (ecdh_clnt_cert) - { - /* Send empty client key exch message */ - n = 0; - } - else - { - /* First check the size of encoding and - * allocate memory accordingly. - */ - encoded_pt_len = - EC_POINT_point2oct(srvr_group, + /* First check the size of encoding and + * allocate memory accordingly. + */ + encoded_pt_len = + EC_POINT_point2oct(srvr_group, EC_KEY_get0_public_key(clnt_ecdh), POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL); - encodedPoint = (unsigned char *) - OPENSSL_malloc(encoded_pt_len * + encodedPoint = (unsigned char *) + OPENSSL_malloc(encoded_pt_len * sizeof(unsigned char)); - bn_ctx = BN_CTX_new(); - if ((encodedPoint == NULL) || - (bn_ctx == NULL)) - { - OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_MALLOC_FAILURE); - goto err; - } - - /* Encode the public key */ - encoded_pt_len = EC_POINT_point2oct(srvr_group, - EC_KEY_get0_public_key(clnt_ecdh), - POINT_CONVERSION_UNCOMPRESSED, - encodedPoint, encoded_pt_len, bn_ctx); - - n = 0; - if ((alg_a & SSL_aPSK) && psk_len != 0) - { - i = strlen(s->session->psk_identity); - s2n(i, p); - memcpy(p, s->session->psk_identity, i); - p += i; - n = i + 2; - } - - *p = encoded_pt_len; /* length of encoded point */ - /* Encoded point will be copied here */ - p += 1; - n += 1; - /* copy the point */ - memcpy((unsigned char *)p, encodedPoint, encoded_pt_len); - /* increment n to account for length field */ - n += encoded_pt_len; + bn_ctx = BN_CTX_new(); + if ((encodedPoint == NULL) || + (bn_ctx == NULL)) + { + OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_MALLOC_FAILURE); + goto err; } + /* Encode the public key */ + encoded_pt_len = EC_POINT_point2oct(srvr_group, + EC_KEY_get0_public_key(clnt_ecdh), + POINT_CONVERSION_UNCOMPRESSED, + encodedPoint, encoded_pt_len, bn_ctx); + + n = 0; + if ((alg_a & SSL_aPSK) && psk_len != 0) + { + i = strlen(s->session->psk_identity); + s2n(i, p); + memcpy(p, s->session->psk_identity, i); + p += i; + n = i + 2; + } + + *p = encoded_pt_len; /* length of encoded point */ + /* Encoded point will be copied here */ + p += 1; + n += 1; + /* copy the point */ + memcpy((unsigned char *)p, encodedPoint, encoded_pt_len); + /* increment n to account for length field */ + n += encoded_pt_len; + /* Free allocated memory */ BN_CTX_free(bn_ctx); if (encodedPoint != NULL) OPENSSL_free(encodedPoint); @@ -2560,12 +2465,10 @@ err: } /* 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 certificates can be used. + * check the cert exists and if we have a suitable digest for TLS 1.2. */ static int ssl3_check_client_certificate(SSL *s) { - unsigned long alg_k; if (!s->cert || !s->cert->key->x509 || !s->cert->key->privatekey) return 0; /* If no suitable signature algorithm can't use certificate */ @@ -2576,29 +2479,6 @@ static int ssl3_check_client_certificate(SSL *s) if (s->cert->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT && !tls1_check_chain(s, NULL, NULL, NULL, -2)) return 0; - alg_k=s->s3->tmp.new_cipher->algorithm_mkey; - /* See if we can use client certificate for fixed DH */ - if (alg_k & (SSL_kDHr|SSL_kDHd)) - { - SESS_CERT *scert = s->session->sess_cert; - int i = scert->peer_cert_type; - EVP_PKEY *clkey = NULL, *spkey = NULL; - clkey = s->cert->key->privatekey; - /* If client key not DH assume it can be used */ - if (EVP_PKEY_id(clkey) != EVP_PKEY_DH) - return 1; - if (i >= 0) - spkey = X509_get_pubkey(scert->peer_pkeys[i].x509); - if (spkey) - { - /* Compare server and client parameters */ - i = EVP_PKEY_cmp_parameters(clkey, spkey); - EVP_PKEY_free(spkey); - if (i != 1) - return 0; - } - s->s3->flags |= TLS1_FLAGS_SKIP_CERT_VERIFY; - } return 1; } diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c index bd8761e85..c151a8b9c 100644 --- a/ssl/s3_lib.c +++ b/ssl/s3_lib.c @@ -2538,8 +2538,6 @@ int ssl3_get_req_cert_type(SSL *s, unsigned char *p) #ifndef OPENSSL_NO_ECDSA int have_ecdsa_sign = 0; #endif - int nostrict = 1; - unsigned long alg_k; /* If we have custom certificate types set, use them */ if (s->cert->client_certificate_types) @@ -2550,8 +2548,6 @@ int ssl3_get_req_cert_type(SSL *s, unsigned char *p) } /* get configured sigalgs */ siglen = tls12_get_psigalgs(s, &sig); - if (s->cert->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT) - nostrict = 0; for (i = 0; i < siglen; i+=2, sig+=2) { switch(sig[1]) @@ -2571,45 +2567,12 @@ int ssl3_get_req_cert_type(SSL *s, unsigned char *p) } } - alg_k = s->s3->tmp.new_cipher->algorithm_mkey; - -#ifndef OPENSSL_NO_DH - if (alg_k & (SSL_kDHr|SSL_kEDH)) - { - /* Since this refers to a certificate signed with an RSA - * algorithm, only check for rsa signing in strict mode. - */ - if (nostrict || have_rsa_sign) - p[ret++]=SSL3_CT_RSA_FIXED_DH; -# ifndef OPENSSL_NO_DSA - if (nostrict || have_dsa_sign) - p[ret++]=SSL3_CT_DSS_FIXED_DH; -# endif - } - if ((s->version == SSL3_VERSION) && - (alg_k & (SSL_kEDH|SSL_kDHd|SSL_kDHr))) - { - p[ret++]=SSL3_CT_RSA_EPHEMERAL_DH; -# ifndef OPENSSL_NO_DSA - p[ret++]=SSL3_CT_DSS_EPHEMERAL_DH; -# endif - } -#endif /* !OPENSSL_NO_DH */ if (have_rsa_sign) p[ret++]=SSL3_CT_RSA_SIGN; #ifndef OPENSSL_NO_DSA if (have_dsa_sign) p[ret++]=SSL3_CT_DSS_SIGN; #endif -#ifndef OPENSSL_NO_ECDH - if ((alg_k & (SSL_kECDHr|SSL_kECDHe)) && (s->version >= TLS1_VERSION)) - { - if (nostrict || have_rsa_sign) - p[ret++]=TLS_CT_RSA_FIXED_ECDH; - if (nostrict || have_ecdsa_sign) - p[ret++]=TLS_CT_ECDSA_FIXED_ECDH; - } -#endif #ifndef OPENSSL_NO_ECDSA /* ECDSA certs can be used with RSA cipher suites as well diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c index 235ababce..231c47fcc 100644 --- a/ssl/s3_srvr.c +++ b/ssl/s3_srvr.c @@ -259,7 +259,6 @@ int ssl3_accept(SSL *s) s->init_num=0; s->s3->flags &= ~SSL3_FLAGS_SGC_RESTART_DONE; - s->s3->flags &= ~TLS1_FLAGS_SKIP_CERT_VERIFY; if (s->state != SSL_ST_RENEGOTIATE) { @@ -493,17 +492,7 @@ int ssl3_accept(SSL *s) ret=ssl3_get_client_key_exchange(s); if (ret <= 0) goto end; - if (ret == 2) - { - /* For the ECDH ciphersuites when - * the client sends its ECDH pub key in - * a certificate, the CertificateVerify - * message is not sent. - */ - s->init_num = 0; - s->state = SSL3_ST_SR_CHANGE; - } - else if (SSL_USE_SIGALGS(s)) + if (SSL_USE_SIGALGS(s)) { s->state=SSL3_ST_SR_CERT_VRFY_A; s->init_num=0; @@ -1885,13 +1874,12 @@ int ssl3_get_client_key_exchange(SSL *s) unsigned long alg_a; uint8_t *premaster_secret = NULL; size_t premaster_secret_len = 0; - int skip_certificate_verify = 0; RSA *rsa=NULL; uint8_t *decrypt_buf = NULL; EVP_PKEY *pkey=NULL; #ifndef OPENSSL_NO_DH BIGNUM *pub=NULL; - DH *dh_srvr, *dh_clnt = NULL; + DH *dh_srvr; #endif #ifndef OPENSSL_NO_ECDH @@ -1972,8 +1960,7 @@ int ssl3_get_client_key_exchange(SSL *s) } /* Depending on the key exchange method, compute |premaster_secret| and - * |premaster_secret_len|. Also, for DH and ECDH, set - * |skip_certificate_verify| as appropriate. */ + * |premaster_secret_len|. */ if (alg_k & SSL_kRSA) { CBS encrypted_premaster_secret; @@ -2139,6 +2126,7 @@ int ssl3_get_client_key_exchange(SSL *s) EVP_PKEY *skey = NULL; if (!CBS_get_u16_length_prefixed(&client_key_exchange, &dh_Yc) || + CBS_len(&dh_Yc) == 0 || CBS_len(&client_key_exchange) != 0) { OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG); @@ -2172,33 +2160,7 @@ int ssl3_get_client_key_exchange(SSL *s) else dh_srvr=s->s3->tmp.dh; - if (CBS_len(&dh_Yc) == 0) - { - /* Get pubkey from the client certificate. This is the - * 'implicit' case of ClientDiffieHellman. - * - * TODO(davidben): Either lose this code or fix a bug - * (or get the spec changed): if there is a fixed_dh - * client certificate, per spec, the 'implicit' mode - * MUST be used. This logic will still accept 'explicit' - * mode. */ - EVP_PKEY *clkey=X509_get_pubkey(s->session->peer); - if (clkey) - { - if (EVP_PKEY_cmp_parameters(clkey, skey) == 1) - dh_clnt = EVP_PKEY_get1_DH(clkey); - } - if (dh_clnt == NULL) - { - al=SSL_AD_HANDSHAKE_FAILURE; - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, SSL_R_MISSING_TMP_DH_KEY); - goto f_err; - } - EVP_PKEY_free(clkey); - pub = dh_clnt->pub_key; - } - else - pub = BN_bin2bn(CBS_data(&dh_Yc), CBS_len(&dh_Yc), NULL); + pub = BN_bin2bn(CBS_data(&dh_Yc), CBS_len(&dh_Yc), NULL); if (pub == NULL) { OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, SSL_R_BN_LIB); @@ -2223,15 +2185,10 @@ int ssl3_get_client_key_exchange(SSL *s) DH_free(s->s3->tmp.dh); s->s3->tmp.dh=NULL; - if (dh_clnt) - DH_free(dh_clnt); - else - BN_clear_free(pub); + BN_clear_free(pub); pub=NULL; premaster_secret_len = dh_len; - if (dh_clnt) - skip_certificate_verify = 1; } #endif @@ -2242,6 +2199,7 @@ int ssl3_get_client_key_exchange(SSL *s) const EC_KEY *tkey; const EC_GROUP *group; const BIGNUM *priv_key; + CBS ecdh_Yc; /* initialize structures for server's ECDH key pair */ if ((srvr_ecdh = EC_KEY_new()) == NULL) @@ -2281,72 +2239,28 @@ int ssl3_get_client_key_exchange(SSL *s) goto err; } - if (CBS_len(&client_key_exchange) == 0) + /* Get client's public key from encoded point + * in the ClientKeyExchange message. + */ + if (!CBS_get_u8_length_prefixed(&client_key_exchange, &ecdh_Yc) || + CBS_len(&client_key_exchange) != 0) { - /* Client Publickey was in Client Certificate */ - - if (alg_k & SSL_kEECDH) - { - al=SSL_AD_HANDSHAKE_FAILURE; - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, SSL_R_MISSING_TMP_ECDH_KEY); - goto f_err; - } - if (((clnt_pub_pkey=X509_get_pubkey(s->session->peer)) - == NULL) || - (clnt_pub_pkey->type != EVP_PKEY_EC)) - { - /* XXX: For now, we do not support client - * authentication using ECDH certificates - * so this branch (n == 0L) of the code is - * never executed. When that support is - * added, we ought to ensure the key - * received in the certificate is - * authorized for key agreement. - * ECDH_compute_key implicitly checks that - * the two ECDH shares are for the same - * group. - */ - al=SSL_AD_HANDSHAKE_FAILURE; - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, SSL_R_UNABLE_TO_DECODE_ECDH_CERTS); - goto f_err; - } - - if (EC_POINT_copy(clnt_ecpoint, - EC_KEY_get0_public_key(clnt_pub_pkey->pkey.ec)) == 0) - { - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, ERR_R_EC_LIB); - goto err; - } - /* Skip certificate verify processing */ - skip_certificate_verify = 1; + al = SSL_AD_DECODE_ERROR; + OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, SSL_R_DECODE_ERROR); + goto f_err; } - else + + if ((bn_ctx = BN_CTX_new()) == NULL) { - CBS ecdh_Yc; + OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, ERR_R_MALLOC_FAILURE); + goto err; + } - /* Get client's public key from encoded point - * in the ClientKeyExchange message. - */ - if (!CBS_get_u8_length_prefixed(&client_key_exchange, &ecdh_Yc) || - CBS_len(&client_key_exchange) != 0) - { - al = SSL_AD_DECODE_ERROR; - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, SSL_R_DECODE_ERROR); - goto f_err; - } - - if ((bn_ctx = BN_CTX_new()) == NULL) - { - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, ERR_R_MALLOC_FAILURE); - goto err; - } - - if (!EC_POINT_oct2point(group, clnt_ecpoint, - CBS_data(&ecdh_Yc), CBS_len(&ecdh_Yc), bn_ctx)) - { - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, ERR_R_EC_LIB); - goto err; - } + if (!EC_POINT_oct2point(group, clnt_ecpoint, + CBS_data(&ecdh_Yc), CBS_len(&ecdh_Yc), bn_ctx)) + { + OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, ERR_R_EC_LIB); + goto err; } /* Allocate a buffer for both the secret and the PSK. */ @@ -2441,7 +2355,7 @@ int ssl3_get_client_key_exchange(SSL *s) OPENSSL_cleanse(premaster_secret, premaster_secret_len); OPENSSL_free(premaster_secret); - return skip_certificate_verify ? 2 : 1; + return 1; f_err: ssl3_send_alert(s,SSL3_AL_FATAL,al); err: