Protocol version selection and negotiation rewrite
[openssl.git] / ssl / ssl_lib.c
index d598f91eb79c5d66ec6c96cc0fb9701ca44cc03f..760014d739eed93f874160e68832205d451919a5 100644 (file)
@@ -293,6 +293,8 @@ SSL *SSL_new(SSL_CTX *ctx)
     RECORD_LAYER_init(&s->rlayer, s);
 
     s->options = ctx->options;
+    s->min_proto_version = ctx->min_proto_version;
+    s->max_proto_version = ctx->max_proto_version;
     s->mode = ctx->mode;
     s->max_cert_list = ctx->max_cert_list;
     s->references = 1;
@@ -344,8 +346,8 @@ SSL *SSL_new(SSL_CTX *ctx)
 # ifndef OPENSSL_NO_EC
     if (ctx->tlsext_ecpointformatlist) {
         s->tlsext_ecpointformatlist =
-            BUF_memdup(ctx->tlsext_ecpointformatlist,
-                       ctx->tlsext_ecpointformatlist_length);
+            OPENSSL_memdup(ctx->tlsext_ecpointformatlist,
+                           ctx->tlsext_ecpointformatlist_length);
         if (!s->tlsext_ecpointformatlist)
             goto err;
         s->tlsext_ecpointformatlist_length =
@@ -353,8 +355,8 @@ SSL *SSL_new(SSL_CTX *ctx)
     }
     if (ctx->tlsext_ellipticcurvelist) {
         s->tlsext_ellipticcurvelist =
-            BUF_memdup(ctx->tlsext_ellipticcurvelist,
-                       ctx->tlsext_ellipticcurvelist_length);
+            OPENSSL_memdup(ctx->tlsext_ellipticcurvelist,
+                           ctx->tlsext_ellipticcurvelist_length);
         if (!s->tlsext_ellipticcurvelist)
             goto err;
         s->tlsext_ellipticcurvelist_length =
@@ -1198,6 +1200,12 @@ long SSL_ctrl(SSL *s, int cmd, long larg, void *parg)
             return 1;
         else
             return 0;
+    case SSL_CTRL_SET_MIN_PROTO_VERSION:
+        return ssl_set_version_bound(s->ctx->method->version, (int)larg,
+                                     &s->min_proto_version);
+    case SSL_CTRL_SET_MAX_PROTO_VERSION:
+        return ssl_set_version_bound(s->ctx->method->version, (int)larg,
+                                     &s->max_proto_version);
     default:
         return (s->method->ssl_ctrl(s, cmd, larg, parg));
     }
@@ -1314,6 +1322,12 @@ long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
         return (ctx->cert->cert_flags |= larg);
     case SSL_CTRL_CLEAR_CERT_FLAGS:
         return (ctx->cert->cert_flags &= ~larg);
+    case SSL_CTRL_SET_MIN_PROTO_VERSION:
+        return ssl_set_version_bound(ctx->method->version, (int)larg,
+                                     &ctx->min_proto_version);
+    case SSL_CTRL_SET_MAX_PROTO_VERSION:
+        return ssl_set_version_bound(ctx->method->version, (int)larg,
+                                     &ctx->max_proto_version);
     default:
         return (ctx->method->ssl_ctx_ctrl(ctx, cmd, larg, parg));
     }
@@ -1781,7 +1795,7 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth)
     }
 
     if (FIPS_mode() && (meth->version < TLS1_VERSION)) {
-        SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE);
+        SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_AT_LEAST_TLS_1_0_NEEDED_IN_FIPS_MODE);
         return NULL;
     }
 
@@ -1794,6 +1808,8 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth)
         goto err;
 
     ret->method = meth;
+    ret->min_proto_version = 0;
+    ret->max_proto_version = 0;
     ret->session_cache_mode = SSL_SESS_CACHE_SERVER;
     ret->session_cache_size = SSL_SESSION_CACHE_MAX_SIZE_DEFAULT;
     /* We take the system default. */
