bn/asm/rsaz-*.pl: allow spaces in Perl path name.
[oweals/openssl.git] / ssl / s3_srvr.c
index 619c710ca4226eb97ad8942e729cc1afae1254ec..e1d35f791127d0a5ce04d45395891c98b287839b 100644 (file)
@@ -353,12 +353,11 @@ int ssl3_accept(SSL *s)
                case SSL3_ST_SR_CLNT_HELLO_C:
 
                        s->shutdown=0;
-                       if (s->rwstate != SSL_X509_LOOKUP)
-                       {
-                               ret=ssl3_get_client_hello(s);
-                               if (ret <= 0) goto end;
-                       }
+                       ret=ssl3_get_client_hello(s);
+                       if (ret <= 0) goto end;
 #ifndef OPENSSL_NO_SRP
+                       s->state = SSL3_ST_SR_CLNT_HELLO_D;
+               case SSL3_ST_SR_CLNT_HELLO_D:
                        {
                        int al;
                        if ((ret = ssl_check_srp_ext_ClientHello(s,&al))  < 0)
@@ -403,38 +402,16 @@ int ssl3_accept(SSL *s)
                                        s->state=SSL3_ST_SW_CHANGE_A;
 #endif
                        else
-#ifndef OPENSSL_NO_TLSEXT
-                               s->state = SSL3_ST_SW_SUPPLEMENTAL_DATA_A;
-#else
-                       s->state = SSL3_ST_SW_CERT_A;
-#endif
+                                       s->state = SSL3_ST_SW_CERT_A;
                        s->init_num = 0;
                        break;
 
-#ifndef OPENSSL_NO_TLSEXT
-               case SSL3_ST_SW_SUPPLEMENTAL_DATA_A:
-               case SSL3_ST_SW_SUPPLEMENTAL_DATA_B:
-                       /* We promised to send an audit proof in the hello. */
-                       if (s->s3->tlsext_authz_promised_to_client)
-                               {
-                               ret = tls1_send_server_supplemental_data(s);
-                               if (ret <= 0) goto end;
-                               }
-                       else
-                               skip = 1;
-
-                       s->state = SSL3_ST_SW_CERT_A;
-                       s->init_num = 0;
-                       break;
-#endif
-
                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 */
-                       if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL)
-                               && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)
-                               && !(s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5))
+                       if (!(s->s3->tmp.new_cipher->algorithm_auth & (SSL_aNULL|SSL_aKRB5|SSL_aSRP))
+                               && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK))
                                {
                                ret=ssl3_send_server_certificate(s);
                                if (ret <= 0) goto end;
@@ -537,7 +514,9 @@ int ssl3_accept(SSL *s)
                                  * (against the specs, but s3_clnt.c accepts this for SSL 3) */
                                 !(s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) ||
                                 /* never request cert in Kerberos ciphersuites */
-                               (s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5)
+                               (s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5) ||
+                               /* don't request certificate for SRP auth */
+                               (s->s3->tmp.new_cipher->algorithm_auth & SSL_aSRP)
                                /* With normal PSK Certificates and
                                 * Certificate Requests are omitted */
                                || (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK))
@@ -695,6 +674,7 @@ int ssl3_accept(SSL *s)
                case SSL3_ST_SR_CERT_VRFY_A:
                case SSL3_ST_SR_CERT_VRFY_B:
 
+                       s->s3->flags |= SSL3_FLAGS_CCS_OK;
                        /* we should decide if we expected this one */
                        ret=ssl3_get_cert_verify(s);
                        if (ret <= 0) goto end;
@@ -722,6 +702,7 @@ int ssl3_accept(SSL *s)
 
                case SSL3_ST_SR_FINISHED_A:
                case SSL3_ST_SR_FINISHED_B:
+                       s->s3->flags |= SSL3_FLAGS_CCS_OK;
                        ret=ssl3_get_finished(s,SSL3_ST_SR_FINISHED_A,
                                SSL3_ST_SR_FINISHED_B);
                        if (ret <= 0) goto end;
@@ -792,7 +773,10 @@ int ssl3_accept(SSL *s)
                                s->s3->tmp.next_state=SSL3_ST_SR_FINISHED_A;
 #else
                                if (s->s3->next_proto_neg_seen)
+                                       {
+                                       s->s3->flags |= SSL3_FLAGS_CCS_OK;
                                        s->s3->tmp.next_state=SSL3_ST_SR_NEXT_PROTO_A;
+                                       }
                                else
                                        s->s3->tmp.next_state=SSL3_ST_SR_FINISHED_A;
 #endif
@@ -940,6 +924,9 @@ int ssl3_get_client_hello(SSL *s)
 #endif
        STACK_OF(SSL_CIPHER) *ciphers=NULL;
 
