| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // This file includes code SSLClientSocketNSS::DoVerifyCertComplete() derived | 5 // This file includes code SSLClientSocketNSS::DoVerifyCertComplete() derived |
| 6 // from AuthCertificateCallback() in | 6 // from AuthCertificateCallback() in |
| 7 // mozilla/security/manager/ssl/src/nsNSSCallbacks.cpp. | 7 // mozilla/security/manager/ssl/src/nsNSSCallbacks.cpp. |
| 8 | 8 |
| 9 /* ***** BEGIN LICENSE BLOCK ***** | 9 /* ***** BEGIN LICENSE BLOCK ***** |
| 10 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 | 10 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 |
| (...skipping 2129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2140 CERTCertList** result_certs, | 2140 CERTCertList** result_certs, |
| 2141 void** result_private_key) { | 2141 void** result_private_key) { |
| 2142 SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg); | 2142 SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg); |
| 2143 | 2143 |
| 2144 that->client_auth_cert_needed_ = !that->ssl_config_.send_client_cert; | 2144 that->client_auth_cert_needed_ = !that->ssl_config_.send_client_cert; |
| 2145 #if defined(OS_WIN) | 2145 #if defined(OS_WIN) |
| 2146 if (that->ssl_config_.send_client_cert) { | 2146 if (that->ssl_config_.send_client_cert) { |
| 2147 if (that->ssl_config_.client_cert) { | 2147 if (that->ssl_config_.client_cert) { |
| 2148 PCCERT_CONTEXT cert_context = | 2148 PCCERT_CONTEXT cert_context = |
| 2149 that->ssl_config_.client_cert->os_cert_handle(); | 2149 that->ssl_config_.client_cert->os_cert_handle(); |
| 2150 if (VLOG_IS_ON(1)) { | 2150 PCERT_KEY_CONTEXT key_context = reinterpret_cast<PCERT_KEY_CONTEXT>( |
| 2151 do { | 2151 PORT_ZAlloc(sizeof(CERT_KEY_CONTEXT))); |
| 2152 DWORD size_needed = 0; | 2152 if (!key_context) |
| 2153 BOOL got_info = CertGetCertificateContextProperty( | 2153 return SECFailure; |
| 2154 cert_context, CERT_KEY_PROV_INFO_PROP_ID, NULL, &size_needed); | 2154 key_context->cbSize = sizeof(*key_context); |
| 2155 if (!got_info) { | |
| 2156 VLOG(1) << "Failed to get key prov info size " << GetLastError(); | |
| 2157 break; | |
| 2158 } | |
| 2159 std::vector<BYTE> raw_info(size_needed); | |
| 2160 got_info = CertGetCertificateContextProperty( | |
| 2161 cert_context, CERT_KEY_PROV_INFO_PROP_ID, &raw_info[0], | |
| 2162 &size_needed); | |
| 2163 if (!got_info) { | |
| 2164 VLOG(1) << "Failed to get key prov info " << GetLastError(); | |
| 2165 break; | |
| 2166 } | |
| 2167 PCRYPT_KEY_PROV_INFO info = | |
| 2168 reinterpret_cast<PCRYPT_KEY_PROV_INFO>(&raw_info[0]); | |
| 2169 VLOG(1) << "Container Name: " << info->pwszContainerName | |
| 2170 << "\nProvider Name: " << info->pwszProvName | |
| 2171 << "\nProvider Type: " << info->dwProvType | |
| 2172 << "\nFlags: " << info->dwFlags | |
| 2173 << "\nProvider Param Count: " << info->cProvParam | |
| 2174 << "\nKey Specifier: " << info->dwKeySpec; | |
| 2175 } while (false); | |
| 2176 | 2155 |
| 2177 do { | |
| 2178 DWORD size_needed = 0; | |
| 2179 BOOL got_identifier = CertGetCertificateContextProperty( | |
| 2180 cert_context, CERT_KEY_IDENTIFIER_PROP_ID, NULL, &size_needed); | |
| 2181 if (!got_identifier) { | |
| 2182 VLOG(1) << "Failed to get key identifier size " | |
| 2183 << GetLastError(); | |
| 2184 break; | |
| 2185 } | |
| 2186 std::vector<BYTE> raw_id(size_needed); | |
| 2187 got_identifier = CertGetCertificateContextProperty( | |
| 2188 cert_context, CERT_KEY_IDENTIFIER_PROP_ID, &raw_id[0], | |
| 2189 &size_needed); | |
| 2190 if (!got_identifier) { | |
| 2191 VLOG(1) << "Failed to get key identifier " << GetLastError(); | |
| 2192 break; | |
| 2193 } | |
| 2194 VLOG(1) << "Key Identifier: " << base::HexEncode(&raw_id[0], | |
| 2195 size_needed); | |
| 2196 } while (false); | |
| 2197 } | |
| 2198 HCRYPTPROV provider = NULL; | |
| 2199 DWORD key_spec = AT_KEYEXCHANGE; | |
| 2200 BOOL must_free = FALSE; | 2156 BOOL must_free = FALSE; |
| 2201 BOOL acquired_key = CryptAcquireCertificatePrivateKey( | 2157 BOOL acquired_key = CryptAcquireCertificatePrivateKey( |
| 2202 cert_context, | 2158 cert_context, |
| 2203 CRYPT_ACQUIRE_CACHE_FLAG | CRYPT_ACQUIRE_COMPARE_KEY_FLAG, | 2159 CRYPT_ACQUIRE_CACHE_FLAG | CRYPT_ACQUIRE_COMPARE_KEY_FLAG, |
| 2204 NULL, &provider, &key_spec, &must_free); | 2160 NULL, &key_context->hCryptProv, &key_context->dwKeySpec, |
| 2205 if (acquired_key && provider) { | 2161 &must_free); |
| 2206 DCHECK_NE(key_spec, CERT_NCRYPT_KEY_SPEC); | 2162 if (acquired_key && key_context->hCryptProv) { |
| 2163 DCHECK_NE(key_context->dwKeySpec, CERT_NCRYPT_KEY_SPEC); |
| 2207 | 2164 |
| 2208 // The certificate cache may have been updated/used, in which case, | 2165 // The certificate cache may have been updated/used, in which case, |
| 2209 // duplicate the existing handle, since NSS will free it when no | 2166 // duplicate the existing handle, since NSS will free it when no |
| 2210 // longer in use. | 2167 // longer in use. |
| 2211 if (!must_free) | 2168 if (!must_free) |
| 2212 CryptContextAddRef(provider, NULL, 0); | 2169 CryptContextAddRef(key_context->hCryptProv, NULL, 0); |
| 2213 | 2170 |
| 2214 SECItem der_cert; | 2171 SECItem der_cert; |
| 2215 der_cert.type = siDERCertBuffer; | 2172 der_cert.type = siDERCertBuffer; |
| 2216 der_cert.data = cert_context->pbCertEncoded; | 2173 der_cert.data = cert_context->pbCertEncoded; |
| 2217 der_cert.len = cert_context->cbCertEncoded; | 2174 der_cert.len = cert_context->cbCertEncoded; |
| 2218 | 2175 |
| 2219 // TODO(rsleevi): Error checking for NSS allocation errors. | 2176 // TODO(rsleevi): Error checking for NSS allocation errors. |
| 2220 *result_certs = CERT_NewCertList(); | 2177 *result_certs = CERT_NewCertList(); |
| 2221 CERTCertDBHandle* db_handle = CERT_GetDefaultCertDB(); | 2178 CERTCertDBHandle* db_handle = CERT_GetDefaultCertDB(); |
| 2222 CERTCertificate* user_cert = CERT_NewTempCertificate( | 2179 CERTCertificate* user_cert = CERT_NewTempCertificate( |
| 2223 db_handle, &der_cert, NULL, PR_FALSE, PR_TRUE); | 2180 db_handle, &der_cert, NULL, PR_FALSE, PR_TRUE); |
| 2224 CERT_AddCertToListTail(*result_certs, user_cert); | 2181 CERT_AddCertToListTail(*result_certs, user_cert); |
| 2225 | 2182 |
| 2226 // Add the intermediates. | 2183 // Add the intermediates. |
| 2227 X509Certificate::OSCertHandles intermediates = | 2184 X509Certificate::OSCertHandles intermediates = |
| 2228 that->ssl_config_.client_cert->GetIntermediateCertificates(); | 2185 that->ssl_config_.client_cert->GetIntermediateCertificates(); |
| 2229 for (X509Certificate::OSCertHandles::const_iterator it = | 2186 for (X509Certificate::OSCertHandles::const_iterator it = |
| 2230 intermediates.begin(); it != intermediates.end(); ++it) { | 2187 intermediates.begin(); it != intermediates.end(); ++it) { |
| 2231 der_cert.data = (*it)->pbCertEncoded; | 2188 der_cert.data = (*it)->pbCertEncoded; |
| 2232 der_cert.len = (*it)->cbCertEncoded; | 2189 der_cert.len = (*it)->cbCertEncoded; |
| 2233 | 2190 |
| 2234 CERTCertificate* intermediate = CERT_NewTempCertificate( | 2191 CERTCertificate* intermediate = CERT_NewTempCertificate( |
| 2235 db_handle, &der_cert, NULL, PR_FALSE, PR_TRUE); | 2192 db_handle, &der_cert, NULL, PR_FALSE, PR_TRUE); |
| 2236 CERT_AddCertToListTail(*result_certs, intermediate); | 2193 CERT_AddCertToListTail(*result_certs, intermediate); |
| 2237 } | 2194 } |
| 2238 // TODO(wtc): |key_spec| should be passed along with |provider|. | 2195 *result_private_key = key_context; |
| 2239 *result_private_key = reinterpret_cast<void*>(provider); | |
| 2240 return SECSuccess; | 2196 return SECSuccess; |
| 2241 } | 2197 } |
| 2198 PORT_Free(key_context); |
| 2242 LOG(WARNING) << "Client cert found without private key"; | 2199 LOG(WARNING) << "Client cert found without private key"; |
| 2243 } | 2200 } |
| 2244 // Send no client certificate. | 2201 // Send no client certificate. |
| 2245 return SECFailure; | 2202 return SECFailure; |
| 2246 } | 2203 } |
| 2247 | 2204 |
| 2248 that->client_certs_.clear(); | 2205 that->client_certs_.clear(); |
| 2249 | 2206 |
| 2250 std::vector<CERT_NAME_BLOB> issuer_list(ca_names->nnames); | 2207 std::vector<CERT_NAME_BLOB> issuer_list(ca_names->nnames); |
| 2251 for (int i = 0; i < ca_names->nnames; ++i) { | 2208 for (int i = 0; i < ca_names->nnames; ++i) { |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2348 if (chain) { | 2305 if (chain) { |
| 2349 identity = reinterpret_cast<SecIdentityRef>( | 2306 identity = reinterpret_cast<SecIdentityRef>( |
| 2350 const_cast<void*>(CFArrayGetValueAtIndex(chain, 0))); | 2307 const_cast<void*>(CFArrayGetValueAtIndex(chain, 0))); |
| 2351 } | 2308 } |
| 2352 if (identity) | 2309 if (identity) |
| 2353 os_error = SecIdentityCopyPrivateKey(identity, &private_key); | 2310 os_error = SecIdentityCopyPrivateKey(identity, &private_key); |
| 2354 | 2311 |
| 2355 if (chain && identity && os_error == noErr) { | 2312 if (chain && identity && os_error == noErr) { |
| 2356 // TODO(rsleevi): Error checking for NSS allocation errors. | 2313 // TODO(rsleevi): Error checking for NSS allocation errors. |
| 2357 *result_certs = CERT_NewCertList(); | 2314 *result_certs = CERT_NewCertList(); |
| 2358 *result_private_key = reinterpret_cast<void*>(private_key); | 2315 *result_private_key = private_key; |
| 2359 | 2316 |
| 2360 for (CFIndex i = 0; i < CFArrayGetCount(chain); ++i) { | 2317 for (CFIndex i = 0; i < CFArrayGetCount(chain); ++i) { |
| 2361 CSSM_DATA cert_data; | 2318 CSSM_DATA cert_data; |
| 2362 SecCertificateRef cert_ref; | 2319 SecCertificateRef cert_ref; |
| 2363 if (i == 0) { | 2320 if (i == 0) { |
| 2364 cert_ref = that->ssl_config_.client_cert->os_cert_handle(); | 2321 cert_ref = that->ssl_config_.client_cert->os_cert_handle(); |
| 2365 } else { | 2322 } else { |
| 2366 cert_ref = reinterpret_cast<SecCertificateRef>( | 2323 cert_ref = reinterpret_cast<SecCertificateRef>( |
| 2367 const_cast<void*>(CFArrayGetValueAtIndex(chain, i))); | 2324 const_cast<void*>(CFArrayGetValueAtIndex(chain, i))); |
| 2368 } | 2325 } |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2505 void* arg) { | 2462 void* arg) { |
| 2506 SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg); | 2463 SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg); |
| 2507 | 2464 |
| 2508 that->handshake_callback_called_ = true; | 2465 that->handshake_callback_called_ = true; |
| 2509 | 2466 |
| 2510 that->UpdateServerCert(); | 2467 that->UpdateServerCert(); |
| 2511 that->UpdateConnectionStatus(); | 2468 that->UpdateConnectionStatus(); |
| 2512 } | 2469 } |
| 2513 | 2470 |
| 2514 } // namespace net | 2471 } // namespace net |
| OLD | NEW |