| 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 | 
|---|