PSK PRF correction.
[openssl.git] / ssl / s3_lib.c
index ad413aa702145327c2050e79818aaa7b4f3f72ea..527ec1f9469ca119d1e889b70b53b2dacd7898c7 100644 (file)
@@ -1612,6 +1612,40 @@ OPENSSL_GLOBAL const SSL_CIPHER ssl3_ciphers[] = {
      256,
      256,
      },
+#ifndef OPENSSL_NO_PSK
+    /* Cipher A8 */
+    {
+     1,
+     TLS1_TXT_PSK_WITH_AES_128_GCM_SHA256,
+     TLS1_CK_PSK_WITH_AES_128_GCM_SHA256,
+     SSL_kPSK,
+     SSL_aPSK,
+     SSL_AES128GCM,
+     SSL_AEAD,
+     SSL_TLSV1_2,
+     SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
+     128,
+     128,
+     },
+
+    /* Cipher A9 */
+    {
+     1,
+     TLS1_TXT_PSK_WITH_AES_256_GCM_SHA384,
+     TLS1_CK_PSK_WITH_AES_256_GCM_SHA384,
+     SSL_kPSK,
+     SSL_aPSK,
+     SSL_AES256GCM,
+     SSL_AEAD,
+     SSL_TLSV1_2,
+     SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384,
+     256,
+     256,
+     },
+
+#endif
 
 #ifndef OPENSSL_NO_CAMELLIA
     /* TLS 1.2 Camellia SHA-256 ciphersuites from RFC5932 */
@@ -2911,7 +2945,6 @@ void ssl3_free(SSL *s)
     OPENSSL_free(s->s3->tmp.ciphers_raw);
     OPENSSL_clear_free(s->s3->tmp.pms, s->s3->tmp.pmslen);
     OPENSSL_free(s->s3->tmp.peer_sigalgs);
-    BIO_free(s->s3->handshake_buffer);
     ssl3_free_digest_list(s);
     OPENSSL_free(s->s3->alpn_selected);
 
@@ -2955,8 +2988,6 @@ void ssl3_clear(SSL *s)
 #endif                         /* !OPENSSL_NO_EC */
 
     init_extra = s->s3->init_extra;
-    BIO_free(s->s3->handshake_buffer);
-    s->s3->handshake_buffer = NULL;
     ssl3_free_digest_list(s);
 
     if (s->s3->alpn_selected) {
@@ -3327,7 +3358,7 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
 
     case SSL_CTRL_GET_PEER_SIGNATURE_NID:
         if (SSL_USE_SIGALGS(s)) {
-            if (s->session && s->session->sess_cert) {
+            if (s->session) {
                 const EVP_MD *sig;
                 sig = s->s3->tmp.peer_md;
                 if (sig) {
@@ -3342,7 +3373,7 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
             return 0;
 
     case SSL_CTRL_GET_SERVER_TMP_KEY:
-        if (s->server || !s->session || !s->session->sess_cert)
+        if (s->server || !s->session)
             return 0;
         else {
             EVP_PKEY *ptmp;
@@ -3902,7 +3933,7 @@ SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
 
 #ifndef OPENSSL_NO_PSK
         /* with PSK there must be server callback set */
-        if ((alg_k & SSL_kPSK) && s->psk_server_callback == NULL)
+        if ((alg_k & SSL_PSK) && s->psk_server_callback == NULL)
             continue;
 #endif                          /* OPENSSL_NO_PSK */
 
@@ -4100,54 +4131,12 @@ int ssl3_shutdown(SSL *s)
 
 int ssl3_write(SSL *s, const void *buf, int len)
 {
-    int ret, n;
-
-#if 0
-    if (s->shutdown & SSL_SEND_SHUTDOWN) {
-        s->rwstate = SSL_NOTHING;
-        return (0);
-    }
-#endif
     clear_sys_error();
     if (s->s3->renegotiate)
         ssl3_renegotiate_check(s);
 
-    /*
-     * This is an experimental flag that sends the last handshake message in
-     * the same packet as the first use data - used to see if it helps the
-     * TCP protocol during session-id reuse
-     */
-    /* The second test is because the buffer may have been removed */
-    if ((s->s3->flags & SSL3_FLAGS_POP_BUFFER) && (s->wbio == s->bbio)) {
-        /* First time through, we write into the buffer */
-        if (s->s3->delay_buf_pop_ret == 0) {
-            ret = ssl3_write_bytes(s, SSL3_RT_APPLICATION_DATA, buf, len);
-            if (ret <= 0)
-                return (ret);
-
-            s->s3->delay_buf_pop_ret = ret;
-        }
-
-        s->rwstate = SSL_WRITING;
-        n = BIO_flush(s->wbio);
-        if (n <= 0)
-            return (n);
-        s->rwstate = SSL_NOTHING;
-
-        /* We have flushed the buffer, so remove it */
-        ssl_free_wbio_buffer(s);
-        s->s3->flags &= ~SSL3_FLAGS_POP_BUFFER;
-
-        ret = s->s3->delay_buf_pop_ret;
-        s->s3->delay_buf_pop_ret = 0;
-    } else {
-        ret = s->method->ssl_write_bytes(s, SSL3_RT_APPLICATION_DATA,
+    return s->method->ssl_write_bytes(s, SSL3_RT_APPLICATION_DATA,
                                          buf, len);
-        if (ret <= 0)
-            return (ret);
-    }
-
-    return (ret);
 }
 
 static int ssl3_read_internal(SSL *s, void *buf, int len, int peek)
@@ -4228,13 +4217,19 @@ int ssl3_renegotiate_check(SSL *s)
 /*
  * If we are using default SHA1+MD5 algorithms switch to new SHA256 PRF and
  * handshake macs if required.
+ *
+ * If PSK and using SHA384 for TLS < 1.2 switch to default.
  */
 long ssl_get_algorithm2(SSL *s)
 {
     long alg2 = s->s3->tmp.new_cipher->algorithm2;
-    if (s->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_SHA256_PRF
-        && alg2 == (SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF))
-        return SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256;
+    if (s->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_SHA256_PRF) {
+        if (alg2 == (SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF))
+            return SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256;
+    } else if (s->s3->tmp.new_cipher->algorithm_mkey & SSL_PSK) {
+        if (alg2 == (SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384))
+            return SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF;
+    }
     return alg2;
 }
 
@@ -4260,3 +4255,18 @@ int ssl_fill_hello_random(SSL *s, int server, unsigned char *result, int len)
     } else
         return RAND_bytes(result, len);
 }
+
+int ssl_generate_master_secret(SSL *s, unsigned char *pms, size_t pmslen,
+                               int free_pms)
+{
+    s->session->master_key_length =
+        s->method->ssl3_enc->generate_master_secret(s, s->session->master_key,
+                                                    pms, pmslen);
+    if (free_pms)
+        OPENSSL_clear_free(pms, pmslen);
+    else
+        OPENSSL_cleanse(pms, pmslen);
+    if (s->server == 0)
+        s->s3->tmp.pms = NULL;
+    return s->session->master_key_length >= 0;
+}