+       if (s->state == SSL3_ST_SR_CLNT_HELLO_C && !s->first_packet)
+               goto retry_cert;
+
        /* We do this so that we will respond with our native type.
         * If we are TLSv1 and we get SSLv3, we will respond with TLSv1,
         * This down switching should be handled by a different method.
@@ -1384,12 +1371,22 @@ int ssl3_get_client_hello(SSL *s)
                        }
                ciphers=NULL;
                /* Let cert callback update server certificates if required */
-               if (s->cert->cert_cb
-                       && s->cert->cert_cb(s, s->cert->cert_cb_arg) <= 0)
+               retry_cert:             
+               if (s->cert->cert_cb)
                        {
-                       al=SSL_AD_INTERNAL_ERROR;
-                       SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_CERT_CB_ERROR);
-                       goto f_err;
+                       int rv = s->cert->cert_cb(s, s->cert->cert_cb_arg);
+                       if (rv == 0)
+                               {
+                               al=SSL_AD_INTERNAL_ERROR;
+                               SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_CERT_CB_ERROR);
+                               goto f_err;
+                               }
+                       if (rv < 0)
+                               {
+                               s->rwstate=SSL_X509_LOOKUP;
+                               return -1;
+                               }
+                       s->rwstate = SSL_NOTHING;
                        }
                c=ssl3_choose_cipher(s,s->session->ciphers,
                                     SSL_get_ciphers(s));
@@ -1476,6 +1473,7 @@ int ssl3_send_server_hello(SSL *s)
        unsigned char *buf;
        unsigned char *p,*d;
        int i,sl;
+       int al = 0;
        unsigned long l;
 
        if (s->state == SSL3_ST_SW_SRVR_HELLO_A)
@@ -1544,8 +1542,9 @@ int ssl3_send_server_hello(SSL *s)
                        SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO,SSL_R_SERVERHELLO_TLSEXT);
                        return -1;
                        }
-               if ((p = ssl_add_serverhello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL)
+               if ((p = ssl_add_serverhello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH, &al)) == NULL)
                        {
+                       ssl3_send_alert(s, SSL3_AL_FATAL, al);
                        SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO,ERR_R_INTERNAL_ERROR);
                        return -1;
                        }
@@ -1866,7 +1865,7 @@ int ssl3_send_server_key_exchange(SSL *s)
                        SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE);
                        goto f_err;
                        }
-               for (i=0; r[i] != NULL && i<4; i++)
+               for (i=0; i < 4 && r[i] != NULL; i++)
                        {
                        nr[i]=BN_num_bytes(r[i]);
 #ifndef OPENSSL_NO_SRP
@@ -1877,7 +1876,7 @@ int ssl3_send_server_key_exchange(SSL *s)
                        n+=2+nr[i];
                        }
 
-               if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL)
+               if (!(s->s3->tmp.new_cipher->algorithm_auth & (SSL_aNULL|SSL_aSRP))
                        && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK))
                        {
                        if ((pkey=ssl_get_sign_pkey(s,s->s3->tmp.new_cipher,&md))
@@ -1901,7 +1900,7 @@ int ssl3_send_server_key_exchange(SSL *s)
                        }
                d = p = ssl_handshake_start(s);
 
-               for (i=0; r[i] != NULL && i<4; i++)
+               for (i=0; i < 4 && r[i] != NULL; i++)
                        {
 #ifndef OPENSSL_NO_SRP
                        if ((i == 2) && (type & SSL_kSRP))
@@ -2121,6 +2120,11 @@ int ssl3_send_certificate_request(SSL *s)
 #ifdef NETSCAPE_HANG_BUG
                if (!SSL_IS_DTLS(s))
                        {
+                       if (!BUF_MEM_grow_clean(buf, s->init_num + 4))
+                               {
+                               SSLerr(SSL_F_SSL3_SEND_CERTIFICATE_REQUEST,ERR_R_BUF_LIB);
+                               goto err;
+                               }
                        p=(unsigned char *)s->init_buf->data + s->init_num;
                        /* do the header */
                        *(p++)=SSL3_MT_SERVER_DONE;
@@ -2844,6 +2848,13 @@ int ssl3_get_client_key_exchange(SSL *s)
                                SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,ERR_R_BN_LIB);
                                goto err;
                                }
+                       if (BN_ucmp(s->srp_ctx.A, s->srp_ctx.N) >= 0
+                               || BN_is_zero(s->srp_ctx.A))
+                               {
+                               al=SSL_AD_ILLEGAL_PARAMETER;
+                               SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_BAD_SRP_PARAMETERS);
+                               goto f_err;
+                               }
                        if (s->session->srp_username != NULL)
                                OPENSSL_free(s->session->srp_username);
                        s->session->srp_username = BUF_strdup(s->srp_ctx.login);
