ssl3ext.c revision c2e0dbddbe15c98d52c4786dac06cb8952a8ae6d
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 */ 9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)/* $Id$ */ 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "nssrenam.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "nss.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ssl.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sslimpl.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sslproto.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "pk11pub.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifdef NO_PKCS11_BYPASS 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "blapit.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "blapi.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "prinit.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static unsigned char key_name[SESS_TICKET_KEY_NAME_LEN]; 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PK11SymKey *session_ticket_enc_key_pkcs11 = NULL; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PK11SymKey *session_ticket_mac_key_pkcs11 = NULL; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef NO_PKCS11_BYPASS 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static unsigned char session_ticket_enc_key[AES_256_KEY_LENGTH]; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static unsigned char session_ticket_mac_key[SHA256_LENGTH]; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRBool session_ticket_keys_initialized = PR_FALSE; 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRCallOnceType generate_session_keys_once; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* forward static function declarations */ 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus ssl3_ParseEncryptedSessionTicket(sslSocket *ss, 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECItem *data, EncryptedSessionTicket *enc_session_ticket); 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus ssl3_AppendToItem(SECItem *item, const unsigned char *buf, 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint32 bytes); 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus ssl3_AppendNumberToItem(SECItem *item, PRUint32 num, 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRInt32 lenSize); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus ssl3_GetSessionTicketKeysPKCS11(sslSocket *ss, 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PK11SymKey **aes_key, PK11SymKey **mac_key); 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef NO_PKCS11_BYPASS 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus ssl3_GetSessionTicketKeys(const unsigned char **aes_key, 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint32 *aes_key_length, const unsigned char **mac_key, 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint32 *mac_key_length); 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRInt32 ssl3_SendRenegotiationInfoXtn(sslSocket * ss, 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRBool append, PRUint32 maxBytes); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus ssl3_HandleRenegotiationInfoXtn(sslSocket *ss, 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint16 ex_type, SECItem *data); 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint16 ex_type, SECItem *data); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus ssl3_ServerHandleNextProtoNegoXtn(sslSocket *ss, 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint16 ex_type, SECItem *data); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRInt32 ssl3_ClientSendNextProtoNegoXtn(sslSocket *ss, PRBool append, 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint32 maxBytes); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRInt32 ssl3_SendUseSRTPXtn(sslSocket *ss, PRBool append, 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint32 maxBytes); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus ssl3_HandleUseSRTPXtn(sslSocket * ss, PRUint16 ex_type, 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECItem *data); 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static SECStatus ssl3_ClientHandleChannelIDXtn(sslSocket *ss, 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PRUint16 ex_type, SECItem *data); 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static PRInt32 ssl3_ClientSendChannelIDXtn(sslSocket *ss, PRBool append, 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PRUint32 maxBytes); 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static SECStatus ssl3_ServerSendStatusRequestXtn(sslSocket * ss, 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PRBool append, PRUint32 maxBytes); 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static SECStatus ssl3_ServerHandleStatusRequestXtn(sslSocket *ss, 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PRUint16 ex_type, SECItem *data); 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static SECStatus ssl3_ClientHandleStatusRequestXtn(sslSocket *ss, 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PRUint16 ex_type, 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SECItem *data); 75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static PRInt32 ssl3_ClientSendStatusRequestXtn(sslSocket * ss, PRBool append, 76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PRUint32 maxBytes); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Write bytes. Using this function means the SECItem structure 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * cannot be freed. The caller is expected to call this function 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * on a shallow copy of the structure. 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_AppendToItem(SECItem *item, const unsigned char *buf, PRUint32 bytes) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bytes > item->len) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_Memcpy(item->data, buf, bytes); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item->data += bytes; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item->len -= bytes; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Write a number in network byte order. Using this function means the 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * SECItem structure cannot be freed. The caller is expected to call 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * this function on a shallow copy of the structure. 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_AppendNumberToItem(SECItem *item, PRUint32 num, PRInt32 lenSize) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECStatus rv; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint8 b[4]; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint8 * p = b; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (lenSize) { 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 4: 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *p++ = (uint8) (num >> 24); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 3: 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *p++ = (uint8) (num >> 16); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 2: 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *p++ = (uint8) (num >> 8); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 1: 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *p = (uint8) num; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendToItem(item, &b[0], lenSize); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus ssl3_SessionTicketShutdown(void* appData, void* nssData) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (session_ticket_enc_key_pkcs11) { 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PK11_FreeSymKey(session_ticket_enc_key_pkcs11); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_ticket_enc_key_pkcs11 = NULL; 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (session_ticket_mac_key_pkcs11) { 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PK11_FreeSymKey(session_ticket_mac_key_pkcs11); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_ticket_mac_key_pkcs11 = NULL; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_Memset(&generate_session_keys_once, 0, 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(generate_session_keys_once)); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRStatus 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_GenerateSessionTicketKeysPKCS11(void *data) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECStatus rv; 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sslSocket *ss = (sslSocket *)data; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECKEYPrivateKey *svrPrivKey = ss->serverCerts[kt_rsa].SERVERKEY; 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECKEYPublicKey *svrPubKey = ss->serverCerts[kt_rsa].serverKeyPair->pubKey; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (svrPrivKey == NULL || svrPubKey == NULL) { 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_DBG(("%d: SSL[%d]: Pub or priv key(s) is NULL.", 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_GETPID(), ss->fd)); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto loser; 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Get a copy of the session keys from shared memory. */ 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_Memcpy(key_name, SESS_TICKET_KEY_NAME_PREFIX, 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(SESS_TICKET_KEY_NAME_PREFIX)); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ssl_GetSessionTicketKeysPKCS11(svrPrivKey, svrPubKey, 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->pkcs11PinArg, &key_name[SESS_TICKET_KEY_NAME_PREFIX_LEN], 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &session_ticket_enc_key_pkcs11, &session_ticket_mac_key_pkcs11)) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PR_FAILURE; 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = NSS_RegisterShutdown(ssl3_SessionTicketShutdown, NULL); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto loser; 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PR_SUCCESS; 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)loser: 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl3_SessionTicketShutdown(NULL, NULL); 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PR_FAILURE; 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_GetSessionTicketKeysPKCS11(sslSocket *ss, PK11SymKey **aes_key, 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PK11SymKey **mac_key) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (PR_CallOnceWithArg(&generate_session_keys_once, 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl3_GenerateSessionTicketKeysPKCS11, ss) != PR_SUCCESS) 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (session_ticket_enc_key_pkcs11 == NULL || 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_ticket_mac_key_pkcs11 == NULL) 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *aes_key = session_ticket_enc_key_pkcs11; 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *mac_key = session_ticket_mac_key_pkcs11; 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef NO_PKCS11_BYPASS 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRStatus 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_GenerateSessionTicketKeys(void) 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_Memcpy(key_name, SESS_TICKET_KEY_NAME_PREFIX, 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(SESS_TICKET_KEY_NAME_PREFIX)); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ssl_GetSessionTicketKeys(&key_name[SESS_TICKET_KEY_NAME_PREFIX_LEN], 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_ticket_enc_key, session_ticket_mac_key)) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PR_FAILURE; 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_ticket_keys_initialized = PR_TRUE; 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PR_SUCCESS; 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_GetSessionTicketKeys(const unsigned char **aes_key, 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint32 *aes_key_length, const unsigned char **mac_key, 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint32 *mac_key_length) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (PR_CallOnce(&generate_session_keys_once, 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl3_GenerateSessionTicketKeys) != SECSuccess) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!session_ticket_keys_initialized) 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *aes_key = session_ticket_enc_key; 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *aes_key_length = sizeof(session_ticket_enc_key); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *mac_key = session_ticket_mac_key; 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *mac_key_length = sizeof(session_ticket_mac_key); 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Table of handlers for received TLS hello extensions, one per extension. 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * In the second generation, this table will be dynamic, and functions 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * will be registered here. 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* This table is used by the server, to handle client hello extensions. */ 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const ssl3HelloExtensionHandler clientHelloHandlers[] = { 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { ssl_server_name_xtn, &ssl3_HandleServerNameXtn }, 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef NSS_ENABLE_ECC 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { ssl_elliptic_curves_xtn, &ssl3_HandleSupportedCurvesXtn }, 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { ssl_ec_point_formats_xtn, &ssl3_HandleSupportedPointFormatsXtn }, 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { ssl_session_ticket_xtn, &ssl3_ServerHandleSessionTicketXtn }, 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { ssl_next_proto_nego_xtn, &ssl3_ServerHandleNextProtoNegoXtn }, 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { ssl_use_srtp_xtn, &ssl3_HandleUseSRTPXtn }, 238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) { ssl_cert_status_xtn, &ssl3_ServerHandleStatusRequestXtn }, 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { -1, NULL } 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* These two tables are used by the client, to handle server hello 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * extensions. */ 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const ssl3HelloExtensionHandler serverHelloHandlersTLS[] = { 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { ssl_server_name_xtn, &ssl3_HandleServerNameXtn }, 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* TODO: add a handler for ssl_ec_point_formats_xtn */ 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { ssl_session_ticket_xtn, &ssl3_ClientHandleSessionTicketXtn }, 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { ssl_next_proto_nego_xtn, &ssl3_ClientHandleNextProtoNegoXtn }, 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ssl_use_srtp_xtn, &ssl3_HandleUseSRTPXtn }, 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ssl_channel_id_xtn, &ssl3_ClientHandleChannelIDXtn }, 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { ssl_cert_status_xtn, &ssl3_ClientHandleStatusRequestXtn }, 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { -1, NULL } 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const ssl3HelloExtensionHandler serverHelloHandlersSSL3[] = { 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { -1, NULL } 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Tables of functions to format TLS hello extensions, one function per 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * extension. 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * These static tables are for the formatting of client hello extensions. 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The server's table of hello senders is dynamic, in the socket struct, 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and sender functions are registered there. 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS] = { 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { ssl_server_name_xtn, &ssl3_SendServerNameXtn }, 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { ssl_renegotiation_info_xtn, &ssl3_SendRenegotiationInfoXtn }, 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef NSS_ENABLE_ECC 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { ssl_elliptic_curves_xtn, &ssl3_SendSupportedCurvesXtn }, 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { ssl_ec_point_formats_xtn, &ssl3_SendSupportedPointFormatsXtn }, 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { ssl_session_ticket_xtn, &ssl3_SendSessionTicketXtn }, 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { ssl_next_proto_nego_xtn, &ssl3_ClientSendNextProtoNegoXtn }, 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ssl_use_srtp_xtn, &ssl3_SendUseSRTPXtn }, 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { ssl_channel_id_xtn, &ssl3_ClientSendChannelIDXtn }, 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ssl_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn } 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* any extra entries will appear as { 0, NULL } */ 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3HelloExtensionSender clientHelloSendersSSL3[SSL_MAX_EXTENSIONS] = { 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { ssl_renegotiation_info_xtn, &ssl3_SendRenegotiationInfoXtn } 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* any extra entries will appear as { 0, NULL } */ 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRBool 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)arrayContainsExtension(const PRUint16 *array, PRUint32 len, PRUint16 ex_type) 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < len; i++) { 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ex_type == array[i]) 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PR_TRUE; 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PR_FALSE; 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRBool 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_ExtensionNegotiated(sslSocket *ss, PRUint16 ex_type) { 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TLSExtensionData *xtnData = &ss->xtnData; 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return arrayContainsExtension(xtnData->negotiated, 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xtnData->numNegotiated, ex_type); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRBool 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_ClientExtensionAdvertised(sslSocket *ss, PRUint16 ex_type) { 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TLSExtensionData *xtnData = &ss->xtnData; 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return arrayContainsExtension(xtnData->advertised, 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xtnData->numAdvertised, ex_type); 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Format an SNI extension, using the name from the socket's URL, 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * unless that name is a dotted decimal string. 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Used by client and server. 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRInt32 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_SendServerNameXtn(sslSocket * ss, PRBool append, 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint32 maxBytes) 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECStatus rv; 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ss) 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ss->sec.isServer) { 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint32 len; 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRNetAddr netAddr; 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* must have a hostname */ 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ss->url || !ss->url[0]) 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* must not be an IPv4 or IPv6 address */ 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (PR_SUCCESS == PR_StringToNetAddr(ss->url, &netAddr)) { 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* is an IP address (v4 or v6) */ 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) len = PORT_Strlen(ss->url); 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (append && maxBytes >= len + 9) { 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* extension_type */ 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendHandshakeNumber(ss, ssl_server_name_xtn, 2); 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) return -1; 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* length of extension_data */ 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendHandshakeNumber(ss, len + 5, 2); 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) return -1; 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* length of server_name_list */ 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendHandshakeNumber(ss, len + 3, 2); 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) return -1; 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Name Type (sni_host_name) */ 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendHandshake(ss, "\0", 1); 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) return -1; 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* HostName (length and value) */ 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendHandshakeVariable(ss, (PRUint8 *)ss->url, len, 2); 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) return -1; 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ss->sec.isServer) { 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TLSExtensionData *xtnData = &ss->xtnData; 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xtnData->advertised[xtnData->numAdvertised++] = 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl_server_name_xtn; 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return len + 9; 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Server side */ 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (append && maxBytes >= 4) { 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, 0, 2); 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) return -1; 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 4; 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* handle an incoming SNI extension, by ignoring it. */ 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_HandleServerNameXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data) 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECItem *names = NULL; 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint32 listCount = 0, namesPos = 0, i; 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TLSExtensionData *xtnData = &ss->xtnData; 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECItem ldata; 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRInt32 listLenBytes = 0; 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ss->sec.isServer) { 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Verify extension_data is empty. */ 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (data->data || data->len || 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !ssl3_ExtensionNegotiated(ss, ssl_server_name_xtn)) { 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* malformed or was not initiated by the client.*/ 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Server side - consume client data and register server sender. */ 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* do not parse the data if don't have user extension handling function. */ 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ss->sniSocketConfig) { 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* length of server_name_list */ 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listLenBytes = ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len); 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (listLenBytes == 0 || listLenBytes != data->len) { 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ldata = *data; 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Calculate the size of the array.*/ 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (listLenBytes > 0) { 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECItem litem; 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECStatus rv; 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRInt32 type; 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Name Type (sni_host_name) */ 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = ssl3_ConsumeHandshakeNumber(ss, 1, &ldata.data, &ldata.len); 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ldata.len) { 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_ConsumeHandshakeVariable(ss, &litem, 2, &ldata.data, &ldata.len); 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) { 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Adjust total length for cunsumed item, item len and type.*/ 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listLenBytes -= litem.len + 3; 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (listLenBytes > 0 && !ldata.len) { 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listCount += 1; 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!listCount) { 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) names = PORT_ZNewArray(SECItem, listCount); 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!names) { 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0;i < listCount;i++) { 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int j; 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRInt32 type; 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECStatus rv; 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRBool nametypePresent = PR_FALSE; 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Name Type (sni_host_name) */ 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = ssl3_ConsumeHandshakeNumber(ss, 1, &data->data, &data->len); 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Check if we have such type in the list */ 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (j = 0;j < listCount && names[j].data;j++) { 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (names[j].type == type) { 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nametypePresent = PR_TRUE; 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* HostName (length and value) */ 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_ConsumeHandshakeVariable(ss, &names[namesPos], 2, 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &data->data, &data->len); 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) { 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto loser; 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (nametypePresent == PR_FALSE) { 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) namesPos += 1; 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Free old and set the new data. */ 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (xtnData->sniNameArr) { 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_Free(ss->xtnData.sniNameArr); 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xtnData->sniNameArr = names; 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xtnData->sniNameArrSize = namesPos; 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xtnData->negotiated[xtnData->numNegotiated++] = ssl_server_name_xtn; 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)loser: 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_Free(names); 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Called by both clients and servers. 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Clients sends a filled in session ticket if one is available, and otherwise 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sends an empty ticket. Servers always send empty tickets. 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRInt32 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_SendSessionTicketXtn( 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sslSocket * ss, 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRBool append, 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint32 maxBytes) 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRInt32 extension_length; 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NewSessionTicket *session_ticket = NULL; 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Ignore the SessionTicket extension if processing is disabled. */ 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ss->opt.enableSessionTickets) 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Empty extension length = extension_type (2-bytes) + 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * length(extension_data) (2-bytes) 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_length = 4; 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* If we are a client then send a session ticket if one is availble. 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Servers that support the extension and are willing to negotiate the 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the extension always respond with an empty extension. 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ss->sec.isServer) { 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sslSessionID *sid = ss->sec.ci.sid; 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_ticket = &sid->u.ssl3.sessionTicket; 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (session_ticket->ticket.data) { 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ss->xtnData.ticketTimestampVerified) { 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_length += session_ticket->ticket.len; 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (!append && 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (session_ticket->ticket_lifetime_hint == 0 || 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (session_ticket->ticket_lifetime_hint + 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_ticket->received_timestamp > ssl_Time()))) { 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_length += session_ticket->ticket.len; 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->xtnData.ticketTimestampVerified = PR_TRUE; 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (append && maxBytes >= extension_length) { 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECStatus rv; 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* extension_type */ 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendHandshakeNumber(ss, ssl_session_ticket_xtn, 2); 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto loser; 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (session_ticket && session_ticket->ticket.data && 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->xtnData.ticketTimestampVerified) { 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendHandshakeVariable(ss, session_ticket->ticket.data, 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_ticket->ticket.len, 2); 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->xtnData.ticketTimestampVerified = PR_FALSE; 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendHandshakeNumber(ss, 0, 2); 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto loser; 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ss->sec.isServer) { 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TLSExtensionData *xtnData = &ss->xtnData; 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xtnData->advertised[xtnData->numAdvertised++] = 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl_session_ticket_xtn; 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (maxBytes < extension_length) { 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_Assert(0); 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return extension_length; 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loser: 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->xtnData.ticketTimestampVerified = PR_FALSE; 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* handle an incoming Next Protocol Negotiation extension. */ 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_ServerHandleNextProtoNegoXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data) 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ss->firstHsDone || data->len != 0) { 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Clients MUST send an empty NPN extension, if any. */ 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID); 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* TODO: server side NPN support would require calling 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ssl3_RegisterServerHelloExtensionSender here in order to echo the 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * extension back to the client. */ 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* ssl3_ValidateNextProtoNego checks that the given block of data is valid: none 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * of the lengths may be 0 and the sum of the lengths must equal the length of 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the block. */ 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_ValidateNextProtoNego(const unsigned char* data, unsigned int length) 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int offset = 0; 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (offset < length) { 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int newOffset = offset + 1 + (unsigned int) data[offset]; 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Reject embedded nulls to protect against buggy applications that 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * store protocol identifiers in null-terminated strings. 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (newOffset > length || data[offset] == 0) { 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID); 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offset = newOffset; 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (offset > length) { 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID); 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, PRUint16 ex_type, 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECItem *data) 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECStatus rv; 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned char resultBuffer[255]; 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECItem result = { siBuffer, resultBuffer, 0 }; 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_Assert(!ss->firstHsDone); 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_ValidateNextProtoNego(data->data, data->len); 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv; 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* ss->nextProtoCallback cannot normally be NULL if we negotiated the 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * extension. However, It is possible that an application erroneously 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * cleared the callback between the time we sent the ClientHello and now. 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_Assert(ss->nextProtoCallback != NULL); 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ss->nextProtoCallback) { 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* XXX Use a better error code. This is an application error, not an 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * NSS bug. */ 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ss->nextProtoCallback(ss->nextProtoArg, ss->fd, data->data, data->len, 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result.data, &result.len, sizeof resultBuffer); 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv; 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* If the callback wrote more than allowed to |result| it has corrupted our 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * stack. */ 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result.len > sizeof resultBuffer) { 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_SetError(SEC_ERROR_OUTPUT_LEN); 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE); 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECITEM_CopyItem(NULL, &ss->ssl3.nextProto, &result); 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRInt32 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_ClientSendNextProtoNegoXtn(sslSocket * ss, PRBool append, 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint32 maxBytes) 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRInt32 extension_length; 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Renegotiations do not send this extension. */ 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ss->nextProtoCallback || ss->firstHsDone) { 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_length = 4; 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (append && maxBytes >= extension_length) { 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECStatus rv; 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendHandshakeNumber(ss, ssl_next_proto_nego_xtn, 2); 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto loser; 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendHandshakeNumber(ss, 0, 2); 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto loser; 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->xtnData.advertised[ss->xtnData.numAdvertised++] = 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl_next_proto_nego_xtn; 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (maxBytes < extension_length) { 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return extension_length; 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)loser: 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_ClientHandleChannelIDXtn(sslSocket *ss, PRUint16 ex_type, 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECItem *data) 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_Assert(ss->getChannelID != NULL); 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (data->len) { 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_SetError(SSL_ERROR_BAD_CHANNEL_ID_DATA); 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRInt32 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_ClientSendChannelIDXtn(sslSocket * ss, PRBool append, 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint32 maxBytes) 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRInt32 extension_length = 4; 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ss->getChannelID) 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (maxBytes < extension_length) { 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_Assert(0); 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (append) { 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECStatus rv; 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendHandshakeNumber(ss, ssl_channel_id_xtn, 2); 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto loser; 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendHandshakeNumber(ss, 0, 2); 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto loser; 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->xtnData.advertised[ss->xtnData.numAdvertised++] = 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl_channel_id_xtn; 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return extension_length; 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)loser: 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static SECStatus 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_ClientHandleStatusRequestXtn(sslSocket *ss, PRUint16 ex_type, 717c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SECItem *data) 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* The echoed extension must be empty. */ 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (data->len != 0) 721c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return SECFailure; 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Keep track of negotiated extensions. */ 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 729c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static PRInt32 730c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ssl3_ServerSendStatusRequestXtn( 731c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) sslSocket * ss, 732c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PRBool append, 733c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PRUint32 maxBytes) 734c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){ 735c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PRInt32 extension_length; 736c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SECStatus rv; 737c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 738c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!ss->certStatusArray) 739c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return 0; 740c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 741c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) extension_length = 2 + 2; 742c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (append && maxBytes >= extension_length) { 743c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /* extension_type */ 744c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) rv = ssl3_AppendHandshakeNumber(ss, ssl_cert_status_xtn, 2); 745c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (rv != SECSuccess) 746c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return -1; 747c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /* length of extension_data */ 748c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) rv = ssl3_AppendHandshakeNumber(ss, 0, 2); 749c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (rv != SECSuccess) 750c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return -1; 751c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 752c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 753c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return extension_length; 754c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 755c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* ssl3_ClientSendStatusRequestXtn builds the status_request extension on the 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * client side. See RFC 4366 section 3.6. */ 758c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static PRInt32 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_ClientSendStatusRequestXtn(sslSocket * ss, PRBool append, 760c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PRUint32 maxBytes) 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRInt32 extension_length; 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ss->opt.enableOCSPStapling) 765c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return 0; 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* extension_type (2-bytes) + 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * length(extension_data) (2-bytes) + 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * status_type (1) + 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * responder_id_list length (2) + 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * request_extensions length (2) 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_length = 9; 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (append && maxBytes >= extension_length) { 776c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SECStatus rv; 777c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TLSExtensionData *xtnData; 778c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 779c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /* extension_type */ 780c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) rv = ssl3_AppendHandshakeNumber(ss, ssl_cert_status_xtn, 2); 781c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (rv != SECSuccess) 782c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return -1; 783c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2); 784c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (rv != SECSuccess) 785c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return -1; 786c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) rv = ssl3_AppendHandshakeNumber(ss, 1 /* status_type ocsp */, 1); 787c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (rv != SECSuccess) 788c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return -1; 789c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /* A zero length responder_id_list means that the responders are 790c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * implicitly known to the server. */ 791c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) rv = ssl3_AppendHandshakeNumber(ss, 0, 2); 792c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (rv != SECSuccess) 793c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return -1; 794c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /* A zero length request_extensions means that there are no extensions. 795c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * Specifically, we don't set the id-pkix-ocsp-nonce extension. This 796c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * means that the server can replay a cached OCSP response to us. */ 797c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) rv = ssl3_AppendHandshakeNumber(ss, 0, 2); 798c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (rv != SECSuccess) 799c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return -1; 800c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 801c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) xtnData = &ss->xtnData; 802c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) xtnData->advertised[xtnData->numAdvertised++] = ssl_cert_status_xtn; 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (maxBytes < extension_length) { 804c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PORT_Assert(0); 805c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return 0; 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return extension_length; 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * NewSessionTicket 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Called from ssl3_HandleFinished 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_SendNewSessionTicket(sslSocket *ss) 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECStatus rv; 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NewSessionTicket ticket; 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECItem plaintext; 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECItem plaintext_item = {0, NULL, 0}; 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECItem ciphertext = {0, NULL, 0}; 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint32 ciphertext_length; 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRBool ms_is_wrapped; 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned char wrapped_ms[SSL3_MASTER_SECRET_LENGTH]; 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECItem ms_item = {0, NULL, 0}; 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL3KEAType effectiveExchKeyType = ssl_kea_null; 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint32 padding_length; 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint32 message_length; 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint32 cert_length; 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint8 length_buf[4]; 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint32 now; 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PK11SymKey *aes_key_pkcs11; 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PK11SymKey *mac_key_pkcs11; 8352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef NO_PKCS11_BYPASS 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const unsigned char *aes_key; 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const unsigned char *mac_key; 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint32 aes_key_length; 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint32 mac_key_length; 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint64 aes_ctx_buf[MAX_CIPHER_CONTEXT_LLONGS]; 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AESContext *aes_ctx; 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SECHashObject *hashObj = NULL; 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint64 hmac_ctx_buf[MAX_MAC_CONTEXT_LLONGS]; 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HMACContext *hmac_ctx; 8452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 8462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CK_MECHANISM_TYPE cipherMech = CKM_AES_CBC; 8472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PK11Context *aes_ctx_pkcs11; 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CK_MECHANISM_TYPE macMech = CKM_SHA256_HMAC; 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PK11Context *hmac_ctx_pkcs11; 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned char computed_mac[TLS_EX_SESS_TICKET_MAC_LENGTH]; 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int computed_mac_length; 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned char iv[AES_BLOCK_SIZE]; 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECItem ivItem; 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECItem *srvName = NULL; 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint32 srvNameLen = 0; 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CK_MECHANISM_TYPE msWrapMech = 0; /* dummy default value, 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * must be >= 0 */ 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_TRC(3, ("%d: SSL3[%d]: send session_ticket handshake", 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_GETPID(), ss->fd)); 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ticket.ticket_lifetime_hint = TLS_EX_SESS_TICKET_LIFETIME_HINT; 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cert_length = (ss->opt.requestCertificate && ss->sec.ci.sid->peerCert) ? 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3 + ss->sec.ci.sid->peerCert->derCert.len : 0; 8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Get IV and encryption keys */ 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ivItem.data = iv; 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ivItem.len = sizeof(iv); 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = PK11_GenerateRandom(iv, sizeof(iv)); 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef NO_PKCS11_BYPASS 8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ss->opt.bypassPKCS11) { 8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_GetSessionTicketKeys(&aes_key, &aes_key_length, 8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &mac_key, &mac_key_length); 8792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else 8802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 8812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_GetSessionTicketKeysPKCS11(ss, &aes_key_pkcs11, 8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &mac_key_pkcs11); 8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ss->ssl3.pwSpec->msItem.len && ss->ssl3.pwSpec->msItem.data) { 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* The master secret is available unwrapped. */ 8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ms_item.data = ss->ssl3.pwSpec->msItem.data; 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ms_item.len = ss->ssl3.pwSpec->msItem.len; 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ms_is_wrapped = PR_FALSE; 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Extract the master secret wrapped. */ 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sslSessionID sid; 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_Memset(&sid, 0, sizeof(sslSessionID)); 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa) { 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) effectiveExchKeyType = kt_rsa; 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) effectiveExchKeyType = ss->ssl3.hs.kea_def->exchKeyType; 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_CacheWrappedMasterSecret(ss, &sid, ss->ssl3.pwSpec, 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) effectiveExchKeyType); 9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv == SECSuccess) { 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sid.u.ssl3.keys.wrapped_master_secret_len > sizeof(wrapped_ms)) 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto loser; 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(wrapped_ms, sid.u.ssl3.keys.wrapped_master_secret, 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sid.u.ssl3.keys.wrapped_master_secret_len); 9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ms_item.data = wrapped_ms; 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ms_item.len = sid.u.ssl3.keys.wrapped_master_secret_len; 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) msWrapMech = sid.u.ssl3.masterWrapMech; 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* TODO: else send an empty ticket. */ 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto loser; 9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ms_is_wrapped = PR_TRUE; 9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Prep to send negotiated name */ 9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) srvName = &ss->ssl3.pwSpec->srvVirtName; 9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (srvName->data && srvName->len) { 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) srvNameLen = 2 + srvName->len; /* len bytes + name len */ 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ciphertext_length = 9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(PRUint16) /* ticket_version */ 9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + sizeof(SSL3ProtocolVersion) /* ssl_version */ 9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + sizeof(ssl3CipherSuite) /* ciphersuite */ 9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + 1 /* compression */ 9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + 10 /* cipher spec parameters */ 9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + 1 /* SessionTicket.ms_is_wrapped */ 9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + 1 /* effectiveExchKeyType */ 9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + 4 /* msWrapMech */ 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + 2 /* master_secret.length */ 9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + ms_item.len /* master_secret */ 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + 1 /* client_auth_type */ 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + cert_length /* cert */ 9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + 1 /* server name type */ 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + srvNameLen /* name len + length field */ 9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + sizeof(ticket.ticket_lifetime_hint); 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) padding_length = AES_BLOCK_SIZE - 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (ciphertext_length % AES_BLOCK_SIZE); 9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ciphertext_length += padding_length; 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_length = 9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(ticket.ticket_lifetime_hint) /* ticket_lifetime_hint */ 9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + 2 /* length field for NewSessionTicket.ticket */ 9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + SESS_TICKET_KEY_NAME_LEN /* key_name */ 9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + AES_BLOCK_SIZE /* iv */ 9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + 2 /* length field for NewSessionTicket.ticket.encrypted_state */ 9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + ciphertext_length /* encrypted_state */ 9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + TLS_EX_SESS_TICKET_MAC_LENGTH; /* mac */ 9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (SECITEM_AllocItem(NULL, &plaintext_item, ciphertext_length) == NULL) 9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto loser; 9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) plaintext = plaintext_item; 9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* ticket_version */ 9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendNumberToItem(&plaintext, TLS_EX_SESS_TICKET_VERSION, 9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(PRUint16)); 9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* ssl_version */ 9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendNumberToItem(&plaintext, ss->version, 9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(SSL3ProtocolVersion)); 9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* ciphersuite */ 9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendNumberToItem(&plaintext, ss->ssl3.hs.cipher_suite, 9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(ssl3CipherSuite)); 9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* compression */ 9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendNumberToItem(&plaintext, ss->ssl3.hs.compression, 1); 9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* cipher spec parameters */ 9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendNumberToItem(&plaintext, ss->sec.authAlgorithm, 1); 9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendNumberToItem(&plaintext, ss->sec.authKeyBits, 4); 9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendNumberToItem(&plaintext, ss->sec.keaType, 1); 9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendNumberToItem(&plaintext, ss->sec.keaKeyBits, 4); 9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* master_secret */ 9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendNumberToItem(&plaintext, ms_is_wrapped, 1); 9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendNumberToItem(&plaintext, effectiveExchKeyType, 1); 9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendNumberToItem(&plaintext, msWrapMech, 4); 9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendNumberToItem(&plaintext, ms_item.len, 2); 9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendToItem(&plaintext, ms_item.data, ms_item.len); 9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* client_identity */ 10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ss->opt.requestCertificate && ss->sec.ci.sid->peerCert) { 10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendNumberToItem(&plaintext, CLIENT_AUTH_CERTIFICATE, 1); 10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendNumberToItem(&plaintext, 10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->sec.ci.sid->peerCert->derCert.len, 3); 10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendToItem(&plaintext, 10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->sec.ci.sid->peerCert->derCert.data, 10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->sec.ci.sid->peerCert->derCert.len); 10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendNumberToItem(&plaintext, 0, 1); 10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* timestamp */ 10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) now = ssl_Time(); 10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendNumberToItem(&plaintext, now, 10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(ticket.ticket_lifetime_hint)); 10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (srvNameLen) { 10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Name Type (sni_host_name) */ 10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendNumberToItem(&plaintext, srvName->type, 1); 10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* HostName (length and value) */ 10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendNumberToItem(&plaintext, srvName->len, 2); 10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendToItem(&plaintext, srvName->data, srvName->len); 10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* No Name */ 10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendNumberToItem(&plaintext, (char)TLS_STE_NO_SERVER_NAME, 10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1); 10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_Assert(plaintext.len == padding_length); 10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < padding_length; i++) 10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) plaintext.data[i] = (unsigned char)padding_length; 10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (SECITEM_AllocItem(NULL, &ciphertext, ciphertext_length) == NULL) { 10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = SECFailure; 10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto loser; 10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Generate encrypted portion of ticket. */ 10482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef NO_PKCS11_BYPASS 10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ss->opt.bypassPKCS11) { 10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) aes_ctx = (AESContext *)aes_ctx_buf; 10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = AES_InitContext(aes_ctx, aes_key, aes_key_length, iv, 10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSS_AES_CBC, 1, AES_BLOCK_SIZE); 10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = AES_Encrypt(aes_ctx, ciphertext.data, &ciphertext.len, 10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ciphertext.len, plaintext_item.data, 10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) plaintext_item.len); 10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 10592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else 10602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 10612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) aes_ctx_pkcs11 = PK11_CreateContextBySymKey(cipherMech, 10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CKA_ENCRYPT, aes_key_pkcs11, &ivItem); 10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!aes_ctx_pkcs11) 10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto loser; 10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = PK11_CipherOp(aes_ctx_pkcs11, ciphertext.data, 10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (int *)&ciphertext.len, ciphertext.len, 10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) plaintext_item.data, plaintext_item.len); 10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PK11_Finalize(aes_ctx_pkcs11); 10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PK11_DestroyContext(aes_ctx_pkcs11, PR_TRUE); 10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Convert ciphertext length to network order. */ 10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) length_buf[0] = (ciphertext.len >> 8) & 0xff; 10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) length_buf[1] = (ciphertext.len ) & 0xff; 10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Compute MAC. */ 10802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef NO_PKCS11_BYPASS 10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ss->opt.bypassPKCS11) { 10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hmac_ctx = (HMACContext *)hmac_ctx_buf; 10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hashObj = HASH_GetRawHashObject(HASH_AlgSHA256); 10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HMAC_Init(hmac_ctx, hashObj, mac_key, 10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mac_key_length, PR_FALSE) != SECSuccess) 10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto loser; 10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HMAC_Begin(hmac_ctx); 10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HMAC_Update(hmac_ctx, key_name, SESS_TICKET_KEY_NAME_LEN); 10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HMAC_Update(hmac_ctx, iv, sizeof(iv)); 10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HMAC_Update(hmac_ctx, (unsigned char *)length_buf, 2); 10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HMAC_Update(hmac_ctx, ciphertext.data, ciphertext.len); 10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HMAC_Finish(hmac_ctx, computed_mac, &computed_mac_length, 10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(computed_mac)); 10952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else 10962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 10972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECItem macParam; 10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) macParam.data = NULL; 11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) macParam.len = 0; 11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hmac_ctx_pkcs11 = PK11_CreateContextBySymKey(macMech, 11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CKA_SIGN, mac_key_pkcs11, &macParam); 11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!hmac_ctx_pkcs11) 11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto loser; 11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = PK11_DigestBegin(hmac_ctx_pkcs11); 11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = PK11_DigestOp(hmac_ctx_pkcs11, key_name, 11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SESS_TICKET_KEY_NAME_LEN); 11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = PK11_DigestOp(hmac_ctx_pkcs11, iv, sizeof(iv)); 11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = PK11_DigestOp(hmac_ctx_pkcs11, (unsigned char *)length_buf, 2); 11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = PK11_DigestOp(hmac_ctx_pkcs11, ciphertext.data, ciphertext.len); 11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = PK11_DigestFinal(hmac_ctx_pkcs11, computed_mac, 11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &computed_mac_length, sizeof(computed_mac)); 11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PK11_DestroyContext(hmac_ctx_pkcs11, PR_TRUE); 11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Serialize the handshake message. */ 11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendHandshakeHeader(ss, new_session_ticket, message_length); 11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendHandshakeNumber(ss, ticket.ticket_lifetime_hint, 11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(ticket.ticket_lifetime_hint)); 11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendHandshakeNumber(ss, 11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_length - sizeof(ticket.ticket_lifetime_hint) - 2, 2); 11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendHandshake(ss, key_name, SESS_TICKET_KEY_NAME_LEN); 11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendHandshake(ss, iv, sizeof(iv)); 11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendHandshakeVariable(ss, ciphertext.data, ciphertext.len, 2); 11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendHandshake(ss, computed_mac, computed_mac_length); 11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)loser: 11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (plaintext_item.data) 11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECITEM_FreeItem(&plaintext_item, PR_FALSE); 11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ciphertext.data) 11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECITEM_FreeItem(&ciphertext, PR_FALSE); 11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv; 11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* When a client receives a SessionTicket extension a NewSessionTicket 11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * message is expected during the handshake. 11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus 11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_ClientHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type, 11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECItem *data) 11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (data->len != 0) 11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Keep track of negotiated extensions. */ 11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; 11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus 11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_ServerHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type, 11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECItem *data) 11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECStatus rv; 11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECItem *decrypted_state = NULL; 11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SessionTicket *parsed_session_ticket = NULL; 11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sslSessionID *sid = NULL; 11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL3Statistics *ssl3stats; 11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Ignore the SessionTicket extension if processing is disabled. */ 11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ss->opt.enableSessionTickets) 11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Keep track of negotiated extensions. */ 11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; 11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Parse the received ticket sent in by the client. We are 11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * lenient about some parse errors, falling back to a fullshake 11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * instead of terminating the current connection. 11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (data->len == 0) { 11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->xtnData.emptySessionTicket = PR_TRUE; 11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECItem extension_data; 11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EncryptedSessionTicket enc_session_ticket; 11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned char computed_mac[TLS_EX_SESS_TICKET_MAC_LENGTH]; 11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int computed_mac_length; 11952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef NO_PKCS11_BYPASS 11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SECHashObject *hashObj; 11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const unsigned char *aes_key; 11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const unsigned char *mac_key; 11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint32 aes_key_length; 12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint32 mac_key_length; 12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint64 hmac_ctx_buf[MAX_MAC_CONTEXT_LLONGS]; 12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HMACContext *hmac_ctx; 12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint64 aes_ctx_buf[MAX_CIPHER_CONTEXT_LLONGS]; 12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AESContext *aes_ctx; 12052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 12062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PK11SymKey *aes_key_pkcs11; 12072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PK11SymKey *mac_key_pkcs11; 12082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PK11Context *hmac_ctx_pkcs11; 12092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CK_MECHANISM_TYPE macMech = CKM_SHA256_HMAC; 12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PK11Context *aes_ctx_pkcs11; 12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CK_MECHANISM_TYPE cipherMech = CKM_AES_CBC; 12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned char * padding; 12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint32 padding_length; 12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned char *buffer; 12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int buffer_len; 12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRInt32 temp; 12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECItem cert_item; 12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRInt8 nameType = TLS_STE_NO_SERVER_NAME; 12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Turn off stateless session resumption if the client sends a 12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * SessionTicket extension, even if the extension turns out to be 12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * malformed (ss->sec.ci.sid is non-NULL when doing session 12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * renegotiation.) 12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ss->sec.ci.sid != NULL) { 12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ss->sec.uncache) 12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->sec.uncache(ss->sec.ci.sid); 12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl_FreeSID(ss->sec.ci.sid); 12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->sec.ci.sid = NULL; 12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_data.data = data->data; /* Keep a copy for future use. */ 12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_data.len = data->len; 12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ssl3_ParseEncryptedSessionTicket(ss, data, &enc_session_ticket) 12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) != SECSuccess) 12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Get session ticket keys. */ 12402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef NO_PKCS11_BYPASS 12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ss->opt.bypassPKCS11) { 12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_GetSessionTicketKeys(&aes_key, &aes_key_length, 12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &mac_key, &mac_key_length); 12442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else 12452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 1246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) { 12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_GetSessionTicketKeysPKCS11(ss, &aes_key_pkcs11, 12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &mac_key_pkcs11); 12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) { 12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_DBG(("%d: SSL[%d]: Unable to get/generate session ticket keys.", 12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_GETPID(), ss->fd)); 12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto loser; 12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* If the ticket sent by the client was generated under a key different 12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * from the one we have, bypass ticket processing. 12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (PORT_Memcmp(enc_session_ticket.key_name, key_name, 12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SESS_TICKET_KEY_NAME_LEN) != 0) { 12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_DBG(("%d: SSL[%d]: Session ticket key_name sent mismatch.", 12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_GETPID(), ss->fd)); 12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto no_ticket; 12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Verify the MAC on the ticket. MAC verification may also 12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * fail if the MAC key has been recently refreshed. 12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 12692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef NO_PKCS11_BYPASS 12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ss->opt.bypassPKCS11) { 12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hmac_ctx = (HMACContext *)hmac_ctx_buf; 12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hashObj = HASH_GetRawHashObject(HASH_AlgSHA256); 12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HMAC_Init(hmac_ctx, hashObj, mac_key, 12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(session_ticket_mac_key), PR_FALSE) != SECSuccess) 12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto no_ticket; 12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HMAC_Begin(hmac_ctx); 12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HMAC_Update(hmac_ctx, extension_data.data, 12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_data.len - TLS_EX_SESS_TICKET_MAC_LENGTH); 12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HMAC_Finish(hmac_ctx, computed_mac, &computed_mac_length, 12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(computed_mac)) != SECSuccess) 12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto no_ticket; 12822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else 12832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 1284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) { 12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECItem macParam; 12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) macParam.data = NULL; 12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) macParam.len = 0; 12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hmac_ctx_pkcs11 = PK11_CreateContextBySymKey(macMech, 12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CKA_SIGN, mac_key_pkcs11, &macParam); 12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!hmac_ctx_pkcs11) { 12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_DBG(("%d: SSL[%d]: Unable to create HMAC context: %d.", 12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_GETPID(), ss->fd, PORT_GetError())); 12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto no_ticket; 12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_DBG(("%d: SSL[%d]: Successfully created HMAC context.", 12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_GETPID(), ss->fd)); 12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = PK11_DigestBegin(hmac_ctx_pkcs11); 12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = PK11_DigestOp(hmac_ctx_pkcs11, extension_data.data, 13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_data.len - TLS_EX_SESS_TICKET_MAC_LENGTH); 13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) { 13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PK11_DestroyContext(hmac_ctx_pkcs11, PR_TRUE); 13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto no_ticket; 13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = PK11_DigestFinal(hmac_ctx_pkcs11, computed_mac, 13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &computed_mac_length, sizeof(computed_mac)); 13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PK11_DestroyContext(hmac_ctx_pkcs11, PR_TRUE); 13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) 13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto no_ticket; 13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (NSS_SecureMemcmp(computed_mac, enc_session_ticket.mac, 13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) computed_mac_length) != 0) { 13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_DBG(("%d: SSL[%d]: Session ticket MAC mismatch.", 13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_GETPID(), ss->fd)); 13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto no_ticket; 13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* We ignore key_name for now. 13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This is ok as MAC verification succeeded. 13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Decrypt the ticket. */ 13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Plaintext is shorter than the ciphertext due to padding. */ 13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decrypted_state = SECITEM_AllocItem(NULL, NULL, 13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enc_session_ticket.encrypted_state.len); 13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef NO_PKCS11_BYPASS 13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ss->opt.bypassPKCS11) { 13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) aes_ctx = (AESContext *)aes_ctx_buf; 13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = AES_InitContext(aes_ctx, aes_key, 13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(session_ticket_enc_key), enc_session_ticket.iv, 13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSS_AES_CBC, 0,AES_BLOCK_SIZE); 13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) { 13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_DBG(("%d: SSL[%d]: Unable to create AES context.", 13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_GETPID(), ss->fd)); 13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto no_ticket; 13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = AES_Decrypt(aes_ctx, decrypted_state->data, 13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &decrypted_state->len, decrypted_state->len, 13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enc_session_ticket.encrypted_state.data, 13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enc_session_ticket.encrypted_state.len); 13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) 13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto no_ticket; 13462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else 13472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 1348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) { 13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECItem ivItem; 13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ivItem.data = enc_session_ticket.iv; 13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ivItem.len = AES_BLOCK_SIZE; 13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) aes_ctx_pkcs11 = PK11_CreateContextBySymKey(cipherMech, 13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CKA_DECRYPT, aes_key_pkcs11, &ivItem); 13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!aes_ctx_pkcs11) { 13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_DBG(("%d: SSL[%d]: Unable to create AES context.", 13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_GETPID(), ss->fd)); 13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto no_ticket; 13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = PK11_CipherOp(aes_ctx_pkcs11, decrypted_state->data, 13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (int *)&decrypted_state->len, decrypted_state->len, 13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enc_session_ticket.encrypted_state.data, 13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enc_session_ticket.encrypted_state.len); 13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PK11_Finalize(aes_ctx_pkcs11); 13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PK11_DestroyContext(aes_ctx_pkcs11, PR_TRUE); 13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) 13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto no_ticket; 13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Check padding. */ 13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) padding_length = 13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (PRUint32)decrypted_state->data[decrypted_state->len - 1]; 13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (padding_length == 0 || padding_length > AES_BLOCK_SIZE) 13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto no_ticket; 13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) padding = &decrypted_state->data[decrypted_state->len - padding_length]; 13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < padding_length; i++, padding++) { 13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (padding_length != (PRUint32)*padding) 13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto no_ticket; 13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Deserialize session state. */ 13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer = decrypted_state->data; 13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_len = decrypted_state->len; 13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parsed_session_ticket = PORT_ZAlloc(sizeof(SessionTicket)); 13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parsed_session_ticket == NULL) { 13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = SECFailure; 13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto loser; 13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Read ticket_version (which is ignored for now.) */ 13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) temp = ssl3_ConsumeHandshakeNumber(ss, 2, &buffer, &buffer_len); 13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (temp < 0) goto no_ticket; 13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parsed_session_ticket->ticket_version = (SSL3ProtocolVersion)temp; 13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Read SSLVersion. */ 13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) temp = ssl3_ConsumeHandshakeNumber(ss, 2, &buffer, &buffer_len); 13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (temp < 0) goto no_ticket; 14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parsed_session_ticket->ssl_version = (SSL3ProtocolVersion)temp; 14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Read cipher_suite. */ 14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) temp = ssl3_ConsumeHandshakeNumber(ss, 2, &buffer, &buffer_len); 14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (temp < 0) goto no_ticket; 14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parsed_session_ticket->cipher_suite = (ssl3CipherSuite)temp; 14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Read compression_method. */ 14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len); 14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (temp < 0) goto no_ticket; 14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parsed_session_ticket->compression_method = (SSLCompressionMethod)temp; 14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Read cipher spec parameters. */ 14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len); 14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (temp < 0) goto no_ticket; 14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parsed_session_ticket->authAlgorithm = (SSLSignType)temp; 14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) temp = ssl3_ConsumeHandshakeNumber(ss, 4, &buffer, &buffer_len); 14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (temp < 0) goto no_ticket; 14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parsed_session_ticket->authKeyBits = (PRUint32)temp; 14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len); 14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (temp < 0) goto no_ticket; 14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parsed_session_ticket->keaType = (SSLKEAType)temp; 14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) temp = ssl3_ConsumeHandshakeNumber(ss, 4, &buffer, &buffer_len); 14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (temp < 0) goto no_ticket; 14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parsed_session_ticket->keaKeyBits = (PRUint32)temp; 14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Read wrapped master_secret. */ 14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len); 14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (temp < 0) goto no_ticket; 14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parsed_session_ticket->ms_is_wrapped = (PRBool)temp; 14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len); 14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (temp < 0) goto no_ticket; 14335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parsed_session_ticket->exchKeyType = (SSL3KEAType)temp; 14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) temp = ssl3_ConsumeHandshakeNumber(ss, 4, &buffer, &buffer_len); 14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (temp < 0) goto no_ticket; 14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parsed_session_ticket->msWrapMech = (CK_MECHANISM_TYPE)temp; 14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) temp = ssl3_ConsumeHandshakeNumber(ss, 2, &buffer, &buffer_len); 14405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (temp < 0) goto no_ticket; 14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parsed_session_ticket->ms_length = (PRUint16)temp; 14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parsed_session_ticket->ms_length == 0 || /* sanity check MS. */ 14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parsed_session_ticket->ms_length > 14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(parsed_session_ticket->master_secret)) 14455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto no_ticket; 14465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Allow for the wrapped master secret to be longer. */ 14485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (buffer_len < sizeof(SSL3_MASTER_SECRET_LENGTH)) 14495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto no_ticket; 14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_Memcpy(parsed_session_ticket->master_secret, buffer, 14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parsed_session_ticket->ms_length); 14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer += parsed_session_ticket->ms_length; 14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_len -= parsed_session_ticket->ms_length; 14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Read client_identity */ 14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len); 14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (temp < 0) 14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto no_ticket; 14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parsed_session_ticket->client_identity.client_auth_type = 14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (ClientAuthenticationType)temp; 14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch(parsed_session_ticket->client_identity.client_auth_type) { 14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case CLIENT_AUTH_ANONYMOUS: 14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case CLIENT_AUTH_CERTIFICATE: 14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_ConsumeHandshakeVariable(ss, &cert_item, 3, 14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &buffer, &buffer_len); 14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto no_ticket; 14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = SECITEM_CopyItem(NULL, &parsed_session_ticket->peer_cert, 14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &cert_item); 14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto no_ticket; 14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto no_ticket; 14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Read timestamp. */ 14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) temp = ssl3_ConsumeHandshakeNumber(ss, 4, &buffer, &buffer_len); 14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (temp < 0) 14785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto no_ticket; 14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parsed_session_ticket->timestamp = (PRUint32)temp; 14805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Read server name */ 14825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nameType = 14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len); 14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (nameType != TLS_STE_NO_SERVER_NAME) { 14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECItem name_item; 14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_ConsumeHandshakeVariable(ss, &name_item, 2, &buffer, 14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &buffer_len); 14885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto no_ticket; 14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = SECITEM_CopyItem(NULL, &parsed_session_ticket->srvName, 14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &name_item); 14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto no_ticket; 14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parsed_session_ticket->srvName.type = nameType; 14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Done parsing. Check that all bytes have been consumed. */ 14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (buffer_len != padding_length) 14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto no_ticket; 14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Use the ticket if it has not expired, otherwise free the allocated 15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * memory since the ticket is of no use. 15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parsed_session_ticket->timestamp != 0 && 15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parsed_session_ticket->timestamp + 15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TLS_EX_SESS_TICKET_LIFETIME_HINT > ssl_Time()) { 15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sid = ssl3_NewSessionID(ss, PR_TRUE); 15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sid == NULL) { 15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = SECFailure; 15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto loser; 15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Copy over parameters. */ 15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sid->version = parsed_session_ticket->ssl_version; 15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sid->u.ssl3.cipherSuite = parsed_session_ticket->cipher_suite; 15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sid->u.ssl3.compression = parsed_session_ticket->compression_method; 15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sid->authAlgorithm = parsed_session_ticket->authAlgorithm; 15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sid->authKeyBits = parsed_session_ticket->authKeyBits; 15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sid->keaType = parsed_session_ticket->keaType; 15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sid->keaKeyBits = parsed_session_ticket->keaKeyBits; 15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Copy master secret. */ 15222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef NO_PKCS11_BYPASS 15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ss->opt.bypassPKCS11 && 15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parsed_session_ticket->ms_is_wrapped) 15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto no_ticket; 15262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parsed_session_ticket->ms_length > 15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(sid->u.ssl3.keys.wrapped_master_secret)) 15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto no_ticket; 15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_Memcpy(sid->u.ssl3.keys.wrapped_master_secret, 15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parsed_session_ticket->master_secret, 15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parsed_session_ticket->ms_length); 15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sid->u.ssl3.keys.wrapped_master_secret_len = 15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parsed_session_ticket->ms_length; 15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sid->u.ssl3.exchKeyType = parsed_session_ticket->exchKeyType; 15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sid->u.ssl3.masterWrapMech = parsed_session_ticket->msWrapMech; 15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sid->u.ssl3.keys.msIsWrapped = 15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parsed_session_ticket->ms_is_wrapped; 15395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sid->u.ssl3.masterValid = PR_TRUE; 15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sid->u.ssl3.keys.resumable = PR_TRUE; 15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Copy over client cert from session ticket if there is one. */ 15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parsed_session_ticket->peer_cert.data != NULL) { 15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sid->peerCert != NULL) 15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CERT_DestroyCertificate(sid->peerCert); 15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sid->peerCert = CERT_NewTempCertificate(ss->dbHandle, 15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &parsed_session_ticket->peer_cert, NULL, PR_FALSE, PR_TRUE); 15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sid->peerCert == NULL) { 15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = SECFailure; 15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto loser; 15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parsed_session_ticket->srvName.data != NULL) { 15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sid->u.ssl3.srvName = parsed_session_ticket->srvName; 15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->statelessResume = PR_TRUE; 15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->sec.ci.sid = sid; 15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (0) { 15625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)no_ticket: 15635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_DBG(("%d: SSL[%d]: Session ticket parsing failed.", 15645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_GETPID(), ss->fd)); 15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl3stats = SSL_GetStatistics(); 15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_AtomicIncrementLong(& ssl3stats->hch_sid_ticket_parse_failures ); 15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = SECSuccess; 15695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)loser: 15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* ss->sec.ci.sid == sid if it did NOT come here via goto statement 15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * in that case do not free sid 15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sid && (ss->sec.ci.sid != sid)) { 15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl_FreeSID(sid); 15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sid = NULL; 15775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (decrypted_state != NULL) { 15795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECITEM_FreeItem(decrypted_state, PR_TRUE); 15805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decrypted_state = NULL; 15815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parsed_session_ticket != NULL) { 15845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parsed_session_ticket->peer_cert.data) { 15855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECITEM_FreeItem(&parsed_session_ticket->peer_cert, PR_FALSE); 15865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_ZFree(parsed_session_ticket, sizeof(SessionTicket)); 15885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv; 15915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 15945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Read bytes. Using this function means the SECItem structure 15955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * cannot be freed. The caller is expected to call this function 15965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * on a shallow copy of the structure. 15975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 15985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus 15995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_ConsumeFromItem(SECItem *item, unsigned char **buf, PRUint32 bytes) 16005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 16015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bytes > item->len) 16025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 16035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *buf = item->data; 16055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item->data += bytes; 16065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item->len -= bytes; 16075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 16085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus 16115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_ParseEncryptedSessionTicket(sslSocket *ss, SECItem *data, 16125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EncryptedSessionTicket *enc_session_ticket) 16135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 16145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ssl3_ConsumeFromItem(data, &enc_session_ticket->key_name, 16155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SESS_TICKET_KEY_NAME_LEN) != SECSuccess) 16165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 16175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ssl3_ConsumeFromItem(data, &enc_session_ticket->iv, 16185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AES_BLOCK_SIZE) != SECSuccess) 16195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 16205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ssl3_ConsumeHandshakeVariable(ss, &enc_session_ticket->encrypted_state, 16215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2, &data->data, &data->len) != SECSuccess) 16225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 16235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ssl3_ConsumeFromItem(data, &enc_session_ticket->mac, 16245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TLS_EX_SESS_TICKET_MAC_LENGTH) != SECSuccess) 16255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 16265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (data->len != 0) /* Make sure that we have consumed all bytes. */ 16275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 16285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 16305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* go through hello extensions in buffer "b". 16335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * For each one, find the extension handler in the table, and 16345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * if present, invoke that handler. 16355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Servers ignore any extensions with unknown extension types. 16365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Clients reject any extensions with unadvertised extension types. 16375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 16385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus 16395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_HandleHelloExtensions(sslSocket *ss, SSL3Opaque **b, PRUint32 *length) 16405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 16415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ssl3HelloExtensionHandler * handlers; 16425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ss->sec.isServer) { 16445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) handlers = clientHelloHandlers; 16455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (ss->version > SSL_LIBRARY_VERSION_3_0) { 16465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) handlers = serverHelloHandlersTLS; 16475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 16485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) handlers = serverHelloHandlersSSL3; 16495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (*length) { 16525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ssl3HelloExtensionHandler * handler; 16535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECStatus rv; 16545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRInt32 extension_type; 16555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECItem extension_data; 16565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Get the extension's type field */ 16585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_type = ssl3_ConsumeHandshakeNumber(ss, 2, b, length); 16595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (extension_type < 0) /* failure to decode extension_type */ 16605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; /* alert already sent */ 16615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* get the data for this extension, so we can pass it or skip it. */ 16635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_ConsumeHandshakeVariable(ss, &extension_data, 2, b, length); 16645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) 16655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv; 16665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Check whether the server sent an extension which was not advertised 16685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * in the ClientHello. 16695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 16705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ss->sec.isServer && 16715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !ssl3_ClientExtensionAdvertised(ss, extension_type)) 16725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; /* TODO: send unsupported_extension alert */ 16735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Check whether an extension has been sent multiple times. */ 16755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ssl3_ExtensionNegotiated(ss, extension_type)) 16765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 16775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* find extension_type in table of Hello Extension Handlers */ 16795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (handler = handlers; handler->ex_type >= 0; handler++) { 16805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* if found, call this handler */ 16815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (handler->ex_type == extension_type) { 16825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = (*handler->ex_handler)(ss, (PRUint16)extension_type, 16835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &extension_data); 16845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Ignore this result */ 16855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Treat all bad extensions as unrecognized types. */ 16865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 16875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 16915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Add a callback function to the table of senders of server hello extensions. 16945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 16955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus 16965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_RegisterServerHelloExtensionSender(sslSocket *ss, PRUint16 ex_type, 16975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl3HelloExtensionSenderFunc cb) 16985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 16995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 17005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl3HelloExtensionSender *sender = &ss->xtnData.serverSenders[0]; 17015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < SSL_MAX_EXTENSIONS; ++i, ++sender) { 17035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!sender->ex_sender) { 17045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sender->ex_type = ex_type; 17055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sender->ex_sender = cb; 17065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 17075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* detect duplicate senders */ 17095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_Assert(sender->ex_type != ex_type); 17105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sender->ex_type == ex_type) { 17115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* duplicate */ 17125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 17135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_Assert(i < SSL_MAX_EXTENSIONS); /* table needs to grow */ 17165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); 17175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 17185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 17195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* call each of the extension senders and return the accumulated length */ 17215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRInt32 17225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_CallHelloExtensionSenders(sslSocket *ss, PRBool append, PRUint32 maxBytes, 17235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ssl3HelloExtensionSender *sender) 17245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 17255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRInt32 total_exten_len = 0; 17265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 17275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!sender) { 17295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sender = ss->version > SSL_LIBRARY_VERSION_3_0 ? 17305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &clientHelloSendersTLS[0] : &clientHelloSendersSSL3[0]; 17315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < SSL_MAX_EXTENSIONS; ++i, ++sender) { 17345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sender->ex_sender) { 17355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRInt32 extLen = (*sender->ex_sender)(ss, append, maxBytes); 17365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (extLen < 0) 17375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; 17385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) maxBytes -= extLen; 17395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) total_exten_len += extLen; 17405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return total_exten_len; 17435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 17445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Extension format: 17475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Extension number: 2 bytes 17485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Extension length: 2 bytes 17495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Verify Data Length: 1 byte 17505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Verify Data (TLS): 12 bytes (client) or 24 bytes (server) 17515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Verify Data (SSL): 36 bytes (client) or 72 bytes (server) 17525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 17535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRInt32 17545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_SendRenegotiationInfoXtn( 17555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sslSocket * ss, 17565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRBool append, 17575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint32 maxBytes) 17585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 17595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRInt32 len, needed; 17605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* In draft-ietf-tls-renegotiation-03, it is NOT RECOMMENDED to send 17625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * both the SCSV and the empty RI, so when we send SCSV in 17635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the initial handshake, we don't also send RI. 17645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 17655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ss || ss->ssl3.hs.sendingSCSV) 17665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 17675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) len = !ss->firstHsDone ? 0 : 17685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (ss->sec.isServer ? ss->ssl3.hs.finishedBytes * 2 17695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : ss->ssl3.hs.finishedBytes); 17705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) needed = 5 + len; 17715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (append && maxBytes >= needed) { 17725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECStatus rv; 17735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* extension_type */ 17745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendHandshakeNumber(ss, ssl_renegotiation_info_xtn, 2); 17755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) return -1; 17765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* length of extension_data */ 17775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendHandshakeNumber(ss, len + 1, 2); 17785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) return -1; 17795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* verify_Data from previous Finished message(s) */ 17805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendHandshakeVariable(ss, 17815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->ssl3.hs.finishedMsgs.data, len, 1); 17825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) return -1; 17835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ss->sec.isServer) { 17845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TLSExtensionData *xtnData = &ss->xtnData; 17855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xtnData->advertised[xtnData->numAdvertised++] = 17865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl_renegotiation_info_xtn; 17875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return needed; 17905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 17915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1792c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static SECStatus 1793c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ssl3_ServerHandleStatusRequestXtn(sslSocket *ss, PRUint16 ex_type, 1794c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SECItem *data) 1795c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){ 1796c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SECStatus rv = SECSuccess; 1797c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PRUint32 len = 0; 1798c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1799c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /* remember that we got this extension. */ 1800c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; 1801c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PORT_Assert(ss->sec.isServer); 1802c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /* prepare to send back the appropriate response */ 1803c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) rv = ssl3_RegisterServerHelloExtensionSender(ss, ex_type, 1804c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ssl3_ServerSendStatusRequestXtn); 1805c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return rv; 1806c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 1807c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 18085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* This function runs in both the client and server. */ 18095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus 18105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_HandleRenegotiationInfoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data) 18115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 18125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECStatus rv = SECSuccess; 18135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint32 len = 0; 18145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ss->firstHsDone) { 18165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) len = ss->sec.isServer ? ss->ssl3.hs.finishedBytes 18175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : ss->ssl3.hs.finishedBytes * 2; 18185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (data->len != 1 + len || 18205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data->data[0] != len || (len && 18215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSS_SecureMemcmp(ss->ssl3.hs.finishedMsgs.data, 18225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data->data + 1, len))) { 18235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Can we do this here? Or, must we arrange for the caller to do it? */ 18245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (void)SSL3_SendAlert(ss, alert_fatal, handshake_failure); 18255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_SetError(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE); 18265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 18275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* remember that we got this extension and it was correct. */ 18295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->peerRequestedProtection = 1; 18305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; 18315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ss->sec.isServer) { 18325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* prepare to send back the appropriate response */ 18335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_RegisterServerHelloExtensionSender(ss, ex_type, 18345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl3_SendRenegotiationInfoXtn); 18355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv; 18375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 18385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRInt32 18405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_SendUseSRTPXtn(sslSocket *ss, PRBool append, PRUint32 maxBytes) 18415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 18425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint32 ext_data_len; 18435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRInt16 i; 18445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECStatus rv; 18455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ss) 18475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 18485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ss->sec.isServer) { 18505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Client side */ 18515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IS_DTLS(ss) || !ss->ssl3.dtlsSRTPCipherCount) 18535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; /* Not relevant */ 18545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ext_data_len = 2 + 2 * ss->ssl3.dtlsSRTPCipherCount + 1; 18565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (append && maxBytes >= 4 + ext_data_len) { 18585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Extension type */ 18595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendHandshakeNumber(ss, ssl_use_srtp_xtn, 2); 18605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) return -1; 18615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Length of extension data */ 18625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendHandshakeNumber(ss, ext_data_len, 2); 18635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) return -1; 18645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Length of the SRTP cipher list */ 18655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendHandshakeNumber(ss, 18665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2 * ss->ssl3.dtlsSRTPCipherCount, 18675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2); 18685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) return -1; 18695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* The SRTP ciphers */ 18705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < ss->ssl3.dtlsSRTPCipherCount; i++) { 18715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendHandshakeNumber(ss, 18725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->ssl3.dtlsSRTPCiphers[i], 18735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2); 18745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Empty MKI value */ 18765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl3_AppendHandshakeVariable(ss, NULL, 0, 1); 18775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->xtnData.advertised[ss->xtnData.numAdvertised++] = 18795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl_use_srtp_xtn; 18805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 4 + ext_data_len; 18835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Server side */ 18865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (append && maxBytes >= 9) { 18875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Extension type */ 18885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendHandshakeNumber(ss, ssl_use_srtp_xtn, 2); 18895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) return -1; 18905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Length of extension data */ 18915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendHandshakeNumber(ss, 5, 2); 18925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) return -1; 18935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Length of the SRTP cipher list */ 18945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendHandshakeNumber(ss, 2, 2); 18955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) return -1; 18965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* The selected cipher */ 18975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendHandshakeNumber(ss, ss->ssl3.dtlsSRTPCipherSuite, 2); 18985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) return -1; 18995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Empty MKI value */ 19005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl3_AppendHandshakeVariable(ss, NULL, 0, 1); 19015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 9; 19045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 19055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus 19075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_HandleUseSRTPXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data) 19085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 19095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECStatus rv; 19105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECItem ciphers = {siBuffer, NULL, 0}; 19112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PRUint16 i; 19122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int j; 19135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint16 cipher = 0; 19145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRBool found = PR_FALSE; 19155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECItem litem; 19165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ss->sec.isServer) { 19185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Client side */ 19195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!data->data || !data->len) { 19205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* malformed */ 19215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 19225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Get the cipher list */ 19255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_ConsumeHandshakeVariable(ss, &ciphers, 2, 19265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &data->data, &data->len); 19275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) { 19285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 19295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Now check that the number of ciphers listed is 1 (len = 2) */ 19315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ciphers.len != 2) { 19325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 19335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Get the selected cipher */ 19365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cipher = (ciphers.data[0] << 8) | ciphers.data[1]; 19375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Now check that this is one of the ciphers we offered */ 19395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < ss->ssl3.dtlsSRTPCipherCount; i++) { 19405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cipher == ss->ssl3.dtlsSRTPCiphers[i]) { 19415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) found = PR_TRUE; 19425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 19435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!found) { 19475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 19485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Get the srtp_mki value */ 19515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_ConsumeHandshakeVariable(ss, &litem, 1, 19525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &data->data, &data->len); 19535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) { 19545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 19555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* We didn't offer an MKI, so this must be 0 length */ 19585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* XXX RFC 5764 Section 4.1.3 says: 19595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If the client detects a nonzero-length MKI in the server's 19605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * response that is different than the one the client offered, 19615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * then the client MUST abort the handshake and SHOULD send an 19625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * invalid_parameter alert. 19635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 19645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Due to a limitation of the ssl3_HandleHelloExtensions function, 19655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * returning SECFailure here won't abort the handshake. It will 19665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * merely cause the use_srtp extension to be not negotiated. We 19675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * should fix this. See NSS bug 753136. 19685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 19695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (litem.len != 0) { 19705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 19715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (data->len != 0) { 19745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* malformed */ 19755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 19765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* OK, this looks fine. */ 19795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ssl_use_srtp_xtn; 19805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->ssl3.dtlsSRTPCipherSuite = cipher; 19815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 19825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Server side */ 19855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IS_DTLS(ss) || !ss->ssl3.dtlsSRTPCipherCount) { 19865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Ignore the extension if we aren't doing DTLS or no DTLS-SRTP 19875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * preferences have been set. */ 19885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 19895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!data->data || data->len < 5) { 19925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* malformed */ 19935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 19945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Get the cipher list */ 19975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_ConsumeHandshakeVariable(ss, &ciphers, 2, 19985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &data->data, &data->len); 19995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) { 20005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 20015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Check that the list is even length */ 20035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ciphers.len % 2) { 20045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 20055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Walk through the offered list and pick the most preferred of our 20085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ciphers, if any */ 20095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; !found && i < ss->ssl3.dtlsSRTPCipherCount; i++) { 20105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (j = 0; j + 1 < ciphers.len; j += 2) { 20115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cipher = (ciphers.data[j] << 8) | ciphers.data[j + 1]; 20125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cipher == ss->ssl3.dtlsSRTPCiphers[i]) { 20135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) found = PR_TRUE; 20145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 20155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Get the srtp_mki value */ 20205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_ConsumeHandshakeVariable(ss, &litem, 1, &data->data, &data->len); 20215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) { 20225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 20235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (data->len != 0) { 20265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; /* Malformed */ 20275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Now figure out what to do */ 20305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!found) { 20315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* No matching ciphers */ 20325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 20335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* OK, we have a valid cipher and we've selected it */ 20365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->ssl3.dtlsSRTPCipherSuite = cipher; 20375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ssl_use_srtp_xtn; 20385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ssl3_RegisterServerHelloExtensionSender(ss, ssl_use_srtp_xtn, 20405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl3_SendUseSRTPXtn); 20415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2042