fix typo and warning
[openssl.git] / ssl / t1_lib.c
index b3166d6254415aa9e0a8dec6c53c33a1539aa3ee..c53eadfe302a1b82f06c21a77bd651a96d99c203 100644 (file)
@@ -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 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
 
 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;
        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 */
        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 */
        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,
                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;
                }
                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
        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;
                }
 
                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;
                {
                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;
        }
 
        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;
        {
        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);
 
        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,
 #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;
        
 
                int r = 1;
        
@@ -2748,8 +2725,8 @@ static int ssl_check_clienthello_tlsext(SSL *s)
                        }
        }
 
                        }
        }
 
-#endif
  err:
  err:
+#endif
        switch (ret)
                {
                case SSL_TLSEXT_ERR_ALERT_FATAL:
        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;
 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
        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.
                {
                /* 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;
        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);
        }
 
        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 */
                        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;
                        {
                        rv = CERT_PKEY_STRICT_FLAGS|CERT_PKEY_EXPLICIT_SIGN|CERT_PKEY_VALID|CERT_PKEY_SIGN;
                        cpk->valid_flags = rv;