Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(69)

Side by Side Diff: net/third_party/nss/ssl/ssl3ext.c

Issue 7058049: Added client-side support for the TLS cached info extension. This feature is disabled by default ... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Added Null pointer check Created 9 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698