@@ -2001,71 +2017,41 @@ void SSL_set_cert_cb(SSL *s, int (*cb) (SSL *ssl, void *arg), void *arg)
 
 void ssl_set_masks(SSL *s, const SSL_CIPHER *cipher)
 {
+#if !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_GOST)
     CERT_PKEY *cpk;
+#endif
     CERT *c = s->cert;
     uint32_t *pvalid = s->s3->tmp.valid_flags;
-    int rsa_enc, rsa_tmp, rsa_sign, dh_tmp, dh_rsa, dh_dsa, dsa_sign;
-    int rsa_enc_export, dh_rsa_export, dh_dsa_export;
-    int rsa_tmp_export, dh_tmp_export, kl;
-    unsigned long mask_k, mask_a, emask_k, emask_a;
+    int rsa_enc, rsa_sign, dh_tmp, dsa_sign;
+    unsigned long mask_k, mask_a;
 #ifndef OPENSSL_NO_EC
-    int have_ecc_cert, ecdsa_ok, ecc_pkey_size;
-    int have_ecdh_tmp, ecdh_ok;
+    int have_ecc_cert, ecdsa_ok;
+    int ecdh_ok;
     X509 *x = NULL;
-    EVP_PKEY *ecc_pkey = NULL;
     int pk_nid = 0, md_nid = 0;
 #endif
     if (c == NULL)
         return;
 
-    kl = SSL_C_EXPORT_PKEYLENGTH(cipher);
-
-#ifndef OPENSSL_NO_RSA
-    rsa_tmp = (c->rsa_tmp != NULL || c->rsa_tmp_cb != NULL);
-    rsa_tmp_export = (c->rsa_tmp_cb != NULL ||
-                      (rsa_tmp && RSA_size(c->rsa_tmp) * 8 <= kl));
-#else
-    rsa_tmp = rsa_tmp_export = 0;
-#endif
 #ifndef OPENSSL_NO_DH
     dh_tmp = (c->dh_tmp != NULL || c->dh_tmp_cb != NULL || c->dh_tmp_auto);
-    dh_tmp_export = !c->dh_tmp_auto && (c->dh_tmp_cb != NULL ||
-                                        (dh_tmp
-                                         && DH_size(c->dh_tmp) * 8 <= kl));
 #else
-    dh_tmp = dh_tmp_export = 0;
+    dh_tmp = 0;
 #endif
 
-#ifndef OPENSSL_NO_EC
-    have_ecdh_tmp = c->ecdh_tmp_auto;
-#endif
-    cpk = &(c->pkeys[SSL_PKEY_RSA_ENC]);
     rsa_enc = pvalid[SSL_PKEY_RSA_ENC] & CERT_PKEY_VALID;
-    rsa_enc_export = (rsa_enc && EVP_PKEY_size(cpk->privatekey) * 8 <= kl);
-    cpk = &(c->pkeys[SSL_PKEY_RSA_SIGN]);
     rsa_sign = pvalid[SSL_PKEY_RSA_SIGN] & CERT_PKEY_SIGN;
-    cpk = &(c->pkeys[SSL_PKEY_DSA_SIGN]);
     dsa_sign = pvalid[SSL_PKEY_DSA_SIGN] & CERT_PKEY_SIGN;
-    cpk = &(c->pkeys[SSL_PKEY_DH_RSA]);
-    dh_rsa = pvalid[SSL_PKEY_DH_RSA] & CERT_PKEY_VALID;
-    dh_rsa_export = (dh_rsa && EVP_PKEY_size(cpk->privatekey) * 8 <= kl);
-    cpk = &(c->pkeys[SSL_PKEY_DH_DSA]);
-    dh_dsa = pvalid[SSL_PKEY_DH_DSA] & CERT_PKEY_VALID;
-    dh_dsa_export = (dh_dsa && EVP_PKEY_size(cpk->privatekey) * 8 <= kl);
-    cpk = &(c->pkeys[SSL_PKEY_ECC]);
 #ifndef OPENSSL_NO_EC
     have_ecc_cert = pvalid[SSL_PKEY_ECC] & CERT_PKEY_VALID;
 #endif
     mask_k = 0;
     mask_a = 0;
-    emask_k = 0;
-    emask_a = 0;
 
 #ifdef CIPHER_DEBUG
     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);
+            "dht=%d re=%d rs=%d ds=%d dhr=%d dhd=%d\n",
+            dh_tmp, rsa_enc, rsa_sign, dsa_sign, dh_rsa, dh_dsa);
 #endif
 
 #ifndef OPENSSL_NO_GOST
@@ -2086,42 +2072,21 @@ void ssl_set_masks(SSL *s, const SSL_CIPHER *cipher)
     }
 #endif
 
-    if (rsa_enc || (rsa_tmp && rsa_sign))
+    if (rsa_enc)
         mask_k |= SSL_kRSA;
-    if (rsa_enc_export || (rsa_tmp_export && (rsa_sign || rsa_enc)))
-        emask_k |= SSL_kRSA;
-
-    if (dh_tmp_export)
-        emask_k |= SSL_kDHE;
 
     if (dh_tmp)
         mask_k |= SSL_kDHE;
 
