X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=ssl%2Ft1_lib.c;h=c53eadfe302a1b82f06c21a77bd651a96d99c203;hp=b3166d6254415aa9e0a8dec6c53c33a1539aa3ee;hb=ddd13d677b0fc62c34d246b3d060c9cb5de04d82;hpb=ed83ba53212f81e590b3cf9adb49c04069430659 diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index b3166d6254..c53eadfe30 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -123,7 +123,7 @@ const char tls1_version_str[]="TLSv1" OPENSSL_VERSION_PTEXT; static int tls_decrypt_ticket(SSL *s, const unsigned char *tick, int ticklen, const unsigned char *sess_id, int sesslen, SSL_SESSION **psess); -static int ssl_check_clienthello_tlsext(SSL *s); +static int ssl_check_clienthello_tlsext_early(SSL *s); int ssl_check_serverhello_tlsext(SSL *s); #endif @@ -525,6 +525,8 @@ int tls1_set_curves_list(unsigned char **pext, size_t *pextlen, ncb.nidcnt = 0; if (!CONF_parse_list(str, ':', 1, nid_cb, &ncb)) return 0; + if (pext == NULL) + return 1; return tls1_set_curves(pext, pextlen, ncb.nid_arr, ncb.nidcnt); } /* For an EC key set TLS id and required compression based on parameters */ @@ -688,7 +690,7 @@ int tls1_check_ec_tmp_key(SSL *s, unsigned long cid) EC_KEY *ec = s->cert->ecdh_tmp; #ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL /* Allow any curve: not just those peer supports */ - if (s->cert->cert_flags & SSL_CERT_FLAG_BROKEN_PROTCOL) + if (s->cert->cert_flags & SSL_CERT_FLAG_BROKEN_PROTOCOL) return 1; #endif /* If Suite B, AES128 MUST use P-256 and AES256 MUST use P-384, @@ -922,6 +924,11 @@ int tls12_check_peer_sigalg(const EVP_MD **pmd, SSL *s, SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG,SSL_R_UNKNOWN_DIGEST); return 0; } + /* Store the digest used so applications can retrieve it if they + * wish. + */ + if (s->session && s->session->sess_cert) + s->session->sess_cert->peer_key->digest = *pmd; return 1; } /* Get a mask of disabled algorithms: an algorithm is disabled @@ -2241,7 +2248,7 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in return 0; } - if (ssl_check_clienthello_tlsext(s) <= 0) + if (ssl_check_clienthello_tlsext_early(s) <= 0) { SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT,SSL_R_CLIENTHELLO_TLSEXT); return 0; @@ -2642,7 +2649,7 @@ int ssl_prepare_serverhello_tlsext(SSL *s) return 1; } -static int ssl_check_clienthello_tlsext(SSL *s) +static int ssl_check_clienthello_tlsext_early(SSL *s) { int ret=SSL_TLSEXT_ERR_NOACK; int al = SSL_AD_UNRECOGNIZED_NAME; @@ -2661,42 +2668,12 @@ static int ssl_check_clienthello_tlsext(SSL *s) else if (s->initial_ctx != NULL && s->initial_ctx->tlsext_servername_callback != 0) ret = s->initial_ctx->tlsext_servername_callback(s, &al, s->initial_ctx->tlsext_servername_arg); - /* If status request then ask callback what to do. - * Note: this must be called after servername callbacks in case - * the certificate has changed. - */ - if ((s->tlsext_status_type != -1) && s->ctx && s->ctx->tlsext_status_cb) - { - int r; - r = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg); - switch (r) - { - /* We don't want to send a status request response */ - case SSL_TLSEXT_ERR_NOACK: - s->tlsext_status_expected = 0; - break; - /* status request response should be sent */ - case SSL_TLSEXT_ERR_OK: - if (s->tlsext_ocsp_resp) - s->tlsext_status_expected = 1; - else - s->tlsext_status_expected = 0; - break; - /* something bad happened */ - case SSL_TLSEXT_ERR_ALERT_FATAL: - ret = SSL_TLSEXT_ERR_ALERT_FATAL; - al = SSL_AD_INTERNAL_ERROR; - goto err; - } - } - else - s->tlsext_status_expected = 0; - #ifdef TLSEXT_TYPE_opaque_prf_input { /* This sort of belongs into ssl_prepare_serverhello_tlsext(), * but we might be sending an alert in response to the client hello, - * so this has to happen here in ssl_check_clienthello_tlsext(). */ + * so this has to happen here in + * ssl_check_clienthello_tlsext_early(). */ int r = 1; @@ -2748,8 +2725,8 @@ static int ssl_check_clienthello_tlsext(SSL *s) } } -#endif err: +#endif switch (ret) { case SSL_TLSEXT_ERR_ALERT_FATAL: @@ -2767,6 +2744,71 @@ static int ssl_check_clienthello_tlsext(SSL *s) } } +int ssl_check_clienthello_tlsext_late(SSL *s) + { + int ret = SSL_TLSEXT_ERR_OK; + int al; + + /* If status request then ask callback what to do. + * Note: this must be called after servername callbacks in case + * the certificate has changed, and must be called after the cipher + * has been chosen because this may influence which certificate is sent + */ + if ((s->tlsext_status_type != -1) && s->ctx && s->ctx->tlsext_status_cb) + { + int r; + CERT_PKEY *certpkey; + certpkey = ssl_get_server_send_pkey(s); + /* If no certificate can't return certificate status */ + if (certpkey == NULL) + { + s->tlsext_status_expected = 0; + return 1; + } + /* Set current certificate to one we will use so + * SSL_get_certificate et al can pick it up. + */ + s->cert->key = certpkey; + r = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg); + switch (r) + { + /* We don't want to send a status request response */ + case SSL_TLSEXT_ERR_NOACK: + s->tlsext_status_expected = 0; + break; + /* status request response should be sent */ + case SSL_TLSEXT_ERR_OK: + if (s->tlsext_ocsp_resp) + s->tlsext_status_expected = 1; + else + s->tlsext_status_expected = 0; + break; + /* something bad happened */ + case SSL_TLSEXT_ERR_ALERT_FATAL: + ret = SSL_TLSEXT_ERR_ALERT_FATAL; + al = SSL_AD_INTERNAL_ERROR; + goto err; + } + } + else + s->tlsext_status_expected = 0; + + err: + switch (ret) + { + case SSL_TLSEXT_ERR_ALERT_FATAL: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + return -1; + + case SSL_TLSEXT_ERR_ALERT_WARNING: + ssl3_send_alert(s, SSL3_AL_WARNING, al); + return 1; + + default: + return 1; + } + } + int ssl_check_serverhello_tlsext(SSL *s) { int ret=SSL_TLSEXT_ERR_NOACK; @@ -3394,7 +3436,7 @@ int tls1_process_sigalgs(SSL *s, const unsigned char *data, int dsize) tls1_set_shared_sigalgs(s); #ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL - if (s->cert->cert_flags & SSL_CERT_FLAG_BROKEN_PROTCOL) + if (s->cert->cert_flags & SSL_CERT_FLAG_BROKEN_PROTOCOL) { /* Use first set signature preference to force message * digest, ignoring any peer preferences. @@ -3714,6 +3756,8 @@ int tls1_set_sigalgs_list(CERT *c, const char *str, int client) sig.sigalgcnt = 0; if (!CONF_parse_list(str, ':', 1, sig_cb, &sig)) return 0; + if (c == NULL) + return 1; return tls1_set_sigalgs(c, sig.sigalgs, sig.sigalgcnt, client); } @@ -3834,7 +3878,7 @@ int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain, goto end; #ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL /* Allow any certificate to pass test */ - if (s->cert->cert_flags & SSL_CERT_FLAG_BROKEN_PROTCOL) + if (s->cert->cert_flags & SSL_CERT_FLAG_BROKEN_PROTOCOL) { rv = CERT_PKEY_STRICT_FLAGS|CERT_PKEY_EXPLICIT_SIGN|CERT_PKEY_VALID|CERT_PKEY_SIGN; cpk->valid_flags = rv;