Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(88)

Unified Diff: net/third_party/nss/ssl/ssl3con.c

Issue 23880004: Merge 220595 "On Windows, prefer to generate SHA-1 signatures fo..." (Closed) Base URL: svn://svn.chromium.org/chrome/branches/1599/src/
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/third_party/nss/patches/tls12backuphash.patch ('k') | net/third_party/nss/ssl/sslimpl.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/third_party/nss/ssl/ssl3con.c
===================================================================
--- net/third_party/nss/ssl/ssl3con.c (revision 221205)
+++ net/third_party/nss/ssl/ssl3con.c (working copy)
@@ -3674,6 +3674,22 @@
ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE);
return SECFailure;
}
+
+#ifdef _WIN32
+ /* A backup SHA-1 hash for a potential client auth signature. */
+ if (!ss->sec.isServer) {
+ ss->ssl3.hs.md5 = PK11_CreateDigestContext(SEC_OID_SHA1);
+ if (ss->ssl3.hs.md5 == NULL) {
+ ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
+ return SECFailure;
+ }
+
+ if (PK11_DigestBegin(ss->ssl3.hs.md5) != SECSuccess) {
+ ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
+ return SECFailure;
+ }
+ }
+#endif
} else {
/* Both ss->ssl3.hs.md5 and ss->ssl3.hs.sha should be NULL or
* created successfully. */
@@ -3784,6 +3800,13 @@
ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE);
return rv;
}
+ if (ss->ssl3.hs.md5) {
+ rv = PK11_DigestOp(ss->ssl3.hs.md5, b, l);
+ if (rv != SECSuccess) {
+ ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
+ return rv;
+ }
+ }
} else {
rv = PK11_DigestOp(ss->ssl3.hs.md5, b, l);
if (rv != SECSuccess) {
@@ -4532,6 +4555,30 @@
return rv;
}
+static SECStatus
+ssl3_ComputeBackupHandshakeHashes(sslSocket * ss,
+ SSL3Hashes * hashes) /* output goes here. */
+{
+ SECStatus rv = SECSuccess;
+
+ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
+ PORT_Assert( ss->ssl3.hs.hashType == handshake_hash_single );
+
+ rv = PK11_DigestFinal(ss->ssl3.hs.md5, hashes->u.raw, &hashes->len,
+ sizeof(hashes->u.raw));
+ if (rv != SECSuccess) {
+ ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
+ rv = SECFailure;
+ goto loser;
+ }
+ hashes->hashAlg = SEC_OID_SHA1;
+
+loser:
+ PK11_DestroyContext(ss->ssl3.hs.md5, PR_TRUE);
+ ss->ssl3.hs.md5 = NULL;
+ return rv;
+}
+
/*
* SSL 2 based implementations pass in the initial outbound buffer
* so that the handshake hash can contain the included information.
@@ -5781,7 +5828,17 @@
SSL_GETPID(), ss->fd));
ssl_GetSpecReadLock(ss);
- rv = ssl3_ComputeHandshakeHashes(ss, ss->ssl3.pwSpec, &hashes, 0);
+ /* In TLS 1.2, ssl3_ComputeHandshakeHashes always uses the handshake hash
+ * function (SHA-256). If the server or the client does not support SHA-256
+ * as a signature hash, we can either maintain a backup SHA-1 handshake
+ * hash or buffer all handshake messages.
+ */
+ if (ss->ssl3.hs.hashType == handshake_hash_single && ss->ssl3.hs.md5) {
+ rv = ssl3_ComputeBackupHandshakeHashes(ss, &hashes);
+ PORT_Assert(ss->ssl3.hs.md5 == NULL);
+ } else {
+ rv = ssl3_ComputeHandshakeHashes(ss, ss->ssl3.pwSpec, &hashes, 0);
+ }
ssl_ReleaseSpecReadLock(ss);
if (rv != SECSuccess) {
goto done; /* err code was set by ssl3_ComputeHandshakeHashes */
@@ -5835,11 +5892,6 @@
if (rv != SECSuccess) {
goto done;
}
- /* We always sign using the handshake hash function. It's possible that
- * a server could support SHA-256 as the handshake hash but not as a
- * signature hash. In that case we wouldn't be able to do client
- * certificates with it. The alternative is to buffer all handshake
- * messages. */
sigAndHash.hashAlg = hashes.hashAlg;
rv = ssl3_AppendSignatureAndHashAlgorithm(ss, &sigAndHash);
@@ -6731,6 +6783,31 @@
}
goto send_no_certificate;
}
+
+ if (isTLS12 && ss->ssl3.hs.md5) {
+ PRBool need_backup_hash = PR_FALSE;
+#ifdef _WIN32
+ /* If the key is in CAPI, assume conservatively that the CAPI
+ * service provider may be unable to sign SHA-256 hashes.
+ * Use SHA-1 if the server supports it. */
+ if (ss->ssl3.platformClientKey->dwKeySpec !=
+ CERT_NCRYPT_KEY_SPEC) {
+ for (i = 0; i < algorithms.len; i += 2) {
+ /* CAPI only supports RSA and DSA signatures. */
+ if (algorithms.data[i] == tls_hash_sha1 &&
+ (algorithms.data[i+1] == tls_sig_rsa ||
+ algorithms.data[i+1] == tls_sig_dsa)) {
+ need_backup_hash = PR_TRUE;
+ break;
+ }
+ }
+ }
+#endif /* _WIN32 */
+ if (!need_backup_hash) {
+ PK11_DestroyContext(ss->ssl3.hs.md5, PR_TRUE);
+ ss->ssl3.hs.md5 = NULL;
+ }
+ }
break; /* not an error */
}
#endif /* NSS_PLATFORM_CLIENT_AUTH */
@@ -6964,6 +7041,13 @@
(ss->ssl3.platformClientKey ||
ss->ssl3.clientPrivateKey != NULL);
+ if (!sendClientCert &&
+ ss->ssl3.hs.hashType == handshake_hash_single && ss->ssl3.hs.md5) {
+ /* Don't need the backup handshake hash. */
+ PK11_DestroyContext(ss->ssl3.hs.md5, PR_TRUE);
+ ss->ssl3.hs.md5 = NULL;
+ }
+
/* We must wait for the server's certificate to be authenticated before
* sending the client certificate in order to disclosing the client
* certificate to an attacker that does not have a valid cert for the
« no previous file with comments | « net/third_party/nss/patches/tls12backuphash.patch ('k') | net/third_party/nss/ssl/sslimpl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698