Loading CHANGES +4 −0 Original line number Diff line number Diff line Loading @@ -4,6 +4,10 @@ Changes between 1.0.1 and 1.1.0 [xx XXX xxxx] *) Support for fixed DH ciphersuite client authentication: where both server and client use DH certificates with common parameters. [Steve Henson] *) Support for fixed DH ciphersuites: those requiring DH server certificates. [Steve Henson] Loading ssl/s3_clnt.c +73 −19 Original line number Diff line number Diff line Loading @@ -2428,7 +2428,21 @@ int ssl3_send_client_key_exchange(SSL *s) goto err; } } if (s->s3->flags & TLS1_FLAGS_SKIP_CERT_VERIFY) { /* Use client certificate key */ EVP_PKEY *clkey = s->cert->key->privatekey; if (clkey) dh_clnt = EVP_PKEY_get1_DH(clkey); if (dh_clnt == NULL) { SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); goto err; } } else { /* generate a new random key */ if ((dh_clnt=DHparams_dup(dh_srvr)) == NULL) { Loading @@ -2441,6 +2455,7 @@ int ssl3_send_client_key_exchange(SSL *s) DH_free(dh_clnt); goto err; } } /* use the 'p' output buffer for the DH key, but * make sure to clear it out afterwards */ Loading @@ -2463,11 +2478,16 @@ 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; } DH_free(dh_clnt); Loading Loading @@ -3054,6 +3074,40 @@ err: return(-1); } /* Check a certificate can be used for client authentication. Currently * just check cert exists and if static DH client certificates can be used. */ 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; 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; } int ssl3_send_client_certificate(SSL *s) { X509 *x509=NULL; Loading @@ -3063,12 +3117,10 @@ int ssl3_send_client_certificate(SSL *s) if (s->state == SSL3_ST_CW_CERT_A) { if ((s->cert == NULL) || (s->cert->key->x509 == NULL) || (s->cert->key->privatekey == NULL)) s->state=SSL3_ST_CW_CERT_B; else if (ssl3_check_client_certificate(s)) s->state=SSL3_ST_CW_CERT_C; else s->state=SSL3_ST_CW_CERT_B; } /* We need to get a client cert */ Loading Loading @@ -3100,6 +3152,8 @@ int ssl3_send_client_certificate(SSL *s) if (x509 != NULL) X509_free(x509); if (pkey != NULL) EVP_PKEY_free(pkey); if (i && !ssl3_check_client_certificate(s)) i = 0; if (i == 0) { if (s->version == SSL3_VERSION) Loading ssl/s3_srvr.c +46 −30 Original line number Diff line number Diff line Loading @@ -298,6 +298,7 @@ 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) { Loading Loading @@ -2132,7 +2133,7 @@ int ssl3_get_client_key_exchange(SSL *s) #endif #ifndef OPENSSL_NO_DH BIGNUM *pub=NULL; DH *dh_srvr; DH *dh_srvr, *dh_clnt = NULL; #endif #ifndef OPENSSL_NO_KRB5 KSSL_ERR kssl_err; Loading Loading @@ -2266,8 +2267,11 @@ int ssl3_get_client_key_exchange(SSL *s) #ifndef OPENSSL_NO_DH if (alg_k & (SSL_kEDH|SSL_kDHr|SSL_kDHd)) { int idx = -1; EVP_PKEY *skey = NULL; if (n) n2s(p,i); if (n != i+2) if (n && n != i+2) { if (!(s->options & SSL_OP_SSLEAY_080_CLIENT_DH_BUG)) { Loading @@ -2280,23 +2284,13 @@ int ssl3_get_client_key_exchange(SSL *s) i=(int)n; } } if (n == 0L) /* the parameters are in the cert */ { al=SSL_AD_HANDSHAKE_FAILURE; SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_UNABLE_TO_DECODE_DH_CERTS); goto f_err; } else { int idx = -1; if (alg_k & SSL_kDHr) idx = SSL_PKEY_DH_RSA; else if (alg_k & SSL_kDHd) idx = SSL_PKEY_DH_DSA; if (idx >= 0) { EVP_PKEY *skey = s->cert->pkeys[idx].privatekey; skey = s->cert->pkeys[idx].privatekey; if ((skey == NULL) || (skey->type != EVP_PKEY_DH) || (skey->pkey.dh == NULL)) Loading @@ -2315,8 +2309,26 @@ int ssl3_get_client_key_exchange(SSL *s) } else dh_srvr=s->s3->tmp.dh; } if (n == 0L) { /* Get pubkey from cert */ 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; SSLerr(SSL_F_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(p,i,NULL); if (pub == NULL) { Loading @@ -2335,13 +2347,17 @@ 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); pub=NULL; s->session->master_key_length= s->method->ssl3_enc->generate_master_secret(s, s->session->master_key,p,i); OPENSSL_cleanse(p,i); if (dh_clnt) return 2; } else #endif Loading Loading
CHANGES +4 −0 Original line number Diff line number Diff line Loading @@ -4,6 +4,10 @@ Changes between 1.0.1 and 1.1.0 [xx XXX xxxx] *) Support for fixed DH ciphersuite client authentication: where both server and client use DH certificates with common parameters. [Steve Henson] *) Support for fixed DH ciphersuites: those requiring DH server certificates. [Steve Henson] Loading
ssl/s3_clnt.c +73 −19 Original line number Diff line number Diff line Loading @@ -2428,7 +2428,21 @@ int ssl3_send_client_key_exchange(SSL *s) goto err; } } if (s->s3->flags & TLS1_FLAGS_SKIP_CERT_VERIFY) { /* Use client certificate key */ EVP_PKEY *clkey = s->cert->key->privatekey; if (clkey) dh_clnt = EVP_PKEY_get1_DH(clkey); if (dh_clnt == NULL) { SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); goto err; } } else { /* generate a new random key */ if ((dh_clnt=DHparams_dup(dh_srvr)) == NULL) { Loading @@ -2441,6 +2455,7 @@ int ssl3_send_client_key_exchange(SSL *s) DH_free(dh_clnt); goto err; } } /* use the 'p' output buffer for the DH key, but * make sure to clear it out afterwards */ Loading @@ -2463,11 +2478,16 @@ 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; } DH_free(dh_clnt); Loading Loading @@ -3054,6 +3074,40 @@ err: return(-1); } /* Check a certificate can be used for client authentication. Currently * just check cert exists and if static DH client certificates can be used. */ 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; 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; } int ssl3_send_client_certificate(SSL *s) { X509 *x509=NULL; Loading @@ -3063,12 +3117,10 @@ int ssl3_send_client_certificate(SSL *s) if (s->state == SSL3_ST_CW_CERT_A) { if ((s->cert == NULL) || (s->cert->key->x509 == NULL) || (s->cert->key->privatekey == NULL)) s->state=SSL3_ST_CW_CERT_B; else if (ssl3_check_client_certificate(s)) s->state=SSL3_ST_CW_CERT_C; else s->state=SSL3_ST_CW_CERT_B; } /* We need to get a client cert */ Loading Loading @@ -3100,6 +3152,8 @@ int ssl3_send_client_certificate(SSL *s) if (x509 != NULL) X509_free(x509); if (pkey != NULL) EVP_PKEY_free(pkey); if (i && !ssl3_check_client_certificate(s)) i = 0; if (i == 0) { if (s->version == SSL3_VERSION) Loading
ssl/s3_srvr.c +46 −30 Original line number Diff line number Diff line Loading @@ -298,6 +298,7 @@ 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) { Loading Loading @@ -2132,7 +2133,7 @@ int ssl3_get_client_key_exchange(SSL *s) #endif #ifndef OPENSSL_NO_DH BIGNUM *pub=NULL; DH *dh_srvr; DH *dh_srvr, *dh_clnt = NULL; #endif #ifndef OPENSSL_NO_KRB5 KSSL_ERR kssl_err; Loading Loading @@ -2266,8 +2267,11 @@ int ssl3_get_client_key_exchange(SSL *s) #ifndef OPENSSL_NO_DH if (alg_k & (SSL_kEDH|SSL_kDHr|SSL_kDHd)) { int idx = -1; EVP_PKEY *skey = NULL; if (n) n2s(p,i); if (n != i+2) if (n && n != i+2) { if (!(s->options & SSL_OP_SSLEAY_080_CLIENT_DH_BUG)) { Loading @@ -2280,23 +2284,13 @@ int ssl3_get_client_key_exchange(SSL *s) i=(int)n; } } if (n == 0L) /* the parameters are in the cert */ { al=SSL_AD_HANDSHAKE_FAILURE; SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_UNABLE_TO_DECODE_DH_CERTS); goto f_err; } else { int idx = -1; if (alg_k & SSL_kDHr) idx = SSL_PKEY_DH_RSA; else if (alg_k & SSL_kDHd) idx = SSL_PKEY_DH_DSA; if (idx >= 0) { EVP_PKEY *skey = s->cert->pkeys[idx].privatekey; skey = s->cert->pkeys[idx].privatekey; if ((skey == NULL) || (skey->type != EVP_PKEY_DH) || (skey->pkey.dh == NULL)) Loading @@ -2315,8 +2309,26 @@ int ssl3_get_client_key_exchange(SSL *s) } else dh_srvr=s->s3->tmp.dh; } if (n == 0L) { /* Get pubkey from cert */ 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; SSLerr(SSL_F_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(p,i,NULL); if (pub == NULL) { Loading @@ -2335,13 +2347,17 @@ 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); pub=NULL; s->session->master_key_length= s->method->ssl3_enc->generate_master_secret(s, s->session->master_key,p,i); OPENSSL_cleanse(p,i); if (dh_clnt) return 2; } else #endif Loading