Add Next Protocol Negotiation.
[openssl.git] / ssl / s3_both.c
index a6d869df59e862be10547a97afd1168b7196ea44..89f7c42f03f1bf72759902bb7954005e8d36e56c 100644 (file)
@@ -202,15 +202,40 @@ int ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen)
        return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
        }
 
+#ifndef OPENSSL_NO_NPN
+/* ssl3_take_mac calculates the Finished MAC for the handshakes messages seen to far. */
+static void ssl3_take_mac(SSL *s)
+       {
+       const char *sender;
+       int slen;
+
+       if (s->state & SSL_ST_CONNECT)
+               {
+               sender=s->method->ssl3_enc->server_finished_label;
+               slen=s->method->ssl3_enc->server_finished_label_len;
+               }
+       else
+               {
+               sender=s->method->ssl3_enc->client_finished_label;
+               slen=s->method->ssl3_enc->client_finished_label_len;
+               }
+
+       s->s3->tmp.peer_finish_md_len = s->method->ssl3_enc->final_finish_mac(s,
+               sender,slen,s->s3->tmp.peer_finish_md);
+       }
+#endif
+
 int ssl3_get_finished(SSL *s, int a, int b)
        {
        int al,i,ok;
        long n;
        unsigned char *p;
 
+#ifdef OPENSSL_NO_NPN
        /* the mac has already been generated when we received the
         * change cipher spec message and is in s->s3->tmp.peer_finish_md
         */ 
+#endif
 
        n=s->method->ssl_get_message(s,
                a,
@@ -514,6 +539,15 @@ long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok)
                s->init_num += i;
                n -= i;
                }
+
+#ifndef OPENSSL_NO_NPN
+       /* If receiving Finished, record MAC of prior handshake messages for
+        * Finished verification. */
+       if (*s->init_buf->data == SSL3_MT_FINISHED)
+               ssl3_take_mac(s);
+#endif
+
+       /* Feed this message into MAC computation. */
        ssl3_finish_mac(s, (unsigned char *)s->init_buf->data, s->init_num + 4);
        if (s->msg_callback)
                s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, s->init_buf->data, (size_t)s->init_num + 4, s, s->msg_callback_arg);