More tweaks for comments due indent issues
[openssl.git] / ssl / ssl_lib.c
index f779ce66d715dcd8c7e9bcd2dd8524770194130a..569f57e341d3d949273b81aceefbeb205108d96a 100644 (file)
@@ -201,10 +201,15 @@ int SSL_clear(SSL *s)
        s->hit=0;
        s->shutdown=0;
 
-#if 0 /* Disabled since version 1.10 of this file (early return not
-       * needed because SSL_clear is not called when doing renegotiation) */
-       /* This is set if we are doing dynamic renegotiation so keep
-        * the old cipher.  It is sort of a SSL_clear_lite :-) */
+#if 0
+    /*
+     * Disabled since version 1.10 of this file (early return not
+     * needed because SSL_clear is not called when doing renegotiation)
+     */
+    /*
+     * This is set if we are doing dynamic renegotiation so keep
+     * the old cipher.  It is sort of a SSL_clear_lite :-)
+     */
        if (s->renegotiate) return(1);
 #else
        if (s->renegotiate)
@@ -416,13 +421,7 @@ SSL *SSL_new(SSL_CTX *ctx)
        return(s);
 err:
        if (s != NULL)
-               {
-               if (s->cert != NULL)
-                       ssl_cert_free(s->cert);
-               if (s->ctx != NULL)
-                       SSL_CTX_free(s->ctx); /* decrement reference count */
-               OPENSSL_free(s);
-               }
+               SSL_free(s);
        SSLerr(SSL_F_SSL_NEW,ERR_R_MALLOC_FAILURE);
        return(NULL);
        }
@@ -647,8 +646,10 @@ void SSL_free(SSL *s)
                OPENSSL_free(s->next_proto_negotiated);
 #endif
 
+#ifndef OPENSSL_NO_SRTP
         if (s->srtp_profiles)
             sk_SRTP_PROTECTION_PROFILE_free(s->srtp_profiles);
+#endif
 
        OPENSSL_free(s);
        }
@@ -1128,18 +1129,6 @@ long SSL_ctrl(SSL *s,int cmd,long larg,void *parg)
                l=s->max_cert_list;
                s->max_cert_list=larg;
                return(l);
-       case SSL_CTRL_SET_MTU:
-#ifndef OPENSSL_NO_DTLS1
-               if (larg < (long)dtls1_min_mtu())
-                       return 0;
-#endif
-
-               if (SSL_IS_DTLS(s))
-                       {
-                       s->d1->mtu = larg;
-                       return larg;
-                       }
-               return 0;
        case SSL_CTRL_SET_MAX_SEND_FRAGMENT:
                if (larg < 512 || larg > SSL3_RT_MAX_PLAIN_LENGTH)
                        return 0;
