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

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: Check whether the CAPI service provider supports SHA-256. 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 | « net/third_party/nss/patches/tls12backuphash.patch ('k') | 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 ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
3943 return SECFailure;
3944 }
3945
3946 if (PK11_DigestBegin(ss->ssl3.hs.md5) != SECSuccess) {
3947 ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
3948 return SECFailure;
3949 }
3950 }
3951 #endif
3936 } else { 3952 } else {
3937 /* Both ss->ssl3.hs.md5 and ss->ssl3.hs.sha should be NULL or 3953 /* Both ss->ssl3.hs.md5 and ss->ssl3.hs.sha should be NULL or
3938 * created successfully. */ 3954 * created successfully. */
3939 ss->ssl3.hs.md5 = PK11_CreateDigestContext(SEC_OID_MD5); 3955 ss->ssl3.hs.md5 = PK11_CreateDigestContext(SEC_OID_MD5);
3940 if (ss->ssl3.hs.md5 == NULL) { 3956 if (ss->ssl3.hs.md5 == NULL) {
3941 ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE); 3957 ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
3942 return SECFailure; 3958 return SECFailure;
3943 } 3959 }
3944 ss->ssl3.hs.sha = PK11_CreateDigestContext(SEC_OID_SHA1); 3960 ss->ssl3.hs.sha = PK11_CreateDigestContext(SEC_OID_SHA1);
3945 if (ss->ssl3.hs.sha == NULL) { 3961 if (ss->ssl3.hs.sha == NULL) {
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
4036 } 4052 }
4037 return rv; 4053 return rv;
4038 } 4054 }
4039 #endif 4055 #endif
4040 if (ss->ssl3.hs.hashType == handshake_hash_single) { 4056 if (ss->ssl3.hs.hashType == handshake_hash_single) {
4041 rv = PK11_DigestOp(ss->ssl3.hs.sha, b, l); 4057 rv = PK11_DigestOp(ss->ssl3.hs.sha, b, l);
4042 if (rv != SECSuccess) { 4058 if (rv != SECSuccess) {
4043 ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE); 4059 ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE);
4044 return rv; 4060 return rv;
4045 } 4061 }
4062 if (ss->ssl3.hs.md5) {
4063 rv = PK11_DigestOp(ss->ssl3.hs.md5, b, l);
4064 if (rv != SECSuccess) {
4065 ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
4066 return rv;
4067 }
4068 }
4046 } else { 4069 } else {
4047 rv = PK11_DigestOp(ss->ssl3.hs.md5, b, l); 4070 rv = PK11_DigestOp(ss->ssl3.hs.md5, b, l);
4048 if (rv != SECSuccess) { 4071 if (rv != SECSuccess) {
4049 ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE); 4072 ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
4050 return rv; 4073 return rv;
4051 } 4074 }
4052 rv = PK11_DigestOp(ss->ssl3.hs.sha, b, l); 4075 rv = PK11_DigestOp(ss->ssl3.hs.sha, b, l);
4053 if (rv != SECSuccess) { 4076 if (rv != SECSuccess) {
4054 ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE); 4077 ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
4055 return rv; 4078 return rv;
(...skipping 728 matching lines...) Expand 10 before | Expand all | Expand 10 after
4784 rv = SECFailure; 4807 rv = SECFailure;
4785 } 4808 }
4786 if (shaStateBuf != shaStackBuf) { 4809 if (shaStateBuf != shaStackBuf) {
4787 PORT_ZFree(shaStateBuf, shaStateLen); 4810 PORT_ZFree(shaStateBuf, shaStateLen);
4788 } 4811 }
4789 } 4812 }
4790 } 4813 }
4791 return rv; 4814 return rv;
4792 } 4815 }
4793 4816
4817 static SECStatus
4818 ssl3_ComputeBackupHandshakeHashes(sslSocket * ss,
4819 SSL3Hashes * hashes) /* output goes here. */
4820 {
4821 SECStatus rv = SECSuccess;
4822
4823 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
4824 PORT_Assert( ss->ssl3.hs.hashType == handshake_hash_single );
4825
4826 rv = PK11_DigestFinal(ss->ssl3.hs.md5, hashes->u.raw, &hashes->len,
4827 sizeof(hashes->u.raw));
4828 if (rv != SECSuccess) {
4829 ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
4830 rv = SECFailure;
4831 goto loser;
4832 }
4833 hashes->hashAlg = SEC_OID_SHA1;
4834
4835 loser:
4836 PK11_DestroyContext(ss->ssl3.hs.md5, PR_TRUE);
4837 ss->ssl3.hs.md5 = NULL;
4838 return rv;
4839 }
4840
4794 /* 4841 /*
4795 * SSL 2 based implementations pass in the initial outbound buffer 4842 * SSL 2 based implementations pass in the initial outbound buffer
4796 * so that the handshake hash can contain the included information. 4843 * so that the handshake hash can contain the included information.
4797 * 4844 *
4798 * Called from ssl2_BeginClientHandshake() in sslcon.c 4845 * Called from ssl2_BeginClientHandshake() in sslcon.c
4799 */ 4846 */
4800 SECStatus 4847 SECStatus
4801 ssl3_StartHandshakeHash(sslSocket *ss, unsigned char * buf, int length) 4848 ssl3_StartHandshakeHash(sslSocket *ss, unsigned char * buf, int length)
4802 { 4849 {
4803 SECStatus rv; 4850 SECStatus rv;
(...skipping 1233 matching lines...) Expand 10 before | Expand all | Expand 10 after
6037 unsigned int len; 6084 unsigned int len;
6038 SSL3SignatureAndHashAlgorithm sigAndHash; 6085 SSL3SignatureAndHashAlgorithm sigAndHash;
6039 6086
6040 PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); 6087 PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
6041 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); 6088 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
6042 6089
6043 SSL_TRC(3, ("%d: SSL3[%d]: send certificate_verify handshake", 6090 SSL_TRC(3, ("%d: SSL3[%d]: send certificate_verify handshake",
6044 SSL_GETPID(), ss->fd)); 6091 SSL_GETPID(), ss->fd));
6045 6092
6046 ssl_GetSpecReadLock(ss); 6093 ssl_GetSpecReadLock(ss);
6047 rv = ssl3_ComputeHandshakeHashes(ss, ss->ssl3.pwSpec, &hashes, 0); 6094 /* In TLS 1.2, ssl3_ComputeHandshakeHashes always uses the handshake hash
6095 * function (SHA-256). If the server or the client does not support SHA-256
6096 * as a signature hash, we can either maintain a backup SHA-1 handshake
6097 * hash or buffer all handshake messages.
6098 */
6099 if (ss->ssl3.hs.hashType == handshake_hash_single && ss->ssl3.hs.md5) {
6100 » rv = ssl3_ComputeBackupHandshakeHashes(ss, &hashes);
agl 2013/08/28 22:16:03 (doesn't matter): here you are using tabs rather t
6101 » PORT_Assert(ss->ssl3.hs.md5 == NULL);
6102 } else {
6103 » rv = ssl3_ComputeHandshakeHashes(ss, ss->ssl3.pwSpec, &hashes, 0);
6104 }
6048 ssl_ReleaseSpecReadLock(ss); 6105 ssl_ReleaseSpecReadLock(ss);
6049 if (rv != SECSuccess) { 6106 if (rv != SECSuccess) {
6050 goto done; /* err code was set by ssl3_ComputeHandshakeHashes */ 6107 goto done; /* err code was set by ssl3_ComputeHandshakeHashes */
6051 } 6108 }
6052 6109
6053 isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0); 6110 isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0);
6054 isTLS12 = (PRBool)(ss->ssl3.pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2); 6111 isTLS12 = (PRBool)(ss->ssl3.pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2);
6055 if (ss->ssl3.platformClientKey) { 6112 if (ss->ssl3.platformClientKey) {
6056 #ifdef NSS_PLATFORM_CLIENT_AUTH 6113 #ifdef NSS_PLATFORM_CLIENT_AUTH
6057 keyType = CERT_GetCertKeyType( 6114 keyType = CERT_GetCertKeyType(
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
6091 rv = ssl3_AppendHandshakeHeader(ss, certificate_verify, len); 6148 rv = ssl3_AppendHandshakeHeader(ss, certificate_verify, len);
6092 if (rv != SECSuccess) { 6149 if (rv != SECSuccess) {
6093 goto done; /* error code set by AppendHandshake */ 6150 goto done; /* error code set by AppendHandshake */
6094 } 6151 }
6095 if (isTLS12) { 6152 if (isTLS12) {
6096 rv = ssl3_TLSSignatureAlgorithmForKeyType(keyType, 6153 rv = ssl3_TLSSignatureAlgorithmForKeyType(keyType,
6097 &sigAndHash.sigAlg); 6154 &sigAndHash.sigAlg);
6098 if (rv != SECSuccess) { 6155 if (rv != SECSuccess) {
6099 goto done; 6156 goto done;
6100 } 6157 }
6101 /* 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
6103 * signature hash. In that case we wouldn't be able to do client
6104 * certificates with it. The alternative is to buffer all handshake
6105 * messages. */
6106 sigAndHash.hashAlg = hashes.hashAlg; 6158 sigAndHash.hashAlg = hashes.hashAlg;
6107 6159
6108 rv = ssl3_AppendSignatureAndHashAlgorithm(ss, &sigAndHash); 6160 rv = ssl3_AppendSignatureAndHashAlgorithm(ss, &sigAndHash);
6109 if (rv != SECSuccess) { 6161 if (rv != SECSuccess) {
6110 goto done; /* err set by AppendHandshake. */ 6162 goto done; /* err set by AppendHandshake. */
6111 } 6163 }
6112 } 6164 }
6113 rv = ssl3_AppendHandshakeVariable(ss, buf.data, buf.len, 2); 6165 rv = ssl3_AppendHandshakeVariable(ss, buf.data, buf.len, 2);
6114 if (rv != SECSuccess) { 6166 if (rv != SECSuccess) {
6115 goto done; /* error code set by AppendHandshake */ 6167 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) { 7039 if (ss->ssl3.clientCertificate != NULL) {
6988 CERT_DestroyCertificate(ss->ssl3.clientCertificate); 7040 CERT_DestroyCertificate(ss->ssl3.clientCertificate);
6989 ss->ssl3.clientCertificate = NULL; 7041 ss->ssl3.clientCertificate = NULL;
6990 } 7042 }
6991 if (ss->ssl3.platformClientKey) { 7043 if (ss->ssl3.platformClientKey) {
6992 ssl_FreePlatformKey(ss->ssl3.platformClientKey); 7044 ssl_FreePlatformKey(ss->ssl3.platformClientKey);
6993 ss->ssl3.platformClientKey = (PlatformKey)NULL; 7045 ss->ssl3.platformClientKey = (PlatformKey)NULL;
6994 } 7046 }
6995 goto send_no_certificate; 7047 goto send_no_certificate;
6996 } 7048 }
7049
7050 if (isTLS12 && ss->ssl3.hs.md5) {
7051 PRBool need_backup_hash = PR_FALSE;
7052 #ifdef _WIN32
7053 /* If the key is in CAPI, check if the CAPI service provider
7054 * supports SHA-256. Use SHA-1 if it doesn't. */
7055 if (ss->ssl3.platformClientKey->dwKeySpec !=
7056 CERT_NCRYPT_KEY_SPEC) {
7057 HCRYPTPROV prov = ss->ssl3.platformClientKey->hCryptProv;
7058 PROV_ENUMALGS alg_info;
7059 DWORD size = sizeof(alg_info);
7060 DWORD flags = CRYPT_FIRST;
7061 need_backup_hash = PR_TRUE;
7062 while (CryptGetProvParam(prov, PP_ENUMALGS,
wtc 2013/08/28 22:05:45 It may be cheaper to check SHA-256 support by tryi
7063 (BYTE *)&alg_info, &size, flags)) {
7064 if (alg_info.aiAlgid == CALG_SHA_256) {
7065 need_backup_hash = PR_FALSE;
7066 break;
7067 }
7068 size = sizeof(alg_info);
7069 flags = CRYPT_NEXT;
7070 }
7071 }
7072 #endif /* _WIN32 */
7073 if (!need_backup_hash) {
7074 PK11_DestroyContext(ss->ssl3.hs.md5, PR_TRUE);
7075 ss->ssl3.hs.md5 = NULL;
7076 }
7077 }
6997 break; /* not an error */ 7078 break; /* not an error */
6998 } 7079 }
6999 #endif /* NSS_PLATFORM_CLIENT_AUTH */ 7080 #endif /* NSS_PLATFORM_CLIENT_AUTH */
7000 /* check what the callback function returned */ 7081 /* check what the callback function returned */
7001 if ((!ss->ssl3.clientCertificate) || (!ss->ssl3.clientPrivateKey)) { 7082 if ((!ss->ssl3.clientCertificate) || (!ss->ssl3.clientPrivateKey)) {
7002 /* we are missing either the key or cert */ 7083 /* we are missing either the key or cert */
7003 if (ss->ssl3.clientCertificate) { 7084 if (ss->ssl3.clientCertificate) {
7004 /* got a cert, but no key - free it */ 7085 /* got a cert, but no key - free it */
7005 CERT_DestroyCertificate(ss->ssl3.clientCertificate); 7086 CERT_DestroyCertificate(ss->ssl3.clientCertificate);
7006 ss->ssl3.clientCertificate = NULL; 7087 ss->ssl3.clientCertificate = NULL;
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
7220 PRBool sendClientCert; 7301 PRBool sendClientCert;
7221 7302
7222 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); 7303 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
7223 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); 7304 PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
7224 7305
7225 sendClientCert = !ss->ssl3.sendEmptyCert && 7306 sendClientCert = !ss->ssl3.sendEmptyCert &&
7226 ss->ssl3.clientCertChain != NULL && 7307 ss->ssl3.clientCertChain != NULL &&
7227 (ss->ssl3.platformClientKey || 7308 (ss->ssl3.platformClientKey ||
7228 ss->ssl3.clientPrivateKey != NULL); 7309 ss->ssl3.clientPrivateKey != NULL);
7229 7310
7311 if (!sendClientCert &&
7312 ss->ssl3.hs.hashType == handshake_hash_single && ss->ssl3.hs.md5) {
7313 /* Don't need the backup handshake hash. */
7314 PK11_DestroyContext(ss->ssl3.hs.md5, PR_TRUE);
7315 ss->ssl3.hs.md5 = NULL;
7316 }
7317
7230 /* We must wait for the server's certificate to be authenticated before 7318 /* We must wait for the server's certificate to be authenticated before
7231 * sending the client certificate in order to disclosing the client 7319 * sending the client certificate in order to disclosing the client
7232 * certificate to an attacker that does not have a valid cert for the 7320 * certificate to an attacker that does not have a valid cert for the
7233 * domain we are connecting to. 7321 * domain we are connecting to.
7234 * 7322 *
7235 * XXX: We should do the same for the NPN extension, but for that we 7323 * 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 7324 * need an option to give the application the ability to leak the NPN
7237 * information to get better performance. 7325 * information to get better performance.
7238 * 7326 *
7239 * During the initial handshake on a connection, we never send/receive 7327 * 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); 12352 PORT_Free(ss->ssl3.hs.recvdFragments.buf);
12265 } 12353 }
12266 } 12354 }
12267 12355
12268 ss->ssl3.initialized = PR_FALSE; 12356 ss->ssl3.initialized = PR_FALSE;
12269 12357
12270 SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE); 12358 SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE);
12271 } 12359 }
12272 12360
12273 /* End of ssl3con.c */ 12361 /* End of ssl3con.c */
OLDNEW
« 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