| OLD | NEW |
| 1 /* | 1 /* |
| 2 * SSL3 Protocol | 2 * SSL3 Protocol |
| 3 * | 3 * |
| 4 * ***** BEGIN LICENSE BLOCK ***** | 4 * ***** BEGIN LICENSE BLOCK ***** |
| 5 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 | 5 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 |
| 6 * | 6 * |
| 7 * The contents of this file are subject to the Mozilla Public License Version | 7 * The contents of this file are subject to the Mozilla Public License Version |
| 8 * 1.1 (the "License"); you may not use this file except in compliance with | 8 * 1.1 (the "License"); you may not use this file except in compliance with |
| 9 * the License. You may obtain a copy of the License at | 9 * the License. You may obtain a copy of the License at |
| 10 * http://www.mozilla.org/MPL/ | 10 * http://www.mozilla.org/MPL/ |
| (...skipping 23 matching lines...) Expand all Loading... |
| 34 * under the terms of either the GPL or the LGPL, and not to allow others to | 34 * under the terms of either the GPL or the LGPL, and not to allow others to |
| 35 * use your version of this file under the terms of the MPL, indicate your | 35 * use your version of this file under the terms of the MPL, indicate your |
| 36 * decision by deleting the provisions above and replace them with the notice | 36 * decision by deleting the provisions above and replace them with the notice |
| 37 * and other provisions required by the GPL or the LGPL. If you do not delete | 37 * and other provisions required by the GPL or the LGPL. If you do not delete |
| 38 * the provisions above, a recipient may use your version of this file under | 38 * the provisions above, a recipient may use your version of this file under |
| 39 * the terms of any one of the MPL, the GPL or the LGPL. | 39 * the terms of any one of the MPL, the GPL or the LGPL. |
| 40 * | 40 * |
| 41 * ***** END LICENSE BLOCK ***** */ | 41 * ***** END LICENSE BLOCK ***** */ |
| 42 | 42 |
| 43 /* TLS extension code moved here from ssl3ecc.c */ | 43 /* TLS extension code moved here from ssl3ecc.c */ |
| 44 /* $Id: ssl3ext.c,v 1.14 2010/04/03 19:19:07 nelson%bolyard.com Exp $ */ | 44 /* $Id: ssl3ext.c,v 1.21 2012/02/15 21:52:08 kaie%kuix.de Exp $ */ |
| 45 | 45 |
| 46 #include "nssrenam.h" | 46 #include "nssrenam.h" |
| 47 #include "nss.h" | 47 #include "nss.h" |
| 48 #include "ssl.h" | 48 #include "ssl.h" |
| 49 #include "sslimpl.h" | 49 #include "sslimpl.h" |
| 50 #include "sslproto.h" | 50 #include "sslproto.h" |
| 51 #include "pk11pub.h" | 51 #include "pk11pub.h" |
| 52 #include "blapi.h" | 52 #include "blapi.h" |
| 53 #include "prinit.h" | 53 #include "prinit.h" |
| 54 | 54 |
| 55 static unsigned char key_name[SESS_TICKET_KEY_NAME_LEN]; | 55 static unsigned char key_name[SESS_TICKET_KEY_NAME_LEN]; |
| 56 static PK11SymKey *session_ticket_enc_key_pkcs11 = NULL; | 56 static PK11SymKey *session_ticket_enc_key_pkcs11 = NULL; |
| 57 static PK11SymKey *session_ticket_mac_key_pkcs11 = NULL; | 57 static PK11SymKey *session_ticket_mac_key_pkcs11 = NULL; |
| 58 | 58 |
| 59 static unsigned char session_ticket_enc_key[32]; | 59 static unsigned char session_ticket_enc_key[AES_256_KEY_LENGTH]; |
| 60 static unsigned char session_ticket_mac_key[SHA256_LENGTH]; | 60 static unsigned char session_ticket_mac_key[SHA256_LENGTH]; |
| 61 | 61 |
| 62 static PRBool session_ticket_keys_initialized = PR_FALSE; | 62 static PRBool session_ticket_keys_initialized = PR_FALSE; |
| 63 static PRCallOnceType generate_session_keys_once; | 63 static PRCallOnceType generate_session_keys_once; |
| 64 | 64 |
| 65 /* forward static function declarations */ | 65 /* forward static function declarations */ |
| 66 static SECStatus ssl3_ParseEncryptedSessionTicket(sslSocket *ss, | 66 static SECStatus ssl3_ParseEncryptedSessionTicket(sslSocket *ss, |
| 67 SECItem *data, EncryptedSessionTicket *enc_session_ticket); | 67 SECItem *data, EncryptedSessionTicket *enc_session_ticket); |
| 68 static SECStatus ssl3_AppendToItem(SECItem *item, const unsigned char *buf, | 68 static SECStatus ssl3_AppendToItem(SECItem *item, const unsigned char *buf, |
| 69 PRUint32 bytes); | 69 PRUint32 bytes); |
| 70 static SECStatus ssl3_AppendNumberToItem(SECItem *item, PRUint32 num, | 70 static SECStatus ssl3_AppendNumberToItem(SECItem *item, PRUint32 num, |
| 71 PRInt32 lenSize); | 71 PRInt32 lenSize); |
| 72 static SECStatus ssl3_GetSessionTicketKeysPKCS11(sslSocket *ss, | 72 static SECStatus ssl3_GetSessionTicketKeysPKCS11(sslSocket *ss, |
| 73 PK11SymKey **aes_key, PK11SymKey **mac_key); | 73 PK11SymKey **aes_key, PK11SymKey **mac_key); |
| 74 static SECStatus ssl3_GetSessionTicketKeys(const unsigned char **aes_key, | 74 static SECStatus ssl3_GetSessionTicketKeys(const unsigned char **aes_key, |
| 75 PRUint32 *aes_key_length, const unsigned char **mac_key, | 75 PRUint32 *aes_key_length, const unsigned char **mac_key, |
| 76 PRUint32 *mac_key_length); | 76 PRUint32 *mac_key_length); |
| 77 static PRInt32 ssl3_SendRenegotiationInfoXtn(sslSocket * ss, | 77 static PRInt32 ssl3_SendRenegotiationInfoXtn(sslSocket * ss, |
| 78 PRBool append, PRUint32 maxBytes); | 78 PRBool append, PRUint32 maxBytes); |
| 79 static SECStatus ssl3_HandleRenegotiationInfoXtn(sslSocket *ss, | 79 static SECStatus ssl3_HandleRenegotiationInfoXtn(sslSocket *ss, |
| 80 PRUint16 ex_type, SECItem *data); | 80 PRUint16 ex_type, SECItem *data); |
| 81 static SECStatus ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, |
| 82 PRUint16 ex_type, SECItem *data); |
| 83 static SECStatus ssl3_ServerHandleNextProtoNegoXtn(sslSocket *ss, |
| 84 PRUint16 ex_type, SECItem *data); |
| 85 static PRInt32 ssl3_ClientSendNextProtoNegoXtn(sslSocket *ss, PRBool append, |
| 86 PRUint32 maxBytes); |
| 81 static SECStatus ssl3_ServerHandleEncryptedClientCertsXtn(sslSocket *ss, | 87 static SECStatus ssl3_ServerHandleEncryptedClientCertsXtn(sslSocket *ss, |
| 82 PRUint16 ex_type, SECItem *data); | 88 PRUint16 ex_type, SECItem *data); |
| 83 static SECStatus ssl3_ClientHandleEncryptedClientCertsXtn(sslSocket *ss, | 89 static SECStatus ssl3_ClientHandleEncryptedClientCertsXtn(sslSocket *ss, |
| 84 PRUint16 ex_type, SECItem *data); | 90 PRUint16 ex_type, SECItem *data); |
| 85 static PRInt32 ssl3_SendEncryptedClientCertsXtn(sslSocket *ss, | 91 static PRInt32 ssl3_SendEncryptedClientCertsXtn(sslSocket *ss, |
| 86 PRBool append, PRUint32 maxBytes); | 92 PRBool append, PRUint32 maxBytes); |
| 87 | 93 |
| 88 /* | 94 /* |
| 89 * Write bytes. Using this function means the SECItem structure | 95 * Write bytes. Using this function means the SECItem structure |
| 90 * cannot be freed. The caller is expected to call this function | 96 * cannot be freed. The caller is expected to call this function |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 235 /* This table is used by the server, to handle client hello extensions. */ | 241 /* This table is used by the server, to handle client hello extensions. */ |
| 236 static const ssl3HelloExtensionHandler clientHelloHandlers[] = { | 242 static const ssl3HelloExtensionHandler clientHelloHandlers[] = { |
| 237 { ssl_server_name_xtn, &ssl3_HandleServerNameXtn }, | 243 { ssl_server_name_xtn, &ssl3_HandleServerNameXtn }, |
| 238 #ifdef NSS_ENABLE_ECC | 244 #ifdef NSS_ENABLE_ECC |
| 239 { ssl_elliptic_curves_xtn, &ssl3_HandleSupportedCurvesXtn }, | 245 { ssl_elliptic_curves_xtn, &ssl3_HandleSupportedCurvesXtn }, |
| 240 { ssl_ec_point_formats_xtn, &ssl3_HandleSupportedPointFormatsXtn }, | 246 { ssl_ec_point_formats_xtn, &ssl3_HandleSupportedPointFormatsXtn }, |
| 241 #endif | 247 #endif |
| 242 { ssl_session_ticket_xtn, &ssl3_ServerHandleSessionTicketXtn }, | 248 { ssl_session_ticket_xtn, &ssl3_ServerHandleSessionTicketXtn }, |
| 243 { ssl_encrypted_client_certs, &ssl3_ServerHandleEncryptedClientCertsXtn }, | 249 { ssl_encrypted_client_certs, &ssl3_ServerHandleEncryptedClientCertsXtn }, |
| 244 { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, | 250 { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, |
| 245 { ssl_next_proto_neg_xtn, &ssl3_ServerHandleNextProtoNegoXtn }, | 251 { ssl_next_proto_nego_xtn, &ssl3_ServerHandleNextProtoNegoXtn }, |
| 246 { ssl_cached_info_xtn, &ssl3_ServerHandleCachedInfoXtn }, | |
| 247 { ssl_ob_cert_xtn, &ssl3_ServerHandleOBCertXtn }, | 252 { ssl_ob_cert_xtn, &ssl3_ServerHandleOBCertXtn }, |
| 248 { -1, NULL } | 253 { -1, NULL } |
| 249 }; | 254 }; |
| 250 | 255 |
| 251 /* These two tables are used by the client, to handle server hello | 256 /* These two tables are used by the client, to handle server hello |
| 252 * extensions. */ | 257 * extensions. */ |
| 253 static const ssl3HelloExtensionHandler serverHelloHandlersTLS[] = { | 258 static const ssl3HelloExtensionHandler serverHelloHandlersTLS[] = { |
| 254 { ssl_server_name_xtn, &ssl3_HandleServerNameXtn }, | 259 { ssl_server_name_xtn, &ssl3_HandleServerNameXtn }, |
| 255 /* TODO: add a handler for ssl_ec_point_formats_xtn */ | 260 /* TODO: add a handler for ssl_ec_point_formats_xtn */ |
| 256 { ssl_session_ticket_xtn, &ssl3_ClientHandleSessionTicketXtn }, | 261 { ssl_session_ticket_xtn, &ssl3_ClientHandleSessionTicketXtn }, |
| 257 { ssl_encrypted_client_certs, &ssl3_ClientHandleEncryptedClientCertsXtn }, | 262 { ssl_encrypted_client_certs, &ssl3_ClientHandleEncryptedClientCertsXtn }, |
| 258 { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, | 263 { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, |
| 259 { ssl_next_proto_neg_xtn, &ssl3_ClientHandleNextProtoNegoXtn }, | 264 { ssl_next_proto_nego_xtn, &ssl3_ClientHandleNextProtoNegoXtn }, |
| 260 { ssl_cached_info_xtn, &ssl3_ClientHandleCachedInfoXtn }, | |
| 261 { ssl_cert_status_xtn, &ssl3_ClientHandleStatusRequestXtn }, | 265 { ssl_cert_status_xtn, &ssl3_ClientHandleStatusRequestXtn }, |
| 262 { ssl_ob_cert_xtn, &ssl3_ClientHandleOBCertXtn }, | 266 { ssl_ob_cert_xtn, &ssl3_ClientHandleOBCertXtn }, |
| 263 { -1, NULL } | 267 { -1, NULL } |
| 264 }; | 268 }; |
| 265 | 269 |
| 266 static const ssl3HelloExtensionHandler serverHelloHandlersSSL3[] = { | 270 static const ssl3HelloExtensionHandler serverHelloHandlersSSL3[] = { |
| 267 { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, | 271 { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, |
| 268 { -1, NULL } | 272 { -1, NULL } |
| 269 }; | 273 }; |
| 270 | 274 |
| 271 /* Tables of functions to format TLS hello extensions, one function per | 275 /* Tables of functions to format TLS hello extensions, one function per |
| 272 * extension. | 276 * extension. |
| 273 * These static tables are for the formatting of client hello extensions. | 277 * These static tables are for the formatting of client hello extensions. |
| 274 * The server's table of hello senders is dynamic, in the socket struct, | 278 * The server's table of hello senders is dynamic, in the socket struct, |
| 275 * and sender functions are registered there. | 279 * and sender functions are registered there. |
| 276 */ | 280 */ |
| 277 static const | 281 static const |
| 278 ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS] = { | 282 ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS] = { |
| 279 { ssl_server_name_xtn, &ssl3_SendServerNameXtn }, | 283 { ssl_server_name_xtn, &ssl3_SendServerNameXtn }, |
| 280 { ssl_renegotiation_info_xtn, &ssl3_SendRenegotiationInfoXtn }, | 284 { ssl_renegotiation_info_xtn, &ssl3_SendRenegotiationInfoXtn }, |
| 281 #ifdef NSS_ENABLE_ECC | 285 #ifdef NSS_ENABLE_ECC |
| 282 { ssl_elliptic_curves_xtn, &ssl3_SendSupportedCurvesXtn }, | 286 { ssl_elliptic_curves_xtn, &ssl3_SendSupportedCurvesXtn }, |
| 283 { ssl_ec_point_formats_xtn, &ssl3_SendSupportedPointFormatsXtn }, | 287 { ssl_ec_point_formats_xtn, &ssl3_SendSupportedPointFormatsXtn }, |
| 284 #endif | 288 #endif |
| 285 { ssl_session_ticket_xtn, &ssl3_SendSessionTicketXtn }, | 289 { ssl_session_ticket_xtn, &ssl3_SendSessionTicketXtn }, |
| 286 { ssl_encrypted_client_certs, &ssl3_SendEncryptedClientCertsXtn }, | 290 { ssl_encrypted_client_certs, &ssl3_SendEncryptedClientCertsXtn }, |
| 287 { ssl_next_proto_neg_xtn, &ssl3_ClientSendNextProtoNegoXtn }, | 291 { ssl_next_proto_nego_xtn, &ssl3_ClientSendNextProtoNegoXtn }, |
| 288 { ssl_cached_info_xtn, &ssl3_ClientSendCachedInfoXtn }, | |
| 289 { ssl_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn }, | 292 { ssl_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn }, |
| 290 { ssl_ob_cert_xtn, &ssl3_SendOBCertXtn } | 293 { ssl_ob_cert_xtn, &ssl3_SendOBCertXtn } |
| 291 /* any extra entries will appear as { 0, NULL } */ | 294 /* any extra entries will appear as { 0, NULL } */ |
| 292 }; | 295 }; |
| 293 | 296 |
| 294 static const | 297 static const |
| 295 ssl3HelloExtensionSender clientHelloSendersSSL3[SSL_MAX_EXTENSIONS] = { | 298 ssl3HelloExtensionSender clientHelloSendersSSL3[SSL_MAX_EXTENSIONS] = { |
| 296 { ssl_renegotiation_info_xtn, &ssl3_SendRenegotiationInfoXtn } | 299 { ssl_renegotiation_info_xtn, &ssl3_SendRenegotiationInfoXtn } |
| 297 /* any extra entries will appear as { 0, NULL } */ | 300 /* any extra entries will appear as { 0, NULL } */ |
| 298 }; | 301 }; |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 548 return 0; | 551 return 0; |
| 549 } | 552 } |
| 550 return extension_length; | 553 return extension_length; |
| 551 | 554 |
| 552 loser: | 555 loser: |
| 553 ss->xtnData.ticketTimestampVerified = PR_FALSE; | 556 ss->xtnData.ticketTimestampVerified = PR_FALSE; |
| 554 return -1; | 557 return -1; |
| 555 } | 558 } |
| 556 | 559 |
| 557 /* handle an incoming Next Protocol Negotiation extension. */ | 560 /* handle an incoming Next Protocol Negotiation extension. */ |
| 558 SECStatus | 561 static SECStatus |
| 559 ssl3_ServerHandleNextProtoNegoXtn(sslSocket * ss, PRUint16 ex_type, SECItem *dat
a) | 562 ssl3_ServerHandleNextProtoNegoXtn(sslSocket * ss, PRUint16 ex_type, SECItem *dat
a) |
| 560 { | 563 { |
| 561 if (data->len != 0) { | 564 if (ss->firstHsDone || data->len != 0) { |
| 562 /* Clients MUST send an empty NPN extension, if any. */ | 565 /* Clients MUST send an empty NPN extension, if any. */ |
| 566 PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID); |
| 563 return SECFailure; | 567 return SECFailure; |
| 564 } | 568 } |
| 565 | 569 |
| 566 return SECSuccess; | 570 return SECSuccess; |
| 567 } | 571 } |
| 568 | 572 |
| 569 /* ssl3_ValidateNextProtoNego checks that the given block of data is valid: none | 573 /* ssl3_ValidateNextProtoNego checks that the given block of data is valid: none |
| 570 * of the lengths may be 0 and the sum of the lengths must equal the length of | 574 * of the lengths may be 0 and the sum of the lengths must equal the length of |
| 571 * the block. */ | 575 * the block. */ |
| 572 SECStatus | 576 SECStatus |
| 573 ssl3_ValidateNextProtoNego(const unsigned char* data, unsigned short length) | 577 ssl3_ValidateNextProtoNego(const unsigned char* data, unsigned int length) |
| 574 { | 578 { |
| 575 unsigned int offset = 0; | 579 unsigned int offset = 0; |
| 576 | 580 |
| 577 while (offset < length) { | 581 while (offset < length) { |
| 578 » if (data[offset] == 0) { | 582 » unsigned int newOffset = offset + 1 + (unsigned int) data[offset]; |
| 583 » /* Reject embedded nulls to protect against buggy applications that |
| 584 » * store protocol identifiers in null-terminated strings. |
| 585 » */ |
| 586 » if (newOffset > length || data[offset] == 0) { |
| 579 PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID); | 587 PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID); |
| 580 return SECFailure; | 588 return SECFailure; |
| 581 } | 589 } |
| 582 » offset += (unsigned int)data[offset] + 1; | 590 » offset = newOffset; |
| 583 } | 591 } |
| 584 | 592 |
| 585 if (offset > length) { | 593 if (offset > length) { |
| 586 PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID); | 594 PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID); |
| 587 return SECFailure; | 595 return SECFailure; |
| 588 } | 596 } |
| 589 | 597 |
| 590 return SECSuccess; | 598 return SECSuccess; |
| 591 } | 599 } |
| 592 | 600 |
| 593 SECStatus | 601 static SECStatus |
| 594 ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, PRUint16 ex_type, | 602 ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, PRUint16 ex_type, |
| 595 SECItem *data) | 603 » » » » SECItem *data) |
| 596 { | 604 { |
| 597 SECStatus rv; | 605 SECStatus rv; |
| 598 unsigned char result[255]; | 606 unsigned char resultBuffer[255]; |
| 599 unsigned int result_len; | 607 SECItem result = { siBuffer, resultBuffer, 0 }; |
| 608 |
| 609 if (ss->firstHsDone) { |
| 610 » PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID); |
| 611 » return SECFailure; |
| 612 } |
| 600 | 613 |
| 601 rv = ssl3_ValidateNextProtoNego(data->data, data->len); | 614 rv = ssl3_ValidateNextProtoNego(data->data, data->len); |
| 602 if (rv != SECSuccess) | 615 if (rv != SECSuccess) |
| 603 return rv; | 616 return rv; |
| 604 | 617 |
| 605 rv = ss->nextProtoCallback(ss->nextProtoArg, ss->fd, | 618 /* ss->nextProtoCallback cannot normally be NULL if we negotiated the |
| 606 data->data, data->len, | 619 * extension. However, It is possible that an application erroneously |
| 607 result, &result_len); | 620 * cleared the callback between the time we sent the ClientHello and now. |
| 621 */ |
| 622 PORT_Assert(ss->nextProtoCallback != NULL); |
| 623 if (!ss->nextProtoCallback) { |
| 624 » PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); |
| 625 » return SECFailure; |
| 626 } |
| 627 |
| 628 rv = ss->nextProtoCallback(ss->nextProtoArg, ss->fd, data->data, data->len, |
| 629 » » » result.data, &result.len, sizeof resultBuffer); |
| 608 if (rv != SECSuccess) | 630 if (rv != SECSuccess) |
| 609 return rv; | 631 return rv; |
| 610 /* If the callback wrote more than allowed to |result| it has corrupted our | 632 /* If the callback wrote more than allowed to |result| it has corrupted our |
| 611 * stack. */ | 633 * stack. */ |
| 612 PORT_Assert(result_len <= sizeof(result)); | 634 if (result.len > sizeof result) { |
| 635 » PORT_SetError(SEC_ERROR_OUTPUT_LEN); |
| 636 » return SECFailure; |
| 637 } |
| 613 | 638 |
| 614 if (ss->ssl3.nextProto.data) | 639 SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE); |
| 615 » PORT_Free(ss->ssl3.nextProto.data); | 640 return SECITEM_CopyItem(NULL, &ss->ssl3.nextProto, &result); |
| 616 ss->ssl3.nextProto.data = PORT_Alloc(result_len); | |
| 617 PORT_Memcpy(ss->ssl3.nextProto.data, result, result_len); | |
| 618 ss->ssl3.nextProto.len = result_len; | |
| 619 return SECSuccess; | |
| 620 } | 641 } |
| 621 | 642 |
| 622 PRInt32 | 643 static PRInt32 |
| 623 ssl3_ClientSendNextProtoNegoXtn(sslSocket * ss, | 644 ssl3_ClientSendNextProtoNegoXtn(sslSocket * ss, PRBool append, |
| 624 » » » PRBool append, | 645 » » » » PRUint32 maxBytes) |
| 625 » » » PRUint32 maxBytes) | |
| 626 { | 646 { |
| 627 PRInt32 extension_length; | 647 PRInt32 extension_length; |
| 628 | 648 |
| 629 /* Renegotiations do not send this extension. */ | 649 /* Renegotiations do not send this extension. */ |
| 630 if (!ss->nextProtoCallback || ss->firstHsDone) { | 650 if (!ss->nextProtoCallback || ss->firstHsDone) { |
| 631 return 0; | 651 return 0; |
| 632 } | 652 } |
| 633 | 653 |
| 634 extension_length = 4; | 654 extension_length = 4; |
| 635 | 655 |
| 636 if (append && maxBytes >= extension_length) { | 656 if (append && maxBytes >= extension_length) { |
| 637 SECStatus rv; | 657 SECStatus rv; |
| 638 » rv = ssl3_AppendHandshakeNumber(ss, ssl_next_proto_neg_xtn, 2); | 658 » rv = ssl3_AppendHandshakeNumber(ss, ssl_next_proto_nego_xtn, 2); |
| 639 if (rv != SECSuccess) | 659 if (rv != SECSuccess) |
| 640 goto loser; | 660 goto loser; |
| 641 rv = ssl3_AppendHandshakeNumber(ss, 0, 2); | 661 rv = ssl3_AppendHandshakeNumber(ss, 0, 2); |
| 642 if (rv != SECSuccess) | 662 if (rv != SECSuccess) |
| 643 goto loser; | 663 goto loser; |
| 644 ss->xtnData.advertised[ss->xtnData.numAdvertised++] = | 664 ss->xtnData.advertised[ss->xtnData.numAdvertised++] = |
| 645 » » ssl_next_proto_neg_xtn; | 665 » » ssl_next_proto_nego_xtn; |
| 646 } else if (maxBytes < extension_length) { | 666 } else if (maxBytes < extension_length) { |
| 647 return 0; | 667 return 0; |
| 648 } | 668 } |
| 649 | 669 |
| 650 return extension_length; | 670 return extension_length; |
| 651 | 671 |
| 652 loser: | 672 loser: |
| 653 return -1; | 673 return -1; |
| 654 } | 674 } |
| 655 | 675 |
| 656 SECStatus | 676 SECStatus |
| 657 ssl3_ClientHandleStatusRequestXtn(sslSocket *ss, PRUint16 ex_type, | 677 ssl3_ClientHandleStatusRequestXtn(sslSocket *ss, PRUint16 ex_type, |
| 658 SECItem *data) | 678 SECItem *data) |
| 659 { | 679 { |
| 660 /* If we didn't request this extension, then the server may not echo it. */ | 680 /* If we didn't request this extension, then the server may not echo it. */ |
| 661 if (!ss->opt.enableOCSPStapling) | 681 if (!ss->opt.enableOCSPStapling) |
| 662 return SECFailure; | 682 return SECFailure; |
| 663 | 683 |
| 664 /* The echoed extension must be empty. */ | 684 /* The echoed extension must be empty. */ |
| 665 if (data->len != 0) | 685 if (data->len != 0) |
| 666 return SECFailure; | 686 return SECFailure; |
| 667 | 687 |
| 668 ss->ssl3.hs.may_get_cert_status = PR_TRUE; | 688 ss->ssl3.hs.may_get_cert_status = PR_TRUE; |
| 669 | 689 |
| 670 /* Keep track of negotiated extensions. */ | 690 /* Keep track of negotiated extensions. */ |
| 671 ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; | 691 ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; |
| 672 | 692 |
| 673 return SECSuccess; | 693 return SECSuccess; |
| 674 } | 694 } |
| 675 | 695 |
| 676 /* ssl3_ClientSendCachedInfoXtn builds the cached_info extension on the | |
| 677 * client side. */ | |
| 678 PRInt32 | |
| 679 ssl3_ClientSendCachedInfoXtn(sslSocket * ss, PRBool append, | |
| 680 PRUint32 maxBytes) | |
| 681 { | |
| 682 PRInt32 extension_length; | |
| 683 PRBool send_empty; | |
| 684 CERTCertificate ** predictedCertChain; | |
| 685 | |
| 686 if (!ss->opt.enableCachedInfo) | |
| 687 return 0; | |
| 688 | |
| 689 predictedCertChain = ss->ssl3.predictedCertChain; | |
| 690 send_empty = (predictedCertChain == NULL); | |
| 691 | |
| 692 /* minimum extension: | |
| 693 * extension_type (2-bytes) + | |
| 694 * length(extension_data) (2-bytes) + | |
| 695 * length(cached_info) (2-bytes) + | |
| 696 */ | |
| 697 extension_length = send_empty ? 6 : 16; | |
| 698 | |
| 699 if (append && maxBytes >= extension_length) { | |
| 700 SECStatus rv; | |
| 701 | |
| 702 /* ExtensionType */ | |
| 703 rv = ssl3_AppendHandshakeNumber(ss, ssl_cached_info_xtn, 2); | |
| 704 if (rv != SECSuccess) | |
| 705 return -1; | |
| 706 /* Extension Length */ | |
| 707 rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2); | |
| 708 if (rv != SECSuccess) | |
| 709 return -1; | |
| 710 if (send_empty) { | |
| 711 /* Cached Information Length */ | |
| 712 rv = ssl3_AppendHandshakeNumber(ss, 0, 2); | |
| 713 if (rv != SECSuccess) | |
| 714 return -1; | |
| 715 } else { | |
| 716 PRUint64 certChainHash; | |
| 717 int i; | |
| 718 PRUint8* digestPtr = (PRUint8*) &certChainHash; | |
| 719 | |
| 720 /* Cached Information Length */ | |
| 721 rv = ssl3_AppendHandshakeNumber(ss, 10, 2); | |
| 722 if (rv != SECSuccess) | |
| 723 return -1; | |
| 724 /* Cached Information Type */ | |
| 725 rv = ssl3_AppendHandshakeNumber(ss, 1 /* certificate_chain */, 1); | |
| 726 if (rv != SECSuccess) | |
| 727 return -1; | |
| 728 /* hash length */ | |
| 729 rv = ssl3_AppendHandshakeNumber(ss, 8, 1); | |
| 730 if (rv != SECSuccess) | |
| 731 return -1; | |
| 732 /* hash */ | |
| 733 FNV1A64_Init(&certChainHash); | |
| 734 for (i = 0; predictedCertChain[i] != NULL; i++) { | |
| 735 unsigned int certLen = predictedCertChain[i]->derCert.len; | |
| 736 unsigned char certLenArray[3] = { | |
| 737 certLen >> 16, | |
| 738 certLen >> 8, | |
| 739 certLen | |
| 740 }; | |
| 741 FNV1A64_Update(&certChainHash, certLenArray, 3); | |
| 742 FNV1A64_Update(&certChainHash, | |
| 743 predictedCertChain[i]->derCert.data, certLen); | |
| 744 } | |
| 745 FNV1A64_Final(&certChainHash); | |
| 746 rv = ssl3_AppendHandshake(ss, &certChainHash, 8); | |
| 747 if (rv != SECSuccess) | |
| 748 return -1; | |
| 749 for (i = 0; i < 8; i++) { | |
| 750 ss->ssl3.certChainDigest[i] = digestPtr[i]; | |
| 751 } | |
| 752 } | |
| 753 | |
| 754 } else if (maxBytes < extension_length) { | |
| 755 PORT_Assert(0); | |
| 756 return 0; | |
| 757 } | |
| 758 ss->xtnData.advertised[ss->xtnData.numAdvertised++] = | |
| 759 ssl_cached_info_xtn; | |
| 760 return extension_length; | |
| 761 } | |
| 762 | |
| 763 SECStatus | |
| 764 ssl3_ServerHandleCachedInfoXtn(sslSocket *ss, PRUint16 ex_type, | |
| 765 SECItem *data) | |
| 766 { | |
| 767 SECStatus rv; | |
| 768 unsigned char *cached_info = data->data; | |
| 769 unsigned int remaining_len; | |
| 770 | |
| 771 /* Ignore the extension if it isn't enabled. */ | |
| 772 if (!ss->opt.enableCachedInfo) | |
| 773 return SECSuccess; | |
| 774 | |
| 775 if (data->len < 2) | |
| 776 return SECFailure; | |
| 777 remaining_len = (cached_info[0] << 8) | cached_info[1]; | |
| 778 if (remaining_len > 2048 || remaining_len != data->len - 2) | |
| 779 return SECFailure; | |
| 780 cached_info += 2; | |
| 781 | |
| 782 /* Handle reconnaissance case. */ | |
| 783 if (remaining_len == 0) { | |
| 784 /* The client supports information caching, but provides no information | |
| 785 * about what information types it supports */ | |
| 786 ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; | |
| 787 rv = ssl3_RegisterServerHelloExtensionSender(ss, ex_type, | |
| 788 ssl3_ServerSendCachedInfoXtn); | |
| 789 return rv; | |
| 790 } | |
| 791 | |
| 792 /* Iterate over the CachedObjects and pick the first item of type | |
| 793 * certificate_chain, while ignoring everything else. */ | |
| 794 while (remaining_len >= 2) { | |
| 795 unsigned char cached_object_type = *cached_info++; | |
| 796 unsigned int cached_object_length = *cached_info++; | |
| 797 remaining_len -= 2; | |
| 798 if (remaining_len < cached_object_length) | |
| 799 return SECFailure; | |
| 800 if (cached_object_length != 8) /* The digest must be present. */ | |
| 801 return SECFailure; | |
| 802 if (cached_object_type == cached_info_certificate_chain && | |
| 803 !ss->ssl3.cachedInfoCertChainDigestReceived) { | |
| 804 ss->ssl3.cachedInfoCertChainDigestReceived = PR_TRUE; | |
| 805 memcpy(ss->ssl3.certChainDigest, cached_info, 8); | |
| 806 } | |
| 807 remaining_len -= cached_object_length; | |
| 808 cached_info += cached_object_length; | |
| 809 } | |
| 810 | |
| 811 if (remaining_len != 0) | |
| 812 return SECFailure; | |
| 813 | |
| 814 if (ss->ssl3.cachedInfoCertChainDigestReceived) { | |
| 815 ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; | |
| 816 rv = ssl3_RegisterServerHelloExtensionSender(ss, ex_type, | |
| 817 ssl3_ServerSendCachedInfoXtn); | |
| 818 return SECSuccess; | |
| 819 } | |
| 820 | |
| 821 return SECSuccess; | |
| 822 } | |
| 823 | |
| 824 /* ssl3_ServerSendCachedInfoXtn builds the cached_info extension on the | |
| 825 * server side. */ | |
| 826 PRInt32 | |
| 827 ssl3_ServerSendCachedInfoXtn(sslSocket * ss, PRBool append, | |
| 828 PRUint32 maxBytes) | |
| 829 { | |
| 830 PRInt32 extension_length = 2 /* extension type */ + | |
| 831 2 /* extension length */ + | |
| 832 2 /* cached_info length */ + | |
| 833 1 /* CachedInformationType */ + | |
| 834 1 /* hash value length (0) */; | |
| 835 SECStatus rv; | |
| 836 | |
| 837 PORT_Assert(ss->opt.enableCachedInfo); | |
| 838 | |
| 839 if (append && maxBytes >= extension_length) { | |
| 840 /* ExtensionType */ | |
| 841 rv = ssl3_AppendHandshakeNumber(ss, ssl_cached_info_xtn, 2); | |
| 842 if (rv != SECSuccess) | |
| 843 return -1; | |
| 844 /* Extension Length */ | |
| 845 rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2); | |
| 846 if (rv != SECSuccess) | |
| 847 return -1; | |
| 848 /* Cached Information Length */ | |
| 849 rv = ssl3_AppendHandshakeNumber(ss, 2, 2); | |
| 850 if (rv != SECSuccess) | |
| 851 return -1; | |
| 852 /* Cached Information Type */ | |
| 853 rv = ssl3_AppendHandshakeNumber(ss, 1 /* certificate_chain */, 1); | |
| 854 if (rv != SECSuccess) | |
| 855 return -1; | |
| 856 /* hash length */ | |
| 857 rv = ssl3_AppendHandshakeNumber(ss, 0, 1); | |
| 858 if (rv != SECSuccess) | |
| 859 return -1; | |
| 860 } else if (maxBytes < extension_length) { | |
| 861 PORT_Assert(0); | |
| 862 return 0; | |
| 863 } | |
| 864 | |
| 865 return extension_length; | |
| 866 } | |
| 867 | |
| 868 SECStatus | |
| 869 ssl3_ClientHandleCachedInfoXtn(sslSocket *ss, PRUint16 ex_type, | |
| 870 SECItem *data) | |
| 871 { | |
| 872 unsigned char * cached_info = data->data; | |
| 873 unsigned int remaining_cached_info_length; | |
| 874 PRBool has_correct_cert_chain = PR_FALSE; | |
| 875 | |
| 876 /* If we didn't request this extension, then the server may not echo it. */ | |
| 877 if (!ss->opt.enableCachedInfo) | |
| 878 return SECFailure; | |
| 879 | |
| 880 if (data->len == 0) { | |
| 881 /* The server supports information caching, but provides no information | |
| 882 * about what information types it supports */ | |
| 883 ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; | |
| 884 return SECSuccess; | |
| 885 } | |
| 886 | |
| 887 if (data->len < 2) | |
| 888 return SECFailure; | |
| 889 remaining_cached_info_length = (cached_info[0] << 8) | cached_info[1]; | |
| 890 if (remaining_cached_info_length != data->len - 2) | |
| 891 return SECFailure; | |
| 892 cached_info += 2; | |
| 893 while (remaining_cached_info_length >= 2) { | |
| 894 /* The server supports only those CachedInformationType types that are | |
| 895 * identified by a present CachedObject */ | |
| 896 unsigned char cached_object_type; | |
| 897 unsigned int cached_object_length; | |
| 898 unsigned char cached_object_digest[8]; | |
| 899 cached_object_type = *cached_info++; | |
| 900 cached_object_length = *cached_info++; | |
| 901 remaining_cached_info_length -= 2; | |
| 902 if (remaining_cached_info_length < cached_object_length) | |
| 903 return SECFailure; | |
| 904 if (cached_object_length != 0 && cached_object_length != 8) | |
| 905 return SECFailure; | |
| 906 remaining_cached_info_length -= cached_object_length; | |
| 907 if (cached_object_type == cached_info_certificate_chain) { | |
| 908 if (cached_object_length == 0) | |
| 909 has_correct_cert_chain = PR_TRUE; | |
| 910 else { /* Hashes must match */ | |
| 911 int i; | |
| 912 for (i = 0; i < 8; i++) | |
| 913 cached_object_digest[i] = *cached_info++; | |
| 914 if (!memcmp(cached_object_digest, ss->ssl3.certChainDigest, 8)) | |
| 915 has_correct_cert_chain = PR_TRUE; | |
| 916 } | |
| 917 } | |
| 918 } | |
| 919 | |
| 920 if (remaining_cached_info_length != 0) | |
| 921 return SECFailure; | |
| 922 | |
| 923 if (has_correct_cert_chain) { | |
| 924 ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; | |
| 925 return SECSuccess; | |
| 926 } | |
| 927 | |
| 928 return SECFailure; | |
| 929 } | |
| 930 | |
| 931 /* ssl3_ClientSendStatusRequestXtn builds the status_request extension on the | 696 /* ssl3_ClientSendStatusRequestXtn builds the status_request extension on the |
| 932 * client side. See RFC 4366 section 3.6. */ | 697 * client side. See RFC 4366 section 3.6. */ |
| 933 PRInt32 | 698 PRInt32 |
| 934 ssl3_ClientSendStatusRequestXtn(sslSocket * ss, PRBool append, | 699 ssl3_ClientSendStatusRequestXtn(sslSocket * ss, PRBool append, |
| 935 PRUint32 maxBytes) | 700 PRUint32 maxBytes) |
| 936 { | 701 { |
| 937 PRInt32 extension_length; | 702 PRInt32 extension_length; |
| 938 | 703 |
| 939 if (!ss->opt.enableOCSPStapling) | 704 if (!ss->opt.enableOCSPStapling) |
| 940 return 0; | 705 return 0; |
| (...skipping 778 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1719 ss->sec.ci.sid = sid; | 1484 ss->sec.ci.sid = sid; |
| 1720 } | 1485 } |
| 1721 } | 1486 } |
| 1722 | 1487 |
| 1723 if (0) { | 1488 if (0) { |
| 1724 no_ticket: | 1489 no_ticket: |
| 1725 SSL_DBG(("%d: SSL[%d]: Session ticket parsing failed.", | 1490 SSL_DBG(("%d: SSL[%d]: Session ticket parsing failed.", |
| 1726 SSL_GETPID(), ss->fd)); | 1491 SSL_GETPID(), ss->fd)); |
| 1727 ssl3stats = SSL_GetStatistics(); | 1492 ssl3stats = SSL_GetStatistics(); |
| 1728 SSL_AtomicIncrementLong(& ssl3stats->hch_sid_ticket_parse_failures ); | 1493 SSL_AtomicIncrementLong(& ssl3stats->hch_sid_ticket_parse_failures ); |
| 1729 if (sid) { | |
| 1730 ssl_FreeSID(sid); | |
| 1731 sid = NULL; | |
| 1732 } | |
| 1733 } | 1494 } |
| 1734 rv = SECSuccess; | 1495 rv = SECSuccess; |
| 1735 | 1496 |
| 1736 loser: | 1497 loser: |
| 1498 /* ss->sec.ci.sid == sid if it did NOT come here via goto statement |
| 1499 * in that case do not free sid |
| 1500 */ |
| 1501 if (sid && (ss->sec.ci.sid != sid)) { |
| 1502 ssl_FreeSID(sid); |
| 1503 sid = NULL; |
| 1504 } |
| 1737 if (decrypted_state != NULL) { | 1505 if (decrypted_state != NULL) { |
| 1738 SECITEM_FreeItem(decrypted_state, PR_TRUE); | 1506 SECITEM_FreeItem(decrypted_state, PR_TRUE); |
| 1739 decrypted_state = NULL; | 1507 decrypted_state = NULL; |
| 1740 } | 1508 } |
| 1741 | 1509 |
| 1742 if (parsed_session_ticket != NULL) { | 1510 if (parsed_session_ticket != NULL) { |
| 1743 if (parsed_session_ticket->peer_cert.data) { | 1511 if (parsed_session_ticket->peer_cert.data) { |
| 1744 SECITEM_FreeItem(&parsed_session_ticket->peer_cert, PR_FALSE); | 1512 SECITEM_FreeItem(&parsed_session_ticket->peer_cert, PR_FALSE); |
| 1745 } | 1513 } |
| 1746 PORT_ZFree(parsed_session_ticket, sizeof(SessionTicket)); | 1514 PORT_ZFree(parsed_session_ticket, sizeof(SessionTicket)); |
| (...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2094 | 1862 |
| 2095 /* The echoed extension must be empty. */ | 1863 /* The echoed extension must be empty. */ |
| 2096 if (data->len != 0) | 1864 if (data->len != 0) |
| 2097 return SECFailure; | 1865 return SECFailure; |
| 2098 | 1866 |
| 2099 /* Keep track of negotiated extensions. */ | 1867 /* Keep track of negotiated extensions. */ |
| 2100 ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; | 1868 ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; |
| 2101 | 1869 |
| 2102 return SECSuccess; | 1870 return SECSuccess; |
| 2103 } | 1871 } |
| OLD | NEW |