@@ -1464,12 +1453,14 @@ int ssl_cipher_list_to_bytes(SSL *s,STACK_OF(SSL_CIPHER) *sk,unsigned char *p,
        SSL_CIPHER *c;
        CERT *ct = s->cert;
        unsigned char *q;
-       int no_scsv = s->renegotiate;
+       int empty_reneg_info_scsv = !s->renegotiate;
        /* Set disabled masks for this session */
        ssl_set_client_disabled(s);
 
        if (sk == NULL) return(0);
        q=p;
+       if (put_cb == NULL)
+               put_cb = s->method->put_cipher_by_char;
 
        for (i=0; i<sk_SSL_CIPHER_num(sk); i++)
                {
@@ -1482,29 +1473,40 @@ int ssl_cipher_list_to_bytes(SSL *s,STACK_OF(SSL_CIPHER) *sk,unsigned char *p,
 #ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL
                if (c->id == SSL3_CK_SCSV)
                        {
-                       if (no_scsv)
+                       if (!empty_reneg_info_scsv)
                                continue;
                        else
-                               no_scsv = 1;
+                               empty_reneg_info_scsv = 0;
                        }
 #endif
-               j = put_cb ? put_cb(c,p) : ssl_put_cipher_by_char(s,c,p);
+               j = put_cb(c,p);
                p+=j;
                }
-       /* If p == q, no ciphers and caller indicates an error. Otherwise
-        * add SCSV if not renegotiating.
-        */
-       if (p != q && !no_scsv)
+       /* If p == q, no ciphers; caller indicates an error.
+        * Otherwise, add applicable SCSVs. */
+       if (p != q)
                {
-               static SSL_CIPHER scsv =
+               if (empty_reneg_info_scsv)
                        {
-                       0, NULL, SSL3_CK_SCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0
-                       };
-               j = put_cb ? put_cb(&scsv,p) : ssl_put_cipher_by_char(s,&scsv,p);
-               p+=j;
+                       static SSL_CIPHER scsv =
+                               {
+                               0, NULL, SSL3_CK_SCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0
+                               };
+                       j = put_cb(&scsv,p);
+                       p+=j;
 #ifdef OPENSSL_RI_DEBUG
-               fprintf(stderr, "SCSV sent by client\n");
+                       fprintf(stderr, "TLS_EMPTY_RENEGOTIATION_INFO_SCSV sent by client\n");
 #endif
+                       }
+               if (s->mode & SSL_MODE_SEND_FALLBACK_SCSV)
+                       {
+                       static SSL_CIPHER scsv =
+                               {
+                               0, NULL, SSL3_CK_FALLBACK_SCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0
+                               };
+                       j = put_cb(&scsv,p);
+                       p+=j;
+                       }
                }
 
        return(p-q);
@@ -1516,11 +1518,12 @@ STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s,unsigned char *p,int num,
        const SSL_CIPHER *c;
        STACK_OF(SSL_CIPHER) *sk;
        int i,n;
+
        if (s->s3)
                s->s3->send_connection_binding = 0;
 
        n=ssl_put_cipher_by_char(s,NULL,NULL);
-       if ((num%n) != 0)
+       if (n == 0 || (num%n) != 0)
                {
                SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST,SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST);
                return(NULL);
@@ -1545,7 +1548,7 @@ STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s,unsigned char *p,int num,
 
        for (i=0; i<num; i+=n)
                {
-               /* Check for SCSV */
+               /* Check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV */
                if (s->s3 && (n != 3 || !p[0]) &&
                        (p[n-2] == ((SSL3_CK_SCSV >> 8) & 0xff)) &&
                        (p[n-1] == (SSL3_CK_SCSV & 0xff)))
@@ -1565,6 +1568,24 @@ STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s,unsigned char *p,int num,
                        continue;
                        }
 
+               /* Check for TLS_FALLBACK_SCSV */
+               if ((n != 3 || !p[0]) &&
+                       (p[n-2] == ((SSL3_CK_FALLBACK_SCSV >> 8) & 0xff)) &&
+                       (p[n-1] == (SSL3_CK_FALLBACK_SCSV & 0xff)))
+                       {
+                       /* The SCSV indicates that the client previously tried a higher version.
+                        * Fail if the current version is an unexpected downgrade. */
+                       if (!SSL_ctrl(s, SSL_CTRL_CHECK_PROTO_VERSION, 0, NULL))
+                               {
+                               SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST,SSL_R_INAPPROPRIATE_FALLBACK);
+                               if (s->s3)
+                                       ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_INAPPROPRIATE_FALLBACK);
+                               goto err;
+                               }
+                       p += n;
+                       continue;
+                       }
+
                c=ssl_get_cipher_by_char(s,p);
                p+=n;
                if (c != NULL)
@@ -1896,7 +1917,8 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth)
        ret->quiet_shutdown=0;
 
 /*     ret->cipher=NULL;*/
-/*     ret->s2->challenge=NULL;
+/*-
+       ret->s2->challenge=NULL;
        ret->master_key=NULL;
        ret->key_arg=NULL;
        ret->s2->conn_id=NULL; */
@@ -2125,8 +2147,10 @@ void SSL_CTX_free(SSL_CTX *a)
        a->comp_methods = NULL;
 #endif
 
+#ifndef OPENSSL_NO_SRTP
         if (a->srtp_profiles)
                 sk_SRTP_PROTECTION_PROFILE_free(a->srtp_profiles);
