util/incore update.
[openssl.git] / ssl / s3_srvr.c
index 2f3158b4ce221ca9c8b2d41851d6003c77cfc167..04dbb7a735c4290fee1903f2358e38b94a344293 100644 (file)
 
 #include <stdio.h>
 #include "ssl_locl.h"
-#include "kssl_lcl.h"
 #include "../crypto/constant_time_locl.h"
 #include <openssl/buffer.h>
 #include <openssl/rand.h>
 # include <openssl/dh.h>
 #endif
 #include <openssl/bn.h>
-#ifndef OPENSSL_NO_KRB5
-# include <openssl/krb5_asn.h>
-#endif
 #include <openssl/md5.h>
 
 #ifndef OPENSSL_NO_SSL3_METHOD
@@ -421,11 +417,10 @@ int ssl3_accept(SSL *s)
         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 */
+            /* normal PSK or SRP */
             if (!
                 (s->s3->tmp.
-                 new_cipher->algorithm_auth & (SSL_aNULL | SSL_aKRB5 |
-                                               SSL_aSRP))
+                 new_cipher->algorithm_auth & (SSL_aNULL | SSL_aSRP))
 && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) {
                 ret = ssl3_send_server_certificate(s);
                 if (ret <= 0)
@@ -516,16 +511,12 @@ int ssl3_accept(SSL *s)
                     * RFC 2246):
                     */
                    ((s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) &&
-                    /*
-                     * ... except when the application insists on
-                     * verification (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
+                    * ... except when the application insists on
+                    * verification (against the specs, but s3_clnt.c accepts
+                    * this for SSL 3)
                     */
-                   (s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5) ||
+                   !(s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) ||
                    /* don't request certificate for SRP auth */
                    (s->s3->tmp.new_cipher->algorithm_auth & SSL_aSRP)
                    /*
@@ -682,15 +673,6 @@ int ssl3_accept(SSL *s)
 
         case SSL3_ST_SR_CERT_VRFY_A:
         case SSL3_ST_SR_CERT_VRFY_B:
-            /*
-             * This *should* be the first time we enable CCS, but be
-             * extra careful about surrounding code changes. We need
-             * to set this here because we don't know if we're
-             * expecting a CertificateVerify or not.
-             */
-            if (!s->s3->change_cipher_spec)
-                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;
@@ -710,11 +692,10 @@ int ssl3_accept(SSL *s)
         case SSL3_ST_SR_NEXT_PROTO_A:
         case SSL3_ST_SR_NEXT_PROTO_B:
             /*
-             * Enable CCS for resumed handshakes with NPN.
-             * In a full handshake with NPN, we end up here through
-             * SSL3_ST_SR_CERT_VRFY_B, where SSL3_FLAGS_CCS_OK was
-             * already set. Receiving a CCS clears the flag, so make
-             * sure not to re-enable it to ban duplicates.
+             * Enable CCS for NPN. Receiving a CCS clears the flag, so make
+             * sure not to re-enable it to ban duplicates. This *should* be the
+             * first time we have received one - but we check anyway to be
+             * cautious.
              * s->s3->change_cipher_spec is set when a CCS is
              * processed in s3_pkt.c, and remains set until
              * the client's Finished message is read.
@@ -733,10 +714,8 @@ int ssl3_accept(SSL *s)
         case SSL3_ST_SR_FINISHED_A:
         case SSL3_ST_SR_FINISHED_B:
             /*
-             * Enable CCS for resumed handshakes without NPN.
-             * In a full handshake, we end up here through
-             * SSL3_ST_SR_CERT_VRFY_B, where SSL3_FLAGS_CCS_OK was
-             * already set. Receiving a CCS clears the flag, so make
+             * Enable CCS for handshakes without NPN. In NPN the CCS flag has
+             * already been set. Receiving a CCS clears the flag, so make
              * sure not to re-enable it to ban duplicates.
              * s->s3->change_cipher_spec is set when a CCS is
              * processed in s3_pkt.c, and remains set until
@@ -2135,9 +2114,6 @@ int ssl3_get_client_key_exchange(SSL *s)
     BIGNUM *pub = NULL;
     DH *dh_srvr, *dh_clnt = NULL;
 #endif
-#ifndef OPENSSL_NO_KRB5
-    KSSL_ERR kssl_err;
-#endif                          /* OPENSSL_NO_KRB5 */
 
 #ifndef OPENSSL_NO_EC
     EC_KEY *srvr_ecdh = NULL;
@@ -2403,189 +2379,6 @@ int ssl3_get_client_key_exchange(SSL *s)
             return 2;
     } else
 #endif
