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

Side by Side Diff: net/third_party/nss/ssl/ssl3con.c

Issue 23545010: On Windows, prepare to generate SHA-1 signatures for TLS 1.2 client authentication. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | net/third_party/nss/ssl/sslimpl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* 2 /*
3 * SSL3 Protocol 3 * SSL3 Protocol
4 * 4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public 5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this 6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 7 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8 8
9 /* TODO(ekr): Implement HelloVerifyRequest on server side. OK for now. */ 9 /* TODO(ekr): Implement HelloVerifyRequest on server side. OK for now. */
10 10
(...skipping 3915 matching lines...) Expand 10 before | Expand all | Expand 10 after
3926 if (ss->ssl3.hs.sha == NULL) { 3926 if (ss->ssl3.hs.sha == NULL) {
3927 ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE); 3927 ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
3928 return SECFailure; 3928 return SECFailure;
3929 } 3929 }
3930 ss->ssl3.hs.hashType = handshake_hash_single; 3930 ss->ssl3.hs.hashType = handshake_hash_single;
3931 3931
3932 if (PK11_DigestBegin(ss->ssl3.hs.sha) != SECSuccess) { 3932 if (PK11_DigestBegin(ss->ssl3.hs.sha) != SECSuccess) {
3933 ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE); 3933 ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE);
3934 return SECFailure; 3934 return SECFailure;
3935 } 3935 }
3936
3937 #ifdef _WIN32
3938 /* A backup SHA-1 hash for a potential client auth signature. */
3939 if (!ss->sec.isServer) {
3940 ss->ssl3.hs.md5 = PK11_CreateDigestContext(SEC_OID_SHA1);
3941 if (ss->ssl3.hs.md5 == NULL) {
3942 PK11_DestroyContext(ss->ssl3.hs.sha, PR_TRUE);
agl 2013/08/28 15:15:08 Is destroying hs.sha needed here? It's not done in
wtc 2013/08/28 22:05:45 Done.
3943 ss->ssl3.hs.sha = NULL;
3944 ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
3945 return SECFailure;
3946 }
3947
3948 if (PK11_DigestBegin(ss->ssl3.hs.md5) != SECSuccess) {
3949 ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
3950 return SECFailure;
3951 }
3952 }
3953 #endif
3936 } else { 3954 } else {
3937 /* Both ss->ssl3.hs.md5 and ss->ssl3.hs.sha should be NULL or 3955 /* Both ss->ssl3.hs.md5 and ss->ssl3.hs.sha should be NULL or
3938 * created successfully. */ 3956 * created successfully. */
3939 ss->ssl3.hs.md5 = PK11_CreateDigestContext(SEC_OID_MD5); 3957 ss->ssl3.hs.md5 = PK11_CreateDigestContext(SEC_OID_MD5);
3940 if (ss->ssl3.hs.md5 == NULL) { 3958 if (ss->ssl3.hs.md5 == NULL) {
3941 ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE); 3959 ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
3942 return SECFailure; 3960 return SECFailure;
3943 } 3961 }
3944 ss->ssl3.hs.sha = PK11_CreateDigestContext(SEC_OID_SHA1); 3962 ss->ssl3.hs.sha = PK11_CreateDigestContext(SEC_OID_SHA1);
3945 if (ss->ssl3.hs.sha == NULL) { 3963 if (ss->ssl3.hs.sha == NULL) {
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
4036 } 4054 }
4037 return rv; 4055 return rv;
4038 } 4056 }
4039 #endif 4057 #endif
4040 if (ss->ssl3.hs.hashType == handshake_hash_single) { 4058 if (ss->ssl3.hs.hashType == handshake_hash_single) {
4041 rv = PK11_DigestOp(ss->ssl3.hs.sha, b, l); 4059 rv = PK11_DigestOp(ss->ssl3.hs.sha, b, l);
4042 if (rv != SECSuccess) { 4060 if (rv != SECSuccess) {
4043 ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE); 4061 ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE);
4044 return rv; 4062 return rv;
4045 } 4063 }
4064 if (ss->ssl3.hs.md5) {
4065 rv = PK11_DigestOp(ss->ssl3.hs.md5, b, l);
4066 if (rv != SECSuccess) {
4067 ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
4068 return rv;
4069 }
4070 }
4046 } else { 4071 } else {
Ryan Sleevi 2013/08/28 20:40:09 Does it make sense to collapse the if on line 4058
wtc 2013/08/28 22:05:45 Yes. The code can be further simplified if we only
4047 rv = PK11_DigestOp(ss->ssl3.hs.md5, b, l); 4072 rv = PK11_DigestOp(ss->ssl3.hs.md5, b, l);
4048 if (rv != SECSuccess) { 4073 if (rv != SECSuccess) {
4049 ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE); 4074 ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
4050 return rv; 4075 return rv;
4051 } 4076 }
4052 rv = PK11_DigestOp(ss->ssl3.hs.sha, b, l); 4077 rv = PK11_DigestOp(ss->ssl3.hs.sha, b, l);
4053 if (rv != SECSuccess) { 4078 if (rv != SECSuccess) {
4054 ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE); 4079 ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
4055 return rv; 4080 return rv;
4056 } 4081 }
(...skipping 727 matching lines...) Expand 10 before | Expand all | Expand 10 after
4784 rv = SECFailure; 4809 rv = SECFailure;
4785 } 4810 }
4786 if (shaStateBuf != shaStackBuf) { 4811 if (shaStateBuf != shaStackBuf) {
4787 PORT_ZFree(shaStateBuf, shaStateLen); 4812 PORT_ZFree(shaStateBuf, shaStateLen);
4788 } 4813 }
4789 } 4814 }
4790 } 4815 }
4791 return rv; 4816 return rv;
4792 } 4817 }
4793 4818
4819 static SECStatus
4820 ssl3_ComputeBackupHandshakeHashes(sslSocket * ss,
4821 SSL3Hashes * hashes) /* output goes here. */
4822 {
4823 SECStatus rv = SECSuccess;
4824
4825 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
4826 PORT_Assert( ss->ssl3.hs.hashType == handshake_hash_single );
4827
4828 rv = PK11_DigestFinal(ss->ssl3.hs.md5, hashes->u.raw, &hashes->len,
4829 sizeof(hashes->u.raw));
4830 if (rv != SECSuccess) {
4831 ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
4832 rv = SECFailure;
4833 goto loser;
4834 }
4835 hashes->hashAlg = SEC_OID_SHA1;
4836
4837 loser:
4838 PK11_DestroyContext(ss->ssl3.hs.md5, PR_TRUE);
4839 ss->ssl3.hs.md5 = NULL;
4840 return rv;
4841 }
4842
4794 /* 4843 /*
4795 * SSL 2 based implementations pass in the initial outbound buffer 4844 * SSL 2 based implementations pass in the initial outbound buffer
4796 * so that the handshake hash can contain the included information. 4845 * so that the handshake hash can contain the included information.
4797 * 4846 *
4798 * Called from ssl2_BeginClientHandshake() in sslcon.c 4847 * Called from ssl2_BeginClientHandshake() in sslcon.c
4799 */ 4848 */
4800 SECStatus 4849 SECStatus
4801 ssl3_StartHandshakeHash(sslSocket *ss, unsigned char * buf, int length) 4850 ssl3_StartHandshakeHash(sslSocket *ss, unsigned char * buf, int length)
4802 { 4851 {
4803 SECStatus rv; 4852 SECStatus rv;
(...skipping 1233 matching lines...) Expand 10 before | Expand all | Expand 10 after
6037 unsigned int len; 6086 unsigned int len;
6038 SSL3SignatureAndHashAlgorithm sigAndHash; 6087 SSL3SignatureAndHashAlgorithm sigAndHash;
6039 6088
6040 PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); 6089 PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
6041 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); 6090 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
6042 6091
6043 SSL_TRC(3, ("%d: SSL3[%d]: send certificate_verify handshake", 6092 SSL_TRC(3, ("%d: SSL3[%d]: send certificate_verify handshake",
6044 SSL_GETPID(), ss->fd)); 6093 SSL_GETPID(), ss->fd));
6045 6094
6046 ssl_GetSpecReadLock(ss); 6095 ssl_GetSpecReadLock(ss);
6047 rv = ssl3_ComputeHandshakeHashes(ss, ss->ssl3.pwSpec, &hashes, 0); 6096 if (ss->ssl3.hs.hashType == handshake_hash_single && ss->ssl3.hs.md5) {
6097 » rv = ssl3_ComputeBackupHandshakeHashes(ss, &hashes);
Ryan Sleevi 2013/08/28 20:40:09 Given that ssl3_ComputeBackupHandshakeHashes has a
wtc 2013/08/28 22:05:45 That was my original plan. I didn't do that for tw
6098 » PORT_Assert(ss->ssl3.hs.md5 == NULL);
6099 } else {
6100 » rv = ssl3_ComputeHandshakeHashes(ss, ss->ssl3.pwSpec, &hashes, 0);
6101 }
6048 ssl_ReleaseSpecReadLock(ss); 6102 ssl_ReleaseSpecReadLock(ss);
6049 if (rv != SECSuccess) { 6103 if (rv != SECSuccess) {
6050 goto done; /* err code was set by ssl3_ComputeHandshakeHashes */ 6104 goto done; /* err code was set by ssl3_ComputeHandshakeHashes */
6051 } 6105 }
6052 6106
6053 isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0); 6107 isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0);
6054 isTLS12 = (PRBool)(ss->ssl3.pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2); 6108 isTLS12 = (PRBool)(ss->ssl3.pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2);
6055 if (ss->ssl3.platformClientKey) { 6109 if (ss->ssl3.platformClientKey) {
6056 #ifdef NSS_PLATFORM_CLIENT_AUTH 6110 #ifdef NSS_PLATFORM_CLIENT_AUTH
6057 keyType = CERT_GetCertKeyType( 6111 keyType = CERT_GetCertKeyType(
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
6095 if (isTLS12) { 6149 if (isTLS12) {
6096 rv = ssl3_TLSSignatureAlgorithmForKeyType(keyType, 6150 rv = ssl3_TLSSignatureAlgorithmForKeyType(keyType,
6097 &sigAndHash.sigAlg); 6151 &sigAndHash.sigAlg);
6098 if (rv != SECSuccess) { 6152 if (rv != SECSuccess) {
6099 goto done; 6153 goto done;
6100 } 6154 }
6101 /* We always sign using the handshake hash function. It's possible that 6155 /* We always sign using the handshake hash function. It's possible that
6102 * a server could support SHA-256 as the handshake hash but not as a 6156 * a server could support SHA-256 as the handshake hash but not as a
6103 * signature hash. In that case we wouldn't be able to do client 6157 * signature hash. In that case we wouldn't be able to do client
6104 * certificates with it. The alternative is to buffer all handshake 6158 * certificates with it. The alternative is to buffer all handshake
6105 * messages. */ 6159 * messages. */
Ryan Sleevi 2013/08/28 20:40:09 This comment seems inaccurate now.
wtc 2013/08/28 22:05:45 Thanks. This is also not the best place for this c
6106 sigAndHash.hashAlg = hashes.hashAlg; 6160 sigAndHash.hashAlg = hashes.hashAlg;
6107 6161
6108 rv = ssl3_AppendSignatureAndHashAlgorithm(ss, &sigAndHash); 6162 rv = ssl3_AppendSignatureAndHashAlgorithm(ss, &sigAndHash);
6109 if (rv != SECSuccess) { 6163 if (rv != SECSuccess) {
6110 goto done; /* err set by AppendHandshake. */ 6164 goto done; /* err set by AppendHandshake. */
6111 } 6165 }
6112 } 6166 }
6113 rv = ssl3_AppendHandshakeVariable(ss, buf.data, buf.len, 2); 6167 rv = ssl3_AppendHandshakeVariable(ss, buf.data, buf.len, 2);
6114 if (rv != SECSuccess) { 6168 if (rv != SECSuccess) {
6115 goto done; /* error code set by AppendHandshake */ 6169 goto done; /* error code set by AppendHandshake */
(...skipping 871 matching lines...) Expand 10 before | Expand all | Expand 10 after
6987 if (ss->ssl3.clientCertificate != NULL) { 7041 if (ss->ssl3.clientCertificate != NULL) {
6988 CERT_DestroyCertificate(ss->ssl3.clientCertificate); 7042 CERT_DestroyCertificate(ss->ssl3.clientCertificate);
6989 ss->ssl3.clientCertificate = NULL; 7043 ss->ssl3.clientCertificate = NULL;
6990 } 7044 }
6991 if (ss->ssl3.platformClientKey) { 7045 if (ss->ssl3.platformClientKey) {
6992 ssl_FreePlatformKey(ss->ssl3.platformClientKey); 7046 ssl_FreePlatformKey(ss->ssl3.platformClientKey);
6993 ss->ssl3.platformClientKey = (PlatformKey)NULL; 7047 ss->ssl3.platformClientKey = (PlatformKey)NULL;
6994 } 7048 }
6995 goto send_no_certificate; 7049 goto send_no_certificate;
6996 } 7050 }
7051
7052 if (isTLS12 && ss->ssl3.hs.md5) {
7053 PRBool need_backup_hash = PR_FALSE;
7054 #ifdef _WIN32
7055 /* If the key is in CAPI, assume conservatively that the CAPI
7056 * service provider may be unable to sign SHA-256 hashes.
7057 * Use SHA-1 if the server supports it. */
7058 if (ss->ssl3.platformClientKey->dwKeySpec !=
7059 CERT_NCRYPT_KEY_SPEC) {
7060 /* CAPI only supports RSA and DSA signatures. Ideally we
7061 * should get the key type. Since DSA client keys are rare,
7062 * assume we have an RSA client key. */
Ryan Sleevi 2013/08/28 20:40:09 Why not also support DSA? if (algorithms.data[i]
wtc 2013/08/28 22:05:45 Originally I thought I'd need to call keyT
7063 for (i = 0; i < algorithms.len; i += 2) {
7064 if (algorithms.data[i] == tls_hash_sha1 &&
7065 algorithms.data[i + 1] == tls_sig_rsa) {
7066 need_backup_hash = PR_TRUE;
7067 break;
7068 }
7069 }
7070 }
7071 #endif /* _WIN32 */
7072 if (!need_backup_hash) {
7073 PK11_DestroyContext(ss->ssl3.hs.md5, PR_TRUE);
7074 ss->ssl3.hs.md5 = NULL;
7075 }
7076 }
6997 break; /* not an error */ 7077 break; /* not an error */
6998 } 7078 }
6999 #endif /* NSS_PLATFORM_CLIENT_AUTH */ 7079 #endif /* NSS_PLATFORM_CLIENT_AUTH */
7000 /* check what the callback function returned */ 7080 /* check what the callback function returned */
7001 if ((!ss->ssl3.clientCertificate) || (!ss->ssl3.clientPrivateKey)) { 7081 if ((!ss->ssl3.clientCertificate) || (!ss->ssl3.clientPrivateKey)) {
7002 /* we are missing either the key or cert */ 7082 /* we are missing either the key or cert */
7003 if (ss->ssl3.clientCertificate) { 7083 if (ss->ssl3.clientCertificate) {
7004 /* got a cert, but no key - free it */ 7084 /* got a cert, but no key - free it */
7005 CERT_DestroyCertificate(ss->ssl3.clientCertificate); 7085 CERT_DestroyCertificate(ss->ssl3.clientCertificate);
7006 ss->ssl3.clientCertificate = NULL; 7086 ss->ssl3.clientCertificate = NULL;
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
7220 PRBool sendClientCert; 7300 PRBool sendClientCert;
7221 7301
7222 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); 7302 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
7223 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); 7303 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
7224 7304
7225 sendClientCert = !ss->ssl3.sendEmptyCert && 7305 sendClientCert = !ss->ssl3.sendEmptyCert &&
7226 ss->ssl3.clientCertChain != NULL && 7306 ss->ssl3.clientCertChain != NULL &&
7227 (ss->ssl3.platformClientKey || 7307 (ss->ssl3.platformClientKey ||
7228 ss->ssl3.clientPrivateKey != NULL); 7308 ss->ssl3.clientPrivateKey != NULL);
7229 7309
7310 if (!sendClientCert &&
7311 ss->ssl3.hs.hashType == handshake_hash_single && ss->ssl3.hs.md5) {
7312 /* Don't need the backup handshake hash. */
7313 PK11_DestroyContext(ss->ssl3.hs.md5, PR_TRUE);
7314 ss->ssl3.hs.md5 = NULL;
7315 }
Ryan Sleevi 2013/08/28 20:40:09 I think it's very weird to do the cleanup in this
wtc 2013/08/28 22:05:45 This is to stop the backup SHA-1 hashing as soon a
7316
7230 /* We must wait for the server's certificate to be authenticated before 7317 /* We must wait for the server's certificate to be authenticated before
7231 * sending the client certificate in order to disclosing the client 7318 * sending the client certificate in order to disclosing the client
7232 * certificate to an attacker that does not have a valid cert for the 7319 * certificate to an attacker that does not have a valid cert for the
7233 * domain we are connecting to. 7320 * domain we are connecting to.
7234 * 7321 *
7235 * XXX: We should do the same for the NPN extension, but for that we 7322 * XXX: We should do the same for the NPN extension, but for that we
7236 * need an option to give the application the ability to leak the NPN 7323 * need an option to give the application the ability to leak the NPN
7237 * information to get better performance. 7324 * information to get better performance.
7238 * 7325 *
7239 * During the initial handshake on a connection, we never send/receive 7326 * During the initial handshake on a connection, we never send/receive
(...skipping 5024 matching lines...) Expand 10 before | Expand all | Expand 10 after
12264 PORT_Free(ss->ssl3.hs.recvdFragments.buf); 12351 PORT_Free(ss->ssl3.hs.recvdFragments.buf);
12265 } 12352 }
12266 } 12353 }
12267 12354
12268 ss->ssl3.initialized = PR_FALSE; 12355 ss->ssl3.initialized = PR_FALSE;
12269 12356
12270 SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE); 12357 SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE);
12271 } 12358 }
12272 12359
12273 /* End of ssl3con.c */ 12360 /* End of ssl3con.c */
OLDNEW
« no previous file with comments | « no previous file | net/third_party/nss/ssl/sslimpl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698