@@ -2872,6 +2883,8 @@ int ssl3_get_client_key_exchange(SSL *s)
                        unsigned char premaster_secret[32], *start;
                        size_t outlen=32, inlen;
                        unsigned long alg_a;
+                       int Ttag, Tclass;
+                       long Tlen;
 
                        /* Get our certificate private key*/
                        alg_a = s->s3->tmp.new_cipher->algorithm_auth;
@@ -2893,26 +2906,15 @@ int ssl3_get_client_key_exchange(SSL *s)
                                        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
+                       if (ASN1_get_object((const unsigned char **)&p, &Tlen, &Ttag, &Tclass, n) != V_ASN1_CONSTRUCTED || 
+                               Ttag != V_ASN1_SEQUENCE ||
+                               Tclass != V_ASN1_UNIVERSAL) 
                                {
                                SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_DECRYPTION_FAILED);
                                goto gerr;
                                }
+                       start = p;
+                       inlen = Tlen;
                        if (EVP_PKEY_decrypt(pkey_ctx,premaster_secret,&outlen,start,inlen) <=0) 
 
                                {
@@ -2976,7 +2978,7 @@ int ssl3_get_cert_verify(SSL *s)
                SSL3_ST_SR_CERT_VRFY_A,
                SSL3_ST_SR_CERT_VRFY_B,
                -1,
-               516, /* Enough for 4096 bit RSA key with TLS v1.2 */
+               SSL3_RT_MAX_PLAIN_LENGTH,
                &ok);
 
        if (!ok) return((int)n);
@@ -3627,98 +3629,4 @@ int ssl3_get_next_proto(SSL *s)
        }
 # endif
 
-int tls1_send_server_supplemental_data(SSL *s)
-       {
-       size_t length = 0;
-       const unsigned char *authz, *orig_authz;
-       unsigned char *p;
-       size_t authz_length, i;
-
-       if (s->state != SSL3_ST_SW_SUPPLEMENTAL_DATA_A)
-               return ssl3_do_write(s, SSL3_RT_HANDSHAKE);
-
-       orig_authz = authz = ssl_get_authz_data(s, &authz_length);
-       if (authz == NULL)
-               {
-               /* This should never occur. */
-               return 0;
-               }
-
-       /* First we walk over the authz data to see how long the handshake
-        * message will be. */
-       for (i = 0; i < authz_length; i++)
-               {
-               unsigned short len;
-               unsigned char type;
-
-               type = *(authz++);
-               n2s(authz, len);
-               /* n2s increments authz by 2*/
-               i += 2;
-
-               if (memchr(s->s3->tlsext_authz_client_types,
-                          type,
-                          s->s3->tlsext_authz_client_types_len) != NULL)
-                       length += 1 /* authz type */ + 2 /* length */ + len;
-
-               authz += len;
-               i += len;
-               }
-
-       length += 1 /* handshake type */ +
-                 3 /* handshake length */ +
-                 3 /* supplemental data length */ +
-                 2 /* supplemental entry type */ +
-                 2 /* supplemental entry length */;
-
-       if (!BUF_MEM_grow_clean(s->init_buf, length))
-               {
-               SSLerr(SSL_F_TLS1_SEND_SERVER_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB);
-               return 0;
-               }
-
-       p = (unsigned char *)s->init_buf->data;
-       *(p++) = SSL3_MT_SUPPLEMENTAL_DATA;
-       /* Handshake length */
-       l2n3(length - 4, p);
-       /* Length of supplemental data */
-       l2n3(length - 7, p);
-       /* Supplemental data type */
-       s2n(TLSEXT_SUPPLEMENTALDATATYPE_authz_data, p);
-       /* Its length */
-       s2n(length - 11, p);
-
-       authz = orig_authz;
-
-       /* Walk over the authz again and append the selected elements. */
-       for (i = 0; i < authz_length; i++)
-               {
-               unsigned short len;
-               unsigned char type;
-
-               type = *(authz++);
-               n2s(authz, len);
-               /* n2s increments authz by 2 */
-               i += 2;
-
-               if (memchr(s->s3->tlsext_authz_client_types,
-                          type,
-                          s->s3->tlsext_authz_client_types_len) != NULL)
-                       {
-                       *(p++) = type;
-                       s2n(len, p);
-                       memcpy(p, authz, len);
-                       p += len;
-                       }
-
-               authz += len;
-               i += len;
-               }
-
-       s->state = SSL3_ST_SW_SUPPLEMENTAL_DATA_B;
-       s->init_num = length;
-       s->init_off = 0;
-
-       return ssl3_do_write(s, SSL3_RT_HANDSHAKE);
-       }
 #endif