Chromium Code Reviews| 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); |