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