+#endif
 
 #ifndef OPENSSL_NO_PSK
        if (a->psk_identity_hint)
@@ -2263,7 +2287,7 @@ void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher)
        
 
 #ifdef CIPHER_DEBUG
-       printf("rt=%d rte=%d dht=%d ecdht=%d re=%d ree=%d rs=%d ds=%d dhr=%d dhd=%d\n",
+       fprintf(stderr,"rt=%d rte=%d dht=%d ecdht=%d re=%d ree=%d rs=%d ds=%d dhr=%d dhd=%d\n",
                rsa_tmp,rsa_tmp_export,dh_tmp,have_ecdh_tmp,
                rsa_enc,rsa_enc_export,rsa_sign,dsa_sign,dh_rsa,dh_dsa);
 #endif
@@ -2341,8 +2365,10 @@ void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher)
                x = cpk->x509;
                /* This call populates extension flags (ex_flags) */
                X509_check_purpose(x, -1, 0);
+#ifndef OPENSSL_NO_ECDH
                ecdh_ok = (x->ex_flags & EXFLAG_KUSAGE) ?
                    (x->ex_kusage & X509v3_KU_KEY_AGREEMENT) : 1;
+#endif
                ecdsa_ok = (x->ex_flags & EXFLAG_KUSAGE) ?
                    (x->ex_kusage & X509v3_KU_DIGITAL_SIGNATURE) : 1;
                if (!(cpk->valid_flags & CERT_PKEY_SIGN))
@@ -3152,19 +3178,54 @@ SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl)
 
 SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX* ctx)
        {
+       CERT *ocert = ssl->cert;
        if (ssl->ctx == ctx)
                return ssl->ctx;
 #ifndef OPENSSL_NO_TLSEXT
        if (ctx == NULL)
                ctx = ssl->initial_ctx;
 #endif
-       if (ssl->cert != NULL)
-               ssl_cert_free(ssl->cert);
        ssl->cert = ssl_cert_dup(ctx->cert);
+       if (ocert)
+               {
+               /* Preserve any already negotiated parameters */
+               if (ssl->server)
+                       {
+                       ssl->cert->peer_sigalgs = ocert->peer_sigalgs;
+                       ssl->cert->peer_sigalgslen = ocert->peer_sigalgslen;
+                       ocert->peer_sigalgs = NULL;
+                       ssl->cert->ciphers_raw = ocert->ciphers_raw;
+                       ssl->cert->ciphers_rawlen = ocert->ciphers_rawlen;
+                       ocert->ciphers_raw = NULL;
+                       }
+               ssl_cert_free(ocert);
+               }
+
+       /*
+        * Program invariant: |sid_ctx| has fixed size (SSL_MAX_SID_CTX_LENGTH),
+        * so setter APIs must prevent invalid lengths from entering the system.
+        */
+       OPENSSL_assert(ssl->sid_ctx_length <= sizeof(ssl->sid_ctx));
+
+       /*
+        * If the session ID context matches that of the parent SSL_CTX,
+        * inherit it from the new SSL_CTX as well. If however the context does
+        * not match (i.e., it was set per-ssl with SSL_set_session_id_context),
+        * leave it unchanged.
+        */
+       if ((ssl->ctx != NULL) &&
+               (ssl->sid_ctx_length == ssl->ctx->sid_ctx_length) &&
+               (memcmp(ssl->sid_ctx, ssl->ctx->sid_ctx, ssl->sid_ctx_length) == 0))
+               {
+               ssl->sid_ctx_length = ctx->sid_ctx_length;
+               memcpy(&ssl->sid_ctx, &ctx->sid_ctx, sizeof(ssl->sid_ctx));
+               }
+
        CRYPTO_add(&ctx->references,1,CRYPTO_LOCK_SSL_CTX);
        if (ssl->ctx != NULL)
                SSL_CTX_free(ssl->ctx); /* decrement reference count */
        ssl->ctx = ctx;
+
        return(ssl->ctx);
        }