-    if (dh_rsa)
-        mask_k |= SSL_kDHr;
-    if (dh_rsa_export)
-        emask_k |= SSL_kDHr;
-
-    if (dh_dsa)
-        mask_k |= SSL_kDHd;
-    if (dh_dsa_export)
-        emask_k |= SSL_kDHd;
-
-    if (mask_k & (SSL_kDHr | SSL_kDHd))
-        mask_a |= SSL_aDH;
-
     if (rsa_enc || rsa_sign) {
         mask_a |= SSL_aRSA;
-        emask_a |= SSL_aRSA;
     }
 
     if (dsa_sign) {
         mask_a |= SSL_aDSS;
-        emask_a |= SSL_aDSS;
     }
 
     mask_a |= SSL_aNULL;
-    emask_a |= SSL_aNULL;
 
     /*
      * An ECC certificate may be usable for ECDH and/or ECDSA cipher suites
@@ -2137,49 +2102,32 @@ void ssl_set_masks(SSL *s, const SSL_CIPHER *cipher)
         ecdsa_ok = ex_kusage & X509v3_KU_DIGITAL_SIGNATURE;
         if (!(pvalid[SSL_PKEY_ECC] & CERT_PKEY_SIGN))
             ecdsa_ok = 0;
-        ecc_pkey = X509_get_pubkey(x);
-        ecc_pkey_size = (ecc_pkey != NULL) ? EVP_PKEY_bits(ecc_pkey) : 0;
-        EVP_PKEY_free(ecc_pkey);
         OBJ_find_sigid_algs(X509_get_signature_nid(x), &md_nid, &pk_nid);
         if (ecdh_ok) {
 
             if (pk_nid == NID_rsaEncryption || pk_nid == NID_rsa) {
                 mask_k |= SSL_kECDHr;
                 mask_a |= SSL_aECDH;
-                if (ecc_pkey_size <= 163) {
-                    emask_k |= SSL_kECDHr;
-                    emask_a |= SSL_aECDH;
-                }
             }
 
             if (pk_nid == NID_X9_62_id_ecPublicKey) {
                 mask_k |= SSL_kECDHe;
                 mask_a |= SSL_aECDH;
-                if (ecc_pkey_size <= 163) {
-                    emask_k |= SSL_kECDHe;
-                    emask_a |= SSL_aECDH;
-                }
             }
         }
         if (ecdsa_ok) {
             mask_a |= SSL_aECDSA;
-            emask_a |= SSL_aECDSA;
         }
     }
 #endif
 
 #ifndef OPENSSL_NO_EC
-    if (have_ecdh_tmp) {
-        mask_k |= SSL_kECDHE;
-        emask_k |= SSL_kECDHE;
-    }
+    mask_k |= SSL_kECDHE;
 #endif
 
 #ifndef OPENSSL_NO_PSK
     mask_k |= SSL_kPSK;
     mask_a |= SSL_aPSK;
-    emask_k |= SSL_kPSK;
-    emask_a |= SSL_aPSK;
     if (mask_k & SSL_kRSA)
         mask_k |= SSL_kRSAPSK;
     if (mask_k & SSL_kDHE)
@@ -2190,8 +2138,6 @@ void ssl_set_masks(SSL *s, const SSL_CIPHER *cipher)
 
     s->s3->tmp.mask_k = mask_k;
     s->s3->tmp.mask_a = mask_a;
-    s->s3->tmp.export_mask_k = emask_k;
-    s->s3->tmp.export_mask_a = emask_a;
 }
 
 #ifndef OPENSSL_NO_EC
@@ -2199,8 +2145,6 @@ void ssl_set_masks(SSL *s, const SSL_CIPHER *cipher)
 int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s)
 {
     unsigned long alg_k, alg_a;
-    EVP_PKEY *pkey = NULL;
-    int keysize = 0;
     int md_nid = 0, pk_nid = 0;
     const SSL_CIPHER *cs = s->s3->tmp.new_cipher;
     uint32_t ex_kusage = X509_get_key_usage(x);
@@ -2208,17 +2152,6 @@ int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s)
     alg_k = cs->algorithm_mkey;
     alg_a = cs->algorithm_auth;
 
-    if (SSL_C_IS_EXPORT(cs)) {
-        /* ECDH key length in export ciphers must be <= 163 bits */
-        pkey = X509_get_pubkey(x);
-        if (pkey == NULL)
-            return 0;
-        keysize = EVP_PKEY_bits(pkey);
-        EVP_PKEY_free(pkey);
-        if (keysize > 163)
-            return 0;
-    }
-
     OBJ_find_sigid_algs(X509_get_signature_nid(x), &md_nid, &pk_nid);
 
     if (alg_k & SSL_kECDHe || alg_k & SSL_kECDHr) {
@@ -3083,44 +3016,6 @@ int SSL_want(const SSL *s)
     return (s->rwstate);
 }
 
