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 8000 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8011 goto loser; | 8011 goto loser; |
8012 } | 8012 } |
8013 goto cert_block; | 8013 goto cert_block; |
8014 } | 8014 } |
8015 | 8015 |
8016 ss->ssl3.peerCertArena = arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); | 8016 ss->ssl3.peerCertArena = arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); |
8017 if ( arena == NULL ) { | 8017 if ( arena == NULL ) { |
8018 goto loser; /* don't send alerts on memory errors */ | 8018 goto loser; /* don't send alerts on memory errors */ |
8019 } | 8019 } |
8020 | 8020 |
8021 /* First get the peer cert. */ | 8021 if (length == 12 && ssl3_ExtensionNegotiated(ss, ssl_cached_info_xtn)) { |
8022 remaining -= 3; | 8022 /* We are dealing with a certificate_chain digest */ |
8023 if (remaining < 0) | 8023 » ssl3CertNode *certNodeCurrent; |
8024 » goto decode_loser; | |
8025 | 8024 |
8026 size = ssl3_ConsumeHandshakeNumber(ss, 3, &b, &length); | 8025 » /* Make sure the digests match. */ |
8027 if (size <= 0) | 8026 » if (memcmp(b+4, ss->ssl3.certChainDigest, 8)) { |
wtc
2011/06/20 22:21:51
Nit: add spaces around the '+' sign.
rkn
2011/06/20 23:52:51
Done.
| |
8028 » goto loser;» /* fatal alert already sent by ConsumeHandshake. */ | 8027 desc = handshake_failure; |
8029 | 8028 goto alert_loser; |
8030 if (remaining < size) | |
8031 » goto decode_loser; | |
8032 | |
8033 certItem.data = b; | |
8034 certItem.len = size; | |
8035 b += size; | |
8036 length -= size; | |
8037 remaining -= size; | |
8038 | |
8039 ss->sec.peerCert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL, | |
8040 PR_FALSE, PR_TRUE); | |
8041 if (ss->sec.peerCert == NULL) { | |
8042 » /* We should report an alert if the cert was bad, but not if the | |
8043 » * problem was just some local problem, like memory error. | |
8044 » */ | |
8045 » goto ambiguous_err; | |
8046 } | |
8047 | |
8048 /* Now get all of the CA certs. */ | |
8049 while (remaining > 0) { | |
8050 » remaining -= 3; | |
8051 » if (remaining < 0) | |
8052 » goto decode_loser; | |
8053 | |
8054 » size = ssl3_ConsumeHandshakeNumber(ss, 3, &b, &length); | |
8055 » if (size <= 0) | |
8056 » goto loser;»/* fatal alert already sent by ConsumeHandshake. */ | |
8057 | |
8058 » if (remaining < size) | |
8059 » goto decode_loser; | |
8060 | |
8061 » certItem.data = b; | |
8062 » certItem.len = size; | |
8063 » b += size; | |
8064 » length -= size; | |
8065 » remaining -= size; | |
8066 | |
8067 » c = PORT_ArenaNew(arena, ssl3CertNode); | |
8068 » if (c == NULL) { | |
8069 » goto loser;»/* don't send alerts on memory errors */ | |
8070 } | 8029 } |
8071 | 8030 |
8072 » c->cert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL, | 8031 ss->ssl3.digestReceived = PR_TRUE; |
wtc
2011/06/20 22:21:51
Nit: perhaps we should do this before the memcmp c
rkn
2011/06/20 23:52:51
Done.
| |
8073 » PR_FALSE, PR_TRUE); | 8032 |
8074 » if (c->cert == NULL) { | 8033 /* First get the peer cert. */ |
8034 if (ss->ssl3.predictedCertChain[0] == NULL) { | |
8035 desc = handshake_failure; | |
8036 goto alert_loser; | |
8037 » } | |
8038 ss->sec.peerCert = CERT_DupCertificate(ss->ssl3.predictedCertChain[0]); | |
8039 » | |
8040 /* Now get all of the CA certs. */ | |
8041 » if (ss->ssl3.predictedCertChain[1] == NULL) { | |
8042 » ss->ssl3.peerCertChain = NULL; | |
8043 » } else { | |
8044 » int i = 1; | |
8045 » ss->ssl3.peerCertChain = certNodeCurrent | |
8046 » = PORT_ArenaNew(arena, ssl3CertNode); | |
8047 » if (certNodeCurrent == NULL) { | |
8048 » goto loser;» /* don't send alerts on memory errors */ | |
8049 » } | |
8050 » while (ss->ssl3.predictedCertChain[i] != NULL) { | |
8051 » certNodeCurrent->cert = | |
8052 » » CERT_DupCertificate(ss->ssl3.predictedCertChain[i]); | |
8053 » » i++; | |
8054 » » if (ss->ssl3.predictedCertChain[i] == NULL) { | |
8055 » » certNodeCurrent->next = NULL; | |
8056 » » } else { | |
8057 » » certNodeCurrent->next = PORT_ArenaNew(arena, ssl3CertNode); | |
8058 » » if (certNodeCurrent->next == NULL) { | |
8059 » » goto loser; /* don't send alerts on memory errors */ | |
8060 » » } | |
8061 » » certNodeCurrent = certNodeCurrent->next; | |
8062 » » } | |
8063 » } | |
8064 » } | |
wtc
2011/06/20 22:21:51
I believe we can rewrite lines 8041-8064 as follow
rkn
2011/06/20 23:52:51
Done. I made this change, but I added the line
| |
8065 } else { | |
8066 /* We are dealing with a regular certificate message */ | |
8067 ss->ssl3.digestReceived = PR_FALSE; | |
8068 | |
8069 /* First get the peer cert. */ | |
8070 remaining -= 3; | |
8071 if (remaining < 0) | |
8072 » goto decode_loser; | |
8073 | |
8074 size = ssl3_ConsumeHandshakeNumber(ss, 3, &b, &length); | |
8075 if (size <= 0) | |
8076 » goto loser;»/* fatal alert already sent by ConsumeHandshake. */ | |
8077 | |
8078 if (remaining < size) | |
8079 » goto decode_loser; | |
8080 | |
8081 certItem.data = b; | |
8082 certItem.len = size; | |
8083 b += size; | |
8084 length -= size; | |
8085 remaining -= size; | |
8086 | |
8087 ss->sec.peerCert = CERT_NewTempCertificate(ss->dbHandle, &certItem, | |
8088 » » » » » » NULL, PR_FALSE, PR_TRUE); | |
8089 if (ss->sec.peerCert == NULL) { | |
8090 » /* We should report an alert if the cert was bad, but not if the | |
8091 » * problem was just some local problem, like memory error. | |
8092 » */ | |
8075 goto ambiguous_err; | 8093 goto ambiguous_err; |
8076 » } | 8094 } |
8077 | 8095 |
8078 » if (c->cert->trust) | 8096 /* Now get all of the CA certs. */ |
8079 » trusted = PR_TRUE; | 8097 while (remaining > 0) { |
8080 | 8098 » remaining -= 3; |
8081 » c->next = NULL; | 8099 » if (remaining < 0) |
8082 » if (lastCert) { | 8100 » goto decode_loser; |
8083 » lastCert->next = c; | 8101 |
8084 » } else { | 8102 » size = ssl3_ConsumeHandshakeNumber(ss, 3, &b, &length); |
8085 » certs = c; | 8103 » if (size <= 0) |
8086 » } | 8104 » goto loser; /* fatal alert already sent by ConsumeHandshake. */ |
8087 » lastCert = c; | 8105 |
8106 » if (remaining < size) | |
8107 » goto decode_loser; | |
8108 | |
8109 » certItem.data = b; | |
8110 » certItem.len = size; | |
8111 » b += size; | |
8112 » length -= size; | |
8113 » remaining -= size; | |
8114 » | |
8115 » c = PORT_ArenaNew(arena, ssl3CertNode); | |
8116 » if (c == NULL) { | |
8117 » goto loser;» /* don't send alerts on memory errors */ | |
8118 » } | |
8119 | |
8120 » c->cert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL, | |
8121 » » » » » PR_FALSE, PR_TRUE); | |
8122 » if (c->cert == NULL) { | |
8123 » goto ambiguous_err; | |
8124 » } | |
8125 | |
8126 » if (c->cert->trust) | |
8127 » trusted = PR_TRUE; | |
wtc
2011/06/20 22:21:51
We probably should duplicate these two lines (line
rkn
2011/06/20 23:52:51
I am holding off on making this change, because I
| |
8128 | |
8129 » c->next = NULL; | |
8130 » if (lastCert) { | |
8131 » lastCert->next = c; | |
8132 » } else { | |
8133 » certs = c; | |
8134 » } | |
8135 » lastCert = c; | |
8136 } | |
8137 | |
8138 if (remaining != 0) | |
8139 goto decode_loser; | |
8088 } | 8140 } |
8089 | 8141 |
8090 if (remaining != 0) | |
8091 goto decode_loser; | |
8092 | |
8093 SECKEY_UpdateCertPQG(ss->sec.peerCert); | 8142 SECKEY_UpdateCertPQG(ss->sec.peerCert); |
8094 | 8143 |
8095 /* | 8144 /* |
8096 * Ask caller-supplied callback function to validate cert chain. | 8145 * Ask caller-supplied callback function to validate cert chain. |
8097 */ | 8146 */ |
8098 rv = (SECStatus)(*ss->authCertificate)(ss->authCertificateArg, ss->fd, | 8147 rv = (SECStatus)(*ss->authCertificate)(ss->authCertificateArg, ss->fd, |
8099 PR_TRUE, isServer); | 8148 PR_TRUE, isServer); |
8100 if (rv) { | 8149 if (rv) { |
8101 errCode = PORT_GetError(); | 8150 errCode = PORT_GetError(); |
8102 if (!ss->handleBadCert) { | 8151 if (!ss->handleBadCert) { |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8243 | 8292 |
8244 goto alert_loser; | 8293 goto alert_loser; |
8245 | 8294 |
8246 decode_loser: | 8295 decode_loser: |
8247 desc = isTLS ? decode_error : bad_certificate; | 8296 desc = isTLS ? decode_error : bad_certificate; |
8248 | 8297 |
8249 alert_loser: | 8298 alert_loser: |
8250 (void)SSL3_SendAlert(ss, alert_fatal, desc); | 8299 (void)SSL3_SendAlert(ss, alert_fatal, desc); |
8251 | 8300 |
8252 loser: | 8301 loser: |
8253 ss->ssl3.peerCertChain = certs; certs = NULL; arena = NULL; | 8302 if (ss->ssl3.peerCertChain == NULL) { |
8303 ss->ssl3.peerCertChain = certs; certs = NULL; arena = NULL; | |
8304 } | |
8305 PORT_Assert(certs == NULL); | |
8254 ssl3_CleanupPeerCerts(ss); | 8306 ssl3_CleanupPeerCerts(ss); |
8255 | 8307 |
8256 if (ss->sec.peerCert != NULL) { | 8308 if (ss->sec.peerCert != NULL) { |
8257 CERT_DestroyCertificate(ss->sec.peerCert); | 8309 CERT_DestroyCertificate(ss->sec.peerCert); |
8258 ss->sec.peerCert = NULL; | 8310 ss->sec.peerCert = NULL; |
8259 } | 8311 } |
8260 (void)ssl_MapLowLevelError(errCode); | 8312 (void)ssl_MapLowLevelError(errCode); |
8261 return SECFailure; | 8313 return SECFailure; |
8262 } | 8314 } |
8263 | 8315 |
(...skipping 1465 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
9729 ssl_GetXmitBufLock(ss); /**************************************/ | 9781 ssl_GetXmitBufLock(ss); /**************************************/ |
9730 | 9782 |
9731 /* start off a new handshake. */ | 9783 /* start off a new handshake. */ |
9732 rv = (ss->sec.isServer) ? ssl3_SendHelloRequest(ss) | 9784 rv = (ss->sec.isServer) ? ssl3_SendHelloRequest(ss) |
9733 : ssl3_SendClientHello(ss); | 9785 : ssl3_SendClientHello(ss); |
9734 | 9786 |
9735 ssl_ReleaseXmitBufLock(ss); /**************************************/ | 9787 ssl_ReleaseXmitBufLock(ss); /**************************************/ |
9736 return rv; | 9788 return rv; |
9737 } | 9789 } |
9738 | 9790 |
9791 static void | |
9792 ssl3_CleanupPredictedPeerCertificates(sslSocket *ss) { | |
9793 unsigned int i; | |
9794 | |
9795 if (!ss->ssl3.predictedCertChain) | |
9796 return; | |
9797 | |
9798 for (i = 0; ss->ssl3.predictedCertChain[i]; i++) { | |
9799 CERT_DestroyCertificate(ss->ssl3.predictedCertChain[i]); | |
9800 } | |
9801 | |
9802 PORT_Free(ss->ssl3.predictedCertChain); | |
9803 ss->ssl3.predictedCertChain = NULL; | |
9804 } | |
9805 | |
9739 /* Called from ssl_DestroySocketContents() in sslsock.c */ | 9806 /* Called from ssl_DestroySocketContents() in sslsock.c */ |
9740 void | 9807 void |
9741 ssl3_DestroySSL3Info(sslSocket *ss) | 9808 ssl3_DestroySSL3Info(sslSocket *ss) |
9742 { | 9809 { |
9743 | 9810 |
9744 if (ss->ssl3.clientCertificate != NULL) | 9811 if (ss->ssl3.clientCertificate != NULL) |
9745 CERT_DestroyCertificate(ss->ssl3.clientCertificate); | 9812 CERT_DestroyCertificate(ss->ssl3.clientCertificate); |
9746 | 9813 |
9747 if (ss->ssl3.clientPrivateKey != NULL) | 9814 if (ss->ssl3.clientPrivateKey != NULL) |
9748 SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey); | 9815 SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey); |
9749 #ifdef NSS_PLATFORM_CLIENT_AUTH | 9816 #ifdef NSS_PLATFORM_CLIENT_AUTH |
9750 if (ss->ssl3.platformClientKey) | 9817 if (ss->ssl3.platformClientKey) |
9751 ssl_FreePlatformKey(ss->ssl3.platformClientKey); | 9818 ssl_FreePlatformKey(ss->ssl3.platformClientKey); |
9752 #endif /* NSS_PLATFORM_CLIENT_AUTH */ | 9819 #endif /* NSS_PLATFORM_CLIENT_AUTH */ |
9753 | 9820 |
9754 if (ss->ssl3.peerCertArena != NULL) | 9821 if (ss->ssl3.peerCertArena != NULL) |
9755 ssl3_CleanupPeerCerts(ss); | 9822 ssl3_CleanupPeerCerts(ss); |
9756 | 9823 |
9757 if (ss->ssl3.clientCertChain != NULL) { | 9824 if (ss->ssl3.clientCertChain != NULL) { |
9758 CERT_DestroyCertificateList(ss->ssl3.clientCertChain); | 9825 CERT_DestroyCertificateList(ss->ssl3.clientCertChain); |
9759 ss->ssl3.clientCertChain = NULL; | 9826 ss->ssl3.clientCertChain = NULL; |
9760 } | 9827 } |
9761 | 9828 |
9829 if (ss->ssl3.predictedCertChain != NULL) | |
9830 ssl3_CleanupPredictedPeerCertificates(ss); | |
9831 | |
9762 /* clean up handshake */ | 9832 /* clean up handshake */ |
9763 if (ss->opt.bypassPKCS11) { | 9833 if (ss->opt.bypassPKCS11) { |
9764 SHA1_DestroyContext((SHA1Context *)ss->ssl3.hs.sha_cx, PR_FALSE); | 9834 SHA1_DestroyContext((SHA1Context *)ss->ssl3.hs.sha_cx, PR_FALSE); |
9765 MD5_DestroyContext((MD5Context *)ss->ssl3.hs.md5_cx, PR_FALSE); | 9835 MD5_DestroyContext((MD5Context *)ss->ssl3.hs.md5_cx, PR_FALSE); |
9766 } | 9836 } |
9767 if (ss->ssl3.hs.md5) { | 9837 if (ss->ssl3.hs.md5) { |
9768 PK11_DestroyContext(ss->ssl3.hs.md5,PR_TRUE); | 9838 PK11_DestroyContext(ss->ssl3.hs.md5,PR_TRUE); |
9769 } | 9839 } |
9770 if (ss->ssl3.hs.sha) { | 9840 if (ss->ssl3.hs.sha) { |
9771 PK11_DestroyContext(ss->ssl3.hs.sha,PR_TRUE); | 9841 PK11_DestroyContext(ss->ssl3.hs.sha,PR_TRUE); |
(...skipping 20 matching lines...) Expand all Loading... | |
9792 | 9862 |
9793 ss->ssl3.initialized = PR_FALSE; | 9863 ss->ssl3.initialized = PR_FALSE; |
9794 | 9864 |
9795 if (ss->ssl3.nextProto.data) { | 9865 if (ss->ssl3.nextProto.data) { |
9796 PORT_Free(ss->ssl3.nextProto.data); | 9866 PORT_Free(ss->ssl3.nextProto.data); |
9797 ss->ssl3.nextProto.data = NULL; | 9867 ss->ssl3.nextProto.data = NULL; |
9798 } | 9868 } |
9799 } | 9869 } |
9800 | 9870 |
9801 /* End of ssl3con.c */ | 9871 /* End of ssl3con.c */ |
OLD | NEW |