Chromium Code Reviews| 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 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 240 }; | 240 }; |
| 241 | 241 |
| 242 /* These two tables are used by the client, to handle server hello | 242 /* These two tables are used by the client, to handle server hello |
| 243 * extensions. */ | 243 * extensions. */ |
| 244 static const ssl3HelloExtensionHandler serverHelloHandlersTLS[] = { | 244 static const ssl3HelloExtensionHandler serverHelloHandlersTLS[] = { |
| 245 { ssl_server_name_xtn, &ssl3_HandleServerNameXtn }, | 245 { ssl_server_name_xtn, &ssl3_HandleServerNameXtn }, |
| 246 /* TODO: add a handler for ssl_ec_point_formats_xtn */ | 246 /* TODO: add a handler for ssl_ec_point_formats_xtn */ |
| 247 { ssl_session_ticket_xtn, &ssl3_ClientHandleSessionTicketXtn }, | 247 { ssl_session_ticket_xtn, &ssl3_ClientHandleSessionTicketXtn }, |
| 248 { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, | 248 { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, |
| 249 { ssl_next_proto_neg_xtn, &ssl3_ClientHandleNextProtoNegoXtn }, | 249 { ssl_next_proto_neg_xtn, &ssl3_ClientHandleNextProtoNegoXtn }, |
| 250 { ssl_cached_info_xtn, &ssl3_ClientHandleCachedInfoXtn }, | |
| 250 { ssl_cert_status_xtn, &ssl3_ClientHandleStatusRequestXtn }, | 251 { ssl_cert_status_xtn, &ssl3_ClientHandleStatusRequestXtn }, |
| 251 { ssl_snap_start_xtn, &ssl3_ClientHandleSnapStartXtn }, | 252 { ssl_snap_start_xtn, &ssl3_ClientHandleSnapStartXtn }, |
| 252 { -1, NULL } | 253 { -1, NULL } |
| 253 }; | 254 }; |
| 254 | 255 |
| 255 static const ssl3HelloExtensionHandler serverHelloHandlersSSL3[] = { | 256 static const ssl3HelloExtensionHandler serverHelloHandlersSSL3[] = { |
| 256 { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, | 257 { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, |
| 257 { -1, NULL } | 258 { -1, NULL } |
| 258 }; | 259 }; |
| 259 | 260 |
| 260 /* Tables of functions to format TLS hello extensions, one function per | 261 /* Tables of functions to format TLS hello extensions, one function per |
| 261 * extension. | 262 * extension. |
| 262 * These static tables are for the formatting of client hello extensions. | 263 * These static tables are for the formatting of client hello extensions. |
| 263 * The server's table of hello senders is dynamic, in the socket struct, | 264 * The server's table of hello senders is dynamic, in the socket struct, |
| 264 * and sender functions are registered there. | 265 * and sender functions are registered there. |
| 265 */ | 266 */ |
| 266 static const | 267 static const |
| 267 ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS] = { | 268 ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS] = { |
| 268 { ssl_server_name_xtn, &ssl3_SendServerNameXtn }, | 269 { ssl_server_name_xtn, &ssl3_SendServerNameXtn }, |
| 269 { ssl_renegotiation_info_xtn, &ssl3_SendRenegotiationInfoXtn }, | 270 { ssl_renegotiation_info_xtn, &ssl3_SendRenegotiationInfoXtn }, |
| 270 #ifdef NSS_ENABLE_ECC | 271 #ifdef NSS_ENABLE_ECC |
| 271 { ssl_elliptic_curves_xtn, &ssl3_SendSupportedCurvesXtn }, | 272 { ssl_elliptic_curves_xtn, &ssl3_SendSupportedCurvesXtn }, |
| 272 { ssl_ec_point_formats_xtn, &ssl3_SendSupportedPointFormatsXtn }, | 273 { ssl_ec_point_formats_xtn, &ssl3_SendSupportedPointFormatsXtn }, |
| 273 #endif | 274 #endif |
| 274 { ssl_session_ticket_xtn, &ssl3_SendSessionTicketXtn }, | 275 { ssl_session_ticket_xtn, &ssl3_SendSessionTicketXtn }, |
| 275 { ssl_next_proto_neg_xtn, &ssl3_ClientSendNextProtoNegoXtn }, | 276 { ssl_next_proto_neg_xtn, &ssl3_ClientSendNextProtoNegoXtn }, |
| 277 { ssl_cached_info_xtn, &ssl3_ClientSendCachedInfoXtn }, | |
| 276 { ssl_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn }, | 278 { ssl_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn }, |
| 277 { ssl_snap_start_xtn, &ssl3_SendSnapStartXtn } | 279 { ssl_snap_start_xtn, &ssl3_SendSnapStartXtn } |
| 278 /* NOTE: The Snap Start sender MUST be the last extension in the list. */ | 280 /* NOTE: The Snap Start sender MUST be the last extension in the list. */ |
| 279 /* any extra entries will appear as { 0, NULL } */ | 281 /* any extra entries will appear as { 0, NULL } */ |
| 280 }; | 282 }; |
| 281 | 283 |
| 282 static const | 284 static const |
| 283 ssl3HelloExtensionSender clientHelloSendersSSL3[SSL_MAX_EXTENSIONS] = { | 285 ssl3HelloExtensionSender clientHelloSendersSSL3[SSL_MAX_EXTENSIONS] = { |
| 284 { ssl_renegotiation_info_xtn, &ssl3_SendRenegotiationInfoXtn } | 286 { ssl_renegotiation_info_xtn, &ssl3_SendRenegotiationInfoXtn } |
| 285 /* any extra entries will appear as { 0, NULL } */ | 287 /* any extra entries will appear as { 0, NULL } */ |
| (...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 674 return SECFailure; | 676 return SECFailure; |
| 675 | 677 |
| 676 ss->ssl3.hs.may_get_cert_status = PR_TRUE; | 678 ss->ssl3.hs.may_get_cert_status = PR_TRUE; |
| 677 | 679 |
| 678 /* Keep track of negotiated extensions. */ | 680 /* Keep track of negotiated extensions. */ |
| 679 ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; | 681 ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; |
| 680 | 682 |
| 681 return SECSuccess; | 683 return SECSuccess; |
| 682 } | 684 } |
| 683 | 685 |
| 686 /* ssl3_ClientSendCachedInfoXtn builds the cached_info extension on the | |
| 687 * client side. */ | |
| 688 PRInt32 | |
| 689 ssl3_ClientSendCachedInfoXtn(sslSocket * ss, PRBool append, | |
| 690 PRUint32 maxBytes) | |
| 691 { | |
| 692 PRInt32 extension_length; | |
| 693 PRBool send_empty; | |
| 694 | |
| 695 if (!ss->opt.enableCachedInfo) | |
| 696 return 0; | |
| 697 | |
| 698 CERTCertificate ** predictedCertChain = ss->ssl3.predictedCertChain; | |
| 699 //send_empty = (predictedCertChain == NULL || predictedCertChain[0] == NULL) | |
| 700 // ? PR_TRUE : PR_FALSE; | |
| 701 send_empty = (predictedCertChain == NULL) ? PR_TRUE : PR_FALSE; | |
| 702 | |
| 703 /* minimum extension: | |
| 704 * extension_type (2-bytes) + | |
| 705 * length(extension_data) (2-bytes) + | |
| 706 * length(cached_info) (2-bytes) + | |
| 707 */ | |
| 708 extension_length = send_empty ? 6 : 16; | |
| 709 | |
| 710 if (append && maxBytes >= extension_length) { | |
| 711 SECStatus rv; | |
| 712 TLSExtensionData *xtnData; | |
| 713 | |
| 714 /* ExtensionType */ | |
| 715 rv = ssl3_AppendHandshakeNumber(ss, ssl_cached_info_xtn, 2); | |
| 716 if (rv != SECSuccess) | |
| 717 return -1; | |
| 718 /* Extension Length */ | |
| 719 rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2); | |
| 720 if (rv != SECSuccess) | |
| 721 return -1; | |
| 722 if (send_empty) { | |
| 723 /* Cached Information Length */ | |
| 724 rv = ssl3_AppendHandshakeNumber(ss, 0, 2); | |
| 725 if (rv != SECSuccess) | |
| 726 return -1; | |
| 727 } else { | |
| 728 /* Cached Information Length */ | |
| 729 rv = ssl3_AppendHandshakeNumber(ss, 10, 2); | |
| 730 if (rv != SECSuccess) | |
| 731 return -1; | |
| 732 /* Cached Information Type */ | |
| 733 rv = ssl3_AppendHandshakeNumber(ss, 1 /* certificate_chain */, 1); | |
| 734 if (rv != SECSuccess) | |
| 735 return -1; | |
| 736 /* hash length */ | |
| 737 rv = ssl3_AppendHandshakeNumber(ss, 8, 1); | |
| 738 if (rv != SECSuccess) | |
| 739 return -1; | |
| 740 /* hash */ | |
| 741 PRUint64 certChainHash; | |
| 742 FNV1A64_Init(&certChainHash); | |
| 743 int i; | |
| 744 for (i = 0; predictedCertChain[i] != NULL; i++) { | |
| 745 unsigned int certLen = predictedCertChain[i]->derCert.len; | |
| 746 unsigned char certLenArray[3] = | |
| 747 {(certLen & 0xff0000) >> 16, (certLen & 0xff00) >> 8, certLe n & 0xff}; | |
| 748 FNV1A64_Update(&certChainHash, certLenArray, 3); | |
| 749 FNV1A64_Update(&certChainHash, predictedCertChain[i]->derCert.da ta, certLen); | |
| 750 } | |
|
wtc
2011/06/03 22:56:55
Fold these long lines.
rkn
2011/06/04 20:50:19
Done.
| |
| 751 FNV1A64_Final(&certChainHash); | |
| 752 rv = ssl3_AppendHandshake(ss, &certChainHash, 8); | |
| 753 if (rv != SECSuccess) | |
| 754 return -1; | |
| 755 } | |
| 756 | |
| 757 } else if (maxBytes < extension_length) { | |
| 758 PORT_Assert(0); | |
| 759 return 0; | |
| 760 } | |
| 761 ss->xtnData.advertised[ss->xtnData.numAdvertised++] = | |
| 762 ssl_cached_info_xtn; | |
| 763 return extension_length; | |
| 764 } | |
| 765 | |
| 766 SECStatus | |
| 767 ssl3_ClientHandleCachedInfoXtn(sslSocket *ss, PRUint16 ex_type, | |
| 768 SECItem *data) | |
| 769 { | |
| 770 /* If we didn't request this extension, then the server may not echo it. */ | |
| 771 if (!ss->opt.enableCachedInfo) | |
| 772 return SECFailure; | |
| 773 | |
| 774 if (data->len == 0) { | |
| 775 /* The server supports information caching, but provides no information | |
| 776 * about what information types it supports */ | |
| 777 ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; | |
| 778 return SECSuccess; | |
| 779 } | |
| 780 | |
| 781 if (data->len < 2) | |
| 782 return SECFailure; | |
| 783 unsigned char * cached_info = data->data; | |
| 784 unsigned int remaining_cached_info_length = | |
| 785 (cached_info[0] << 8) | cached_info[1]; | |
| 786 if (remaining_cached_info_length != data->len - 2) | |
| 787 return SECFailure; | |
| 788 cached_info += 2; | |
| 789 PRBool has_certificate_chain = PR_FALSE; | |
| 790 while (remaining_cached_info_length >= 2) { | |
| 791 /* The server supports only those CachedInformationType types that are | |
| 792 * identified by a present CachedObject */ | |
| 793 unsigned char cached_object_type; | |
| 794 unsigned int cached_object_length; | |
| 795 cached_object_type = *cached_info++; | |
| 796 cached_object_length = *cached_info++; | |
| 797 remaining_cached_info_length -= 2; | |
| 798 if (remaining_cached_info_length < cached_object_length) | |
| 799 return SECFailure; | |
| 800 if (cached_object_length != 0 && cached_object_length != 8) | |
| 801 return SECFailure; | |
| 802 remaining_cached_info_length -= cached_object_length; | |
| 803 if (cached_object_type == cached_info_certificate_chain) { | |
| 804 has_certificate_chain = PR_TRUE; | |
| 805 //TODO(rkn): Should also check that the hash matches our cached | |
| 806 //hash. So we need to store the hash. | |
| 807 } | |
| 808 } | |
| 809 | |
| 810 if (remaining_cached_info_length != 0) | |
| 811 return SECFailure; | |
| 812 | |
| 813 if (has_certificate_chain) { | |
| 814 ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; | |
| 815 return SECSuccess; | |
| 816 } | |
| 817 | |
| 818 return SECFailure; | |
| 819 } | |
| 820 | |
| 684 /* ssl3_ClientSendStatusRequestXtn builds the status_request extension on the | 821 /* ssl3_ClientSendStatusRequestXtn builds the status_request extension on the |
| 685 * client side. See RFC 4366 section 3.6. */ | 822 * client side. See RFC 4366 section 3.6. */ |
| 686 PRInt32 | 823 PRInt32 |
| 687 ssl3_ClientSendStatusRequestXtn(sslSocket * ss, PRBool append, | 824 ssl3_ClientSendStatusRequestXtn(sslSocket * ss, PRBool append, |
| 688 PRUint32 maxBytes) | 825 PRUint32 maxBytes) |
| 689 { | 826 { |
| 690 PRInt32 extension_length; | 827 PRInt32 extension_length; |
| 691 | 828 |
| 692 if (!ss->opt.enableOCSPStapling) | 829 if (!ss->opt.enableOCSPStapling) |
| 693 return 0; | 830 return 0; |
| (...skipping 1019 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1713 ss->peerRequestedProtection = 1; | 1850 ss->peerRequestedProtection = 1; |
| 1714 ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; | 1851 ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; |
| 1715 if (ss->sec.isServer) { | 1852 if (ss->sec.isServer) { |
| 1716 /* prepare to send back the appropriate response */ | 1853 /* prepare to send back the appropriate response */ |
| 1717 rv = ssl3_RegisterServerHelloExtensionSender(ss, ex_type, | 1854 rv = ssl3_RegisterServerHelloExtensionSender(ss, ex_type, |
| 1718 ssl3_SendRenegotiationInfoXtn); | 1855 ssl3_SendRenegotiationInfoXtn); |
| 1719 } | 1856 } |
| 1720 return rv; | 1857 return rv; |
| 1721 } | 1858 } |
| 1722 | 1859 |
| OLD | NEW |