-/**
- * \brief Set the callback for generating temporary RSA keys.
- * \param ctx the SSL context.
- * \param cb the callback
- */
-
-#ifndef OPENSSL_NO_RSA
-void SSL_CTX_set_tmp_rsa_callback(SSL_CTX *ctx, RSA *(*cb) (SSL *ssl,
-                                                            int is_export,
-                                                            int keylength))
-{
-    SSL_CTX_callback_ctrl(ctx, SSL_CTRL_SET_TMP_RSA_CB, (void (*)(void))cb);
-}
-
-void SSL_set_tmp_rsa_callback(SSL *ssl, RSA *(*cb) (SSL *ssl,
-                                                    int is_export,
-                                                    int keylength))
-{
-    SSL_callback_ctrl(ssl, SSL_CTRL_SET_TMP_RSA_CB, (void (*)(void))cb);
-}
-#endif
-
-#ifdef DOXYGEN
-/**
- * \brief The RSA temporary key callback function.
- * \param ssl the SSL session.
- * \param is_export \c TRUE if the temp RSA key is for an export ciphersuite.
- * \param keylength if \c is_export is \c TRUE, then \c keylength is the size
- * of the required key in bits.
- * \return the temporary RSA key.
- * \sa SSL_CTX_set_tmp_rsa_callback, SSL_set_tmp_rsa_callback
- */
-
-RSA *cb(SSL *ssl, int is_export, int keylength)
-{
-}
-#endif
-
 /**
  * \brief Set the callback for generating temporary DH keys.
  * \param ctx the SSL context.
@@ -3152,7 +3047,7 @@ int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *identity_hint)
     }
     OPENSSL_free(ctx->cert->psk_identity_hint);
     if (identity_hint != NULL) {
-        ctx->cert->psk_identity_hint = BUF_strdup(identity_hint);
+        ctx->cert->psk_identity_hint = OPENSSL_strdup(identity_hint);
         if (ctx->cert->psk_identity_hint == NULL)
             return 0;
     } else
@@ -3171,7 +3066,7 @@ int SSL_use_psk_identity_hint(SSL *s, const char *identity_hint)
     }
     OPENSSL_free(s->cert->psk_identity_hint);
     if (identity_hint != NULL) {
-        s->cert->psk_identity_hint = BUF_strdup(identity_hint);
+        s->cert->psk_identity_hint = OPENSSL_strdup(identity_hint);
         if (s->cert->psk_identity_hint == NULL)
             return 0;
     } else
@@ -3283,9 +3178,9 @@ void SSL_set_not_resumable_session_callback(SSL *ssl,
 EVP_MD_CTX *ssl_replace_hash(EVP_MD_CTX **hash, const EVP_MD *md)
 {
     ssl_clear_hash_ctx(hash);
-    *hash = EVP_MD_CTX_create();
+    *hash = EVP_MD_CTX_new();
     if (*hash == NULL || (md && EVP_DigestInit_ex(*hash, md, NULL) <= 0)) {
-        EVP_MD_CTX_destroy(*hash);
+        EVP_MD_CTX_free(*hash);
         *hash = NULL;
         return NULL;
     }
@@ -3296,26 +3191,30 @@ void ssl_clear_hash_ctx(EVP_MD_CTX **hash)
 {
 
     if (*hash)
-        EVP_MD_CTX_destroy(*hash);
+        EVP_MD_CTX_free(*hash);
     *hash = NULL;
 }
 
 /* Retrieve handshake hashes */
 int ssl_handshake_hash(SSL *s, unsigned char *out, int outlen)
 {
-    EVP_MD_CTX ctx;
+    EVP_MD_CTX *ctx = NULL;
     EVP_MD_CTX *hdgst = s->s3->handshake_dgst;
     int ret = EVP_MD_CTX_size(hdgst);
-    EVP_MD_CTX_init(&ctx);
     if (ret < 0 || ret > outlen) {
         ret = 0;
         goto err;
     }
-    if (!EVP_MD_CTX_copy_ex(&ctx, hdgst)
-        || EVP_DigestFinal_ex(&ctx, out, NULL) <= 0)
+    ctx = EVP_MD_CTX_new();
+    if (ctx == NULL) {
+        ret = 0;
+        goto err;
+    }
+    if (!EVP_MD_CTX_copy_ex(ctx, hdgst)
+        || EVP_DigestFinal_ex(ctx, out, NULL) <= 0)
         ret = 0;
  err:
-    EVP_MD_CTX_cleanup(&ctx);
+    EVP_MD_CTX_free(ctx);
     return ret;
 }