15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * SSL3 Protocol
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * This Source Code Form is subject to the terms of the Mozilla Public
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * License, v. 2.0. If a copy of the MPL was not distributed with this
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* TLS extension code moved here from ssl3ecc.c */
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "nssrenam.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "nss.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ssl.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sslimpl.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sslproto.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "pk11pub.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifdef NO_PKCS11_BYPASS
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "blapit.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "blapi.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "prinit.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static unsigned char  key_name[SESS_TICKET_KEY_NAME_LEN];
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PK11SymKey    *session_ticket_enc_key_pkcs11 = NULL;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PK11SymKey    *session_ticket_mac_key_pkcs11 = NULL;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef NO_PKCS11_BYPASS
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static unsigned char  session_ticket_enc_key[AES_256_KEY_LENGTH];
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static unsigned char  session_ticket_mac_key[SHA256_LENGTH];
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRBool         session_ticket_keys_initialized = PR_FALSE;
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRCallOnceType generate_session_keys_once;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* forward static function declarations */
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus ssl3_ParseEncryptedSessionTicket(sslSocket *ss,
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECItem *data, EncryptedSessionTicket *enc_session_ticket);
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus ssl3_AppendToItem(SECItem *item, const unsigned char *buf,
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32 bytes);
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus ssl3_AppendNumberToItem(SECItem *item, PRUint32 num,
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRInt32 lenSize);
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus ssl3_GetSessionTicketKeysPKCS11(sslSocket *ss,
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PK11SymKey **aes_key, PK11SymKey **mac_key);
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef NO_PKCS11_BYPASS
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus ssl3_GetSessionTicketKeys(const unsigned char **aes_key,
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32 *aes_key_length, const unsigned char **mac_key,
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32 *mac_key_length);
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRInt32 ssl3_SendRenegotiationInfoXtn(sslSocket * ss,
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRBool append, PRUint32 maxBytes);
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus ssl3_HandleRenegotiationInfoXtn(sslSocket *ss,
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint16 ex_type, SECItem *data);
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss,
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			PRUint16 ex_type, SECItem *data);
55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstatic SECStatus ssl3_ClientHandleAppProtoXtn(sslSocket *ss,
56eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch			PRUint16 ex_type, SECItem *data);
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus ssl3_ServerHandleNextProtoNegoXtn(sslSocket *ss,
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			PRUint16 ex_type, SECItem *data);
59eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstatic PRInt32 ssl3_ClientSendAppProtoXtn(sslSocket *ss, PRBool append,
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)					  PRUint32 maxBytes);
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRInt32 ssl3_ClientSendNextProtoNegoXtn(sslSocket *ss, PRBool append,
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					       PRUint32 maxBytes);
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRInt32 ssl3_SendUseSRTPXtn(sslSocket *ss, PRBool append,
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32 maxBytes);
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus ssl3_HandleUseSRTPXtn(sslSocket * ss, PRUint16 ex_type,
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECItem *data);
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static SECStatus ssl3_ClientHandleChannelIDXtn(sslSocket *ss,
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PRUint16 ex_type, SECItem *data);
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static PRInt32 ssl3_ClientSendChannelIDXtn(sslSocket *ss, PRBool append,
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PRUint32 maxBytes);
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static SECStatus ssl3_ServerSendStatusRequestXtn(sslSocket * ss,
72a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    PRBool append, PRUint32 maxBytes);
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static SECStatus ssl3_ServerHandleStatusRequestXtn(sslSocket *ss,
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    PRUint16 ex_type, SECItem *data);
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static SECStatus ssl3_ClientHandleStatusRequestXtn(sslSocket *ss,
76a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                                   PRUint16 ex_type,
77a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                                   SECItem *data);
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static PRInt32 ssl3_ClientSendStatusRequestXtn(sslSocket * ss, PRBool append,
79a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                               PRUint32 maxBytes);
80868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)static PRInt32 ssl3_ClientSendSigAlgsXtn(sslSocket *ss, PRBool append,
81868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                         PRUint32 maxBytes);
82868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)static SECStatus ssl3_ServerHandleSigAlgsXtn(sslSocket *ss, PRUint16 ex_type,
83868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                             SECItem *data);
84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)static PRInt32 ssl3_ClientSendSignedCertTimestampXtn(sslSocket *ss,
85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)						     PRBool append,
86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)						     PRUint32 maxBytes);
87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)static SECStatus ssl3_ClientHandleSignedCertTimestampXtn(sslSocket *ss,
88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)							 PRUint16 ex_type,
89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)							 SECItem *data);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Write bytes.  Using this function means the SECItem structure
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * cannot be freed.  The caller is expected to call this function
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * on a shallow copy of the structure.
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_AppendToItem(SECItem *item, const unsigned char *buf, PRUint32 bytes)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (bytes > item->len)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Memcpy(item->data, buf, bytes);
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    item->data += bytes;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    item->len -= bytes;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Write a number in network byte order. Using this function means the
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * SECItem structure cannot be freed.  The caller is expected to call
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * this function on a shallow copy of the structure.
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_AppendNumberToItem(SECItem *item, PRUint32 num, PRInt32 lenSize)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECStatus rv;
117a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    PRUint8   b[4];
118a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    PRUint8 * p = b;
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (lenSize) {
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case 4:
122a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	*p++ = (PRUint8) (num >> 24);
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case 3:
124a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	*p++ = (PRUint8) (num >> 16);
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case 2:
126a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	*p++ = (PRUint8) (num >> 8);
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case 1:
128a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	*p = (PRUint8) num;
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ssl3_AppendToItem(item, &b[0], lenSize);
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return rv;
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus ssl3_SessionTicketShutdown(void* appData, void* nssData)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (session_ticket_enc_key_pkcs11) {
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PK11_FreeSymKey(session_ticket_enc_key_pkcs11);
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	session_ticket_enc_key_pkcs11 = NULL;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (session_ticket_mac_key_pkcs11) {
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PK11_FreeSymKey(session_ticket_mac_key_pkcs11);
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	session_ticket_mac_key_pkcs11 = NULL;
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Memset(&generate_session_keys_once, 0,
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	sizeof(generate_session_keys_once));
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess;
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRStatus
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_GenerateSessionTicketKeysPKCS11(void *data)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECStatus rv;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSocket *ss = (sslSocket *)data;
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECKEYPrivateKey *svrPrivKey = ss->serverCerts[kt_rsa].SERVERKEY;
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECKEYPublicKey *svrPubKey = ss->serverCerts[kt_rsa].serverKeyPair->pubKey;
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (svrPrivKey == NULL || svrPubKey == NULL) {
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SSL_DBG(("%d: SSL[%d]: Pub or priv key(s) is NULL.",
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			SSL_GETPID(), ss->fd));
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	goto loser;
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Get a copy of the session keys from shared memory. */
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Memcpy(key_name, SESS_TICKET_KEY_NAME_PREFIX,
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	sizeof(SESS_TICKET_KEY_NAME_PREFIX));
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ssl_GetSessionTicketKeysPKCS11(svrPrivKey, svrPubKey,
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->pkcs11PinArg, &key_name[SESS_TICKET_KEY_NAME_PREFIX_LEN],
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    &session_ticket_enc_key_pkcs11, &session_ticket_mac_key_pkcs11))
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return PR_FAILURE;
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = NSS_RegisterShutdown(ssl3_SessionTicketShutdown, NULL);
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	goto loser;
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return PR_SUCCESS;
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)loser:
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl3_SessionTicketShutdown(NULL, NULL);
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return PR_FAILURE;
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_GetSessionTicketKeysPKCS11(sslSocket *ss, PK11SymKey **aes_key,
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                PK11SymKey **mac_key)
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (PR_CallOnceWithArg(&generate_session_keys_once,
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ssl3_GenerateSessionTicketKeysPKCS11, ss) != PR_SUCCESS)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (session_ticket_enc_key_pkcs11 == NULL ||
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	session_ticket_mac_key_pkcs11 == NULL)
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *aes_key = session_ticket_enc_key_pkcs11;
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *mac_key = session_ticket_mac_key_pkcs11;
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess;
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef NO_PKCS11_BYPASS
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRStatus
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_GenerateSessionTicketKeys(void)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Memcpy(key_name, SESS_TICKET_KEY_NAME_PREFIX,
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	sizeof(SESS_TICKET_KEY_NAME_PREFIX));
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ssl_GetSessionTicketKeys(&key_name[SESS_TICKET_KEY_NAME_PREFIX_LEN],
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    session_ticket_enc_key, session_ticket_mac_key))
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return PR_FAILURE;
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    session_ticket_keys_initialized = PR_TRUE;
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return PR_SUCCESS;
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_GetSessionTicketKeys(const unsigned char **aes_key,
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32 *aes_key_length, const unsigned char **mac_key,
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32 *mac_key_length)
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (PR_CallOnce(&generate_session_keys_once,
221a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	    ssl3_GenerateSessionTicketKeys) != PR_SUCCESS)
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!session_ticket_keys_initialized)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *aes_key = session_ticket_enc_key;
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *aes_key_length = sizeof(session_ticket_enc_key);
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *mac_key = session_ticket_mac_key;
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *mac_key_length = sizeof(session_ticket_mac_key);
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess;
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Table of handlers for received TLS hello extensions, one per extension.
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * In the second generation, this table will be dynamic, and functions
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * will be registered here.
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* This table is used by the server, to handle client hello extensions. */
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const ssl3HelloExtensionHandler clientHelloHandlers[] = {
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { ssl_server_name_xtn,        &ssl3_HandleServerNameXtn },
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef NSS_ENABLE_ECC
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { ssl_elliptic_curves_xtn,    &ssl3_HandleSupportedCurvesXtn },
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { ssl_ec_point_formats_xtn,   &ssl3_HandleSupportedPointFormatsXtn },
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { ssl_session_ticket_xtn,     &ssl3_ServerHandleSessionTicketXtn },
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn },
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { ssl_next_proto_nego_xtn,    &ssl3_ServerHandleNextProtoNegoXtn },
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { ssl_use_srtp_xtn,           &ssl3_HandleUseSRTPXtn },
251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    { ssl_cert_status_xtn,        &ssl3_ServerHandleStatusRequestXtn },
252868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    { ssl_signature_algorithms_xtn, &ssl3_ServerHandleSigAlgsXtn },
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { -1, NULL }
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* These two tables are used by the client, to handle server hello
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * extensions. */
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const ssl3HelloExtensionHandler serverHelloHandlersTLS[] = {
259a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    { ssl_server_name_xtn,        &ssl3_HandleServerNameXtn },
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* TODO: add a handler for ssl_ec_point_formats_xtn */
261a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    { ssl_session_ticket_xtn,     &ssl3_ClientHandleSessionTicketXtn },
262a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn },
263a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    { ssl_next_proto_nego_xtn,    &ssl3_ClientHandleNextProtoNegoXtn },
264a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    { ssl_app_layer_protocol_xtn, &ssl3_ClientHandleAppProtoXtn },
265a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    { ssl_use_srtp_xtn,           &ssl3_HandleUseSRTPXtn },
266a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    { ssl_channel_id_xtn,         &ssl3_ClientHandleChannelIDXtn },
267a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    { ssl_cert_status_xtn,        &ssl3_ClientHandleStatusRequestXtn },
268f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    { ssl_signed_certificate_timestamp_xtn,
269f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      &ssl3_ClientHandleSignedCertTimestampXtn },
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { -1, NULL }
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const ssl3HelloExtensionHandler serverHelloHandlersSSL3[] = {
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn },
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { -1, NULL }
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Tables of functions to format TLS hello extensions, one function per
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * extension.
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * These static tables are for the formatting of client hello extensions.
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The server's table of hello senders is dynamic, in the socket struct,
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and sender functions are registered there.
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS] = {
2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    { ssl_server_name_xtn,        &ssl3_SendServerNameXtn        },
2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    { ssl_renegotiation_info_xtn, &ssl3_SendRenegotiationInfoXtn },
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef NSS_ENABLE_ECC
2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    { ssl_elliptic_curves_xtn,    &ssl3_SendSupportedCurvesXtn },
2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    { ssl_ec_point_formats_xtn,   &ssl3_SendSupportedPointFormatsXtn },
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    { ssl_session_ticket_xtn,     &ssl3_SendSessionTicketXtn },
2935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    { ssl_next_proto_nego_xtn,    &ssl3_ClientSendNextProtoNegoXtn },
2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    { ssl_app_layer_protocol_xtn, &ssl3_ClientSendAppProtoXtn },
2955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    { ssl_use_srtp_xtn,           &ssl3_SendUseSRTPXtn },
2965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    { ssl_channel_id_xtn,         &ssl3_ClientSendChannelIDXtn },
2975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    { ssl_cert_status_xtn,        &ssl3_ClientSendStatusRequestXtn },
298f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    { ssl_signed_certificate_timestamp_xtn,
2995c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      &ssl3_ClientSendSignedCertTimestampXtn },
3005c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    /* WebSphere Application Server 7.0 is intolerant to the last extension
3015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu     * being zero-length. It is not intolerant of TLS 1.2, so move
3025c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu     * signature_algorithms to the end. */
3035c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    { ssl_signature_algorithms_xtn, &ssl3_ClientSendSigAlgsXtn }
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* any extra entries will appear as { 0, NULL }    */
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3HelloExtensionSender clientHelloSendersSSL3[SSL_MAX_EXTENSIONS] = {
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { ssl_renegotiation_info_xtn, &ssl3_SendRenegotiationInfoXtn }
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* any extra entries will appear as { 0, NULL }    */
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRBool
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)arrayContainsExtension(const PRUint16 *array, PRUint32 len, PRUint16 ex_type)
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int i;
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (i = 0; i < len; i++) {
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ex_type == array[i])
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return PR_TRUE;
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return PR_FALSE;
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRBool
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_ExtensionNegotiated(sslSocket *ss, PRUint16 ex_type) {
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TLSExtensionData *xtnData = &ss->xtnData;
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return arrayContainsExtension(xtnData->negotiated,
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	                          xtnData->numNegotiated, ex_type);
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRBool
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_ClientExtensionAdvertised(sslSocket *ss, PRUint16 ex_type) {
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TLSExtensionData *xtnData = &ss->xtnData;
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return arrayContainsExtension(xtnData->advertised,
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	                          xtnData->numAdvertised, ex_type);
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Format an SNI extension, using the name from the socket's URL,
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * unless that name is a dotted decimal string.
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Used by client and server.
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRInt32
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_SendServerNameXtn(sslSocket * ss, PRBool append,
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       PRUint32 maxBytes)
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECStatus rv;
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss)
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	return 0;
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss->sec.isServer) {
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        PRUint32 len;
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        PRNetAddr netAddr;
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* must have a hostname */
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (!ss->url || !ss->url[0])
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return 0;
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* must not be an IPv4 or IPv6 address */
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (PR_SUCCESS == PR_StringToNetAddr(ss->url, &netAddr)) {
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            /* is an IP address (v4 or v6) */
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return 0;
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        len  = PORT_Strlen(ss->url);
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (append && maxBytes >= len + 9) {
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            /* extension_type */
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            rv = ssl3_AppendHandshakeNumber(ss, ssl_server_name_xtn, 2);
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (rv != SECSuccess) return -1;
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            /* length of extension_data */
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            rv = ssl3_AppendHandshakeNumber(ss, len + 5, 2);
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (rv != SECSuccess) return -1;
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            /* length of server_name_list */
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            rv = ssl3_AppendHandshakeNumber(ss, len + 3, 2);
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (rv != SECSuccess) return -1;
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            /* Name Type (sni_host_name) */
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            rv = ssl3_AppendHandshake(ss,       "\0",    1);
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (rv != SECSuccess) return -1;
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            /* HostName (length and value) */
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            rv = ssl3_AppendHandshakeVariable(ss, (PRUint8 *)ss->url, len, 2);
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (rv != SECSuccess) return -1;
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (!ss->sec.isServer) {
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                TLSExtensionData *xtnData = &ss->xtnData;
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                xtnData->advertised[xtnData->numAdvertised++] =
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    ssl_server_name_xtn;
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return len + 9;
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Server side */
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (append && maxBytes >= 4) {
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = ssl3_AppendHandshakeNumber(ss, ssl_server_name_xtn, 2);
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (rv != SECSuccess)  return -1;
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* length of extension_data */
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = ssl3_AppendHandshakeNumber(ss, 0, 2);
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (rv != SECSuccess) return -1;
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 4;
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* handle an incoming SNI extension, by ignoring it. */
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_HandleServerNameXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data)
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECItem *names = NULL;
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32 listCount = 0, namesPos = 0, i;
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TLSExtensionData *xtnData = &ss->xtnData;
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECItem  ldata;
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRInt32  listLenBytes = 0;
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss->sec.isServer) {
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* Verify extension_data is empty. */
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (data->data || data->len ||
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            !ssl3_ExtensionNegotiated(ss, ssl_server_name_xtn)) {
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            /* malformed or was not initiated by the client.*/
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return SECFailure;
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return SECSuccess;
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Server side - consume client data and register server sender. */
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* do not parse the data if don't have user extension handling function. */
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss->sniSocketConfig) {
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return SECSuccess;
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* length of server_name_list */
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    listLenBytes = ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len);
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (listLenBytes == 0 || listLenBytes != data->len) {
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return SECFailure;
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ldata = *data;
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Calculate the size of the array.*/
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (listLenBytes > 0) {
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        SECItem litem;
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        SECStatus rv;
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        PRInt32  type;
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* Name Type (sni_host_name) */
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        type = ssl3_ConsumeHandshakeNumber(ss, 1, &ldata.data, &ldata.len);
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (!ldata.len) {
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return SECFailure;
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = ssl3_ConsumeHandshakeVariable(ss, &litem, 2, &ldata.data, &ldata.len);
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (rv != SECSuccess) {
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return SECFailure;
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* Adjust total length for cunsumed item, item len and type.*/
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        listLenBytes -= litem.len + 3;
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (listLenBytes > 0 && !ldata.len) {
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return SECFailure;
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        listCount += 1;
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!listCount) {
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return SECFailure;
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    names = PORT_ZNewArray(SECItem, listCount);
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!names) {
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return SECFailure;
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (i = 0;i < listCount;i++) {
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        int j;
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        PRInt32  type;
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        SECStatus rv;
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        PRBool nametypePresent = PR_FALSE;
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* Name Type (sni_host_name) */
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        type = ssl3_ConsumeHandshakeNumber(ss, 1, &data->data, &data->len);
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* Check if we have such type in the list */
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        for (j = 0;j < listCount && names[j].data;j++) {
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (names[j].type == type) {
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                nametypePresent = PR_TRUE;
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                break;
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* HostName (length and value) */
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = ssl3_ConsumeHandshakeVariable(ss, &names[namesPos], 2,
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           &data->data, &data->len);
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (rv != SECSuccess) {
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            goto loser;
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (nametypePresent == PR_FALSE) {
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            namesPos += 1;
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Free old and set the new data. */
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (xtnData->sniNameArr) {
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        PORT_Free(ss->xtnData.sniNameArr);
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xtnData->sniNameArr = names;
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xtnData->sniNameArrSize = namesPos;
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xtnData->negotiated[xtnData->numNegotiated++] = ssl_server_name_xtn;
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess;
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)loser:
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Free(names);
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECFailure;
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Called by both clients and servers.
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Clients sends a filled in session ticket if one is available, and otherwise
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sends an empty ticket.  Servers always send empty tickets.
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRInt32
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_SendSessionTicketXtn(
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			sslSocket * ss,
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			PRBool      append,
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			PRUint32    maxBytes)
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRInt32 extension_length;
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NewSessionTicket *session_ticket = NULL;
5075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    sslSessionID *sid = ss->sec.ci.sid;
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Ignore the SessionTicket extension if processing is disabled. */
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss->opt.enableSessionTickets)
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return 0;
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Empty extension length = extension_type (2-bytes) +
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * length(extension_data) (2-bytes)
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extension_length = 4;
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* If we are a client then send a session ticket if one is availble.
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Servers that support the extension and are willing to negotiate the
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * the extension always respond with an empty extension.
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss->sec.isServer) {
5235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	/* The caller must be holding sid->u.ssl3.lock for reading. We cannot
5245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	 * just acquire and release the lock within this function because the
5255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	 * caller will call this function twice, and we need the inputs to be
5265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	 * consistent between the two calls. Note that currently the caller
5275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	 * will only be holding the lock when we are the client and when we're
5285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	 * attempting to resume an existing session.
5295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	 */
5305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	session_ticket = &sid->u.ssl3.locked.sessionTicket;
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (session_ticket->ticket.data) {
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (ss->xtnData.ticketTimestampVerified) {
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		extension_length += session_ticket->ticket.len;
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else if (!append &&
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		(session_ticket->ticket_lifetime_hint == 0 ||
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		(session_ticket->ticket_lifetime_hint +
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    session_ticket->received_timestamp > ssl_Time()))) {
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		extension_length += session_ticket->ticket.len;
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ss->xtnData.ticketTimestampVerified = PR_TRUE;
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (append && maxBytes >= extension_length) {
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SECStatus rv;
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* extension_type */
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = ssl3_AppendHandshakeNumber(ss, ssl_session_ticket_xtn, 2);
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (rv != SECSuccess)
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto loser;
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (session_ticket && session_ticket->ticket.data &&
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->xtnData.ticketTimestampVerified) {
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    rv = ssl3_AppendHandshakeVariable(ss, session_ticket->ticket.data,
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		session_ticket->ticket.len, 2);
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->xtnData.ticketTimestampVerified = PR_FALSE;
5565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	    ss->xtnData.sentSessionTicketInClientHello = PR_TRUE;
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else {
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    rv = ssl3_AppendHandshakeNumber(ss, 0, 2);
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (rv != SECSuccess)
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto loser;
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!ss->sec.isServer) {
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    TLSExtensionData *xtnData = &ss->xtnData;
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xtnData->advertised[xtnData->numAdvertised++] =
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ssl_session_ticket_xtn;
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (maxBytes < extension_length) {
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_Assert(0);
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return 0;
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return extension_length;
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loser:
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss->xtnData.ticketTimestampVerified = PR_FALSE;
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return -1;
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* handle an incoming Next Protocol Negotiation extension. */
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_ServerHandleNextProtoNegoXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data)
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ss->firstHsDone || data->len != 0) {
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Clients MUST send an empty NPN extension, if any. */
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* TODO: server side NPN support would require calling
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * ssl3_RegisterServerHelloExtensionSender here in order to echo the
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * extension back to the client. */
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess;
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* ssl3_ValidateNextProtoNego checks that the given block of data is valid: none
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * of the lengths may be 0 and the sum of the lengths must equal the length of
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the block. */
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_ValidateNextProtoNego(const unsigned char* data, unsigned int length)
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned int offset = 0;
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (offset < length) {
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	unsigned int newOffset = offset + 1 + (unsigned int) data[offset];
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Reject embedded nulls to protect against buggy applications that
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * store protocol identifiers in null-terminated strings.
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (newOffset > length || data[offset] == 0) {
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return SECFailure;
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	offset = newOffset;
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (offset > length) {
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess;
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, PRUint16 ex_type,
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				  SECItem *data)
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECStatus rv;
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned char resultBuffer[255];
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECItem result = { siBuffer, resultBuffer, 0 };
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Assert(!ss->firstHsDone);
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
636a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    if (ssl3_ExtensionNegotiated(ss, ssl_app_layer_protocol_xtn)) {
6375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	/* If the server negotiated ALPN then it has already told us what protocol
6385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	 * to use, so it doesn't make sense for us to try to negotiate a different
6395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	 * one by sending the NPN handshake message. However, if we've negotiated
6405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	 * NPN then we're required to send the NPN handshake message. Thus, these
6415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	 * two extensions cannot both be negotiated on the same connection. */
642eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch	PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
643eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch	return SECFailure;
644eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    }
645eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ssl3_ValidateNextProtoNego(data->data, data->len);
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess)
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return rv;
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* ss->nextProtoCallback cannot normally be NULL if we negotiated the
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * extension. However, It is possible that an application erroneously
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * cleared the callback between the time we sent the ClientHello and now.
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Assert(ss->nextProtoCallback != NULL);
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss->nextProtoCallback) {
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* XXX Use a better error code. This is an application error, not an
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * NSS bug. */
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ss->nextProtoCallback(ss->nextProtoArg, ss->fd, data->data, data->len,
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			       result.data, &result.len, sizeof resultBuffer);
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess)
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return rv;
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* If the callback wrote more than allowed to |result| it has corrupted our
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * stack. */
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (result.len > sizeof resultBuffer) {
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(SEC_ERROR_OUTPUT_LEN);
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE);
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECITEM_CopyItem(NULL, &ss->ssl3.nextProto, &result);
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
679eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstatic SECStatus
680eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochssl3_ClientHandleAppProtoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data)
681eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch{
682eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const unsigned char* d = data->data;
683eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    PRUint16 name_list_len;
684eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    SECItem protocol_name;
685eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
686eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (ssl3_ExtensionNegotiated(ss, ssl_next_proto_nego_xtn)) {
687eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch	PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
688eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch	return SECFailure;
689eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    }
690eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
691eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    /* The extension data from the server has the following format:
692eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch     *   uint16 name_list_len;
693eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch     *   uint8 len;
694eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch     *   uint8 protocol_name[len]; */
695eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (data->len < 4 || data->len > 2 + 1 + 255) {
696eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch	PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
697eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch	return SECFailure;
698eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    }
699eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
700eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    name_list_len = ((PRUint16) d[0]) << 8 |
701eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch	            ((PRUint16) d[1]);
7025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (name_list_len != data->len - 2 || d[2] != data->len - 3) {
703eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch	PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
704eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch	return SECFailure;
705eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    }
706eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
707eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    protocol_name.data = data->data + 3;
708eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    protocol_name.len = data->len - 3;
709eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
710eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE);
711eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    ss->ssl3.nextProtoState = SSL_NEXT_PROTO_SELECTED;
712eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
713eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return SECITEM_CopyItem(NULL, &ss->ssl3.nextProto, &protocol_name);
714eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
715eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRInt32
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_ClientSendNextProtoNegoXtn(sslSocket * ss, PRBool append,
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				PRUint32 maxBytes)
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRInt32 extension_length;
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Renegotiations do not send this extension. */
7235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (!ss->opt.enableNPN || !ss->nextProtoCallback || ss->firstHsDone) {
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return 0;
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extension_length = 4;
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (append && maxBytes >= extension_length) {
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SECStatus rv;
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl3_AppendHandshakeNumber(ss, ssl_next_proto_nego_xtn, 2);
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (rv != SECSuccess)
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto loser;
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl3_AppendHandshakeNumber(ss, 0, 2);
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (rv != SECSuccess)
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto loser;
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ssl_next_proto_nego_xtn;
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (maxBytes < extension_length) {
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return 0;
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return extension_length;
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)loser:
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return -1;
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
749eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstatic PRInt32
750eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochssl3_ClientSendAppProtoXtn(sslSocket * ss, PRBool append, PRUint32 maxBytes)
751eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch{
752eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    PRInt32 extension_length;
753ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    unsigned char *alpn_protos = NULL;
754eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
755eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    /* Renegotiations do not send this extension. */
7565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (!ss->opt.enableALPN || !ss->opt.nextProtoNego.data || ss->firstHsDone) {
757eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch	return 0;
758eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    }
759eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
760eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    extension_length = 2 /* extension type */ + 2 /* extension length */ +
7615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)		       2 /* protocol name list length */ +
7625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)		       ss->opt.nextProtoNego.len;
763eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
764eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (append && maxBytes >= extension_length) {
765ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch	/* NPN requires that the client's fallback protocol is first in the
766ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch	 * list. However, ALPN sends protocols in preference order. So we
767ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch	 * allocate a buffer and move the first protocol to the end of the
768ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch	 * list. */
769eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch	SECStatus rv;
770ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch	const unsigned int len = ss->opt.nextProtoNego.len;
771ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
772ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch	alpn_protos = PORT_Alloc(len);
773ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch	if (alpn_protos == NULL) {
774ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch	    return SECFailure;
775ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch	}
776ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch	if (len > 0) {
777ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch	    /* Each protocol string is prefixed with a single byte length. */
778ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch	    unsigned int i = ss->opt.nextProtoNego.data[0] + 1;
779ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch	    if (i <= len) {
780ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch		memcpy(alpn_protos, &ss->opt.nextProtoNego.data[i], len - i);
781ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch		memcpy(alpn_protos + len - i, ss->opt.nextProtoNego.data, i);
782ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch	    } else {
783ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch		/* This seems to be invalid data so we'll send as-is. */
784ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch		memcpy(alpn_protos, ss->opt.nextProtoNego.data, len);
785ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch	    }
786ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch	}
787ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
788a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	rv = ssl3_AppendHandshakeNumber(ss, ssl_app_layer_protocol_xtn, 2);
7895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	if (rv != SECSuccess) {
790eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch	    goto loser;
7915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	}
792eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch	rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2);
7935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	if (rv != SECSuccess) {
794eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch	    goto loser;
7955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	}
796ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch	rv = ssl3_AppendHandshakeVariable(ss, alpn_protos, len, 2);
797ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch	PORT_Free(alpn_protos);
798ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch	alpn_protos = NULL;
7995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	if (rv != SECSuccess) {
800eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch	    goto loser;
8015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	}
802eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch	ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
803a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)		ssl_app_layer_protocol_xtn;
804eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    } else if (maxBytes < extension_length) {
805eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch	return 0;
806eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    }
807eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
808eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return extension_length;
809eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
810eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochloser:
8115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (alpn_protos) {
812ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch	PORT_Free(alpn_protos);
8135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
814eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return -1;
815eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
816eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_ClientHandleChannelIDXtn(sslSocket *ss, PRUint16 ex_type,
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			     SECItem *data)
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Assert(ss->getChannelID != NULL);
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (data->len) {
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(SSL_ERROR_BAD_CHANNEL_ID_DATA);
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess;
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRInt32
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_ClientSendChannelIDXtn(sslSocket * ss, PRBool append,
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    PRUint32 maxBytes)
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRInt32 extension_length = 4;
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss->getChannelID)
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return 0;
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (maxBytes < extension_length) {
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_Assert(0);
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return 0;
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (ss->sec.ci.sid->cached != never_cached &&
846f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        ss->sec.ci.sid->u.ssl3.originalHandshakeHash.len == 0) {
847f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        /* We can't do ChannelID on a connection if we're resuming and didn't
848f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)         * do ChannelID on the original connection: without ChannelID on the
849f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)         * original connection we didn't record the handshake hashes needed for
850f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)         * the signature. */
851f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	return 0;
852f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
853f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (append) {
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SECStatus rv;
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl3_AppendHandshakeNumber(ss, ssl_channel_id_xtn, 2);
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (rv != SECSuccess)
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto loser;
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl3_AppendHandshakeNumber(ss, 0, 2);
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (rv != SECSuccess)
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto loser;
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ssl_channel_id_xtn;
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return extension_length;
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)loser:
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return -1;
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
872c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static SECStatus
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_ClientHandleStatusRequestXtn(sslSocket *ss, PRUint16 ex_type,
874c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 SECItem *data)
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* The echoed extension must be empty. */
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (data->len != 0)
878c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       return SECFailure;
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Keep track of negotiated extensions. */
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess;
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
886c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static PRInt32
887c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ssl3_ServerSendStatusRequestXtn(
888c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)			sslSocket * ss,
889c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)			PRBool      append,
890c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)			PRUint32    maxBytes)
891c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){
892c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    PRInt32 extension_length;
893c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    SECStatus rv;
894a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    int i;
895a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    PRBool haveStatus = PR_FALSE;
896c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
897a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    for (i = kt_null; i < kt_kea_size; i++) {
898a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	/* TODO: This is a temporary workaround.
899a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	 *       The correct code needs to see if we have an OCSP response for
900a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	 *       the server certificate being used, rather than if we have any
901a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	 *       OCSP response. See also ssl3_SendCertificateStatus.
902a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	 */
903a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	if (ss->certStatusArray[i] && ss->certStatusArray[i]->len) {
904a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	    haveStatus = PR_TRUE;
905a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	    break;
906a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	}
907a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    }
908a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    if (!haveStatus)
909c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)	return 0;
910c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
911c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    extension_length = 2 + 2;
912c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (append && maxBytes >= extension_length) {
913c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)	/* extension_type */
914c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)	rv = ssl3_AppendHandshakeNumber(ss, ssl_cert_status_xtn, 2);
915c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)	if (rv != SECSuccess)
916c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)	    return -1;
917c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)	/* length of extension_data */
918c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)	rv = ssl3_AppendHandshakeNumber(ss, 0, 2);
919c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)	if (rv != SECSuccess)
920c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)	    return -1;
921c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
922c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
923c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return extension_length;
924c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
925c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* ssl3_ClientSendStatusRequestXtn builds the status_request extension on the
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * client side. See RFC 4366 section 3.6. */
928c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static PRInt32
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_ClientSendStatusRequestXtn(sslSocket * ss, PRBool append,
930c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                               PRUint32 maxBytes)
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRInt32 extension_length;
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss->opt.enableOCSPStapling)
935c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       return 0;
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* extension_type (2-bytes) +
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * length(extension_data) (2-bytes) +
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * status_type (1) +
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * responder_id_list length (2) +
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * request_extensions length (2)
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extension_length = 9;
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (append && maxBytes >= extension_length) {
946c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       SECStatus rv;
947c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       TLSExtensionData *xtnData;
948c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
949c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       /* extension_type */
950c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       rv = ssl3_AppendHandshakeNumber(ss, ssl_cert_status_xtn, 2);
951c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       if (rv != SECSuccess)
952c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)           return -1;
953c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2);
954c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       if (rv != SECSuccess)
955c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)           return -1;
956c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       rv = ssl3_AppendHandshakeNumber(ss, 1 /* status_type ocsp */, 1);
957c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       if (rv != SECSuccess)
958c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)           return -1;
959c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       /* A zero length responder_id_list means that the responders are
960c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        * implicitly known to the server. */
961c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       rv = ssl3_AppendHandshakeNumber(ss, 0, 2);
962c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       if (rv != SECSuccess)
963c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)           return -1;
964c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       /* A zero length request_extensions means that there are no extensions.
965c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        * Specifically, we don't set the id-pkix-ocsp-nonce extension. This
966c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        * means that the server can replay a cached OCSP response to us. */
967c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       rv = ssl3_AppendHandshakeNumber(ss, 0, 2);
968c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       if (rv != SECSuccess)
969c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)           return -1;
970c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
971c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       xtnData = &ss->xtnData;
972c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       xtnData->advertised[xtnData->numAdvertised++] = ssl_cert_status_xtn;
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (maxBytes < extension_length) {
974c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       PORT_Assert(0);
975c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       return 0;
9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return extension_length;
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * NewSessionTicket
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Called from ssl3_HandleFinished
9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_SendNewSessionTicket(sslSocket *ss)
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int                  i;
9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECStatus            rv;
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NewSessionTicket     ticket;
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECItem              plaintext;
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECItem              plaintext_item = {0, NULL, 0};
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECItem              ciphertext     = {0, NULL, 0};
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32             ciphertext_length;
9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRBool               ms_is_wrapped;
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned char        wrapped_ms[SSL3_MASTER_SECRET_LENGTH];
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECItem              ms_item = {0, NULL, 0};
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SSL3KEAType          effectiveExchKeyType = ssl_kea_null;
9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32             padding_length;
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32             message_length;
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32             cert_length;
1001a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    PRUint8              length_buf[4];
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32             now;
10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PK11SymKey          *aes_key_pkcs11;
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PK11SymKey          *mac_key_pkcs11;
10052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef NO_PKCS11_BYPASS
10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const unsigned char *aes_key;
10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const unsigned char *mac_key;
10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32             aes_key_length;
10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32             mac_key_length;
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint64             aes_ctx_buf[MAX_CIPHER_CONTEXT_LLONGS];
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AESContext          *aes_ctx;
10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const SECHashObject *hashObj = NULL;
10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint64             hmac_ctx_buf[MAX_MAC_CONTEXT_LLONGS];
10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HMACContext         *hmac_ctx;
10152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
10162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CK_MECHANISM_TYPE    cipherMech = CKM_AES_CBC;
10172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PK11Context         *aes_ctx_pkcs11;
10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CK_MECHANISM_TYPE    macMech = CKM_SHA256_HMAC;
10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PK11Context         *hmac_ctx_pkcs11;
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned char        computed_mac[TLS_EX_SESS_TICKET_MAC_LENGTH];
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned int         computed_mac_length;
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned char        iv[AES_BLOCK_SIZE];
10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECItem              ivItem;
10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECItem             *srvName = NULL;
10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32             srvNameLen = 0;
10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CK_MECHANISM_TYPE    msWrapMech = 0; /* dummy default value,
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          * must be >= 0 */
10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SSL_TRC(3, ("%d: SSL3[%d]: send session_ticket handshake",
10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		SSL_GETPID(), ss->fd));
10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ticket.ticket_lifetime_hint = TLS_EX_SESS_TICKET_LIFETIME_HINT;
10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cert_length = (ss->opt.requestCertificate && ss->sec.ci.sid->peerCert) ?
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	3 + ss->sec.ci.sid->peerCert->derCert.len : 0;
10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Get IV and encryption keys */
10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ivItem.data = iv;
10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ivItem.len = sizeof(iv);
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = PK11_GenerateRandom(iv, sizeof(iv));
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess) goto loser;
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef NO_PKCS11_BYPASS
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ss->opt.bypassPKCS11) {
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl3_GetSessionTicketKeys(&aes_key, &aes_key_length,
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    &mac_key, &mac_key_length);
10492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else
10502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
10512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    {
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl3_GetSessionTicketKeysPKCS11(ss, &aes_key_pkcs11,
10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    &mac_key_pkcs11);
10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess) goto loser;
10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ss->ssl3.pwSpec->msItem.len && ss->ssl3.pwSpec->msItem.data) {
10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* The master secret is available unwrapped. */
10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ms_item.data = ss->ssl3.pwSpec->msItem.data;
10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ms_item.len = ss->ssl3.pwSpec->msItem.len;
10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ms_is_wrapped = PR_FALSE;
10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Extract the master secret wrapped. */
10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	sslSessionID sid;
10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_Memset(&sid, 0, sizeof(sslSessionID));
10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa) {
10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    effectiveExchKeyType = kt_rsa;
10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else {
10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    effectiveExchKeyType = ss->ssl3.hs.kea_def->exchKeyType;
10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl3_CacheWrappedMasterSecret(ss, &sid, ss->ssl3.pwSpec,
10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    effectiveExchKeyType);
10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (rv == SECSuccess) {
10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (sid.u.ssl3.keys.wrapped_master_secret_len > sizeof(wrapped_ms))
10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		goto loser;
10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    memcpy(wrapped_ms, sid.u.ssl3.keys.wrapped_master_secret,
10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		sid.u.ssl3.keys.wrapped_master_secret_len);
10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ms_item.data = wrapped_ms;
10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ms_item.len = sid.u.ssl3.keys.wrapped_master_secret_len;
10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    msWrapMech = sid.u.ssl3.masterWrapMech;
10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else {
10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* TODO: else send an empty ticket. */
10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto loser;
10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ms_is_wrapped = PR_TRUE;
10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Prep to send negotiated name */
10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    srvName = &ss->ssl3.pwSpec->srvVirtName;
10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (srvName->data && srvName->len) {
10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        srvNameLen = 2 + srvName->len; /* len bytes + name len */
10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ciphertext_length =
10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	sizeof(PRUint16)                     /* ticket_version */
10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	+ sizeof(SSL3ProtocolVersion)        /* ssl_version */
10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	+ sizeof(ssl3CipherSuite)            /* ciphersuite */
10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	+ 1                                  /* compression */
11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	+ 10                                 /* cipher spec parameters */
11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	+ 1                                  /* SessionTicket.ms_is_wrapped */
11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	+ 1                                  /* effectiveExchKeyType */
11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	+ 4                                  /* msWrapMech */
11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	+ 2                                  /* master_secret.length */
11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	+ ms_item.len                        /* master_secret */
11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	+ 1                                  /* client_auth_type */
11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	+ cert_length                        /* cert */
11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        + 1                                  /* server name type */
11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        + srvNameLen                         /* name len + length field */
11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	+ sizeof(ticket.ticket_lifetime_hint);
11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    padding_length =  AES_BLOCK_SIZE -
11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	(ciphertext_length % AES_BLOCK_SIZE);
11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ciphertext_length += padding_length;
11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    message_length =
11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	sizeof(ticket.ticket_lifetime_hint)    /* ticket_lifetime_hint */
11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	+ 2 /* length field for NewSessionTicket.ticket */
11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	+ SESS_TICKET_KEY_NAME_LEN             /* key_name */
11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	+ AES_BLOCK_SIZE                       /* iv */
11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	+ 2 /* length field for NewSessionTicket.ticket.encrypted_state */
11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	+ ciphertext_length                    /* encrypted_state */
11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	+ TLS_EX_SESS_TICKET_MAC_LENGTH;       /* mac */
11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (SECITEM_AllocItem(NULL, &plaintext_item, ciphertext_length) == NULL)
11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	goto loser;
11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    plaintext = plaintext_item;
11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* ticket_version */
11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ssl3_AppendNumberToItem(&plaintext, TLS_EX_SESS_TICKET_VERSION,
11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	sizeof(PRUint16));
11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess) goto loser;
11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* ssl_version */
11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ssl3_AppendNumberToItem(&plaintext, ss->version,
11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	sizeof(SSL3ProtocolVersion));
11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess) goto loser;
11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* ciphersuite */
11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ssl3_AppendNumberToItem(&plaintext, ss->ssl3.hs.cipher_suite,
11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	sizeof(ssl3CipherSuite));
11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess) goto loser;
11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* compression */
11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ssl3_AppendNumberToItem(&plaintext, ss->ssl3.hs.compression, 1);
11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess) goto loser;
11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* cipher spec parameters */
11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ssl3_AppendNumberToItem(&plaintext, ss->sec.authAlgorithm, 1);
11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess) goto loser;
11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ssl3_AppendNumberToItem(&plaintext, ss->sec.authKeyBits, 4);
11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess) goto loser;
11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ssl3_AppendNumberToItem(&plaintext, ss->sec.keaType, 1);
11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess) goto loser;
11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ssl3_AppendNumberToItem(&plaintext, ss->sec.keaKeyBits, 4);
11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess) goto loser;
11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* master_secret */
11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ssl3_AppendNumberToItem(&plaintext, ms_is_wrapped, 1);
11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess) goto loser;
11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ssl3_AppendNumberToItem(&plaintext, effectiveExchKeyType, 1);
11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess) goto loser;
11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ssl3_AppendNumberToItem(&plaintext, msWrapMech, 4);
11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess) goto loser;
11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ssl3_AppendNumberToItem(&plaintext, ms_item.len, 2);
11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess) goto loser;
11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ssl3_AppendToItem(&plaintext, ms_item.data, ms_item.len);
11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess) goto loser;
11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* client_identity */
11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ss->opt.requestCertificate && ss->sec.ci.sid->peerCert) {
11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl3_AppendNumberToItem(&plaintext, CLIENT_AUTH_CERTIFICATE, 1);
11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (rv != SECSuccess) goto loser;
11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl3_AppendNumberToItem(&plaintext,
11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->sec.ci.sid->peerCert->derCert.len, 3);
11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (rv != SECSuccess) goto loser;
11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl3_AppendToItem(&plaintext,
11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->sec.ci.sid->peerCert->derCert.data,
11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->sec.ci.sid->peerCert->derCert.len);
11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (rv != SECSuccess) goto loser;
11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl3_AppendNumberToItem(&plaintext, 0, 1);
11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (rv != SECSuccess) goto loser;
11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* timestamp */
11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    now = ssl_Time();
11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ssl3_AppendNumberToItem(&plaintext, now,
11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	sizeof(ticket.ticket_lifetime_hint));
11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess) goto loser;
11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (srvNameLen) {
11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* Name Type (sni_host_name) */
11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = ssl3_AppendNumberToItem(&plaintext, srvName->type, 1);
11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (rv != SECSuccess) goto loser;
11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* HostName (length and value) */
11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = ssl3_AppendNumberToItem(&plaintext, srvName->len, 2);
11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (rv != SECSuccess) goto loser;
11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = ssl3_AppendToItem(&plaintext, srvName->data, srvName->len);
12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (rv != SECSuccess) goto loser;
12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* No Name */
12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = ssl3_AppendNumberToItem(&plaintext, (char)TLS_STE_NO_SERVER_NAME,
12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     1);
12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (rv != SECSuccess) goto loser;
12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Assert(plaintext.len == padding_length);
12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (i = 0; i < padding_length; i++)
12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	plaintext.data[i] = (unsigned char)padding_length;
12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (SECITEM_AllocItem(NULL, &ciphertext, ciphertext_length) == NULL) {
12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = SECFailure;
12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	goto loser;
12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Generate encrypted portion of ticket. */
12182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef NO_PKCS11_BYPASS
12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ss->opt.bypassPKCS11) {
12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	aes_ctx = (AESContext *)aes_ctx_buf;
12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = AES_InitContext(aes_ctx, aes_key, aes_key_length, iv,
12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    NSS_AES_CBC, 1, AES_BLOCK_SIZE);
12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (rv != SECSuccess) goto loser;
12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = AES_Encrypt(aes_ctx, ciphertext.data, &ciphertext.len,
12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ciphertext.len, plaintext_item.data,
12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    plaintext_item.len);
12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (rv != SECSuccess) goto loser;
12292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else
12302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
12312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    {
12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	aes_ctx_pkcs11 = PK11_CreateContextBySymKey(cipherMech,
12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    CKA_ENCRYPT, aes_key_pkcs11, &ivItem);
12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!aes_ctx_pkcs11)
12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto loser;
12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = PK11_CipherOp(aes_ctx_pkcs11, ciphertext.data,
12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    (int *)&ciphertext.len, ciphertext.len,
12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    plaintext_item.data, plaintext_item.len);
12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PK11_Finalize(aes_ctx_pkcs11);
12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PK11_DestroyContext(aes_ctx_pkcs11, PR_TRUE);
12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (rv != SECSuccess) goto loser;
12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Convert ciphertext length to network order. */
12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    length_buf[0] = (ciphertext.len >> 8) & 0xff;
12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    length_buf[1] = (ciphertext.len     ) & 0xff;
12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Compute MAC. */
12502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef NO_PKCS11_BYPASS
12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ss->opt.bypassPKCS11) {
12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	hmac_ctx = (HMACContext *)hmac_ctx_buf;
12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	hashObj = HASH_GetRawHashObject(HASH_AlgSHA256);
12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (HMAC_Init(hmac_ctx, hashObj, mac_key,
12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		mac_key_length, PR_FALSE) != SECSuccess)
12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto loser;
12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	HMAC_Begin(hmac_ctx);
12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	HMAC_Update(hmac_ctx, key_name, SESS_TICKET_KEY_NAME_LEN);
12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	HMAC_Update(hmac_ctx, iv, sizeof(iv));
12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	HMAC_Update(hmac_ctx, (unsigned char *)length_buf, 2);
12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	HMAC_Update(hmac_ctx, ciphertext.data, ciphertext.len);
12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	HMAC_Finish(hmac_ctx, computed_mac, &computed_mac_length,
12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sizeof(computed_mac));
12652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else
12662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
12672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    {
12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SECItem macParam;
12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	macParam.data = NULL;
12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	macParam.len = 0;
12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	hmac_ctx_pkcs11 = PK11_CreateContextBySymKey(macMech,
12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    CKA_SIGN, mac_key_pkcs11, &macParam);
12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!hmac_ctx_pkcs11)
12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto loser;
12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = PK11_DigestBegin(hmac_ctx_pkcs11);
12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = PK11_DigestOp(hmac_ctx_pkcs11, key_name,
12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    SESS_TICKET_KEY_NAME_LEN);
12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = PK11_DigestOp(hmac_ctx_pkcs11, iv, sizeof(iv));
12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = PK11_DigestOp(hmac_ctx_pkcs11, (unsigned char *)length_buf, 2);
12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = PK11_DigestOp(hmac_ctx_pkcs11, ciphertext.data, ciphertext.len);
12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = PK11_DigestFinal(hmac_ctx_pkcs11, computed_mac,
12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    &computed_mac_length, sizeof(computed_mac));
12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PK11_DestroyContext(hmac_ctx_pkcs11, PR_TRUE);
12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (rv != SECSuccess) goto loser;
12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Serialize the handshake message. */
12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ssl3_AppendHandshakeHeader(ss, new_session_ticket, message_length);
12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess) goto loser;
12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ssl3_AppendHandshakeNumber(ss, ticket.ticket_lifetime_hint,
12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	sizeof(ticket.ticket_lifetime_hint));
12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess) goto loser;
12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ssl3_AppendHandshakeNumber(ss,
12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	message_length - sizeof(ticket.ticket_lifetime_hint) - 2, 2);
12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess) goto loser;
12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ssl3_AppendHandshake(ss, key_name, SESS_TICKET_KEY_NAME_LEN);
13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess) goto loser;
13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ssl3_AppendHandshake(ss, iv, sizeof(iv));
13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess) goto loser;
13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ssl3_AppendHandshakeVariable(ss, ciphertext.data, ciphertext.len, 2);
13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess) goto loser;
13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ssl3_AppendHandshake(ss, computed_mac, computed_mac_length);
13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess) goto loser;
13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)loser:
13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (plaintext_item.data)
13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SECITEM_FreeItem(&plaintext_item, PR_FALSE);
13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ciphertext.data)
13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SECITEM_FreeItem(&ciphertext, PR_FALSE);
13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return rv;
13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* When a client receives a SessionTicket extension a NewSessionTicket
13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * message is expected during the handshake.
13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_ClientHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type,
13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  SECItem *data)
13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (data->len != 0)
13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Keep track of negotiated extensions. */
13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess;
13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_ServerHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type,
13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  SECItem *data)
13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECStatus rv;
13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECItem *decrypted_state = NULL;
13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SessionTicket *parsed_session_ticket = NULL;
13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSessionID *sid = NULL;
13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SSL3Statistics *ssl3stats;
13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Ignore the SessionTicket extension if processing is disabled. */
13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss->opt.enableSessionTickets)
13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECSuccess;
13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Keep track of negotiated extensions. */
13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Parse the received ticket sent in by the client.  We are
13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * lenient about some parse errors, falling back to a fullshake
13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * instead of terminating the current connection.
13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (data->len == 0) {
13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->xtnData.emptySessionTicket = PR_TRUE;
13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	int                    i;
13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SECItem                extension_data;
13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	EncryptedSessionTicket enc_session_ticket;
13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	unsigned char          computed_mac[TLS_EX_SESS_TICKET_MAC_LENGTH];
13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	unsigned int           computed_mac_length;
13652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef NO_PKCS11_BYPASS
13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	const SECHashObject   *hashObj;
13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	const unsigned char   *aes_key;
13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	const unsigned char   *mac_key;
13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PRUint32               aes_key_length;
13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PRUint32               mac_key_length;
13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PRUint64               hmac_ctx_buf[MAX_MAC_CONTEXT_LLONGS];
13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	HMACContext           *hmac_ctx;
13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PRUint64               aes_ctx_buf[MAX_CIPHER_CONTEXT_LLONGS];
13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	AESContext            *aes_ctx;
13752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
13762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	PK11SymKey            *aes_key_pkcs11;
13772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	PK11SymKey            *mac_key_pkcs11;
13782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	PK11Context           *hmac_ctx_pkcs11;
13792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	CK_MECHANISM_TYPE      macMech = CKM_SHA256_HMAC;
13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PK11Context           *aes_ctx_pkcs11;
13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	CK_MECHANISM_TYPE      cipherMech = CKM_AES_CBC;
13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	unsigned char *        padding;
13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PRUint32               padding_length;
13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	unsigned char         *buffer;
13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	unsigned int           buffer_len;
13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PRInt32                temp;
13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SECItem                cert_item;
13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        PRInt8                 nameType = TLS_STE_NO_SERVER_NAME;
13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Turn off stateless session resumption if the client sends a
13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * SessionTicket extension, even if the extension turns out to be
13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * malformed (ss->sec.ci.sid is non-NULL when doing session
13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * renegotiation.)
13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ss->sec.ci.sid != NULL) {
13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (ss->sec.uncache)
13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ss->sec.uncache(ss->sec.ci.sid);
13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ssl_FreeSID(ss->sec.ci.sid);
13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->sec.ci.sid = NULL;
14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	extension_data.data = data->data; /* Keep a copy for future use. */
14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	extension_data.len = data->len;
14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ssl3_ParseEncryptedSessionTicket(ss, data, &enc_session_ticket)
14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    != SECSuccess)
14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return SECFailure;
14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Get session ticket keys. */
14102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef NO_PKCS11_BYPASS
14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ss->opt.bypassPKCS11) {
14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    rv = ssl3_GetSessionTicketKeys(&aes_key, &aes_key_length,
14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		&mac_key, &mac_key_length);
14142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	} else
14152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
1416c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)	{
14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    rv = ssl3_GetSessionTicketKeysPKCS11(ss, &aes_key_pkcs11,
14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		&mac_key_pkcs11);
14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (rv != SECSuccess) {
14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    SSL_DBG(("%d: SSL[%d]: Unable to get/generate session ticket keys.",
14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			SSL_GETPID(), ss->fd));
14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto loser;
14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* If the ticket sent by the client was generated under a key different
14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * from the one we have, bypass ticket processing.
14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (PORT_Memcmp(enc_session_ticket.key_name, key_name,
14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		SESS_TICKET_KEY_NAME_LEN) != 0) {
14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    SSL_DBG(("%d: SSL[%d]: Session ticket key_name sent mismatch.",
14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			SSL_GETPID(), ss->fd));
14335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto no_ticket;
14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Verify the MAC on the ticket.  MAC verification may also
14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * fail if the MAC key has been recently refreshed.
14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
14392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef NO_PKCS11_BYPASS
14405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ss->opt.bypassPKCS11) {
14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    hmac_ctx = (HMACContext *)hmac_ctx_buf;
14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    hashObj = HASH_GetRawHashObject(HASH_AlgSHA256);
14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (HMAC_Init(hmac_ctx, hashObj, mac_key,
14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    sizeof(session_ticket_mac_key), PR_FALSE) != SECSuccess)
14455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		goto no_ticket;
14465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    HMAC_Begin(hmac_ctx);
14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    HMAC_Update(hmac_ctx, extension_data.data,
14485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		extension_data.len - TLS_EX_SESS_TICKET_MAC_LENGTH);
14495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (HMAC_Finish(hmac_ctx, computed_mac, &computed_mac_length,
14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    sizeof(computed_mac)) != SECSuccess)
14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		goto no_ticket;
14522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	} else
14532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
1454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)	{
14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    SECItem macParam;
14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    macParam.data = NULL;
14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    macParam.len = 0;
14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    hmac_ctx_pkcs11 = PK11_CreateContextBySymKey(macMech,
14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		CKA_SIGN, mac_key_pkcs11, &macParam);
14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (!hmac_ctx_pkcs11) {
14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		SSL_DBG(("%d: SSL[%d]: Unable to create HMAC context: %d.",
14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    SSL_GETPID(), ss->fd, PORT_GetError()));
14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		goto no_ticket;
14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else {
14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		SSL_DBG(("%d: SSL[%d]: Successfully created HMAC context.",
14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    SSL_GETPID(), ss->fd));
14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    rv = PK11_DigestBegin(hmac_ctx_pkcs11);
14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    rv = PK11_DigestOp(hmac_ctx_pkcs11, extension_data.data,
14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		extension_data.len - TLS_EX_SESS_TICKET_MAC_LENGTH);
14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (rv != SECSuccess) {
14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		PK11_DestroyContext(hmac_ctx_pkcs11, PR_TRUE);
14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		goto no_ticket;
14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    rv = PK11_DigestFinal(hmac_ctx_pkcs11, computed_mac,
14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		&computed_mac_length, sizeof(computed_mac));
14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PK11_DestroyContext(hmac_ctx_pkcs11, PR_TRUE);
14785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (rv != SECSuccess)
14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		goto no_ticket;
14805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (NSS_SecureMemcmp(computed_mac, enc_session_ticket.mac,
14825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		computed_mac_length) != 0) {
14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    SSL_DBG(("%d: SSL[%d]: Session ticket MAC mismatch.",
14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			SSL_GETPID(), ss->fd));
14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto no_ticket;
14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* We ignore key_name for now.
14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * This is ok as MAC verification succeeded.
14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Decrypt the ticket. */
14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Plaintext is shorter than the ciphertext due to padding. */
14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	decrypted_state = SECITEM_AllocItem(NULL, NULL,
14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    enc_session_ticket.encrypted_state.len);
14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef NO_PKCS11_BYPASS
14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ss->opt.bypassPKCS11) {
15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    aes_ctx = (AESContext *)aes_ctx_buf;
15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    rv = AES_InitContext(aes_ctx, aes_key,
15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		sizeof(session_ticket_enc_key), enc_session_ticket.iv,
15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		NSS_AES_CBC, 0,AES_BLOCK_SIZE);
15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (rv != SECSuccess) {
15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		SSL_DBG(("%d: SSL[%d]: Unable to create AES context.",
15065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    SSL_GETPID(), ss->fd));
15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		goto no_ticket;
15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    rv = AES_Decrypt(aes_ctx, decrypted_state->data,
15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		&decrypted_state->len, decrypted_state->len,
15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		enc_session_ticket.encrypted_state.data,
15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		enc_session_ticket.encrypted_state.len);
15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (rv != SECSuccess)
15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		goto no_ticket;
15162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	} else
15172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
1518c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)	{
15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    SECItem ivItem;
15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ivItem.data = enc_session_ticket.iv;
15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ivItem.len = AES_BLOCK_SIZE;
15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    aes_ctx_pkcs11 = PK11_CreateContextBySymKey(cipherMech,
15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		CKA_DECRYPT, aes_key_pkcs11, &ivItem);
15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (!aes_ctx_pkcs11) {
15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		SSL_DBG(("%d: SSL[%d]: Unable to create AES context.",
15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    SSL_GETPID(), ss->fd));
15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		goto no_ticket;
15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    rv = PK11_CipherOp(aes_ctx_pkcs11, decrypted_state->data,
15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		(int *)&decrypted_state->len, decrypted_state->len,
15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		enc_session_ticket.encrypted_state.data,
15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		enc_session_ticket.encrypted_state.len);
15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PK11_Finalize(aes_ctx_pkcs11);
15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PK11_DestroyContext(aes_ctx_pkcs11, PR_TRUE);
15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (rv != SECSuccess)
15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		goto no_ticket;
15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
15395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Check padding. */
15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	padding_length =
15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    (PRUint32)decrypted_state->data[decrypted_state->len - 1];
15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (padding_length == 0 || padding_length > AES_BLOCK_SIZE)
15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto no_ticket;
15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	padding = &decrypted_state->data[decrypted_state->len - padding_length];
15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	for (i = 0; i < padding_length; i++, padding++) {
15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (padding_length != (PRUint32)*padding)
15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		goto no_ticket;
15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Deserialize session state. */
15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	buffer = decrypted_state->data;
15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	buffer_len = decrypted_state->len;
15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	parsed_session_ticket = PORT_ZAlloc(sizeof(SessionTicket));
15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (parsed_session_ticket == NULL) {
15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    rv = SECFailure;
15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto loser;
15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Read ticket_version (which is ignored for now.) */
15635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	temp = ssl3_ConsumeHandshakeNumber(ss, 2, &buffer, &buffer_len);
15645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (temp < 0) goto no_ticket;
15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	parsed_session_ticket->ticket_version = (SSL3ProtocolVersion)temp;
15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Read SSLVersion. */
15685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	temp = ssl3_ConsumeHandshakeNumber(ss, 2, &buffer, &buffer_len);
15695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (temp < 0) goto no_ticket;
15705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	parsed_session_ticket->ssl_version = (SSL3ProtocolVersion)temp;
15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Read cipher_suite. */
15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	temp =  ssl3_ConsumeHandshakeNumber(ss, 2, &buffer, &buffer_len);
15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (temp < 0) goto no_ticket;
15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	parsed_session_ticket->cipher_suite = (ssl3CipherSuite)temp;
15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Read compression_method. */
15785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len);
15795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (temp < 0) goto no_ticket;
15805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	parsed_session_ticket->compression_method = (SSLCompressionMethod)temp;
15815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Read cipher spec parameters. */
15835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len);
15845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (temp < 0) goto no_ticket;
15855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	parsed_session_ticket->authAlgorithm = (SSLSignType)temp;
15865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	temp = ssl3_ConsumeHandshakeNumber(ss, 4, &buffer, &buffer_len);
15875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (temp < 0) goto no_ticket;
15885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	parsed_session_ticket->authKeyBits = (PRUint32)temp;
15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len);
15905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (temp < 0) goto no_ticket;
15915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	parsed_session_ticket->keaType = (SSLKEAType)temp;
15925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	temp = ssl3_ConsumeHandshakeNumber(ss, 4, &buffer, &buffer_len);
15935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (temp < 0) goto no_ticket;
15945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	parsed_session_ticket->keaKeyBits = (PRUint32)temp;
15955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Read wrapped master_secret. */
15975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len);
15985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (temp < 0) goto no_ticket;
15995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	parsed_session_ticket->ms_is_wrapped = (PRBool)temp;
16005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len);
16025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (temp < 0) goto no_ticket;
16035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	parsed_session_ticket->exchKeyType = (SSL3KEAType)temp;
16045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	temp = ssl3_ConsumeHandshakeNumber(ss, 4, &buffer, &buffer_len);
16065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (temp < 0) goto no_ticket;
16075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	parsed_session_ticket->msWrapMech = (CK_MECHANISM_TYPE)temp;
16085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	temp = ssl3_ConsumeHandshakeNumber(ss, 2, &buffer, &buffer_len);
16105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (temp < 0) goto no_ticket;
16115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	parsed_session_ticket->ms_length = (PRUint16)temp;
16125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (parsed_session_ticket->ms_length == 0 ||  /* sanity check MS. */
16135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    parsed_session_ticket->ms_length >
16145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sizeof(parsed_session_ticket->master_secret))
16155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto no_ticket;
16165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Allow for the wrapped master secret to be longer. */
16185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	if (buffer_len < parsed_session_ticket->ms_length)
16195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto no_ticket;
16205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_Memcpy(parsed_session_ticket->master_secret, buffer,
16215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    parsed_session_ticket->ms_length);
16225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	buffer += parsed_session_ticket->ms_length;
16235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	buffer_len -= parsed_session_ticket->ms_length;
16245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Read client_identity */
16265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len);
16275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (temp < 0)
16285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto no_ticket;
16295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	parsed_session_ticket->client_identity.client_auth_type =
16305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    (ClientAuthenticationType)temp;
16315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	switch(parsed_session_ticket->client_identity.client_auth_type) {
16325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            case CLIENT_AUTH_ANONYMOUS:
16335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break;
16345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            case CLIENT_AUTH_CERTIFICATE:
16355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		rv = ssl3_ConsumeHandshakeVariable(ss, &cert_item, 3,
16365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    &buffer, &buffer_len);
16375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (rv != SECSuccess) goto no_ticket;
16385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		rv = SECITEM_CopyItem(NULL, &parsed_session_ticket->peer_cert,
16395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    &cert_item);
16405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (rv != SECSuccess) goto no_ticket;
16415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break;
16425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            default:
16435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		goto no_ticket;
16445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
16455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Read timestamp. */
16465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	temp = ssl3_ConsumeHandshakeNumber(ss, 4, &buffer, &buffer_len);
16475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (temp < 0)
16485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto no_ticket;
16495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	parsed_session_ticket->timestamp = (PRUint32)temp;
16505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* Read server name */
16525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        nameType =
16535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len);
16545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (nameType != TLS_STE_NO_SERVER_NAME) {
16555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            SECItem name_item;
16565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            rv = ssl3_ConsumeHandshakeVariable(ss, &name_item, 2, &buffer,
16575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               &buffer_len);
16585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (rv != SECSuccess) goto no_ticket;
16595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            rv = SECITEM_CopyItem(NULL, &parsed_session_ticket->srvName,
16605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  &name_item);
16615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (rv != SECSuccess) goto no_ticket;
16625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            parsed_session_ticket->srvName.type = nameType;
16635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
16645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Done parsing.  Check that all bytes have been consumed. */
16665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (buffer_len != padding_length)
16675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto no_ticket;
16685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Use the ticket if it has not expired, otherwise free the allocated
16705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * memory since the ticket is of no use.
16715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
16725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (parsed_session_ticket->timestamp != 0 &&
16735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    parsed_session_ticket->timestamp +
16745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    TLS_EX_SESS_TICKET_LIFETIME_HINT > ssl_Time()) {
16755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sid = ssl3_NewSessionID(ss, PR_TRUE);
16775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (sid == NULL) {
16785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		rv = SECFailure;
16795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		goto loser;
16805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
16815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* Copy over parameters. */
16835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sid->version = parsed_session_ticket->ssl_version;
16845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sid->u.ssl3.cipherSuite = parsed_session_ticket->cipher_suite;
16855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sid->u.ssl3.compression = parsed_session_ticket->compression_method;
16865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sid->authAlgorithm = parsed_session_ticket->authAlgorithm;
16875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sid->authKeyBits = parsed_session_ticket->authKeyBits;
16885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sid->keaType = parsed_session_ticket->keaType;
16895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sid->keaKeyBits = parsed_session_ticket->keaKeyBits;
16905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* Copy master secret. */
16922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef NO_PKCS11_BYPASS
16935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (ss->opt.bypassPKCS11 &&
16945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    parsed_session_ticket->ms_is_wrapped)
16955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		goto no_ticket;
16962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
16975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (parsed_session_ticket->ms_length >
16985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    sizeof(sid->u.ssl3.keys.wrapped_master_secret))
16995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		goto no_ticket;
17005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PORT_Memcpy(sid->u.ssl3.keys.wrapped_master_secret,
17015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		parsed_session_ticket->master_secret,
17025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		parsed_session_ticket->ms_length);
17035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sid->u.ssl3.keys.wrapped_master_secret_len =
17045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		parsed_session_ticket->ms_length;
17055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sid->u.ssl3.exchKeyType = parsed_session_ticket->exchKeyType;
17065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sid->u.ssl3.masterWrapMech = parsed_session_ticket->msWrapMech;
17075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sid->u.ssl3.keys.msIsWrapped =
17085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		parsed_session_ticket->ms_is_wrapped;
17095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sid->u.ssl3.masterValid    = PR_TRUE;
17105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sid->u.ssl3.keys.resumable = PR_TRUE;
17115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* Copy over client cert from session ticket if there is one. */
17135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (parsed_session_ticket->peer_cert.data != NULL) {
17145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (sid->peerCert != NULL)
17155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    CERT_DestroyCertificate(sid->peerCert);
17165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		sid->peerCert = CERT_NewTempCertificate(ss->dbHandle,
17175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    &parsed_session_ticket->peer_cert, NULL, PR_FALSE, PR_TRUE);
17185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (sid->peerCert == NULL) {
17195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    rv = SECFailure;
17205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    goto loser;
17215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
17225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
17235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (parsed_session_ticket->srvName.data != NULL) {
17245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                sid->u.ssl3.srvName = parsed_session_ticket->srvName;
17255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
17265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->statelessResume = PR_TRUE;
17275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->sec.ci.sid = sid;
17285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
17295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
17305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (0) {
17325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)no_ticket:
17335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SSL_DBG(("%d: SSL[%d]: Session ticket parsing failed.",
17345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			SSL_GETPID(), ss->fd));
17355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ssl3stats = SSL_GetStatistics();
17365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SSL_AtomicIncrementLong(& ssl3stats->hch_sid_ticket_parse_failures );
17375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
17385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = SECSuccess;
17395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)loser:
17415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* ss->sec.ci.sid == sid if it did NOT come here via goto statement
17425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * in that case do not free sid
17435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
17445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (sid && (ss->sec.ci.sid != sid)) {
17455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ssl_FreeSID(sid);
17465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sid = NULL;
17475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
17485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (decrypted_state != NULL) {
17495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SECITEM_FreeItem(decrypted_state, PR_TRUE);
17505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	decrypted_state = NULL;
17515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
17525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (parsed_session_ticket != NULL) {
17545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (parsed_session_ticket->peer_cert.data) {
17555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    SECITEM_FreeItem(&parsed_session_ticket->peer_cert, PR_FALSE);
17565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
17575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_ZFree(parsed_session_ticket, sizeof(SessionTicket));
17585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
17595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return rv;
17615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
17645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Read bytes.  Using this function means the SECItem structure
17655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * cannot be freed.  The caller is expected to call this function
17665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * on a shallow copy of the structure.
17675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
17685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus
17695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_ConsumeFromItem(SECItem *item, unsigned char **buf, PRUint32 bytes)
17705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
17715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (bytes > item->len)
17725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
17735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *buf = item->data;
17755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    item->data += bytes;
17765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    item->len -= bytes;
17775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess;
17785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus
17815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_ParseEncryptedSessionTicket(sslSocket *ss, SECItem *data,
17825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 EncryptedSessionTicket *enc_session_ticket)
17835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
17845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ssl3_ConsumeFromItem(data, &enc_session_ticket->key_name,
17855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    SESS_TICKET_KEY_NAME_LEN) != SECSuccess)
17865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
17875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ssl3_ConsumeFromItem(data, &enc_session_ticket->iv,
17885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    AES_BLOCK_SIZE) != SECSuccess)
17895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
17905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ssl3_ConsumeHandshakeVariable(ss, &enc_session_ticket->encrypted_state,
17915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    2, &data->data, &data->len) != SECSuccess)
17925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
17935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ssl3_ConsumeFromItem(data, &enc_session_ticket->mac,
17945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    TLS_EX_SESS_TICKET_MAC_LENGTH) != SECSuccess)
17955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
17965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (data->len != 0)  /* Make sure that we have consumed all bytes. */
17975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
17985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess;
18005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* go through hello extensions in buffer "b".
18035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * For each one, find the extension handler in the table, and
18045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * if present, invoke that handler.
18055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Servers ignore any extensions with unknown extension types.
18065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Clients reject any extensions with unadvertised extension types.
18075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
18085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
18095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_HandleHelloExtensions(sslSocket *ss, SSL3Opaque **b, PRUint32 *length)
18105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
18115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ssl3HelloExtensionHandler * handlers;
18125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ss->sec.isServer) {
18145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        handlers = clientHelloHandlers;
18155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (ss->version > SSL_LIBRARY_VERSION_3_0) {
18165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        handlers = serverHelloHandlersTLS;
18175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
18185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        handlers = serverHelloHandlersSSL3;
18195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
18205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (*length) {
18225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	const ssl3HelloExtensionHandler * handler;
18235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SECStatus rv;
18245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PRInt32   extension_type;
18255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SECItem   extension_data;
18265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Get the extension's type field */
18285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	extension_type = ssl3_ConsumeHandshakeNumber(ss, 2, b, length);
18295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (extension_type < 0)  /* failure to decode extension_type */
18305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return SECFailure;   /* alert already sent */
18315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* get the data for this extension, so we can pass it or skip it. */
18335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl3_ConsumeHandshakeVariable(ss, &extension_data, 2, b, length);
18345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (rv != SECSuccess)
18355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return rv;
18365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Check whether the server sent an extension which was not advertised
18385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * in the ClientHello.
18395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
18405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!ss->sec.isServer &&
18415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    !ssl3_ClientExtensionAdvertised(ss, extension_type))
18425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return SECFailure;  /* TODO: send unsupported_extension alert */
18435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Check whether an extension has been sent multiple times. */
18455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ssl3_ExtensionNegotiated(ss, extension_type))
18465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return SECFailure;
18475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* find extension_type in table of Hello Extension Handlers */
18495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	for (handler = handlers; handler->ex_type >= 0; handler++) {
18505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* if found, call this handler */
18515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (handler->ex_type == extension_type) {
18525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		rv = (*handler->ex_handler)(ss, (PRUint16)extension_type,
18535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	                                         	&extension_data);
18545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		/* Ignore this result */
18555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		/* Treat all bad extensions as unrecognized types. */
18565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        break;
18575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
18585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
18595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
18605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess;
18615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Add a callback function to the table of senders of server hello extensions.
18645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
18655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
18665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_RegisterServerHelloExtensionSender(sslSocket *ss, PRUint16 ex_type,
18675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				        ssl3HelloExtensionSenderFunc cb)
18685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
18695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int i;
18705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl3HelloExtensionSender *sender = &ss->xtnData.serverSenders[0];
18715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (i = 0; i < SSL_MAX_EXTENSIONS; ++i, ++sender) {
18735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (!sender->ex_sender) {
18745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sender->ex_type   = ex_type;
18755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sender->ex_sender = cb;
18765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return SECSuccess;
18775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
18785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* detect duplicate senders */
18795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_Assert(sender->ex_type != ex_type);
18805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (sender->ex_type == ex_type) {
18815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* duplicate */
18825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
18835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
18845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
18855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Assert(i < SSL_MAX_EXTENSIONS); /* table needs to grow */
18865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
18875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECFailure;
18885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* call each of the extension senders and return the accumulated length */
18915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRInt32
18925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_CallHelloExtensionSenders(sslSocket *ss, PRBool append, PRUint32 maxBytes,
18935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               const ssl3HelloExtensionSender *sender)
18945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
18955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRInt32 total_exten_len = 0;
18965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int i;
18975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!sender) {
18995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	sender = ss->version > SSL_LIBRARY_VERSION_3_0 ?
19005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 &clientHelloSendersTLS[0] : &clientHelloSendersSSL3[0];
19015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
19025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (i = 0; i < SSL_MAX_EXTENSIONS; ++i, ++sender) {
19045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (sender->ex_sender) {
19055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PRInt32 extLen = (*sender->ex_sender)(ss, append, maxBytes);
19065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (extLen < 0)
19075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    	return -1;
19085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    maxBytes        -= extLen;
19095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    total_exten_len += extLen;
19105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
19115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
19125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return total_exten_len;
19135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
19145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Extension format:
19175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Extension number:   2 bytes
19185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Extension length:   2 bytes
19195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Verify Data Length: 1 byte
19205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Verify Data (TLS): 12 bytes (client) or 24 bytes (server)
19215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Verify Data (SSL): 36 bytes (client) or 72 bytes (server)
19225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
19235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRInt32
19245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_SendRenegotiationInfoXtn(
19255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			sslSocket * ss,
19265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			PRBool      append,
19275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			PRUint32    maxBytes)
19285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
19295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRInt32 len, needed;
19305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* In draft-ietf-tls-renegotiation-03, it is NOT RECOMMENDED to send
19325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * both the SCSV and the empty RI, so when we send SCSV in
19335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * the initial handshake, we don't also send RI.
19345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
19355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss || ss->ssl3.hs.sendingSCSV)
19365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	return 0;
19375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    len = !ss->firstHsDone ? 0 :
19385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	   (ss->sec.isServer ? ss->ssl3.hs.finishedBytes * 2
19395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			     : ss->ssl3.hs.finishedBytes);
19405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    needed = 5 + len;
19415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (append && maxBytes >= needed) {
19425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SECStatus rv;
19435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* extension_type */
19445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl3_AppendHandshakeNumber(ss, ssl_renegotiation_info_xtn, 2);
19455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (rv != SECSuccess) return -1;
19465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* length of extension_data */
19475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl3_AppendHandshakeNumber(ss, len + 1, 2);
19485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (rv != SECSuccess) return -1;
19495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* verify_Data from previous Finished message(s) */
19505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl3_AppendHandshakeVariable(ss,
19515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		  ss->ssl3.hs.finishedMsgs.data, len, 1);
19525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (rv != SECSuccess) return -1;
19535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!ss->sec.isServer) {
19545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    TLSExtensionData *xtnData = &ss->xtnData;
19555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xtnData->advertised[xtnData->numAdvertised++] =
19565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	                                           ssl_renegotiation_info_xtn;
19575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
19585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
19595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return needed;
19605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
19615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1962c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static SECStatus
1963c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ssl3_ServerHandleStatusRequestXtn(sslSocket *ss, PRUint16 ex_type,
1964c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)				  SECItem *data)
1965c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){
1966c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    SECStatus rv = SECSuccess;
1967c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1968c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    /* remember that we got this extension. */
1969c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
1970c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    PORT_Assert(ss->sec.isServer);
1971c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    /* prepare to send back the appropriate response */
1972c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    rv = ssl3_RegisterServerHelloExtensionSender(ss, ex_type,
1973c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)					    ssl3_ServerSendStatusRequestXtn);
1974c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return rv;
1975c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1976c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
19775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* This function runs in both the client and server.  */
19785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus
19795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_HandleRenegotiationInfoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data)
19805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
19815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECStatus rv = SECSuccess;
19825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32 len = 0;
19835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ss->firstHsDone) {
19855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	len = ss->sec.isServer ? ss->ssl3.hs.finishedBytes
19865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	                       : ss->ssl3.hs.finishedBytes * 2;
19875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
19885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (data->len != 1 + len  ||
19895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	data->data[0] != len  || (len &&
19905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	NSS_SecureMemcmp(ss->ssl3.hs.finishedMsgs.data,
19915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	                 data->data + 1, len))) {
19925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Can we do this here? Or, must we arrange for the caller to do it? */
19935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	(void)SSL3_SendAlert(ss, alert_fatal, handshake_failure);
19945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
19955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
19965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
19975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* remember that we got this extension and it was correct. */
19985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss->peerRequestedProtection = 1;
19995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
20005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ss->sec.isServer) {
20015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* prepare to send back the appropriate response */
20025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl3_RegisterServerHelloExtensionSender(ss, ex_type,
20035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					     ssl3_SendRenegotiationInfoXtn);
20045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
20055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return rv;
20065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
20075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRInt32
20095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_SendUseSRTPXtn(sslSocket *ss, PRBool append, PRUint32 maxBytes)
20105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
20115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint32 ext_data_len;
20125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRInt16 i;
20135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECStatus rv;
20145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss)
20165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return 0;
20175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss->sec.isServer) {
20195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Client side */
20205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!IS_DTLS(ss) || !ss->ssl3.dtlsSRTPCipherCount)
20225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return 0;  /* Not relevant */
20235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ext_data_len = 2 + 2 * ss->ssl3.dtlsSRTPCipherCount + 1;
20255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (append && maxBytes >= 4 + ext_data_len) {
20275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* Extension type */
20285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    rv = ssl3_AppendHandshakeNumber(ss, ssl_use_srtp_xtn, 2);
20295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (rv != SECSuccess) return -1;
20305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* Length of extension data */
20315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    rv = ssl3_AppendHandshakeNumber(ss, ext_data_len, 2);
20325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (rv != SECSuccess) return -1;
20335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* Length of the SRTP cipher list */
20345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    rv = ssl3_AppendHandshakeNumber(ss,
20355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					    2 * ss->ssl3.dtlsSRTPCipherCount,
20365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					    2);
20375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (rv != SECSuccess) return -1;
20385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* The SRTP ciphers */
20395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    for (i = 0; i < ss->ssl3.dtlsSRTPCipherCount; i++) {
20405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		rv = ssl3_AppendHandshakeNumber(ss,
20415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)						ss->ssl3.dtlsSRTPCiphers[i],
20425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)						2);
20435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
20445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* Empty MKI value */
20455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ssl3_AppendHandshakeVariable(ss, NULL, 0, 1);
20465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
20485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ssl_use_srtp_xtn;
20495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
20505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return 4 + ext_data_len;
20525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
20535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Server side */
20555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (append && maxBytes >= 9) {
20565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Extension type */
20575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl3_AppendHandshakeNumber(ss, ssl_use_srtp_xtn, 2);
20585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (rv != SECSuccess) return -1;
20595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Length of extension data */
20605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl3_AppendHandshakeNumber(ss, 5, 2);
20615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (rv != SECSuccess) return -1;
20625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Length of the SRTP cipher list */
20635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl3_AppendHandshakeNumber(ss, 2, 2);
20645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (rv != SECSuccess) return -1;
20655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* The selected cipher */
20665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl3_AppendHandshakeNumber(ss, ss->ssl3.dtlsSRTPCipherSuite, 2);
20675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (rv != SECSuccess) return -1;
20685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Empty MKI value */
20695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ssl3_AppendHandshakeVariable(ss, NULL, 0, 1);
20705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
20715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 9;
20735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
20745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus
20765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_HandleUseSRTPXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data)
20775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
20785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECStatus rv;
20795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECItem ciphers = {siBuffer, NULL, 0};
20802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PRUint16 i;
20812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    unsigned int j;
20825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRUint16 cipher = 0;
20835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRBool found = PR_FALSE;
20845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECItem litem;
20855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss->sec.isServer) {
20875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Client side */
20885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!data->data || !data->len) {
20895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            /* malformed */
20905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return SECFailure;
20915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
20925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Get the cipher list */
20945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl3_ConsumeHandshakeVariable(ss, &ciphers, 2,
20955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					   &data->data, &data->len);
20965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (rv != SECSuccess) {
20975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return SECFailure;
20985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
20995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Now check that the number of ciphers listed is 1 (len = 2) */
21005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ciphers.len != 2) {
21015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return SECFailure;
21025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
21035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Get the selected cipher */
21055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	cipher = (ciphers.data[0] << 8) | ciphers.data[1];
21065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Now check that this is one of the ciphers we offered */
21085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	for (i = 0; i < ss->ssl3.dtlsSRTPCipherCount; i++) {
21095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (cipher == ss->ssl3.dtlsSRTPCiphers[i]) {
21105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		found = PR_TRUE;
21115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break;
21125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
21135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
21145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!found) {
21165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return SECFailure;
21175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
21185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Get the srtp_mki value */
21205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = ssl3_ConsumeHandshakeVariable(ss, &litem, 1,
21215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					   &data->data, &data->len);
21225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (rv != SECSuccess) {
21235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return SECFailure;
21245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
21255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* We didn't offer an MKI, so this must be 0 length */
21275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* XXX RFC 5764 Section 4.1.3 says:
21285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 *   If the client detects a nonzero-length MKI in the server's
21295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 *   response that is different than the one the client offered,
21305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 *   then the client MUST abort the handshake and SHOULD send an
21315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 *   invalid_parameter alert.
21325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 *
21335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * Due to a limitation of the ssl3_HandleHelloExtensions function,
21345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * returning SECFailure here won't abort the handshake.  It will
21355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * merely cause the use_srtp extension to be not negotiated.  We
21365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * should fix this.  See NSS bug 753136.
21375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
21385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (litem.len != 0) {
21395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return SECFailure;
21405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
21415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (data->len != 0) {
21435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            /* malformed */
21445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return SECFailure;
21455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
21465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* OK, this looks fine. */
21485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ssl_use_srtp_xtn;
21495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->ssl3.dtlsSRTPCipherSuite = cipher;
21505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECSuccess;
21515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
21525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Server side */
21545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!IS_DTLS(ss) || !ss->ssl3.dtlsSRTPCipherCount) {
21555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Ignore the extension if we aren't doing DTLS or no DTLS-SRTP
21565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * preferences have been set. */
21575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECSuccess;
21585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
21595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!data->data || data->len < 5) {
21615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* malformed */
21625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
21635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
21645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Get the cipher list */
21665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ssl3_ConsumeHandshakeVariable(ss, &ciphers, 2,
21675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				       &data->data, &data->len);
21685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess) {
21695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
21705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
21715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Check that the list is even length */
21725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ciphers.len % 2) {
21735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
21745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
21755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Walk through the offered list and pick the most preferred of our
21775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * ciphers, if any */
21785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (i = 0; !found && i < ss->ssl3.dtlsSRTPCipherCount; i++) {
21795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	for (j = 0; j + 1 < ciphers.len; j += 2) {
21805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    cipher = (ciphers.data[j] << 8) | ciphers.data[j + 1];
21815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (cipher == ss->ssl3.dtlsSRTPCiphers[i]) {
21825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		found = PR_TRUE;
21835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break;
21845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
21855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
21865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
21875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Get the srtp_mki value */
21895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ssl3_ConsumeHandshakeVariable(ss, &litem, 1, &data->data, &data->len);
21905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess) {
21915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
21925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
21935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (data->len != 0) {
21955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure; /* Malformed */
21965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
21975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Now figure out what to do */
21995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!found) {
22005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* No matching ciphers */
22015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECSuccess;
22025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
22035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* OK, we have a valid cipher and we've selected it */
22055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss->ssl3.dtlsSRTPCipherSuite = cipher;
22065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ssl_use_srtp_xtn;
22075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ssl3_RegisterServerHelloExtensionSender(ss, ssl_use_srtp_xtn,
22095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)						   ssl3_SendUseSRTPXtn);
22105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2211868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2212868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)/* ssl3_ServerHandleSigAlgsXtn handles the signature_algorithms extension
2213868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * from a client.
2214868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * See https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */
2215868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)static SECStatus
2216868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)ssl3_ServerHandleSigAlgsXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data)
2217868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles){
2218868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    SECStatus rv;
2219868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    SECItem algorithms;
2220868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const unsigned char *b;
2221868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    unsigned int numAlgorithms, i;
2222868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2223868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    /* Ignore this extension if we aren't doing TLS 1.2 or greater. */
2224868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (ss->version < SSL_LIBRARY_VERSION_TLS_1_2) {
2225868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	return SECSuccess;
2226868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
2227868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2228868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    /* Keep track of negotiated extensions. */
2229868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
2230868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2231868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    rv = ssl3_ConsumeHandshakeVariable(ss, &algorithms, 2, &data->data,
2232868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)				       &data->len);
2233868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (rv != SECSuccess) {
2234868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	return SECFailure;
2235868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
2236868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    /* Trailing data, empty value, or odd-length value is invalid. */
2237868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (data->len != 0 || algorithms.len == 0 || (algorithms.len & 1) != 0) {
2238868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	PORT_SetError(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO);
2239868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	return SECFailure;
2240868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
2241868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2242868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    numAlgorithms = algorithms.len/2;
2243868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2244868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    /* We don't care to process excessive numbers of algorithms. */
2245868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (numAlgorithms > 512) {
2246868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	numAlgorithms = 512;
2247868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
2248868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2249868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ss->ssl3.hs.clientSigAndHash =
2250868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	    PORT_NewArray(SSL3SignatureAndHashAlgorithm, numAlgorithms);
2251868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (!ss->ssl3.hs.clientSigAndHash) {
2252868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	return SECFailure;
2253868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
2254868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ss->ssl3.hs.numClientSigAndHash = 0;
2255868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2256868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    b = algorithms.data;
2257868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    for (i = 0; i < numAlgorithms; i++) {
2258868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	unsigned char tls_hash = *(b++);
2259868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	unsigned char tls_sig = *(b++);
2260868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	SECOidTag hash = ssl3_TLSHashAlgorithmToOID(tls_hash);
2261868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2262868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	if (hash == SEC_OID_UNKNOWN) {
2263868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	    /* We ignore formats that we don't understand. */
2264868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	    continue;
2265868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	}
2266868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	/* tls_sig support will be checked later in
2267868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	 * ssl3_PickSignatureHashAlgorithm. */
2268868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	ss->ssl3.hs.clientSigAndHash[i].hashAlg = hash;
2269868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	ss->ssl3.hs.clientSigAndHash[i].sigAlg = tls_sig;
2270868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	ss->ssl3.hs.numClientSigAndHash++;
2271868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
2272868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2273868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (!ss->ssl3.hs.numClientSigAndHash) {
2274868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	/* We didn't understand any of the client's requested signature
2275868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	 * formats. We'll use the defaults. */
2276868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	PORT_Free(ss->ssl3.hs.clientSigAndHash);
2277868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	ss->ssl3.hs.clientSigAndHash = NULL;
2278868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
2279868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2280868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return SECSuccess;
2281868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
2282868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2283868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)/* ssl3_ClientSendSigAlgsXtn sends the signature_algorithm extension for TLS
2284868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * 1.2 ClientHellos. */
2285868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)static PRInt32
2286868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)ssl3_ClientSendSigAlgsXtn(sslSocket * ss, PRBool append, PRUint32 maxBytes)
2287868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles){
2288a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    static const unsigned char signatureAlgorithms[] = {
2289a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	/* This block is the contents of our signature_algorithms extension, in
2290a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	 * wire format. See
2291a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	 * https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */
2292a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	tls_hash_sha256, tls_sig_rsa,
2293a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	tls_hash_sha384, tls_sig_rsa,
2294a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	tls_hash_sha1,   tls_sig_rsa,
2295a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#ifdef NSS_ENABLE_ECC
2296a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	tls_hash_sha256, tls_sig_ecdsa,
2297a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	tls_hash_sha384, tls_sig_ecdsa,
2298a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	tls_hash_sha1,   tls_sig_ecdsa,
2299a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#endif
2300a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	tls_hash_sha256, tls_sig_dsa,
2301a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	tls_hash_sha1,   tls_sig_dsa,
2302a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    };
2303868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    PRInt32 extension_length;
2304868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2305868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (ss->version < SSL_LIBRARY_VERSION_TLS_1_2) {
2306868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	return 0;
2307868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
2308868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2309868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    extension_length =
2310868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	2 /* extension type */ +
2311868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	2 /* extension length */ +
2312868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	2 /* supported_signature_algorithms length */ +
2313a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	sizeof(signatureAlgorithms);
2314868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2315868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (append && maxBytes >= extension_length) {
2316868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	SECStatus rv;
2317868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	rv = ssl3_AppendHandshakeNumber(ss, ssl_signature_algorithms_xtn, 2);
2318868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	if (rv != SECSuccess)
2319868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	    goto loser;
2320868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2);
2321868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	if (rv != SECSuccess)
2322868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	    goto loser;
2323a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	rv = ssl3_AppendHandshakeVariable(ss, signatureAlgorithms,
2324a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)					  sizeof(signatureAlgorithms), 2);
2325868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	if (rv != SECSuccess)
2326868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	    goto loser;
2327868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
2328868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)		ssl_signature_algorithms_xtn;
2329868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    } else if (maxBytes < extension_length) {
2330868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	PORT_Assert(0);
2331868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	return 0;
2332868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
2333868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2334868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return extension_length;
2335868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2336868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)loser:
2337868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return -1;
2338868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
2339f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2340f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)unsigned int
2341f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ssl3_CalculatePaddingExtensionLength(unsigned int clientHelloLength)
2342f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles){
2343f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    unsigned int recordLength = 1 /* handshake message type */ +
2344f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)				3 /* handshake message length */ +
2345f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)				clientHelloLength;
2346f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    unsigned int extensionLength;
2347f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2348a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (recordLength < 256 || recordLength >= 512) {
2349f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	return 0;
2350f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
2351f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
23525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    extensionLength = 512 - recordLength;
23535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    /* Extensions take at least four bytes to encode. Always include at least
23545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu     * one byte of data if including the extension. WebSphere Application Server
23555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu     * 7.0 is intolerant to the last extension being zero-length. */
23565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    if (extensionLength < 4 + 1) {
23575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu	extensionLength = 4 + 1;
23585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
2359f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
23605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return extensionLength;
2361f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
2362f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2363f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)/* ssl3_AppendPaddingExtension possibly adds an extension which ensures that a
2364f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * ClientHello record is either < 256 bytes or is >= 512 bytes. This ensures
2365f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * that we don't trigger bugs in F5 products. */
2366f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)PRInt32
2367f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ssl3_AppendPaddingExtension(sslSocket *ss, unsigned int extensionLen,
2368f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)			    PRUint32 maxBytes)
2369f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles){
2370f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    unsigned int paddingLen = extensionLen - 4;
2371a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    static unsigned char padding[256];
2372f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2373f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (extensionLen == 0) {
2374f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	return 0;
2375f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
2376f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2377f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (extensionLen < 4 ||
2378f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	extensionLen > maxBytes ||
2379f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	paddingLen > sizeof(padding)) {
2380f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	PORT_Assert(0);
2381f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	return -1;
2382f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
2383f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2384f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (SECSuccess != ssl3_AppendHandshakeNumber(ss, ssl_padding_xtn, 2))
2385f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	return -1;
2386f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (SECSuccess != ssl3_AppendHandshakeNumber(ss, paddingLen, 2))
2387f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	return -1;
2388f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (SECSuccess != ssl3_AppendHandshake(ss, padding, paddingLen))
2389f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	return -1;
2390f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2391f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return extensionLen;
2392f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
2393f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2394f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)/* ssl3_ClientSendSignedCertTimestampXtn sends the signed_certificate_timestamp
2395f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * extension for TLS ClientHellos. */
2396f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)static PRInt32
2397f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ssl3_ClientSendSignedCertTimestampXtn(sslSocket *ss, PRBool append,
2398f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)				      PRUint32 maxBytes)
2399f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles){
2400f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    PRInt32 extension_length = 2 /* extension_type */ +
2401f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	    2 /* length(extension_data) */;
2402f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2403f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    /* Only send the extension if processing is enabled. */
2404f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (!ss->opt.enableSignedCertTimestamps)
2405f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	return 0;
2406f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2407f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (append && maxBytes >= extension_length) {
2408f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	SECStatus rv;
2409f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	/* extension_type */
2410f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	rv = ssl3_AppendHandshakeNumber(ss,
2411f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)					ssl_signed_certificate_timestamp_xtn,
2412f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)					2);
2413f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	if (rv != SECSuccess)
2414f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	    goto loser;
2415f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	/* zero length */
2416f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	rv = ssl3_AppendHandshakeNumber(ss, 0, 2);
2417f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	if (rv != SECSuccess)
2418f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	    goto loser;
2419f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
2420f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)		ssl_signed_certificate_timestamp_xtn;
2421f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    } else if (maxBytes < extension_length) {
2422f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	PORT_Assert(0);
2423f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	return 0;
2424f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
2425f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2426f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return extension_length;
2427f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)loser:
2428f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return -1;
2429f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
2430f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2431f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)static SECStatus
2432f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ssl3_ClientHandleSignedCertTimestampXtn(sslSocket *ss, PRUint16 ex_type,
2433f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)					SECItem *data)
2434f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles){
2435f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    /* We do not yet know whether we'll be resuming a session or creating
2436f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)     * a new one, so we keep a pointer to the data in the TLSExtensionData
2437f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)     * structure. This pointer is only valid in the scope of
2438f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)     * ssl3_HandleServerHello, and, if not resuming a session, the data is
2439f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)     * copied once a new session structure has been set up.
2440f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)     * All parsing is currently left to the application and we accept
2441f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)     * everything, including empty data.
2442f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)     */
2443f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    SECItem *scts = &ss->xtnData.signedCertTimestamps;
2444f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    PORT_Assert(!scts->data && !scts->len);
2445f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2446f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (!data->len) {
2447f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	/* Empty extension data: RFC 6962 mandates non-empty contents. */
2448f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	return SECFailure;
2449f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
2450f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    *scts = *data;
2451f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    /* Keep track of negotiated extensions. */
2452f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
2453f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return SECSuccess;
2454f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
2455