15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * SSL3 Protocol 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * This Source Code Form is subject to the terms of the Mozilla Public 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * License, v. 2.0. If a copy of the MPL was not distributed with this 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* TLS extension code moved here from ssl3ecc.c */ 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "nssrenam.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "nss.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ssl.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sslimpl.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sslproto.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "pk11pub.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifdef NO_PKCS11_BYPASS 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "blapit.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "blapi.h" 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "prinit.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static unsigned char key_name[SESS_TICKET_KEY_NAME_LEN]; 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PK11SymKey *session_ticket_enc_key_pkcs11 = NULL; 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PK11SymKey *session_ticket_mac_key_pkcs11 = NULL; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef NO_PKCS11_BYPASS 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static unsigned char session_ticket_enc_key[AES_256_KEY_LENGTH]; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static unsigned char session_ticket_mac_key[SHA256_LENGTH]; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRBool session_ticket_keys_initialized = PR_FALSE; 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRCallOnceType generate_session_keys_once; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* forward static function declarations */ 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus ssl3_ParseEncryptedSessionTicket(sslSocket *ss, 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECItem *data, EncryptedSessionTicket *enc_session_ticket); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus ssl3_AppendToItem(SECItem *item, const unsigned char *buf, 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint32 bytes); 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus ssl3_AppendNumberToItem(SECItem *item, PRUint32 num, 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRInt32 lenSize); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus ssl3_GetSessionTicketKeysPKCS11(sslSocket *ss, 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PK11SymKey **aes_key, PK11SymKey **mac_key); 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef NO_PKCS11_BYPASS 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus ssl3_GetSessionTicketKeys(const unsigned char **aes_key, 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint32 *aes_key_length, const unsigned char **mac_key, 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint32 *mac_key_length); 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRInt32 ssl3_SendRenegotiationInfoXtn(sslSocket * ss, 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRBool append, PRUint32 maxBytes); 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus ssl3_HandleRenegotiationInfoXtn(sslSocket *ss, 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint16 ex_type, SECItem *data); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint16 ex_type, SECItem *data); 55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstatic SECStatus ssl3_ClientHandleAppProtoXtn(sslSocket *ss, 56eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch PRUint16 ex_type, SECItem *data); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus ssl3_ServerHandleNextProtoNegoXtn(sslSocket *ss, 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint16 ex_type, SECItem *data); 59eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstatic PRInt32 ssl3_ClientSendAppProtoXtn(sslSocket *ss, PRBool append, 60eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch PRUint32 maxBytes); 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRInt32 ssl3_ClientSendNextProtoNegoXtn(sslSocket *ss, PRBool append, 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint32 maxBytes); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRInt32 ssl3_SendUseSRTPXtn(sslSocket *ss, PRBool append, 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint32 maxBytes); 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus ssl3_HandleUseSRTPXtn(sslSocket * ss, PRUint16 ex_type, 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECItem *data); 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static SECStatus ssl3_ClientHandleChannelIDXtn(sslSocket *ss, 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PRUint16 ex_type, SECItem *data); 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static PRInt32 ssl3_ClientSendChannelIDXtn(sslSocket *ss, PRBool append, 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PRUint32 maxBytes); 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static SECStatus ssl3_ServerSendStatusRequestXtn(sslSocket * ss, 72a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) PRBool append, PRUint32 maxBytes); 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static SECStatus ssl3_ServerHandleStatusRequestXtn(sslSocket *ss, 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PRUint16 ex_type, SECItem *data); 75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static SECStatus ssl3_ClientHandleStatusRequestXtn(sslSocket *ss, 76a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) PRUint16 ex_type, 77a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) SECItem *data); 78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static PRInt32 ssl3_ClientSendStatusRequestXtn(sslSocket * ss, PRBool append, 79a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) PRUint32 maxBytes); 80868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)static PRInt32 ssl3_ClientSendSigAlgsXtn(sslSocket *ss, PRBool append, 81868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) PRUint32 maxBytes); 82868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)static SECStatus ssl3_ServerHandleSigAlgsXtn(sslSocket *ss, PRUint16 ex_type, 83868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SECItem *data); 84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)static PRInt32 ssl3_ClientSendSignedCertTimestampXtn(sslSocket *ss, 85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PRBool append, 86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PRUint32 maxBytes); 87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)static SECStatus ssl3_ClientHandleSignedCertTimestampXtn(sslSocket *ss, 88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PRUint16 ex_type, 89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) SECItem *data); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Write bytes. Using this function means the SECItem structure 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * cannot be freed. The caller is expected to call this function 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * on a shallow copy of the structure. 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_AppendToItem(SECItem *item, const unsigned char *buf, PRUint32 bytes) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bytes > item->len) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_Memcpy(item->data, buf, bytes); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item->data += bytes; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item->len -= bytes; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Write a number in network byte order. Using this function means the 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * SECItem structure cannot be freed. The caller is expected to call 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * this function on a shallow copy of the structure. 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_AppendNumberToItem(SECItem *item, PRUint32 num, PRInt32 lenSize) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECStatus rv; 117a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) PRUint8 b[4]; 118a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) PRUint8 * p = b; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (lenSize) { 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 4: 122a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) *p++ = (PRUint8) (num >> 24); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 3: 124a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) *p++ = (PRUint8) (num >> 16); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 2: 126a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) *p++ = (PRUint8) (num >> 8); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 1: 128a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) *p = (PRUint8) num; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendToItem(item, &b[0], lenSize); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv; 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus ssl3_SessionTicketShutdown(void* appData, void* nssData) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (session_ticket_enc_key_pkcs11) { 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PK11_FreeSymKey(session_ticket_enc_key_pkcs11); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_ticket_enc_key_pkcs11 = NULL; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (session_ticket_mac_key_pkcs11) { 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PK11_FreeSymKey(session_ticket_mac_key_pkcs11); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_ticket_mac_key_pkcs11 = NULL; 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_Memset(&generate_session_keys_once, 0, 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(generate_session_keys_once)); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRStatus 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_GenerateSessionTicketKeysPKCS11(void *data) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECStatus rv; 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sslSocket *ss = (sslSocket *)data; 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECKEYPrivateKey *svrPrivKey = ss->serverCerts[kt_rsa].SERVERKEY; 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECKEYPublicKey *svrPubKey = ss->serverCerts[kt_rsa].serverKeyPair->pubKey; 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (svrPrivKey == NULL || svrPubKey == NULL) { 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_DBG(("%d: SSL[%d]: Pub or priv key(s) is NULL.", 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_GETPID(), ss->fd)); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto loser; 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Get a copy of the session keys from shared memory. */ 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_Memcpy(key_name, SESS_TICKET_KEY_NAME_PREFIX, 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(SESS_TICKET_KEY_NAME_PREFIX)); 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ssl_GetSessionTicketKeysPKCS11(svrPrivKey, svrPubKey, 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->pkcs11PinArg, &key_name[SESS_TICKET_KEY_NAME_PREFIX_LEN], 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &session_ticket_enc_key_pkcs11, &session_ticket_mac_key_pkcs11)) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PR_FAILURE; 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = NSS_RegisterShutdown(ssl3_SessionTicketShutdown, NULL); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto loser; 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PR_SUCCESS; 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)loser: 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl3_SessionTicketShutdown(NULL, NULL); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PR_FAILURE; 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_GetSessionTicketKeysPKCS11(sslSocket *ss, PK11SymKey **aes_key, 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PK11SymKey **mac_key) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (PR_CallOnceWithArg(&generate_session_keys_once, 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl3_GenerateSessionTicketKeysPKCS11, ss) != PR_SUCCESS) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (session_ticket_enc_key_pkcs11 == NULL || 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_ticket_mac_key_pkcs11 == NULL) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *aes_key = session_ticket_enc_key_pkcs11; 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *mac_key = session_ticket_mac_key_pkcs11; 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef NO_PKCS11_BYPASS 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRStatus 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_GenerateSessionTicketKeys(void) 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_Memcpy(key_name, SESS_TICKET_KEY_NAME_PREFIX, 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(SESS_TICKET_KEY_NAME_PREFIX)); 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ssl_GetSessionTicketKeys(&key_name[SESS_TICKET_KEY_NAME_PREFIX_LEN], 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_ticket_enc_key, session_ticket_mac_key)) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PR_FAILURE; 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_ticket_keys_initialized = PR_TRUE; 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PR_SUCCESS; 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_GetSessionTicketKeys(const unsigned char **aes_key, 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint32 *aes_key_length, const unsigned char **mac_key, 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint32 *mac_key_length) 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (PR_CallOnce(&generate_session_keys_once, 221a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ssl3_GenerateSessionTicketKeys) != PR_SUCCESS) 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!session_ticket_keys_initialized) 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *aes_key = session_ticket_enc_key; 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *aes_key_length = sizeof(session_ticket_enc_key); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *mac_key = session_ticket_mac_key; 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *mac_key_length = sizeof(session_ticket_mac_key); 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Table of handlers for received TLS hello extensions, one per extension. 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * In the second generation, this table will be dynamic, and functions 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * will be registered here. 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* This table is used by the server, to handle client hello extensions. */ 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const ssl3HelloExtensionHandler clientHelloHandlers[] = { 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { ssl_server_name_xtn, &ssl3_HandleServerNameXtn }, 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef NSS_ENABLE_ECC 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { ssl_elliptic_curves_xtn, &ssl3_HandleSupportedCurvesXtn }, 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { ssl_ec_point_formats_xtn, &ssl3_HandleSupportedPointFormatsXtn }, 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { ssl_session_ticket_xtn, &ssl3_ServerHandleSessionTicketXtn }, 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { ssl_next_proto_nego_xtn, &ssl3_ServerHandleNextProtoNegoXtn }, 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { ssl_use_srtp_xtn, &ssl3_HandleUseSRTPXtn }, 251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) { ssl_cert_status_xtn, &ssl3_ServerHandleStatusRequestXtn }, 252868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) { ssl_signature_algorithms_xtn, &ssl3_ServerHandleSigAlgsXtn }, 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { -1, NULL } 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* These two tables are used by the client, to handle server hello 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * extensions. */ 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const ssl3HelloExtensionHandler serverHelloHandlersTLS[] = { 259a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) { ssl_server_name_xtn, &ssl3_HandleServerNameXtn }, 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* TODO: add a handler for ssl_ec_point_formats_xtn */ 261a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) { ssl_session_ticket_xtn, &ssl3_ClientHandleSessionTicketXtn }, 262a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, 263a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) { ssl_next_proto_nego_xtn, &ssl3_ClientHandleNextProtoNegoXtn }, 264a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) { ssl_app_layer_protocol_xtn, &ssl3_ClientHandleAppProtoXtn }, 265a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) { ssl_use_srtp_xtn, &ssl3_HandleUseSRTPXtn }, 266a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) { ssl_channel_id_xtn, &ssl3_ClientHandleChannelIDXtn }, 267a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) { ssl_cert_status_xtn, &ssl3_ClientHandleStatusRequestXtn }, 268f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) { ssl_signed_certificate_timestamp_xtn, 269f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) &ssl3_ClientHandleSignedCertTimestampXtn }, 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { -1, NULL } 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const ssl3HelloExtensionHandler serverHelloHandlersSSL3[] = { 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { -1, NULL } 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Tables of functions to format TLS hello extensions, one function per 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * extension. 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * These static tables are for the formatting of client hello extensions. 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The server's table of hello senders is dynamic, in the socket struct, 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and sender functions are registered there. 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS] = { 286eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch { ssl_server_name_xtn, &ssl3_SendServerNameXtn }, 287eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch { ssl_renegotiation_info_xtn, &ssl3_SendRenegotiationInfoXtn }, 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef NSS_ENABLE_ECC 289eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch { ssl_elliptic_curves_xtn, &ssl3_SendSupportedCurvesXtn }, 290eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch { ssl_ec_point_formats_xtn, &ssl3_SendSupportedPointFormatsXtn }, 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 292eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch { ssl_session_ticket_xtn, &ssl3_SendSessionTicketXtn }, 293eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch { ssl_next_proto_nego_xtn, &ssl3_ClientSendNextProtoNegoXtn }, 294a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) { ssl_app_layer_protocol_xtn, &ssl3_ClientSendAppProtoXtn }, 295eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch { ssl_use_srtp_xtn, &ssl3_SendUseSRTPXtn }, 296eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch { ssl_channel_id_xtn, &ssl3_ClientSendChannelIDXtn }, 297eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch { ssl_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn }, 298f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) { ssl_signature_algorithms_xtn, &ssl3_ClientSendSigAlgsXtn }, 299f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) { ssl_signed_certificate_timestamp_xtn, 300f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) &ssl3_ClientSendSignedCertTimestampXtn } 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* any extra entries will appear as { 0, NULL } */ 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3HelloExtensionSender clientHelloSendersSSL3[SSL_MAX_EXTENSIONS] = { 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { ssl_renegotiation_info_xtn, &ssl3_SendRenegotiationInfoXtn } 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* any extra entries will appear as { 0, NULL } */ 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRBool 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)arrayContainsExtension(const PRUint16 *array, PRUint32 len, PRUint16 ex_type) 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < len; i++) { 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ex_type == array[i]) 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PR_TRUE; 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PR_FALSE; 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRBool 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_ExtensionNegotiated(sslSocket *ss, PRUint16 ex_type) { 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TLSExtensionData *xtnData = &ss->xtnData; 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return arrayContainsExtension(xtnData->negotiated, 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xtnData->numNegotiated, ex_type); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRBool 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_ClientExtensionAdvertised(sslSocket *ss, PRUint16 ex_type) { 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TLSExtensionData *xtnData = &ss->xtnData; 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return arrayContainsExtension(xtnData->advertised, 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xtnData->numAdvertised, ex_type); 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Format an SNI extension, using the name from the socket's URL, 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * unless that name is a dotted decimal string. 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Used by client and server. 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRInt32 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_SendServerNameXtn(sslSocket * ss, PRBool append, 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint32 maxBytes) 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECStatus rv; 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ss) 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ss->sec.isServer) { 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint32 len; 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRNetAddr netAddr; 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* must have a hostname */ 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ss->url || !ss->url[0]) 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* must not be an IPv4 or IPv6 address */ 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (PR_SUCCESS == PR_StringToNetAddr(ss->url, &netAddr)) { 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* is an IP address (v4 or v6) */ 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) len = PORT_Strlen(ss->url); 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (append && maxBytes >= len + 9) { 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* extension_type */ 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendHandshakeNumber(ss, ssl_server_name_xtn, 2); 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) return -1; 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* length of extension_data */ 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendHandshakeNumber(ss, len + 5, 2); 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) return -1; 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* length of server_name_list */ 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendHandshakeNumber(ss, len + 3, 2); 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) return -1; 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Name Type (sni_host_name) */ 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendHandshake(ss, "\0", 1); 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) return -1; 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* HostName (length and value) */ 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendHandshakeVariable(ss, (PRUint8 *)ss->url, len, 2); 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) return -1; 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ss->sec.isServer) { 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TLSExtensionData *xtnData = &ss->xtnData; 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xtnData->advertised[xtnData->numAdvertised++] = 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl_server_name_xtn; 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return len + 9; 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Server side */ 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (append && maxBytes >= 4) { 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendHandshakeNumber(ss, ssl_server_name_xtn, 2); 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) return -1; 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* length of extension_data */ 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendHandshakeNumber(ss, 0, 2); 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) return -1; 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 4; 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* handle an incoming SNI extension, by ignoring it. */ 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_HandleServerNameXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data) 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECItem *names = NULL; 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint32 listCount = 0, namesPos = 0, i; 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TLSExtensionData *xtnData = &ss->xtnData; 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECItem ldata; 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRInt32 listLenBytes = 0; 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ss->sec.isServer) { 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Verify extension_data is empty. */ 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (data->data || data->len || 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !ssl3_ExtensionNegotiated(ss, ssl_server_name_xtn)) { 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* malformed or was not initiated by the client.*/ 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Server side - consume client data and register server sender. */ 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* do not parse the data if don't have user extension handling function. */ 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ss->sniSocketConfig) { 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* length of server_name_list */ 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listLenBytes = ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len); 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (listLenBytes == 0 || listLenBytes != data->len) { 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ldata = *data; 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Calculate the size of the array.*/ 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (listLenBytes > 0) { 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECItem litem; 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECStatus rv; 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRInt32 type; 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Name Type (sni_host_name) */ 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = ssl3_ConsumeHandshakeNumber(ss, 1, &ldata.data, &ldata.len); 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ldata.len) { 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_ConsumeHandshakeVariable(ss, &litem, 2, &ldata.data, &ldata.len); 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) { 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Adjust total length for cunsumed item, item len and type.*/ 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listLenBytes -= litem.len + 3; 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (listLenBytes > 0 && !ldata.len) { 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listCount += 1; 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!listCount) { 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) names = PORT_ZNewArray(SECItem, listCount); 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!names) { 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0;i < listCount;i++) { 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int j; 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRInt32 type; 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECStatus rv; 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRBool nametypePresent = PR_FALSE; 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Name Type (sni_host_name) */ 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = ssl3_ConsumeHandshakeNumber(ss, 1, &data->data, &data->len); 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Check if we have such type in the list */ 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (j = 0;j < listCount && names[j].data;j++) { 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (names[j].type == type) { 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nametypePresent = PR_TRUE; 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* HostName (length and value) */ 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_ConsumeHandshakeVariable(ss, &names[namesPos], 2, 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &data->data, &data->len); 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) { 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto loser; 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (nametypePresent == PR_FALSE) { 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) namesPos += 1; 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Free old and set the new data. */ 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (xtnData->sniNameArr) { 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_Free(ss->xtnData.sniNameArr); 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xtnData->sniNameArr = names; 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xtnData->sniNameArrSize = namesPos; 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xtnData->negotiated[xtnData->numNegotiated++] = ssl_server_name_xtn; 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)loser: 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_Free(names); 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Called by both clients and servers. 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Clients sends a filled in session ticket if one is available, and otherwise 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sends an empty ticket. Servers always send empty tickets. 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRInt32 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_SendSessionTicketXtn( 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sslSocket * ss, 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRBool append, 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint32 maxBytes) 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRInt32 extension_length; 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NewSessionTicket *session_ticket = NULL; 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Ignore the SessionTicket extension if processing is disabled. */ 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ss->opt.enableSessionTickets) 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Empty extension length = extension_type (2-bytes) + 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * length(extension_data) (2-bytes) 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_length = 4; 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* If we are a client then send a session ticket if one is availble. 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Servers that support the extension and are willing to negotiate the 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the extension always respond with an empty extension. 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ss->sec.isServer) { 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sslSessionID *sid = ss->sec.ci.sid; 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_ticket = &sid->u.ssl3.sessionTicket; 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (session_ticket->ticket.data) { 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ss->xtnData.ticketTimestampVerified) { 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_length += session_ticket->ticket.len; 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (!append && 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (session_ticket->ticket_lifetime_hint == 0 || 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (session_ticket->ticket_lifetime_hint + 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_ticket->received_timestamp > ssl_Time()))) { 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_length += session_ticket->ticket.len; 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->xtnData.ticketTimestampVerified = PR_TRUE; 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (append && maxBytes >= extension_length) { 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECStatus rv; 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* extension_type */ 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendHandshakeNumber(ss, ssl_session_ticket_xtn, 2); 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto loser; 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (session_ticket && session_ticket->ticket.data && 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->xtnData.ticketTimestampVerified) { 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendHandshakeVariable(ss, session_ticket->ticket.data, 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_ticket->ticket.len, 2); 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->xtnData.ticketTimestampVerified = PR_FALSE; 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendHandshakeNumber(ss, 0, 2); 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto loser; 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ss->sec.isServer) { 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TLSExtensionData *xtnData = &ss->xtnData; 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xtnData->advertised[xtnData->numAdvertised++] = 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl_session_ticket_xtn; 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (maxBytes < extension_length) { 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_Assert(0); 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return extension_length; 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loser: 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->xtnData.ticketTimestampVerified = PR_FALSE; 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* handle an incoming Next Protocol Negotiation extension. */ 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_ServerHandleNextProtoNegoXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data) 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ss->firstHsDone || data->len != 0) { 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Clients MUST send an empty NPN extension, if any. */ 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID); 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* TODO: server side NPN support would require calling 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ssl3_RegisterServerHelloExtensionSender here in order to echo the 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * extension back to the client. */ 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* ssl3_ValidateNextProtoNego checks that the given block of data is valid: none 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * of the lengths may be 0 and the sum of the lengths must equal the length of 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the block. */ 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_ValidateNextProtoNego(const unsigned char* data, unsigned int length) 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int offset = 0; 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (offset < length) { 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int newOffset = offset + 1 + (unsigned int) data[offset]; 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Reject embedded nulls to protect against buggy applications that 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * store protocol identifiers in null-terminated strings. 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (newOffset > length || data[offset] == 0) { 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID); 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offset = newOffset; 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (offset > length) { 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID); 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, PRUint16 ex_type, 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECItem *data) 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECStatus rv; 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned char resultBuffer[255]; 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECItem result = { siBuffer, resultBuffer, 0 }; 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_Assert(!ss->firstHsDone); 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 624a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (ssl3_ExtensionNegotiated(ss, ssl_app_layer_protocol_xtn)) { 625eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); 626eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return SECFailure; 627eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 628eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_ValidateNextProtoNego(data->data, data->len); 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv; 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* ss->nextProtoCallback cannot normally be NULL if we negotiated the 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * extension. However, It is possible that an application erroneously 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * cleared the callback between the time we sent the ClientHello and now. 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_Assert(ss->nextProtoCallback != NULL); 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ss->nextProtoCallback) { 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* XXX Use a better error code. This is an application error, not an 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * NSS bug. */ 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ss->nextProtoCallback(ss->nextProtoArg, ss->fd, data->data, data->len, 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result.data, &result.len, sizeof resultBuffer); 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv; 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* If the callback wrote more than allowed to |result| it has corrupted our 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * stack. */ 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result.len > sizeof resultBuffer) { 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_SetError(SEC_ERROR_OUTPUT_LEN); 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE); 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECITEM_CopyItem(NULL, &ss->ssl3.nextProto, &result); 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 662eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstatic SECStatus 663eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochssl3_ClientHandleAppProtoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data) 664eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch{ 665eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const unsigned char* d = data->data; 666eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch PRUint16 name_list_len; 667eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SECItem protocol_name; 668eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 669eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (ssl3_ExtensionNegotiated(ss, ssl_next_proto_nego_xtn)) { 670eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); 671eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return SECFailure; 672eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 673eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 674eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch /* The extension data from the server has the following format: 675eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * uint16 name_list_len; 676eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * uint8 len; 677eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * uint8 protocol_name[len]; */ 678eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (data->len < 4 || data->len > 2 + 1 + 255) { 679eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID); 680eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return SECFailure; 681eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 682eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 683eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch name_list_len = ((PRUint16) d[0]) << 8 | 684eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ((PRUint16) d[1]); 685eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (name_list_len != data->len - 2 || 686eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch d[2] != data->len - 3) { 687eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID); 688eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return SECFailure; 689eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 690eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 691eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch protocol_name.data = data->data + 3; 692eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch protocol_name.len = data->len - 3; 693eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 694eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE); 695eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ss->ssl3.nextProtoState = SSL_NEXT_PROTO_SELECTED; 696eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; 697eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return SECITEM_CopyItem(NULL, &ss->ssl3.nextProto, &protocol_name); 698eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 699eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRInt32 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_ClientSendNextProtoNegoXtn(sslSocket * ss, PRBool append, 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint32 maxBytes) 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRInt32 extension_length; 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Renegotiations do not send this extension. */ 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ss->nextProtoCallback || ss->firstHsDone) { 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_length = 4; 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (append && maxBytes >= extension_length) { 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECStatus rv; 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendHandshakeNumber(ss, ssl_next_proto_nego_xtn, 2); 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto loser; 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendHandshakeNumber(ss, 0, 2); 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto loser; 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->xtnData.advertised[ss->xtnData.numAdvertised++] = 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl_next_proto_nego_xtn; 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (maxBytes < extension_length) { 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return extension_length; 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)loser: 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 733eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstatic PRInt32 734eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochssl3_ClientSendAppProtoXtn(sslSocket * ss, PRBool append, PRUint32 maxBytes) 735eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch{ 736eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch PRInt32 extension_length; 737ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch unsigned char *alpn_protos = NULL; 738eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 739eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch /* Renegotiations do not send this extension. */ 740eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!ss->opt.nextProtoNego.data || ss->firstHsDone) { 741eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 742eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 743eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 744eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch extension_length = 2 /* extension type */ + 2 /* extension length */ + 745eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2 /* protocol name list length */ + 746eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ss->opt.nextProtoNego.len; 747eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 748eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (append && maxBytes >= extension_length) { 749ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch /* NPN requires that the client's fallback protocol is first in the 750ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch * list. However, ALPN sends protocols in preference order. So we 751ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch * allocate a buffer and move the first protocol to the end of the 752ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch * list. */ 753eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SECStatus rv; 754ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const unsigned int len = ss->opt.nextProtoNego.len; 755ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 756ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch alpn_protos = PORT_Alloc(len); 757ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (alpn_protos == NULL) { 758ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return SECFailure; 759ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 760ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (len > 0) { 761ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch /* Each protocol string is prefixed with a single byte length. */ 762ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch unsigned int i = ss->opt.nextProtoNego.data[0] + 1; 763ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (i <= len) { 764ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch memcpy(alpn_protos, &ss->opt.nextProtoNego.data[i], len - i); 765ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch memcpy(alpn_protos + len - i, ss->opt.nextProtoNego.data, i); 766ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } else { 767ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch /* This seems to be invalid data so we'll send as-is. */ 768ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch memcpy(alpn_protos, ss->opt.nextProtoNego.data, len); 769ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 770ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 771ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 772a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) rv = ssl3_AppendHandshakeNumber(ss, ssl_app_layer_protocol_xtn, 2); 773eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (rv != SECSuccess) 774eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch goto loser; 775eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2); 776eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (rv != SECSuccess) 777eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch goto loser; 778ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch rv = ssl3_AppendHandshakeVariable(ss, alpn_protos, len, 2); 779ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch PORT_Free(alpn_protos); 780ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch alpn_protos = NULL; 781eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (rv != SECSuccess) 782eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch goto loser; 783eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ss->xtnData.advertised[ss->xtnData.numAdvertised++] = 784a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ssl_app_layer_protocol_xtn; 785eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } else if (maxBytes < extension_length) { 786eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 787eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 788eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 789eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return extension_length; 790eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 791eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochloser: 792ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (alpn_protos) 793ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch PORT_Free(alpn_protos); 794eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return -1; 795eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 796eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_ClientHandleChannelIDXtn(sslSocket *ss, PRUint16 ex_type, 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECItem *data) 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_Assert(ss->getChannelID != NULL); 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (data->len) { 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_SetError(SSL_ERROR_BAD_CHANNEL_ID_DATA); 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRInt32 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_ClientSendChannelIDXtn(sslSocket * ss, PRBool append, 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint32 maxBytes) 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRInt32 extension_length = 4; 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ss->getChannelID) 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (maxBytes < extension_length) { 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_Assert(0); 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (ss->sec.ci.sid->cached != never_cached && 826f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ss->sec.ci.sid->u.ssl3.originalHandshakeHash.len == 0) { 827f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) /* We can't do ChannelID on a connection if we're resuming and didn't 828f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * do ChannelID on the original connection: without ChannelID on the 829f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * original connection we didn't record the handshake hashes needed for 830f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * the signature. */ 831f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return 0; 832f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 833f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (append) { 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECStatus rv; 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendHandshakeNumber(ss, ssl_channel_id_xtn, 2); 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto loser; 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendHandshakeNumber(ss, 0, 2); 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto loser; 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->xtnData.advertised[ss->xtnData.numAdvertised++] = 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl_channel_id_xtn; 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return extension_length; 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)loser: 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 852c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static SECStatus 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_ClientHandleStatusRequestXtn(sslSocket *ss, PRUint16 ex_type, 854c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SECItem *data) 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* The echoed extension must be empty. */ 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (data->len != 0) 858c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return SECFailure; 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Keep track of negotiated extensions. */ 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 866c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static PRInt32 867c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ssl3_ServerSendStatusRequestXtn( 868c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) sslSocket * ss, 869c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PRBool append, 870c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PRUint32 maxBytes) 871c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){ 872c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PRInt32 extension_length; 873c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SECStatus rv; 874a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) int i; 875a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) PRBool haveStatus = PR_FALSE; 876c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 877a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) for (i = kt_null; i < kt_kea_size; i++) { 878a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) /* TODO: This is a temporary workaround. 879a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) * The correct code needs to see if we have an OCSP response for 880a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) * the server certificate being used, rather than if we have any 881a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) * OCSP response. See also ssl3_SendCertificateStatus. 882a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) */ 883a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (ss->certStatusArray[i] && ss->certStatusArray[i]->len) { 884a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) haveStatus = PR_TRUE; 885a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) break; 886a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 887a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 888a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (!haveStatus) 889c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return 0; 890c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 891c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) extension_length = 2 + 2; 892c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (append && maxBytes >= extension_length) { 893c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /* extension_type */ 894c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) rv = ssl3_AppendHandshakeNumber(ss, ssl_cert_status_xtn, 2); 895c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (rv != SECSuccess) 896c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return -1; 897c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /* length of extension_data */ 898c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) rv = ssl3_AppendHandshakeNumber(ss, 0, 2); 899c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (rv != SECSuccess) 900c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return -1; 901c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 902c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 903c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return extension_length; 904c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 905c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* ssl3_ClientSendStatusRequestXtn builds the status_request extension on the 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * client side. See RFC 4366 section 3.6. */ 908c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static PRInt32 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_ClientSendStatusRequestXtn(sslSocket * ss, PRBool append, 910c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PRUint32 maxBytes) 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRInt32 extension_length; 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ss->opt.enableOCSPStapling) 915c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return 0; 9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* extension_type (2-bytes) + 9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * length(extension_data) (2-bytes) + 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * status_type (1) + 9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * responder_id_list length (2) + 9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * request_extensions length (2) 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_length = 9; 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (append && maxBytes >= extension_length) { 926c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SECStatus rv; 927c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TLSExtensionData *xtnData; 928c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 929c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /* extension_type */ 930c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) rv = ssl3_AppendHandshakeNumber(ss, ssl_cert_status_xtn, 2); 931c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (rv != SECSuccess) 932c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return -1; 933c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2); 934c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (rv != SECSuccess) 935c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return -1; 936c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) rv = ssl3_AppendHandshakeNumber(ss, 1 /* status_type ocsp */, 1); 937c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (rv != SECSuccess) 938c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return -1; 939c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /* A zero length responder_id_list means that the responders are 940c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * implicitly known to the server. */ 941c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) rv = ssl3_AppendHandshakeNumber(ss, 0, 2); 942c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (rv != SECSuccess) 943c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return -1; 944c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /* A zero length request_extensions means that there are no extensions. 945c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * Specifically, we don't set the id-pkix-ocsp-nonce extension. This 946c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * means that the server can replay a cached OCSP response to us. */ 947c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) rv = ssl3_AppendHandshakeNumber(ss, 0, 2); 948c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (rv != SECSuccess) 949c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return -1; 950c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 951c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) xtnData = &ss->xtnData; 952c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) xtnData->advertised[xtnData->numAdvertised++] = ssl_cert_status_xtn; 9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (maxBytes < extension_length) { 954c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PORT_Assert(0); 955c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return 0; 9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return extension_length; 9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * NewSessionTicket 9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Called from ssl3_HandleFinished 9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus 9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_SendNewSessionTicket(sslSocket *ss) 9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECStatus rv; 9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NewSessionTicket ticket; 9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECItem plaintext; 9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECItem plaintext_item = {0, NULL, 0}; 9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECItem ciphertext = {0, NULL, 0}; 9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint32 ciphertext_length; 9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRBool ms_is_wrapped; 9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned char wrapped_ms[SSL3_MASTER_SECRET_LENGTH]; 9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECItem ms_item = {0, NULL, 0}; 9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL3KEAType effectiveExchKeyType = ssl_kea_null; 9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint32 padding_length; 9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint32 message_length; 9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint32 cert_length; 981a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) PRUint8 length_buf[4]; 9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint32 now; 9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PK11SymKey *aes_key_pkcs11; 9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PK11SymKey *mac_key_pkcs11; 9852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef NO_PKCS11_BYPASS 9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const unsigned char *aes_key; 9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const unsigned char *mac_key; 9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint32 aes_key_length; 9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint32 mac_key_length; 9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint64 aes_ctx_buf[MAX_CIPHER_CONTEXT_LLONGS]; 9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AESContext *aes_ctx; 9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SECHashObject *hashObj = NULL; 9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint64 hmac_ctx_buf[MAX_MAC_CONTEXT_LLONGS]; 9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HMACContext *hmac_ctx; 9952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 9962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CK_MECHANISM_TYPE cipherMech = CKM_AES_CBC; 9972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PK11Context *aes_ctx_pkcs11; 9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CK_MECHANISM_TYPE macMech = CKM_SHA256_HMAC; 9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PK11Context *hmac_ctx_pkcs11; 10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned char computed_mac[TLS_EX_SESS_TICKET_MAC_LENGTH]; 10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int computed_mac_length; 10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned char iv[AES_BLOCK_SIZE]; 10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECItem ivItem; 10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECItem *srvName = NULL; 10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint32 srvNameLen = 0; 10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CK_MECHANISM_TYPE msWrapMech = 0; /* dummy default value, 10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * must be >= 0 */ 10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_TRC(3, ("%d: SSL3[%d]: send session_ticket handshake", 10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_GETPID(), ss->fd)); 10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); 10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); 10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ticket.ticket_lifetime_hint = TLS_EX_SESS_TICKET_LIFETIME_HINT; 10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cert_length = (ss->opt.requestCertificate && ss->sec.ci.sid->peerCert) ? 10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3 + ss->sec.ci.sid->peerCert->derCert.len : 0; 10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Get IV and encryption keys */ 10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ivItem.data = iv; 10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ivItem.len = sizeof(iv); 10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = PK11_GenerateRandom(iv, sizeof(iv)); 10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef NO_PKCS11_BYPASS 10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ss->opt.bypassPKCS11) { 10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_GetSessionTicketKeys(&aes_key, &aes_key_length, 10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &mac_key, &mac_key_length); 10292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else 10302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 10312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_GetSessionTicketKeysPKCS11(ss, &aes_key_pkcs11, 10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &mac_key_pkcs11); 10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ss->ssl3.pwSpec->msItem.len && ss->ssl3.pwSpec->msItem.data) { 10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* The master secret is available unwrapped. */ 10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ms_item.data = ss->ssl3.pwSpec->msItem.data; 10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ms_item.len = ss->ssl3.pwSpec->msItem.len; 10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ms_is_wrapped = PR_FALSE; 10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Extract the master secret wrapped. */ 10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sslSessionID sid; 10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_Memset(&sid, 0, sizeof(sslSessionID)); 10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa) { 10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) effectiveExchKeyType = kt_rsa; 10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) effectiveExchKeyType = ss->ssl3.hs.kea_def->exchKeyType; 10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_CacheWrappedMasterSecret(ss, &sid, ss->ssl3.pwSpec, 10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) effectiveExchKeyType); 10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv == SECSuccess) { 10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sid.u.ssl3.keys.wrapped_master_secret_len > sizeof(wrapped_ms)) 10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto loser; 10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(wrapped_ms, sid.u.ssl3.keys.wrapped_master_secret, 10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sid.u.ssl3.keys.wrapped_master_secret_len); 10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ms_item.data = wrapped_ms; 10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ms_item.len = sid.u.ssl3.keys.wrapped_master_secret_len; 10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) msWrapMech = sid.u.ssl3.masterWrapMech; 10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* TODO: else send an empty ticket. */ 10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto loser; 10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ms_is_wrapped = PR_TRUE; 10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Prep to send negotiated name */ 10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) srvName = &ss->ssl3.pwSpec->srvVirtName; 10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (srvName->data && srvName->len) { 10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) srvNameLen = 2 + srvName->len; /* len bytes + name len */ 10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ciphertext_length = 10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(PRUint16) /* ticket_version */ 10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + sizeof(SSL3ProtocolVersion) /* ssl_version */ 10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + sizeof(ssl3CipherSuite) /* ciphersuite */ 10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + 1 /* compression */ 10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + 10 /* cipher spec parameters */ 10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + 1 /* SessionTicket.ms_is_wrapped */ 10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + 1 /* effectiveExchKeyType */ 10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + 4 /* msWrapMech */ 10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + 2 /* master_secret.length */ 10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + ms_item.len /* master_secret */ 10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + 1 /* client_auth_type */ 10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + cert_length /* cert */ 10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + 1 /* server name type */ 10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + srvNameLen /* name len + length field */ 10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + sizeof(ticket.ticket_lifetime_hint); 10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) padding_length = AES_BLOCK_SIZE - 10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (ciphertext_length % AES_BLOCK_SIZE); 10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ciphertext_length += padding_length; 10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_length = 10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(ticket.ticket_lifetime_hint) /* ticket_lifetime_hint */ 10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + 2 /* length field for NewSessionTicket.ticket */ 10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + SESS_TICKET_KEY_NAME_LEN /* key_name */ 10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + AES_BLOCK_SIZE /* iv */ 11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + 2 /* length field for NewSessionTicket.ticket.encrypted_state */ 11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + ciphertext_length /* encrypted_state */ 11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + TLS_EX_SESS_TICKET_MAC_LENGTH; /* mac */ 11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (SECITEM_AllocItem(NULL, &plaintext_item, ciphertext_length) == NULL) 11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto loser; 11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) plaintext = plaintext_item; 11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* ticket_version */ 11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendNumberToItem(&plaintext, TLS_EX_SESS_TICKET_VERSION, 11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(PRUint16)); 11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* ssl_version */ 11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendNumberToItem(&plaintext, ss->version, 11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(SSL3ProtocolVersion)); 11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* ciphersuite */ 11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendNumberToItem(&plaintext, ss->ssl3.hs.cipher_suite, 11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(ssl3CipherSuite)); 11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* compression */ 11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendNumberToItem(&plaintext, ss->ssl3.hs.compression, 1); 11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* cipher spec parameters */ 11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendNumberToItem(&plaintext, ss->sec.authAlgorithm, 1); 11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendNumberToItem(&plaintext, ss->sec.authKeyBits, 4); 11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendNumberToItem(&plaintext, ss->sec.keaType, 1); 11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendNumberToItem(&plaintext, ss->sec.keaKeyBits, 4); 11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* master_secret */ 11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendNumberToItem(&plaintext, ms_is_wrapped, 1); 11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendNumberToItem(&plaintext, effectiveExchKeyType, 1); 11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendNumberToItem(&plaintext, msWrapMech, 4); 11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendNumberToItem(&plaintext, ms_item.len, 2); 11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendToItem(&plaintext, ms_item.data, ms_item.len); 11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* client_identity */ 11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ss->opt.requestCertificate && ss->sec.ci.sid->peerCert) { 11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendNumberToItem(&plaintext, CLIENT_AUTH_CERTIFICATE, 1); 11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendNumberToItem(&plaintext, 11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->sec.ci.sid->peerCert->derCert.len, 3); 11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendToItem(&plaintext, 11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->sec.ci.sid->peerCert->derCert.data, 11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->sec.ci.sid->peerCert->derCert.len); 11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendNumberToItem(&plaintext, 0, 1); 11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* timestamp */ 11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) now = ssl_Time(); 11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendNumberToItem(&plaintext, now, 11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(ticket.ticket_lifetime_hint)); 11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (srvNameLen) { 11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Name Type (sni_host_name) */ 11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendNumberToItem(&plaintext, srvName->type, 1); 11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* HostName (length and value) */ 11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendNumberToItem(&plaintext, srvName->len, 2); 11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendToItem(&plaintext, srvName->data, srvName->len); 11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* No Name */ 11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendNumberToItem(&plaintext, (char)TLS_STE_NO_SERVER_NAME, 11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1); 11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_Assert(plaintext.len == padding_length); 11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < padding_length; i++) 11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) plaintext.data[i] = (unsigned char)padding_length; 11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (SECITEM_AllocItem(NULL, &ciphertext, ciphertext_length) == NULL) { 11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = SECFailure; 11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto loser; 11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Generate encrypted portion of ticket. */ 11982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef NO_PKCS11_BYPASS 11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ss->opt.bypassPKCS11) { 12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) aes_ctx = (AESContext *)aes_ctx_buf; 12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = AES_InitContext(aes_ctx, aes_key, aes_key_length, iv, 12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSS_AES_CBC, 1, AES_BLOCK_SIZE); 12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = AES_Encrypt(aes_ctx, ciphertext.data, &ciphertext.len, 12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ciphertext.len, plaintext_item.data, 12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) plaintext_item.len); 12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 12092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else 12102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 12112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) aes_ctx_pkcs11 = PK11_CreateContextBySymKey(cipherMech, 12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CKA_ENCRYPT, aes_key_pkcs11, &ivItem); 12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!aes_ctx_pkcs11) 12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto loser; 12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = PK11_CipherOp(aes_ctx_pkcs11, ciphertext.data, 12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (int *)&ciphertext.len, ciphertext.len, 12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) plaintext_item.data, plaintext_item.len); 12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PK11_Finalize(aes_ctx_pkcs11); 12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PK11_DestroyContext(aes_ctx_pkcs11, PR_TRUE); 12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Convert ciphertext length to network order. */ 12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) length_buf[0] = (ciphertext.len >> 8) & 0xff; 12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) length_buf[1] = (ciphertext.len ) & 0xff; 12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Compute MAC. */ 12302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef NO_PKCS11_BYPASS 12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ss->opt.bypassPKCS11) { 12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hmac_ctx = (HMACContext *)hmac_ctx_buf; 12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hashObj = HASH_GetRawHashObject(HASH_AlgSHA256); 12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HMAC_Init(hmac_ctx, hashObj, mac_key, 12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mac_key_length, PR_FALSE) != SECSuccess) 12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto loser; 12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HMAC_Begin(hmac_ctx); 12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HMAC_Update(hmac_ctx, key_name, SESS_TICKET_KEY_NAME_LEN); 12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HMAC_Update(hmac_ctx, iv, sizeof(iv)); 12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HMAC_Update(hmac_ctx, (unsigned char *)length_buf, 2); 12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HMAC_Update(hmac_ctx, ciphertext.data, ciphertext.len); 12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HMAC_Finish(hmac_ctx, computed_mac, &computed_mac_length, 12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(computed_mac)); 12452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else 12462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 12472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECItem macParam; 12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) macParam.data = NULL; 12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) macParam.len = 0; 12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hmac_ctx_pkcs11 = PK11_CreateContextBySymKey(macMech, 12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CKA_SIGN, mac_key_pkcs11, &macParam); 12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!hmac_ctx_pkcs11) 12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto loser; 12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = PK11_DigestBegin(hmac_ctx_pkcs11); 12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = PK11_DigestOp(hmac_ctx_pkcs11, key_name, 12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SESS_TICKET_KEY_NAME_LEN); 12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = PK11_DigestOp(hmac_ctx_pkcs11, iv, sizeof(iv)); 12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = PK11_DigestOp(hmac_ctx_pkcs11, (unsigned char *)length_buf, 2); 12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = PK11_DigestOp(hmac_ctx_pkcs11, ciphertext.data, ciphertext.len); 12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = PK11_DigestFinal(hmac_ctx_pkcs11, computed_mac, 12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &computed_mac_length, sizeof(computed_mac)); 12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PK11_DestroyContext(hmac_ctx_pkcs11, PR_TRUE); 12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Serialize the handshake message. */ 12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendHandshakeHeader(ss, new_session_ticket, message_length); 12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendHandshakeNumber(ss, ticket.ticket_lifetime_hint, 12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(ticket.ticket_lifetime_hint)); 12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendHandshakeNumber(ss, 12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_length - sizeof(ticket.ticket_lifetime_hint) - 2, 2); 12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendHandshake(ss, key_name, SESS_TICKET_KEY_NAME_LEN); 12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendHandshake(ss, iv, sizeof(iv)); 12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendHandshakeVariable(ss, ciphertext.data, ciphertext.len, 2); 12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendHandshake(ss, computed_mac, computed_mac_length); 12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto loser; 12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)loser: 12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (plaintext_item.data) 12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECITEM_FreeItem(&plaintext_item, PR_FALSE); 12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ciphertext.data) 12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECITEM_FreeItem(&ciphertext, PR_FALSE); 12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv; 12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* When a client receives a SessionTicket extension a NewSessionTicket 13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * message is expected during the handshake. 13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus 13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_ClientHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type, 13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECItem *data) 13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (data->len != 0) 13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Keep track of negotiated extensions. */ 13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; 13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus 13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_ServerHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type, 13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECItem *data) 13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECStatus rv; 13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECItem *decrypted_state = NULL; 13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SessionTicket *parsed_session_ticket = NULL; 13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sslSessionID *sid = NULL; 13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL3Statistics *ssl3stats; 13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Ignore the SessionTicket extension if processing is disabled. */ 13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ss->opt.enableSessionTickets) 13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Keep track of negotiated extensions. */ 13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; 13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Parse the received ticket sent in by the client. We are 13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * lenient about some parse errors, falling back to a fullshake 13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * instead of terminating the current connection. 13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (data->len == 0) { 13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->xtnData.emptySessionTicket = PR_TRUE; 13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECItem extension_data; 13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EncryptedSessionTicket enc_session_ticket; 13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned char computed_mac[TLS_EX_SESS_TICKET_MAC_LENGTH]; 13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int computed_mac_length; 13452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef NO_PKCS11_BYPASS 13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SECHashObject *hashObj; 13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const unsigned char *aes_key; 13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const unsigned char *mac_key; 13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint32 aes_key_length; 13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint32 mac_key_length; 13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint64 hmac_ctx_buf[MAX_MAC_CONTEXT_LLONGS]; 13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HMACContext *hmac_ctx; 13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint64 aes_ctx_buf[MAX_CIPHER_CONTEXT_LLONGS]; 13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AESContext *aes_ctx; 13552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 13562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PK11SymKey *aes_key_pkcs11; 13572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PK11SymKey *mac_key_pkcs11; 13582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PK11Context *hmac_ctx_pkcs11; 13592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CK_MECHANISM_TYPE macMech = CKM_SHA256_HMAC; 13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PK11Context *aes_ctx_pkcs11; 13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CK_MECHANISM_TYPE cipherMech = CKM_AES_CBC; 13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned char * padding; 13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint32 padding_length; 13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned char *buffer; 13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int buffer_len; 13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRInt32 temp; 13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECItem cert_item; 13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRInt8 nameType = TLS_STE_NO_SERVER_NAME; 13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Turn off stateless session resumption if the client sends a 13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * SessionTicket extension, even if the extension turns out to be 13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * malformed (ss->sec.ci.sid is non-NULL when doing session 13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * renegotiation.) 13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ss->sec.ci.sid != NULL) { 13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ss->sec.uncache) 13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->sec.uncache(ss->sec.ci.sid); 13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl_FreeSID(ss->sec.ci.sid); 13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->sec.ci.sid = NULL; 13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_data.data = data->data; /* Keep a copy for future use. */ 13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_data.len = data->len; 13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ssl3_ParseEncryptedSessionTicket(ss, data, &enc_session_ticket) 13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) != SECSuccess) 13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Get session ticket keys. */ 13902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef NO_PKCS11_BYPASS 13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ss->opt.bypassPKCS11) { 13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_GetSessionTicketKeys(&aes_key, &aes_key_length, 13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &mac_key, &mac_key_length); 13942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else 13952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 1396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) { 13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_GetSessionTicketKeysPKCS11(ss, &aes_key_pkcs11, 13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &mac_key_pkcs11); 13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) { 14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_DBG(("%d: SSL[%d]: Unable to get/generate session ticket keys.", 14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_GETPID(), ss->fd)); 14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto loser; 14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* If the ticket sent by the client was generated under a key different 14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * from the one we have, bypass ticket processing. 14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (PORT_Memcmp(enc_session_ticket.key_name, key_name, 14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SESS_TICKET_KEY_NAME_LEN) != 0) { 14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_DBG(("%d: SSL[%d]: Session ticket key_name sent mismatch.", 14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_GETPID(), ss->fd)); 14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto no_ticket; 14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Verify the MAC on the ticket. MAC verification may also 14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * fail if the MAC key has been recently refreshed. 14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 14192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef NO_PKCS11_BYPASS 14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ss->opt.bypassPKCS11) { 14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hmac_ctx = (HMACContext *)hmac_ctx_buf; 14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hashObj = HASH_GetRawHashObject(HASH_AlgSHA256); 14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HMAC_Init(hmac_ctx, hashObj, mac_key, 14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(session_ticket_mac_key), PR_FALSE) != SECSuccess) 14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto no_ticket; 14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HMAC_Begin(hmac_ctx); 14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HMAC_Update(hmac_ctx, extension_data.data, 14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_data.len - TLS_EX_SESS_TICKET_MAC_LENGTH); 14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HMAC_Finish(hmac_ctx, computed_mac, &computed_mac_length, 14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(computed_mac)) != SECSuccess) 14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto no_ticket; 14322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else 14332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 1434c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) { 14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECItem macParam; 14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) macParam.data = NULL; 14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) macParam.len = 0; 14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hmac_ctx_pkcs11 = PK11_CreateContextBySymKey(macMech, 14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CKA_SIGN, mac_key_pkcs11, &macParam); 14405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!hmac_ctx_pkcs11) { 14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_DBG(("%d: SSL[%d]: Unable to create HMAC context: %d.", 14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_GETPID(), ss->fd, PORT_GetError())); 14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto no_ticket; 14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 14455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_DBG(("%d: SSL[%d]: Successfully created HMAC context.", 14465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_GETPID(), ss->fd)); 14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = PK11_DigestBegin(hmac_ctx_pkcs11); 14495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = PK11_DigestOp(hmac_ctx_pkcs11, extension_data.data, 14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_data.len - TLS_EX_SESS_TICKET_MAC_LENGTH); 14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) { 14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PK11_DestroyContext(hmac_ctx_pkcs11, PR_TRUE); 14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto no_ticket; 14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = PK11_DigestFinal(hmac_ctx_pkcs11, computed_mac, 14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &computed_mac_length, sizeof(computed_mac)); 14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PK11_DestroyContext(hmac_ctx_pkcs11, PR_TRUE); 14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) 14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto no_ticket; 14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (NSS_SecureMemcmp(computed_mac, enc_session_ticket.mac, 14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) computed_mac_length) != 0) { 14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_DBG(("%d: SSL[%d]: Session ticket MAC mismatch.", 14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_GETPID(), ss->fd)); 14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto no_ticket; 14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* We ignore key_name for now. 14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This is ok as MAC verification succeeded. 14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Decrypt the ticket. */ 14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Plaintext is shorter than the ciphertext due to padding. */ 14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decrypted_state = SECITEM_AllocItem(NULL, NULL, 14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enc_session_ticket.encrypted_state.len); 14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef NO_PKCS11_BYPASS 14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ss->opt.bypassPKCS11) { 14805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) aes_ctx = (AESContext *)aes_ctx_buf; 14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = AES_InitContext(aes_ctx, aes_key, 14825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(session_ticket_enc_key), enc_session_ticket.iv, 14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSS_AES_CBC, 0,AES_BLOCK_SIZE); 14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) { 14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_DBG(("%d: SSL[%d]: Unable to create AES context.", 14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_GETPID(), ss->fd)); 14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto no_ticket; 14885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = AES_Decrypt(aes_ctx, decrypted_state->data, 14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &decrypted_state->len, decrypted_state->len, 14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enc_session_ticket.encrypted_state.data, 14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enc_session_ticket.encrypted_state.len); 14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) 14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto no_ticket; 14962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else 14972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 1498c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) { 14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECItem ivItem; 15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ivItem.data = enc_session_ticket.iv; 15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ivItem.len = AES_BLOCK_SIZE; 15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) aes_ctx_pkcs11 = PK11_CreateContextBySymKey(cipherMech, 15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CKA_DECRYPT, aes_key_pkcs11, &ivItem); 15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!aes_ctx_pkcs11) { 15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_DBG(("%d: SSL[%d]: Unable to create AES context.", 15065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_GETPID(), ss->fd)); 15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto no_ticket; 15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = PK11_CipherOp(aes_ctx_pkcs11, decrypted_state->data, 15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (int *)&decrypted_state->len, decrypted_state->len, 15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enc_session_ticket.encrypted_state.data, 15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enc_session_ticket.encrypted_state.len); 15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PK11_Finalize(aes_ctx_pkcs11); 15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PK11_DestroyContext(aes_ctx_pkcs11, PR_TRUE); 15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) 15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto no_ticket; 15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Check padding. */ 15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) padding_length = 15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (PRUint32)decrypted_state->data[decrypted_state->len - 1]; 15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (padding_length == 0 || padding_length > AES_BLOCK_SIZE) 15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto no_ticket; 15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) padding = &decrypted_state->data[decrypted_state->len - padding_length]; 15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < padding_length; i++, padding++) { 15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (padding_length != (PRUint32)*padding) 15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto no_ticket; 15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Deserialize session state. */ 15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer = decrypted_state->data; 15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_len = decrypted_state->len; 15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parsed_session_ticket = PORT_ZAlloc(sizeof(SessionTicket)); 15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parsed_session_ticket == NULL) { 15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = SECFailure; 15395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto loser; 15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Read ticket_version (which is ignored for now.) */ 15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) temp = ssl3_ConsumeHandshakeNumber(ss, 2, &buffer, &buffer_len); 15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (temp < 0) goto no_ticket; 15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parsed_session_ticket->ticket_version = (SSL3ProtocolVersion)temp; 15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Read SSLVersion. */ 15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) temp = ssl3_ConsumeHandshakeNumber(ss, 2, &buffer, &buffer_len); 15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (temp < 0) goto no_ticket; 15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parsed_session_ticket->ssl_version = (SSL3ProtocolVersion)temp; 15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Read cipher_suite. */ 15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) temp = ssl3_ConsumeHandshakeNumber(ss, 2, &buffer, &buffer_len); 15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (temp < 0) goto no_ticket; 15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parsed_session_ticket->cipher_suite = (ssl3CipherSuite)temp; 15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Read compression_method. */ 15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len); 15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (temp < 0) goto no_ticket; 15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parsed_session_ticket->compression_method = (SSLCompressionMethod)temp; 15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Read cipher spec parameters. */ 15635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len); 15645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (temp < 0) goto no_ticket; 15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parsed_session_ticket->authAlgorithm = (SSLSignType)temp; 15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) temp = ssl3_ConsumeHandshakeNumber(ss, 4, &buffer, &buffer_len); 15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (temp < 0) goto no_ticket; 15685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parsed_session_ticket->authKeyBits = (PRUint32)temp; 15695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len); 15705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (temp < 0) goto no_ticket; 15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parsed_session_ticket->keaType = (SSLKEAType)temp; 15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) temp = ssl3_ConsumeHandshakeNumber(ss, 4, &buffer, &buffer_len); 15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (temp < 0) goto no_ticket; 15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parsed_session_ticket->keaKeyBits = (PRUint32)temp; 15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Read wrapped master_secret. */ 15775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len); 15785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (temp < 0) goto no_ticket; 15795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parsed_session_ticket->ms_is_wrapped = (PRBool)temp; 15805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len); 15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (temp < 0) goto no_ticket; 15835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parsed_session_ticket->exchKeyType = (SSL3KEAType)temp; 15845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) temp = ssl3_ConsumeHandshakeNumber(ss, 4, &buffer, &buffer_len); 15865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (temp < 0) goto no_ticket; 15875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parsed_session_ticket->msWrapMech = (CK_MECHANISM_TYPE)temp; 15885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) temp = ssl3_ConsumeHandshakeNumber(ss, 2, &buffer, &buffer_len); 15905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (temp < 0) goto no_ticket; 15915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parsed_session_ticket->ms_length = (PRUint16)temp; 15925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parsed_session_ticket->ms_length == 0 || /* sanity check MS. */ 15935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parsed_session_ticket->ms_length > 15945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(parsed_session_ticket->master_secret)) 15955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto no_ticket; 15965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Allow for the wrapped master secret to be longer. */ 15985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (buffer_len < sizeof(SSL3_MASTER_SECRET_LENGTH)) 15995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto no_ticket; 16005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_Memcpy(parsed_session_ticket->master_secret, buffer, 16015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parsed_session_ticket->ms_length); 16025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer += parsed_session_ticket->ms_length; 16035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_len -= parsed_session_ticket->ms_length; 16045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Read client_identity */ 16065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len); 16075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (temp < 0) 16085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto no_ticket; 16095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parsed_session_ticket->client_identity.client_auth_type = 16105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (ClientAuthenticationType)temp; 16115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch(parsed_session_ticket->client_identity.client_auth_type) { 16125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case CLIENT_AUTH_ANONYMOUS: 16135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 16145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case CLIENT_AUTH_CERTIFICATE: 16155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_ConsumeHandshakeVariable(ss, &cert_item, 3, 16165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &buffer, &buffer_len); 16175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto no_ticket; 16185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = SECITEM_CopyItem(NULL, &parsed_session_ticket->peer_cert, 16195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &cert_item); 16205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto no_ticket; 16215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 16225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 16235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto no_ticket; 16245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Read timestamp. */ 16265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) temp = ssl3_ConsumeHandshakeNumber(ss, 4, &buffer, &buffer_len); 16275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (temp < 0) 16285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto no_ticket; 16295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parsed_session_ticket->timestamp = (PRUint32)temp; 16305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Read server name */ 16325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nameType = 16335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len); 16345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (nameType != TLS_STE_NO_SERVER_NAME) { 16355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECItem name_item; 16365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_ConsumeHandshakeVariable(ss, &name_item, 2, &buffer, 16375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &buffer_len); 16385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto no_ticket; 16395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = SECITEM_CopyItem(NULL, &parsed_session_ticket->srvName, 16405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &name_item); 16415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) goto no_ticket; 16425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parsed_session_ticket->srvName.type = nameType; 16435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Done parsing. Check that all bytes have been consumed. */ 16465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (buffer_len != padding_length) 16475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto no_ticket; 16485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Use the ticket if it has not expired, otherwise free the allocated 16505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * memory since the ticket is of no use. 16515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 16525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parsed_session_ticket->timestamp != 0 && 16535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parsed_session_ticket->timestamp + 16545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TLS_EX_SESS_TICKET_LIFETIME_HINT > ssl_Time()) { 16555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sid = ssl3_NewSessionID(ss, PR_TRUE); 16575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sid == NULL) { 16585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = SECFailure; 16595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto loser; 16605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Copy over parameters. */ 16635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sid->version = parsed_session_ticket->ssl_version; 16645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sid->u.ssl3.cipherSuite = parsed_session_ticket->cipher_suite; 16655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sid->u.ssl3.compression = parsed_session_ticket->compression_method; 16665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sid->authAlgorithm = parsed_session_ticket->authAlgorithm; 16675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sid->authKeyBits = parsed_session_ticket->authKeyBits; 16685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sid->keaType = parsed_session_ticket->keaType; 16695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sid->keaKeyBits = parsed_session_ticket->keaKeyBits; 16705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Copy master secret. */ 16722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef NO_PKCS11_BYPASS 16735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ss->opt.bypassPKCS11 && 16745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parsed_session_ticket->ms_is_wrapped) 16755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto no_ticket; 16762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 16775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parsed_session_ticket->ms_length > 16785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(sid->u.ssl3.keys.wrapped_master_secret)) 16795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto no_ticket; 16805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_Memcpy(sid->u.ssl3.keys.wrapped_master_secret, 16815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parsed_session_ticket->master_secret, 16825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parsed_session_ticket->ms_length); 16835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sid->u.ssl3.keys.wrapped_master_secret_len = 16845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parsed_session_ticket->ms_length; 16855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sid->u.ssl3.exchKeyType = parsed_session_ticket->exchKeyType; 16865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sid->u.ssl3.masterWrapMech = parsed_session_ticket->msWrapMech; 16875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sid->u.ssl3.keys.msIsWrapped = 16885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parsed_session_ticket->ms_is_wrapped; 16895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sid->u.ssl3.masterValid = PR_TRUE; 16905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sid->u.ssl3.keys.resumable = PR_TRUE; 16915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Copy over client cert from session ticket if there is one. */ 16935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parsed_session_ticket->peer_cert.data != NULL) { 16945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sid->peerCert != NULL) 16955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CERT_DestroyCertificate(sid->peerCert); 16965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sid->peerCert = CERT_NewTempCertificate(ss->dbHandle, 16975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &parsed_session_ticket->peer_cert, NULL, PR_FALSE, PR_TRUE); 16985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sid->peerCert == NULL) { 16995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = SECFailure; 17005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto loser; 17015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parsed_session_ticket->srvName.data != NULL) { 17045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sid->u.ssl3.srvName = parsed_session_ticket->srvName; 17055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->statelessResume = PR_TRUE; 17075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->sec.ci.sid = sid; 17085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (0) { 17125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)no_ticket: 17135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_DBG(("%d: SSL[%d]: Session ticket parsing failed.", 17145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_GETPID(), ss->fd)); 17155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl3stats = SSL_GetStatistics(); 17165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_AtomicIncrementLong(& ssl3stats->hch_sid_ticket_parse_failures ); 17175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = SECSuccess; 17195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)loser: 17215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* ss->sec.ci.sid == sid if it did NOT come here via goto statement 17225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * in that case do not free sid 17235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 17245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sid && (ss->sec.ci.sid != sid)) { 17255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl_FreeSID(sid); 17265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sid = NULL; 17275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (decrypted_state != NULL) { 17295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECITEM_FreeItem(decrypted_state, PR_TRUE); 17305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decrypted_state = NULL; 17315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parsed_session_ticket != NULL) { 17345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parsed_session_ticket->peer_cert.data) { 17355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECITEM_FreeItem(&parsed_session_ticket->peer_cert, PR_FALSE); 17365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_ZFree(parsed_session_ticket, sizeof(SessionTicket)); 17385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv; 17415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 17425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 17445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Read bytes. Using this function means the SECItem structure 17455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * cannot be freed. The caller is expected to call this function 17465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * on a shallow copy of the structure. 17475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 17485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus 17495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_ConsumeFromItem(SECItem *item, unsigned char **buf, PRUint32 bytes) 17505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 17515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bytes > item->len) 17525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 17535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *buf = item->data; 17555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item->data += bytes; 17565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item->len -= bytes; 17575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 17585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 17595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus 17615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_ParseEncryptedSessionTicket(sslSocket *ss, SECItem *data, 17625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EncryptedSessionTicket *enc_session_ticket) 17635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 17645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ssl3_ConsumeFromItem(data, &enc_session_ticket->key_name, 17655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SESS_TICKET_KEY_NAME_LEN) != SECSuccess) 17665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 17675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ssl3_ConsumeFromItem(data, &enc_session_ticket->iv, 17685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AES_BLOCK_SIZE) != SECSuccess) 17695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 17705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ssl3_ConsumeHandshakeVariable(ss, &enc_session_ticket->encrypted_state, 17715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2, &data->data, &data->len) != SECSuccess) 17725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 17735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ssl3_ConsumeFromItem(data, &enc_session_ticket->mac, 17745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TLS_EX_SESS_TICKET_MAC_LENGTH) != SECSuccess) 17755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 17765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (data->len != 0) /* Make sure that we have consumed all bytes. */ 17775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 17785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 17805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 17815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* go through hello extensions in buffer "b". 17835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * For each one, find the extension handler in the table, and 17845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * if present, invoke that handler. 17855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Servers ignore any extensions with unknown extension types. 17865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Clients reject any extensions with unadvertised extension types. 17875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 17885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus 17895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_HandleHelloExtensions(sslSocket *ss, SSL3Opaque **b, PRUint32 *length) 17905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 17915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ssl3HelloExtensionHandler * handlers; 17925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ss->sec.isServer) { 17945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) handlers = clientHelloHandlers; 17955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (ss->version > SSL_LIBRARY_VERSION_3_0) { 17965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) handlers = serverHelloHandlersTLS; 17975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 17985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) handlers = serverHelloHandlersSSL3; 17995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (*length) { 18025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ssl3HelloExtensionHandler * handler; 18035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECStatus rv; 18045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRInt32 extension_type; 18055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECItem extension_data; 18065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Get the extension's type field */ 18085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_type = ssl3_ConsumeHandshakeNumber(ss, 2, b, length); 18095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (extension_type < 0) /* failure to decode extension_type */ 18105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; /* alert already sent */ 18115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* get the data for this extension, so we can pass it or skip it. */ 18135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_ConsumeHandshakeVariable(ss, &extension_data, 2, b, length); 18145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) 18155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv; 18165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Check whether the server sent an extension which was not advertised 18185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * in the ClientHello. 18195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 18205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ss->sec.isServer && 18215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !ssl3_ClientExtensionAdvertised(ss, extension_type)) 18225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; /* TODO: send unsupported_extension alert */ 18235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Check whether an extension has been sent multiple times. */ 18255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ssl3_ExtensionNegotiated(ss, extension_type)) 18265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 18275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* find extension_type in table of Hello Extension Handlers */ 18295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (handler = handlers; handler->ex_type >= 0; handler++) { 18305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* if found, call this handler */ 18315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (handler->ex_type == extension_type) { 18325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = (*handler->ex_handler)(ss, (PRUint16)extension_type, 18335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &extension_data); 18345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Ignore this result */ 18355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Treat all bad extensions as unrecognized types. */ 18365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 18375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 18415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 18425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Add a callback function to the table of senders of server hello extensions. 18445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 18455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus 18465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_RegisterServerHelloExtensionSender(sslSocket *ss, PRUint16 ex_type, 18475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl3HelloExtensionSenderFunc cb) 18485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 18495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 18505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl3HelloExtensionSender *sender = &ss->xtnData.serverSenders[0]; 18515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < SSL_MAX_EXTENSIONS; ++i, ++sender) { 18535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!sender->ex_sender) { 18545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sender->ex_type = ex_type; 18555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sender->ex_sender = cb; 18565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 18575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* detect duplicate senders */ 18595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_Assert(sender->ex_type != ex_type); 18605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sender->ex_type == ex_type) { 18615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* duplicate */ 18625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 18635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_Assert(i < SSL_MAX_EXTENSIONS); /* table needs to grow */ 18665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); 18675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 18685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 18695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* call each of the extension senders and return the accumulated length */ 18715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRInt32 18725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_CallHelloExtensionSenders(sslSocket *ss, PRBool append, PRUint32 maxBytes, 18735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ssl3HelloExtensionSender *sender) 18745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 18755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRInt32 total_exten_len = 0; 18765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 18775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!sender) { 18795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sender = ss->version > SSL_LIBRARY_VERSION_3_0 ? 18805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &clientHelloSendersTLS[0] : &clientHelloSendersSSL3[0]; 18815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < SSL_MAX_EXTENSIONS; ++i, ++sender) { 18845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sender->ex_sender) { 18855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRInt32 extLen = (*sender->ex_sender)(ss, append, maxBytes); 18865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (extLen < 0) 18875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; 18885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) maxBytes -= extLen; 18895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) total_exten_len += extLen; 18905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return total_exten_len; 18935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 18945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Extension format: 18975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Extension number: 2 bytes 18985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Extension length: 2 bytes 18995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Verify Data Length: 1 byte 19005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Verify Data (TLS): 12 bytes (client) or 24 bytes (server) 19015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Verify Data (SSL): 36 bytes (client) or 72 bytes (server) 19025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 19035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRInt32 19045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_SendRenegotiationInfoXtn( 19055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sslSocket * ss, 19065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRBool append, 19075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint32 maxBytes) 19085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 19095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRInt32 len, needed; 19105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* In draft-ietf-tls-renegotiation-03, it is NOT RECOMMENDED to send 19125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * both the SCSV and the empty RI, so when we send SCSV in 19135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the initial handshake, we don't also send RI. 19145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 19155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ss || ss->ssl3.hs.sendingSCSV) 19165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 19175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) len = !ss->firstHsDone ? 0 : 19185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (ss->sec.isServer ? ss->ssl3.hs.finishedBytes * 2 19195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : ss->ssl3.hs.finishedBytes); 19205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) needed = 5 + len; 19215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (append && maxBytes >= needed) { 19225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECStatus rv; 19235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* extension_type */ 19245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendHandshakeNumber(ss, ssl_renegotiation_info_xtn, 2); 19255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) return -1; 19265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* length of extension_data */ 19275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendHandshakeNumber(ss, len + 1, 2); 19285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) return -1; 19295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* verify_Data from previous Finished message(s) */ 19305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendHandshakeVariable(ss, 19315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->ssl3.hs.finishedMsgs.data, len, 1); 19325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) return -1; 19335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ss->sec.isServer) { 19345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TLSExtensionData *xtnData = &ss->xtnData; 19355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xtnData->advertised[xtnData->numAdvertised++] = 19365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl_renegotiation_info_xtn; 19375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return needed; 19405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 19415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1942c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static SECStatus 1943c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ssl3_ServerHandleStatusRequestXtn(sslSocket *ss, PRUint16 ex_type, 1944c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SECItem *data) 1945c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){ 1946c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SECStatus rv = SECSuccess; 1947c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1948c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /* remember that we got this extension. */ 1949c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; 1950c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PORT_Assert(ss->sec.isServer); 1951c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /* prepare to send back the appropriate response */ 1952c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) rv = ssl3_RegisterServerHelloExtensionSender(ss, ex_type, 1953c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ssl3_ServerSendStatusRequestXtn); 1954c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return rv; 1955c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 1956c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 19575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* This function runs in both the client and server. */ 19585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus 19595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_HandleRenegotiationInfoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data) 19605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 19615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECStatus rv = SECSuccess; 19625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint32 len = 0; 19635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ss->firstHsDone) { 19655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) len = ss->sec.isServer ? ss->ssl3.hs.finishedBytes 19665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : ss->ssl3.hs.finishedBytes * 2; 19675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (data->len != 1 + len || 19695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data->data[0] != len || (len && 19705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSS_SecureMemcmp(ss->ssl3.hs.finishedMsgs.data, 19715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data->data + 1, len))) { 19725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Can we do this here? Or, must we arrange for the caller to do it? */ 19735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (void)SSL3_SendAlert(ss, alert_fatal, handshake_failure); 19745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_SetError(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE); 19755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 19765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* remember that we got this extension and it was correct. */ 19785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->peerRequestedProtection = 1; 19795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; 19805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ss->sec.isServer) { 19815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* prepare to send back the appropriate response */ 19825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_RegisterServerHelloExtensionSender(ss, ex_type, 19835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl3_SendRenegotiationInfoXtn); 19845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv; 19865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 19875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRInt32 19895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_SendUseSRTPXtn(sslSocket *ss, PRBool append, PRUint32 maxBytes) 19905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 19915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint32 ext_data_len; 19925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRInt16 i; 19935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECStatus rv; 19945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ss) 19965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 19975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ss->sec.isServer) { 19995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Client side */ 20005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IS_DTLS(ss) || !ss->ssl3.dtlsSRTPCipherCount) 20025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; /* Not relevant */ 20035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ext_data_len = 2 + 2 * ss->ssl3.dtlsSRTPCipherCount + 1; 20055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (append && maxBytes >= 4 + ext_data_len) { 20075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Extension type */ 20085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendHandshakeNumber(ss, ssl_use_srtp_xtn, 2); 20095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) return -1; 20105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Length of extension data */ 20115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendHandshakeNumber(ss, ext_data_len, 2); 20125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) return -1; 20135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Length of the SRTP cipher list */ 20145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendHandshakeNumber(ss, 20155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2 * ss->ssl3.dtlsSRTPCipherCount, 20165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2); 20175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) return -1; 20185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* The SRTP ciphers */ 20195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < ss->ssl3.dtlsSRTPCipherCount; i++) { 20205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendHandshakeNumber(ss, 20215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->ssl3.dtlsSRTPCiphers[i], 20225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2); 20235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Empty MKI value */ 20255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl3_AppendHandshakeVariable(ss, NULL, 0, 1); 20265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->xtnData.advertised[ss->xtnData.numAdvertised++] = 20285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl_use_srtp_xtn; 20295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 4 + ext_data_len; 20325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Server side */ 20355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (append && maxBytes >= 9) { 20365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Extension type */ 20375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendHandshakeNumber(ss, ssl_use_srtp_xtn, 2); 20385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) return -1; 20395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Length of extension data */ 20405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendHandshakeNumber(ss, 5, 2); 20415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) return -1; 20425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Length of the SRTP cipher list */ 20435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendHandshakeNumber(ss, 2, 2); 20445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) return -1; 20455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* The selected cipher */ 20465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_AppendHandshakeNumber(ss, ss->ssl3.dtlsSRTPCipherSuite, 2); 20475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) return -1; 20485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Empty MKI value */ 20495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl3_AppendHandshakeVariable(ss, NULL, 0, 1); 20505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 9; 20535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 20545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus 20565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_HandleUseSRTPXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data) 20575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 20585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECStatus rv; 20595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECItem ciphers = {siBuffer, NULL, 0}; 20602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PRUint16 i; 20612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int j; 20625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRUint16 cipher = 0; 20635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PRBool found = PR_FALSE; 20645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECItem litem; 20655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ss->sec.isServer) { 20675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Client side */ 20685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!data->data || !data->len) { 20695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* malformed */ 20705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 20715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Get the cipher list */ 20745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_ConsumeHandshakeVariable(ss, &ciphers, 2, 20755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &data->data, &data->len); 20765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) { 20775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 20785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Now check that the number of ciphers listed is 1 (len = 2) */ 20805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ciphers.len != 2) { 20815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 20825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Get the selected cipher */ 20855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cipher = (ciphers.data[0] << 8) | ciphers.data[1]; 20865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Now check that this is one of the ciphers we offered */ 20885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < ss->ssl3.dtlsSRTPCipherCount; i++) { 20895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cipher == ss->ssl3.dtlsSRTPCiphers[i]) { 20905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) found = PR_TRUE; 20915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 20925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!found) { 20965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 20975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Get the srtp_mki value */ 21005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_ConsumeHandshakeVariable(ss, &litem, 1, 21015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &data->data, &data->len); 21025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) { 21035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 21045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* We didn't offer an MKI, so this must be 0 length */ 21075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* XXX RFC 5764 Section 4.1.3 says: 21085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If the client detects a nonzero-length MKI in the server's 21095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * response that is different than the one the client offered, 21105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * then the client MUST abort the handshake and SHOULD send an 21115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * invalid_parameter alert. 21125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 21135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Due to a limitation of the ssl3_HandleHelloExtensions function, 21145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * returning SECFailure here won't abort the handshake. It will 21155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * merely cause the use_srtp extension to be not negotiated. We 21165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * should fix this. See NSS bug 753136. 21175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 21185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (litem.len != 0) { 21195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 21205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (data->len != 0) { 21235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* malformed */ 21245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 21255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* OK, this looks fine. */ 21285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ssl_use_srtp_xtn; 21295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->ssl3.dtlsSRTPCipherSuite = cipher; 21305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 21315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Server side */ 21345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IS_DTLS(ss) || !ss->ssl3.dtlsSRTPCipherCount) { 21355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Ignore the extension if we aren't doing DTLS or no DTLS-SRTP 21365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * preferences have been set. */ 21375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 21385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!data->data || data->len < 5) { 21415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* malformed */ 21425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 21435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Get the cipher list */ 21465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_ConsumeHandshakeVariable(ss, &ciphers, 2, 21475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &data->data, &data->len); 21485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) { 21495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 21505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Check that the list is even length */ 21525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ciphers.len % 2) { 21535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 21545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Walk through the offered list and pick the most preferred of our 21575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ciphers, if any */ 21585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; !found && i < ss->ssl3.dtlsSRTPCipherCount; i++) { 21595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (j = 0; j + 1 < ciphers.len; j += 2) { 21605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cipher = (ciphers.data[j] << 8) | ciphers.data[j + 1]; 21615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cipher == ss->ssl3.dtlsSRTPCiphers[i]) { 21625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) found = PR_TRUE; 21635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 21645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Get the srtp_mki value */ 21695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ssl3_ConsumeHandshakeVariable(ss, &litem, 1, &data->data, &data->len); 21705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) { 21715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; 21725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (data->len != 0) { 21755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECFailure; /* Malformed */ 21765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Now figure out what to do */ 21795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!found) { 21805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* No matching ciphers */ 21815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SECSuccess; 21825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* OK, we have a valid cipher and we've selected it */ 21855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->ssl3.dtlsSRTPCipherSuite = cipher; 21865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ssl_use_srtp_xtn; 21875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ssl3_RegisterServerHelloExtensionSender(ss, ssl_use_srtp_xtn, 21895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl3_SendUseSRTPXtn); 21905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2191868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 2192868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)/* ssl3_ServerHandleSigAlgsXtn handles the signature_algorithms extension 2193868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * from a client. 2194868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * See https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */ 2195868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)static SECStatus 2196868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)ssl3_ServerHandleSigAlgsXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data) 2197868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles){ 2198868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SECStatus rv; 2199868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SECItem algorithms; 2200868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const unsigned char *b; 2201868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) unsigned int numAlgorithms, i; 2202868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 2203868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) /* Ignore this extension if we aren't doing TLS 1.2 or greater. */ 2204868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (ss->version < SSL_LIBRARY_VERSION_TLS_1_2) { 2205868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return SECSuccess; 2206868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 2207868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 2208868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) /* Keep track of negotiated extensions. */ 2209868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; 2210868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 2211868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) rv = ssl3_ConsumeHandshakeVariable(ss, &algorithms, 2, &data->data, 2212868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) &data->len); 2213868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (rv != SECSuccess) { 2214868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return SECFailure; 2215868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 2216868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) /* Trailing data, empty value, or odd-length value is invalid. */ 2217868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (data->len != 0 || algorithms.len == 0 || (algorithms.len & 1) != 0) { 2218868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) PORT_SetError(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO); 2219868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return SECFailure; 2220868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 2221868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 2222868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) numAlgorithms = algorithms.len/2; 2223868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 2224868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) /* We don't care to process excessive numbers of algorithms. */ 2225868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (numAlgorithms > 512) { 2226868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) numAlgorithms = 512; 2227868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 2228868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 2229868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ss->ssl3.hs.clientSigAndHash = 2230868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) PORT_NewArray(SSL3SignatureAndHashAlgorithm, numAlgorithms); 2231868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!ss->ssl3.hs.clientSigAndHash) { 2232868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return SECFailure; 2233868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 2234868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ss->ssl3.hs.numClientSigAndHash = 0; 2235868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 2236868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) b = algorithms.data; 2237868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) for (i = 0; i < numAlgorithms; i++) { 2238868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) unsigned char tls_hash = *(b++); 2239868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) unsigned char tls_sig = *(b++); 2240868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SECOidTag hash = ssl3_TLSHashAlgorithmToOID(tls_hash); 2241868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 2242868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (hash == SEC_OID_UNKNOWN) { 2243868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) /* We ignore formats that we don't understand. */ 2244868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) continue; 2245868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 2246868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) /* tls_sig support will be checked later in 2247868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * ssl3_PickSignatureHashAlgorithm. */ 2248868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ss->ssl3.hs.clientSigAndHash[i].hashAlg = hash; 2249868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ss->ssl3.hs.clientSigAndHash[i].sigAlg = tls_sig; 2250868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ss->ssl3.hs.numClientSigAndHash++; 2251868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 2252868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 2253868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!ss->ssl3.hs.numClientSigAndHash) { 2254868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) /* We didn't understand any of the client's requested signature 2255868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * formats. We'll use the defaults. */ 2256868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) PORT_Free(ss->ssl3.hs.clientSigAndHash); 2257868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ss->ssl3.hs.clientSigAndHash = NULL; 2258868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 2259868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 2260868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return SECSuccess; 2261868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 2262868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 2263868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)/* ssl3_ClientSendSigAlgsXtn sends the signature_algorithm extension for TLS 2264868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * 1.2 ClientHellos. */ 2265868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)static PRInt32 2266868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)ssl3_ClientSendSigAlgsXtn(sslSocket * ss, PRBool append, PRUint32 maxBytes) 2267868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles){ 2268a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) static const unsigned char signatureAlgorithms[] = { 2269a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) /* This block is the contents of our signature_algorithms extension, in 2270a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) * wire format. See 2271a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) * https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */ 2272a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) tls_hash_sha256, tls_sig_rsa, 2273a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) tls_hash_sha384, tls_sig_rsa, 2274a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) tls_hash_sha1, tls_sig_rsa, 2275a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#ifdef NSS_ENABLE_ECC 2276a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) tls_hash_sha256, tls_sig_ecdsa, 2277a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) tls_hash_sha384, tls_sig_ecdsa, 2278a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) tls_hash_sha1, tls_sig_ecdsa, 2279a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#endif 2280a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) tls_hash_sha256, tls_sig_dsa, 2281a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) tls_hash_sha1, tls_sig_dsa, 2282a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) }; 2283868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) PRInt32 extension_length; 2284868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 2285868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (ss->version < SSL_LIBRARY_VERSION_TLS_1_2) { 2286868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return 0; 2287868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 2288868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 2289868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) extension_length = 2290868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 2 /* extension type */ + 2291868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 2 /* extension length */ + 2292868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 2 /* supported_signature_algorithms length */ + 2293a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) sizeof(signatureAlgorithms); 2294868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 2295868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (append && maxBytes >= extension_length) { 2296868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SECStatus rv; 2297868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) rv = ssl3_AppendHandshakeNumber(ss, ssl_signature_algorithms_xtn, 2); 2298868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (rv != SECSuccess) 2299868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) goto loser; 2300868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2); 2301868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (rv != SECSuccess) 2302868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) goto loser; 2303a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) rv = ssl3_AppendHandshakeVariable(ss, signatureAlgorithms, 2304a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) sizeof(signatureAlgorithms), 2); 2305868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (rv != SECSuccess) 2306868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) goto loser; 2307868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ss->xtnData.advertised[ss->xtnData.numAdvertised++] = 2308868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ssl_signature_algorithms_xtn; 2309868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else if (maxBytes < extension_length) { 2310868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) PORT_Assert(0); 2311868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return 0; 2312868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 2313868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 2314868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return extension_length; 2315868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 2316868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)loser: 2317868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 2318868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 2319f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 2320f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)unsigned int 2321f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ssl3_CalculatePaddingExtensionLength(unsigned int clientHelloLength) 2322f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles){ 2323f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int recordLength = 1 /* handshake message type */ + 2324f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 3 /* handshake message length */ + 2325f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) clientHelloLength; 2326f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int extensionLength; 2327f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 2328f5859ba46034e02ada5ef522d9d9c09fbbddccd8Ben Murdoch if (recordLength < 256 || recordLength >= 512) { 2329f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return 0; 2330f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 2331f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 2332f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) extensionLength = 512 - recordLength; 2333f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) /* Extensions take at least four bytes to encode. */ 2334f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (extensionLength < 4) { 2335f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) extensionLength = 4; 2336f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 2337f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 2338f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return extensionLength; 2339f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 2340f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 2341f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)/* ssl3_AppendPaddingExtension possibly adds an extension which ensures that a 2342f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * ClientHello record is either < 256 bytes or is >= 512 bytes. This ensures 2343f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * that we don't trigger bugs in F5 products. */ 2344f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)PRInt32 2345f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ssl3_AppendPaddingExtension(sslSocket *ss, unsigned int extensionLen, 2346f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PRUint32 maxBytes) 2347f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles){ 2348f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int paddingLen = extensionLen - 4; 2349f5859ba46034e02ada5ef522d9d9c09fbbddccd8Ben Murdoch unsigned char padding[256]; 2350f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 2351f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (extensionLen == 0) { 2352f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return 0; 2353f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 2354f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 2355f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (extensionLen < 4 || 2356f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) extensionLen > maxBytes || 2357f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) paddingLen > sizeof(padding)) { 2358f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PORT_Assert(0); 2359f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return -1; 2360f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 2361f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 2362f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (SECSuccess != ssl3_AppendHandshakeNumber(ss, ssl_padding_xtn, 2)) 2363f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return -1; 2364f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (SECSuccess != ssl3_AppendHandshakeNumber(ss, paddingLen, 2)) 2365f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return -1; 2366a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) memset(padding, 0, paddingLen); 2367f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (SECSuccess != ssl3_AppendHandshake(ss, padding, paddingLen)) 2368f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return -1; 2369f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 2370f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return extensionLen; 2371f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 2372f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 2373f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)/* ssl3_ClientSendSignedCertTimestampXtn sends the signed_certificate_timestamp 2374f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * extension for TLS ClientHellos. */ 2375f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)static PRInt32 2376f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ssl3_ClientSendSignedCertTimestampXtn(sslSocket *ss, PRBool append, 2377f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PRUint32 maxBytes) 2378f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles){ 2379f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PRInt32 extension_length = 2 /* extension_type */ + 2380f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 2 /* length(extension_data) */; 2381f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 2382f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) /* Only send the extension if processing is enabled. */ 2383f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!ss->opt.enableSignedCertTimestamps) 2384f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return 0; 2385f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 2386f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (append && maxBytes >= extension_length) { 2387f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) SECStatus rv; 2388f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) /* extension_type */ 2389f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) rv = ssl3_AppendHandshakeNumber(ss, 2390f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ssl_signed_certificate_timestamp_xtn, 2391f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 2); 2392f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (rv != SECSuccess) 2393f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) goto loser; 2394f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) /* zero length */ 2395f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) rv = ssl3_AppendHandshakeNumber(ss, 0, 2); 2396f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (rv != SECSuccess) 2397f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) goto loser; 2398f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ss->xtnData.advertised[ss->xtnData.numAdvertised++] = 2399f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ssl_signed_certificate_timestamp_xtn; 2400f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else if (maxBytes < extension_length) { 2401f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PORT_Assert(0); 2402f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return 0; 2403f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 2404f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 2405f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return extension_length; 2406f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)loser: 2407f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return -1; 2408f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 2409f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 2410f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)static SECStatus 2411f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ssl3_ClientHandleSignedCertTimestampXtn(sslSocket *ss, PRUint16 ex_type, 2412f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) SECItem *data) 2413f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles){ 2414f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) /* We do not yet know whether we'll be resuming a session or creating 2415f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * a new one, so we keep a pointer to the data in the TLSExtensionData 2416f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * structure. This pointer is only valid in the scope of 2417f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * ssl3_HandleServerHello, and, if not resuming a session, the data is 2418f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * copied once a new session structure has been set up. 2419f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * All parsing is currently left to the application and we accept 2420f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * everything, including empty data. 2421f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) */ 2422f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) SECItem *scts = &ss->xtnData.signedCertTimestamps; 2423f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PORT_Assert(!scts->data && !scts->len); 2424f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 2425f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!data->len) { 2426f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) /* Empty extension data: RFC 6962 mandates non-empty contents. */ 2427f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return SECFailure; 2428f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 2429f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) *scts = *data; 2430f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) /* Keep track of negotiated extensions. */ 2431f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; 2432f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return SECSuccess; 2433f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 2434