-#ifndef OPENSSL_NO_KRB5
-    if (alg_k & SSL_kKRB5) {
-        krb5_error_code krb5rc;
-        krb5_data enc_ticket;
-        krb5_data authenticator;
-        krb5_data enc_pms;
-        KSSL_CTX *kssl_ctx = s->kssl_ctx;
-        EVP_CIPHER_CTX ciph_ctx;
-        const EVP_CIPHER *enc = NULL;
-        unsigned char iv[EVP_MAX_IV_LENGTH];
-        unsigned char pms[SSL_MAX_MASTER_KEY_LENGTH + EVP_MAX_BLOCK_LENGTH];
-        int padl, outl;
-        krb5_timestamp authtime = 0;
-        krb5_ticket_times ttimes;
-
-        EVP_CIPHER_CTX_init(&ciph_ctx);
-
-        if (!kssl_ctx)
-            kssl_ctx = kssl_ctx_new();
-
-        n2s(p, i);
-        enc_ticket.length = i;
-
-        if (n < (long)(enc_ticket.length + 6)) {
-            SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
-                   SSL_R_DATA_LENGTH_TOO_LONG);
-            goto err;
-        }
-
-        enc_ticket.data = (char *)p;
-        p += enc_ticket.length;
-
-        n2s(p, i);
-        authenticator.length = i;
-
-        if (n < (long)(enc_ticket.length + authenticator.length + 6)) {
-            SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
-                   SSL_R_DATA_LENGTH_TOO_LONG);
-            goto err;
-        }
-
-        authenticator.data = (char *)p;
-        p += authenticator.length;
-
-        n2s(p, i);
-        enc_pms.length = i;
-        enc_pms.data = (char *)p;
-        p += enc_pms.length;
-
-        /*
-         * Note that the length is checked again below, ** after decryption
-         */
-        if (enc_pms.length > sizeof pms) {
-            SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
-                   SSL_R_DATA_LENGTH_TOO_LONG);
-            goto err;
-        }
-
-        if (n != (long)(enc_ticket.length + authenticator.length +
-                        enc_pms.length + 6)) {
-            SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
-                   SSL_R_DATA_LENGTH_TOO_LONG);
-            goto err;
-        }
-
-        if ((krb5rc = kssl_sget_tkt(kssl_ctx, &enc_ticket, &ttimes,
-                                    &kssl_err)) != 0) {
-# ifdef KSSL_DEBUG
-            fprintf(stderr, "kssl_sget_tkt rtn %d [%d]\n",
-                    krb5rc, kssl_err.reason);
-            if (kssl_err.text)
-                fprintf(stderr, "kssl_err text= %s\n", kssl_err.text);
-# endif                         /* KSSL_DEBUG */
-            SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, kssl_err.reason);
-            goto err;
-        }
-
-        /*
-         * Note: no authenticator is not considered an error, ** but will
-         * return authtime == 0.
-         */
-        if ((krb5rc = kssl_check_authent(kssl_ctx, &authenticator,
-                                         &authtime, &kssl_err)) != 0) {
-# ifdef KSSL_DEBUG
-            fprintf(stderr, "kssl_check_authent rtn %d [%d]\n",
-                    krb5rc, kssl_err.reason);
-            if (kssl_err.text)
-                fprintf(stderr, "kssl_err text= %s\n", kssl_err.text);
-# endif                         /* KSSL_DEBUG */
-            SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, kssl_err.reason);
-            goto err;
-        }
-
-        if ((krb5rc = kssl_validate_times(authtime, &ttimes)) != 0) {
-            SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, krb5rc);
-            goto err;
-        }
-# ifdef KSSL_DEBUG
-        kssl_ctx_show(kssl_ctx);
-# endif                         /* KSSL_DEBUG */
-
-        enc = kssl_map_enc(kssl_ctx->enctype);
-        if (enc == NULL)
-            goto err;
-
-        memset(iv, 0, sizeof(iv)); /* per RFC 1510 */
-
-        if (!EVP_DecryptInit_ex(&ciph_ctx, enc, NULL, kssl_ctx->key, iv)) {
-            SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
-                   SSL_R_DECRYPTION_FAILED);
-            goto err;
-        }
-        if (!EVP_DecryptUpdate(&ciph_ctx, pms, &outl,
-                               (unsigned char *)enc_pms.data, enc_pms.length))
-        {
-            SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
-                   SSL_R_DECRYPTION_FAILED);
-            goto err;
-        }
-        if (outl > SSL_MAX_MASTER_KEY_LENGTH) {
-            SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
-                   SSL_R_DATA_LENGTH_TOO_LONG);
-            goto err;
-        }
-        if (!EVP_DecryptFinal_ex(&ciph_ctx, &(pms[outl]), &padl)) {
-            SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
-                   SSL_R_DECRYPTION_FAILED);
-            goto err;
-        }
-        outl += padl;
-        if (outl > SSL_MAX_MASTER_KEY_LENGTH) {
-            SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
-                   SSL_R_DATA_LENGTH_TOO_LONG);
-            goto err;
-        }
-        if (!((pms[0] == (s->client_version >> 8))
-              && (pms[1] == (s->client_version & 0xff)))) {
-            /*
-             * The premaster secret must contain the same version number as
-             * the ClientHello to detect version rollback attacks (strangely,
-             * the protocol does not offer such protection for DH
-             * ciphersuites). However, buggy clients exist that send random
-             * bytes instead of the protocol version. If
-             * SSL_OP_TLS_ROLLBACK_BUG is set, tolerate such clients.
-             * (Perhaps we should have a separate BUG value for the Kerberos
-             * cipher)
-             */
-            if (!(s->options & SSL_OP_TLS_ROLLBACK_BUG)) {
-                SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
-                       SSL_AD_DECODE_ERROR);
-                goto err;
-            }
-        }
-
-        EVP_CIPHER_CTX_cleanup(&ciph_ctx);
-
-        s->session->master_key_length =
-            s->method->ssl3_enc->generate_master_secret(s,
-                                                        s->
-                                                        session->master_key,
-                                                        pms, outl);
-        if (s->session->master_key_length < 0) {
-            al = SSL_AD_INTERNAL_ERROR;
-            SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
-            goto f_err;
-        }
-
-        if (kssl_ctx->client_princ) {
-            size_t len = strlen(kssl_ctx->client_princ);
-            if (len < SSL_MAX_KRB5_PRINCIPAL_LENGTH) {
-                s->session->krb5_client_princ_len = len;
-                memcpy(s->session->krb5_client_princ, kssl_ctx->client_princ,
-                       len);
-            }
-        }
-
-        /*- Was doing kssl_ctx_free() here,
-         *  but it caused problems for apache.
-         *  kssl_ctx = kssl_ctx_free(kssl_ctx);
-         *  if (s->kssl_ctx)  s->kssl_ctx = NULL;
-         */
-    } else
-#endif                          /* OPENSSL_NO_KRB5 */
 
 #ifndef OPENSSL_NO_EC
     if (alg_k & (SSL_kECDHE | SSL_kECDHr | SSL_kECDHe)) {
@@ -2960,39 +2753,31 @@ int ssl3_get_cert_verify(SSL *s)
     EVP_MD_CTX mctx;
     EVP_MD_CTX_init(&mctx);
 
+    /*
+     * We should only process a CertificateVerify message if we have received
+     * a Certificate from the client. If so then |s->session->peer| will be non
+     * NULL. In some instances a CertificateVerify message is not required even
+     * if the peer has sent a Certificate (e.g. such as in the case of static
+     * DH). In that case the ClientKeyExchange processing will skip the
+     * CertificateVerify state so we should not arrive here.
+     */
+    if (s->session->peer == NULL) {
+        ret = 1;
+        goto end;
+    }
+
     n = s->method->ssl_get_message(s,
                                    SSL3_ST_SR_CERT_VRFY_A,
                                    SSL3_ST_SR_CERT_VRFY_B,
-                                   -1, SSL3_RT_MAX_PLAIN_LENGTH, &ok);
+                                   SSL3_MT_CERTIFICATE_VERIFY,
+                                   SSL3_RT_MAX_PLAIN_LENGTH, &ok);
 
     if (!ok)
         return ((int)n);
 
