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 7940 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7951 { | 7951 { |
7952 ssl3CertNode * c; | 7952 ssl3CertNode * c; |
7953 ssl3CertNode * lastCert = NULL; | 7953 ssl3CertNode * lastCert = NULL; |
7954 ssl3CertNode * certs = NULL; | 7954 ssl3CertNode * certs = NULL; |
7955 PRArenaPool * arena = NULL; | 7955 PRArenaPool * arena = NULL; |
7956 CERTCertificate *cert; | 7956 CERTCertificate *cert; |
7957 PRInt32 remaining = 0; | 7957 PRInt32 remaining = 0; |
7958 PRInt32 size; | 7958 PRInt32 size; |
7959 SECStatus rv; | 7959 SECStatus rv; |
7960 PRBool isServer = (PRBool)(!!ss->sec.isServer); | 7960 PRBool isServer = (PRBool)(!!ss->sec.isServer); |
7961 PRBool trusted = PR_FALSE; | |
7962 PRBool isTLS; | 7961 PRBool isTLS; |
7963 SSL3AlertDescription desc = bad_certificate; | 7962 SSL3AlertDescription desc = bad_certificate; |
7964 int errCode = SSL_ERROR_RX_MALFORMED_CERTIFICATE; | 7963 int errCode = SSL_ERROR_RX_MALFORMED_CERTIFICATE; |
7965 SECItem certItem; | 7964 SECItem certItem; |
7966 | 7965 |
7967 SSL_TRC(3, ("%d: SSL3[%d]: handle certificate handshake", | 7966 SSL_TRC(3, ("%d: SSL3[%d]: handle certificate handshake", |
7968 SSL_GETPID(), ss->fd)); | 7967 SSL_GETPID(), ss->fd)); |
7969 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); | 7968 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); |
7970 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); | 7969 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); |
7971 | 7970 |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8011 goto loser; | 8010 goto loser; |
8012 } | 8011 } |
8013 goto cert_block; | 8012 goto cert_block; |
8014 } | 8013 } |
8015 | 8014 |
8016 ss->ssl3.peerCertArena = arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); | 8015 ss->ssl3.peerCertArena = arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); |
8017 if ( arena == NULL ) { | 8016 if ( arena == NULL ) { |
8018 goto loser; /* don't send alerts on memory errors */ | 8017 goto loser; /* don't send alerts on memory errors */ |
8019 } | 8018 } |
8020 | 8019 |
8021 /* First get the peer cert. */ | 8020 if (length == 12 && ssl3_ExtensionNegotiated(ss, ssl_cached_info_xtn)) { |
8022 remaining -= 3; | 8021 /* We are dealing with a certificate_chain digest */ |
8023 if (remaining < 0) | 8022 » int i; |
8024 » goto decode_loser; | |
8025 | 8023 |
8026 size = ssl3_ConsumeHandshakeNumber(ss, 3, &b, &length); | 8024 ss->ssl3.digestReceived = PR_TRUE; |
8027 if (size <= 0) | |
8028 » goto loser;» /* fatal alert already sent by ConsumeHandshake. */ | |
8029 | 8025 |
8030 if (remaining < size) | 8026 » /* Make sure the digests match. */ |
8031 » goto decode_loser; | 8027 » if (memcmp(b + 4, ss->ssl3.certChainDigest, 8)) { |
8032 | 8028 desc = handshake_failure; |
8033 certItem.data = b; | 8029 goto alert_loser; |
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 } | 8030 } |
8071 | 8031 |
8072 » c->cert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL, | 8032 /* First get the peer cert. */ |
8073 » PR_FALSE, PR_TRUE); | 8033 if (ss->ssl3.predictedCertChain[0] == NULL) { |
8074 » if (c->cert == NULL) { | 8034 desc = handshake_failure; |
| 8035 goto alert_loser; |
| 8036 » } |
| 8037 ss->sec.peerCert = CERT_DupCertificate(ss->ssl3.predictedCertChain[0]); |
| 8038 » |
| 8039 /* Now get all of the CA certs. */ |
| 8040 » ss->ssl3.peerCertChain = NULL; |
| 8041 » for (i = 1; ss->ssl3.predictedCertChain[i] != NULL; i++) { |
| 8042 » c = PORT_ArenaNew(arena, ssl3CertNode); |
| 8043 » if (c == NULL) { |
| 8044 » goto loser;» /* don't send alerts on memory errors */ |
| 8045 » } |
| 8046 » c->cert = CERT_DupCertificate(ss->ssl3.predictedCertChain[i]); |
| 8047 » c->next = NULL; |
| 8048 » if (lastCert) { |
| 8049 » lastCert->next = c; |
| 8050 » } else { |
| 8051 » ss->ssl3.peerCertChain = c; |
| 8052 » } |
| 8053 » lastCert = c; |
| 8054 » } |
| 8055 } else { |
| 8056 /* We are dealing with a regular certificate message */ |
| 8057 ss->ssl3.digestReceived = PR_FALSE; |
| 8058 |
| 8059 /* First get the peer cert. */ |
| 8060 remaining -= 3; |
| 8061 if (remaining < 0) |
| 8062 » goto decode_loser; |
| 8063 |
| 8064 size = ssl3_ConsumeHandshakeNumber(ss, 3, &b, &length); |
| 8065 if (size <= 0) |
| 8066 » goto loser;»/* fatal alert already sent by ConsumeHandshake. */ |
| 8067 |
| 8068 if (remaining < size) |
| 8069 » goto decode_loser; |
| 8070 |
| 8071 certItem.data = b; |
| 8072 certItem.len = size; |
| 8073 b += size; |
| 8074 length -= size; |
| 8075 remaining -= size; |
| 8076 |
| 8077 ss->sec.peerCert = CERT_NewTempCertificate(ss->dbHandle, &certItem, |
| 8078 » » » » » » NULL, PR_FALSE, PR_TRUE); |
| 8079 if (ss->sec.peerCert == NULL) { |
| 8080 » /* We should report an alert if the cert was bad, but not if the |
| 8081 » * problem was just some local problem, like memory error. |
| 8082 » */ |
8075 goto ambiguous_err; | 8083 goto ambiguous_err; |
8076 » } | 8084 } |
8077 | 8085 |
8078 » if (c->cert->trust) | 8086 /* Now get all of the CA certs. */ |
8079 » trusted = PR_TRUE; | 8087 while (remaining > 0) { |
8080 | 8088 » remaining -= 3; |
8081 » c->next = NULL; | 8089 » if (remaining < 0) |
8082 » if (lastCert) { | 8090 » goto decode_loser; |
8083 » lastCert->next = c; | 8091 |
8084 » } else { | 8092 » size = ssl3_ConsumeHandshakeNumber(ss, 3, &b, &length); |
8085 » certs = c; | 8093 » if (size <= 0) |
8086 » } | 8094 » goto loser; /* fatal alert already sent by ConsumeHandshake. */ |
8087 » lastCert = c; | 8095 |
| 8096 » if (remaining < size) |
| 8097 » goto decode_loser; |
| 8098 |
| 8099 » certItem.data = b; |
| 8100 » certItem.len = size; |
| 8101 » b += size; |
| 8102 » length -= size; |
| 8103 » remaining -= size; |
| 8104 » |
| 8105 » c = PORT_ArenaNew(arena, ssl3CertNode); |
| 8106 » if (c == NULL) { |
| 8107 » goto loser;» /* don't send alerts on memory errors */ |
| 8108 » } |
| 8109 |
| 8110 » c->cert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL, |
| 8111 » » » » » PR_FALSE, PR_TRUE); |
| 8112 » if (c->cert == NULL) { |
| 8113 » goto ambiguous_err; |
| 8114 » } |
| 8115 |
| 8116 » c->next = NULL; |
| 8117 » if (lastCert) { |
| 8118 » lastCert->next = c; |
| 8119 » } else { |
| 8120 » certs = c; |
| 8121 » } |
| 8122 » lastCert = c; |
| 8123 } |
| 8124 |
| 8125 if (remaining != 0) |
| 8126 goto decode_loser; |
8088 } | 8127 } |
8089 | 8128 |
8090 if (remaining != 0) | |
8091 goto decode_loser; | |
8092 | |
8093 SECKEY_UpdateCertPQG(ss->sec.peerCert); | 8129 SECKEY_UpdateCertPQG(ss->sec.peerCert); |
8094 | 8130 |
8095 /* | 8131 /* |
8096 * Ask caller-supplied callback function to validate cert chain. | 8132 * Ask caller-supplied callback function to validate cert chain. |
8097 */ | 8133 */ |
8098 rv = (SECStatus)(*ss->authCertificate)(ss->authCertificateArg, ss->fd, | 8134 rv = (SECStatus)(*ss->authCertificate)(ss->authCertificateArg, ss->fd, |
8099 PR_TRUE, isServer); | 8135 PR_TRUE, isServer); |
8100 if (rv) { | 8136 if (rv) { |
8101 errCode = PORT_GetError(); | 8137 errCode = PORT_GetError(); |
8102 if (!ss->handleBadCert) { | 8138 if (!ss->handleBadCert) { |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8243 | 8279 |
8244 goto alert_loser; | 8280 goto alert_loser; |
8245 | 8281 |
8246 decode_loser: | 8282 decode_loser: |
8247 desc = isTLS ? decode_error : bad_certificate; | 8283 desc = isTLS ? decode_error : bad_certificate; |
8248 | 8284 |
8249 alert_loser: | 8285 alert_loser: |
8250 (void)SSL3_SendAlert(ss, alert_fatal, desc); | 8286 (void)SSL3_SendAlert(ss, alert_fatal, desc); |
8251 | 8287 |
8252 loser: | 8288 loser: |
8253 ss->ssl3.peerCertChain = certs; certs = NULL; arena = NULL; | 8289 if (ss->ssl3.peerCertChain == NULL) { |
| 8290 ss->ssl3.peerCertChain = certs; certs = NULL; arena = NULL; |
| 8291 } |
| 8292 PORT_Assert(certs == NULL); |
8254 ssl3_CleanupPeerCerts(ss); | 8293 ssl3_CleanupPeerCerts(ss); |
8255 | 8294 |
8256 if (ss->sec.peerCert != NULL) { | 8295 if (ss->sec.peerCert != NULL) { |
8257 CERT_DestroyCertificate(ss->sec.peerCert); | 8296 CERT_DestroyCertificate(ss->sec.peerCert); |
8258 ss->sec.peerCert = NULL; | 8297 ss->sec.peerCert = NULL; |
8259 } | 8298 } |
8260 (void)ssl_MapLowLevelError(errCode); | 8299 (void)ssl_MapLowLevelError(errCode); |
8261 return SECFailure; | 8300 return SECFailure; |
8262 } | 8301 } |
8263 | 8302 |
(...skipping 1465 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9729 ssl_GetXmitBufLock(ss); /**************************************/ | 9768 ssl_GetXmitBufLock(ss); /**************************************/ |
9730 | 9769 |
9731 /* start off a new handshake. */ | 9770 /* start off a new handshake. */ |
9732 rv = (ss->sec.isServer) ? ssl3_SendHelloRequest(ss) | 9771 rv = (ss->sec.isServer) ? ssl3_SendHelloRequest(ss) |
9733 : ssl3_SendClientHello(ss); | 9772 : ssl3_SendClientHello(ss); |
9734 | 9773 |
9735 ssl_ReleaseXmitBufLock(ss); /**************************************/ | 9774 ssl_ReleaseXmitBufLock(ss); /**************************************/ |
9736 return rv; | 9775 return rv; |
9737 } | 9776 } |
9738 | 9777 |
| 9778 static void |
| 9779 ssl3_CleanupPredictedPeerCertificates(sslSocket *ss) { |
| 9780 unsigned int i; |
| 9781 |
| 9782 if (!ss->ssl3.predictedCertChain) |
| 9783 return; |
| 9784 |
| 9785 for (i = 0; ss->ssl3.predictedCertChain[i]; i++) { |
| 9786 CERT_DestroyCertificate(ss->ssl3.predictedCertChain[i]); |
| 9787 } |
| 9788 |
| 9789 PORT_Free(ss->ssl3.predictedCertChain); |
| 9790 ss->ssl3.predictedCertChain = NULL; |
| 9791 } |
| 9792 |
9739 /* Called from ssl_DestroySocketContents() in sslsock.c */ | 9793 /* Called from ssl_DestroySocketContents() in sslsock.c */ |
9740 void | 9794 void |
9741 ssl3_DestroySSL3Info(sslSocket *ss) | 9795 ssl3_DestroySSL3Info(sslSocket *ss) |
9742 { | 9796 { |
9743 | 9797 |
9744 if (ss->ssl3.clientCertificate != NULL) | 9798 if (ss->ssl3.clientCertificate != NULL) |
9745 CERT_DestroyCertificate(ss->ssl3.clientCertificate); | 9799 CERT_DestroyCertificate(ss->ssl3.clientCertificate); |
9746 | 9800 |
9747 if (ss->ssl3.clientPrivateKey != NULL) | 9801 if (ss->ssl3.clientPrivateKey != NULL) |
9748 SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey); | 9802 SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey); |
9749 #ifdef NSS_PLATFORM_CLIENT_AUTH | 9803 #ifdef NSS_PLATFORM_CLIENT_AUTH |
9750 if (ss->ssl3.platformClientKey) | 9804 if (ss->ssl3.platformClientKey) |
9751 ssl_FreePlatformKey(ss->ssl3.platformClientKey); | 9805 ssl_FreePlatformKey(ss->ssl3.platformClientKey); |
9752 #endif /* NSS_PLATFORM_CLIENT_AUTH */ | 9806 #endif /* NSS_PLATFORM_CLIENT_AUTH */ |
9753 | 9807 |
9754 if (ss->ssl3.peerCertArena != NULL) | 9808 if (ss->ssl3.peerCertArena != NULL) |
9755 ssl3_CleanupPeerCerts(ss); | 9809 ssl3_CleanupPeerCerts(ss); |
9756 | 9810 |
9757 if (ss->ssl3.clientCertChain != NULL) { | 9811 if (ss->ssl3.clientCertChain != NULL) { |
9758 CERT_DestroyCertificateList(ss->ssl3.clientCertChain); | 9812 CERT_DestroyCertificateList(ss->ssl3.clientCertChain); |
9759 ss->ssl3.clientCertChain = NULL; | 9813 ss->ssl3.clientCertChain = NULL; |
9760 } | 9814 } |
9761 | 9815 |
| 9816 if (ss->ssl3.predictedCertChain != NULL) |
| 9817 ssl3_CleanupPredictedPeerCertificates(ss); |
| 9818 |
9762 /* clean up handshake */ | 9819 /* clean up handshake */ |
9763 if (ss->opt.bypassPKCS11) { | 9820 if (ss->opt.bypassPKCS11) { |
9764 SHA1_DestroyContext((SHA1Context *)ss->ssl3.hs.sha_cx, PR_FALSE); | 9821 SHA1_DestroyContext((SHA1Context *)ss->ssl3.hs.sha_cx, PR_FALSE); |
9765 MD5_DestroyContext((MD5Context *)ss->ssl3.hs.md5_cx, PR_FALSE); | 9822 MD5_DestroyContext((MD5Context *)ss->ssl3.hs.md5_cx, PR_FALSE); |
9766 } | 9823 } |
9767 if (ss->ssl3.hs.md5) { | 9824 if (ss->ssl3.hs.md5) { |
9768 PK11_DestroyContext(ss->ssl3.hs.md5,PR_TRUE); | 9825 PK11_DestroyContext(ss->ssl3.hs.md5,PR_TRUE); |
9769 } | 9826 } |
9770 if (ss->ssl3.hs.sha) { | 9827 if (ss->ssl3.hs.sha) { |
9771 PK11_DestroyContext(ss->ssl3.hs.sha,PR_TRUE); | 9828 PK11_DestroyContext(ss->ssl3.hs.sha,PR_TRUE); |
(...skipping 20 matching lines...) Expand all Loading... |
9792 | 9849 |
9793 ss->ssl3.initialized = PR_FALSE; | 9850 ss->ssl3.initialized = PR_FALSE; |
9794 | 9851 |
9795 if (ss->ssl3.nextProto.data) { | 9852 if (ss->ssl3.nextProto.data) { |
9796 PORT_Free(ss->ssl3.nextProto.data); | 9853 PORT_Free(ss->ssl3.nextProto.data); |
9797 ss->ssl3.nextProto.data = NULL; | 9854 ss->ssl3.nextProto.data = NULL; |
9798 } | 9855 } |
9799 } | 9856 } |
9800 | 9857 |
9801 /* End of ssl3con.c */ | 9858 /* End of ssl3con.c */ |
OLD | NEW |