Index: net/third_party/nss/ssl/ssl3con.c |
=================================================================== |
--- net/third_party/nss/ssl/ssl3con.c (revision 88612) |
+++ net/third_party/nss/ssl/ssl3con.c (working copy) |
@@ -8018,78 +8018,113 @@ |
goto loser; /* don't send alerts on memory errors */ |
} |
- /* First get the peer cert. */ |
- remaining -= 3; |
- if (remaining < 0) |
- goto decode_loser; |
+ if (length == 12 && ssl3_ExtensionNegotiated(ss, ssl_cached_info_xtn)) { |
wtc
2011/06/17 22:57:09
BUG: you need to check that the received certifica
rkn
2011/06/20 21:21:09
Done.
|
+ /* We are dealing with a certificate_chain digest */ |
- size = ssl3_ConsumeHandshakeNumber(ss, 3, &b, &length); |
- if (size <= 0) |
- goto loser; /* fatal alert already sent by ConsumeHandshake. */ |
- |
- if (remaining < size) |
- goto decode_loser; |
- |
- certItem.data = b; |
- certItem.len = size; |
- b += size; |
- length -= size; |
- remaining -= size; |
- |
- ss->sec.peerCert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL, |
- PR_FALSE, PR_TRUE); |
- if (ss->sec.peerCert == NULL) { |
- /* We should report an alert if the cert was bad, but not if the |
- * problem was just some local problem, like memory error. |
- */ |
- goto ambiguous_err; |
- } |
- |
- /* Now get all of the CA certs. */ |
- while (remaining > 0) { |
- remaining -= 3; |
- if (remaining < 0) |
+ /* First get the peer cert. */ |
+ if (ss->ssl3.predictedCertChain[0] == NULL) { |
+ desc = handshake_failure; |
+ goto alert_loser; |
+ } |
+ ss->sec.peerCert = CERT_DupCertificate(ss->ssl3.predictedCertChain[0]); |
+ |
+ /* Now get all of the CA certs. */ |
+ ssl3CertNode *certNodeCurrent; |
wtc
2011/06/17 22:57:09
Declare the variable at the beginning of the block
rkn
2011/06/20 21:21:09
Done (It is ok to put the declaration after the co
|
+ ss->ssl3.peerCertChain = certNodeCurrent |
+ = PORT_ArenaNew(arena, ssl3CertNode); |
+ if (certNodeCurrent == NULL) { |
+ goto loser; /* don't send alerts on memory errors */ |
+ } |
+ certNodeCurrent->cert = |
+ CERT_DupCertificate(ss->ssl3.predictedCertChain[0]); |
wtc
2011/06/17 22:57:09
ss->ssl3.predictedCertChain[0] should not be added
rkn
2011/06/20 21:21:09
Done.
|
+ int i = 1; |
+ while (ss->ssl3.predictedCertChain[i] != NULL) { |
+ certNodeCurrent->next = PORT_ArenaNew(arena, ssl3CertNode); |
+ if (certNodeCurrent->next == NULL) { |
+ goto loser; /* don't send alerts on memory errors */ |
+ } |
+ certNodeCurrent = certNodeCurrent->next; |
+ certNodeCurrent->cert = |
+ CERT_DupCertificate(ss->ssl3.predictedCertChain[i]); |
+ i++; |
+ } |
+ certNodeCurrent->next = NULL; |
+ } else { |
+ /* We are dealing with a regular certificate message */ |
+ |
+ /* First get the peer cert. */ |
+ remaining -= 3; |
+ if (remaining < 0) |
goto decode_loser; |
- |
- size = ssl3_ConsumeHandshakeNumber(ss, 3, &b, &length); |
- if (size <= 0) |
+ |
+ size = ssl3_ConsumeHandshakeNumber(ss, 3, &b, &length); |
+ if (size <= 0) |
goto loser; /* fatal alert already sent by ConsumeHandshake. */ |
- |
- if (remaining < size) |
+ |
+ if (remaining < size) |
goto decode_loser; |
- |
- certItem.data = b; |
- certItem.len = size; |
- b += size; |
- length -= size; |
- remaining -= size; |
- |
- c = PORT_ArenaNew(arena, ssl3CertNode); |
- if (c == NULL) { |
- goto loser; /* don't send alerts on memory errors */ |
- } |
- |
- c->cert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL, |
- PR_FALSE, PR_TRUE); |
- if (c->cert == NULL) { |
+ |
+ certItem.data = b; |
+ certItem.len = size; |
+ b += size; |
+ length -= size; |
+ remaining -= size; |
+ |
+ ss->sec.peerCert = CERT_NewTempCertificate(ss->dbHandle, &certItem, |
+ NULL, PR_FALSE, PR_TRUE); |
+ if (ss->sec.peerCert == NULL) { |
+ /* We should report an alert if the cert was bad, but not if the |
+ * problem was just some local problem, like memory error. |
+ */ |
goto ambiguous_err; |
- } |
- |
- if (c->cert->trust) |
- trusted = PR_TRUE; |
- |
- c->next = NULL; |
- if (lastCert) { |
- lastCert->next = c; |
- } else { |
- certs = c; |
- } |
- lastCert = c; |
+ } |
+ |
+ /* Now get all of the CA certs. */ |
+ while (remaining > 0) { |
+ remaining -= 3; |
+ if (remaining < 0) |
+ goto decode_loser; |
+ |
+ size = ssl3_ConsumeHandshakeNumber(ss, 3, &b, &length); |
+ if (size <= 0) |
+ goto loser; /* fatal alert already sent by ConsumeHandshake. */ |
+ |
+ if (remaining < size) |
+ goto decode_loser; |
+ |
+ certItem.data = b; |
+ certItem.len = size; |
+ b += size; |
+ length -= size; |
+ remaining -= size; |
+ |
+ c = PORT_ArenaNew(arena, ssl3CertNode); |
+ if (c == NULL) { |
+ goto loser; /* don't send alerts on memory errors */ |
+ } |
+ |
+ c->cert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL, |
+ PR_FALSE, PR_TRUE); |
+ if (c->cert == NULL) { |
+ goto ambiguous_err; |
+ } |
+ |
+ if (c->cert->trust) |
+ trusted = PR_TRUE; |
+ |
+ c->next = NULL; |
+ if (lastCert) { |
+ lastCert->next = c; |
+ } else { |
+ certs = c; |
+ } |
+ lastCert = c; |
+ } |
+ |
+ if (remaining != 0) |
+ goto decode_loser; |
} |
- if (remaining != 0) |
- goto decode_loser; |
- |
SECKEY_UpdateCertPQG(ss->sec.peerCert); |
/* |
@@ -9736,6 +9771,21 @@ |
return rv; |
} |
+static void |
+ssl3_CleanupPredictedPeerCertificates(sslSocket *ss) { |
+ unsigned int i; |
+ |
+ if (!ss->ssl3.predictedCertChain) |
+ return; |
+ |
+ for (i = 0; ss->ssl3.predictedCertChain[i]; i++) { |
+ CERT_DestroyCertificate(ss->ssl3.predictedCertChain[i]); |
+ } |
+ |
+ PORT_Free(ss->ssl3.predictedCertChain); |
+ ss->ssl3.predictedCertChain = NULL; |
+} |
+ |
/* Called from ssl_DestroySocketContents() in sslsock.c */ |
void |
ssl3_DestroySSL3Info(sslSocket *ss) |
@@ -9759,6 +9809,9 @@ |
ss->ssl3.clientCertChain = NULL; |
} |
+ if (ss->ssl3.predictedCertChain != NULL) |
+ ssl3_CleanupPredictedPeerCertificates(ss); |
+ |
/* clean up handshake */ |
if (ss->opt.bypassPKCS11) { |
SHA1_DestroyContext((SHA1Context *)ss->ssl3.hs.sha_cx, PR_FALSE); |