-    if (s->session->peer != NULL) {
-        peer = s->session->peer;
-        pkey = X509_get_pubkey(peer);
-        type = X509_certificate_type(peer, pkey);
-    } else {
-        peer = NULL;
-        pkey = NULL;
-    }
-
-    if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE_VERIFY) {
-        s->s3->tmp.reuse_message = 1;
-        if (peer != NULL) {
-            al = SSL_AD_UNEXPECTED_MESSAGE;
-            SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_MISSING_VERIFY_MESSAGE);
-            goto f_err;
-        }
-        ret = 1;
-        goto end;
-    }
-
-    if (peer == NULL) {
-        SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_NO_CLIENT_CERT_RECEIVED);
-        al = SSL_AD_UNEXPECTED_MESSAGE;
-        goto f_err;
-    }
+    peer = s->session->peer;
+    pkey = X509_get_pubkey(peer);
+    type = X509_certificate_type(peer, pkey);
 
     if (!(type & EVP_PKT_SIGN)) {
         SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,
@@ -3001,12 +2786,6 @@ int ssl3_get_cert_verify(SSL *s)
         goto f_err;
     }
 
-    if (s->s3->change_cipher_spec) {
-        SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_CCS_RECEIVED_EARLY);
-        al = SSL_AD_UNEXPECTED_MESSAGE;
-        goto f_err;
-    }
-
     /* we now have a signature that we need to verify */
     p = (unsigned char *)s->init_msg;
     /* Check for broken implementations of GOST ciphersuites */
@@ -3329,14 +3108,9 @@ int ssl3_send_server_certificate(SSL *s)
     if (s->state == SSL3_ST_SW_CERT_A) {
         cpk = ssl_get_server_send_pkey(s);
         if (cpk == NULL) {
-            /* VRS: allow null cert if auth == KRB5 */
-            if ((s->s3->tmp.new_cipher->algorithm_auth != SSL_aKRB5) ||
-                (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kKRB5)) {
-                SSLerr(SSL_F_SSL3_SEND_SERVER_CERTIFICATE,
-                       ERR_R_INTERNAL_ERROR);
-                s->state = SSL_ST_ERR;
-                return (0);
-            }
+            SSLerr(SSL_F_SSL3_SEND_SERVER_CERTIFICATE, ERR_R_INTERNAL_ERROR);
+            s->state = SSL_ST_ERR;
+            return (0);
         }
 
         if (!ssl3_output_cert_chain(s, cpk)) {