| 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 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 311 LeaveFunction(""); | 311 LeaveFunction(""); |
| 312 } | 312 } |
| 313 | 313 |
| 314 int SSLClientSocketNSS::Init() { | 314 int SSLClientSocketNSS::Init() { |
| 315 EnterFunction(""); | 315 EnterFunction(""); |
| 316 // Initialize the NSS SSL library in a threadsafe way. This also | 316 // Initialize the NSS SSL library in a threadsafe way. This also |
| 317 // initializes the NSS base library. | 317 // initializes the NSS base library. |
| 318 EnsureNSSSSLInit(); | 318 EnsureNSSSSLInit(); |
| 319 if (!NSS_IsInitialized()) | 319 if (!NSS_IsInitialized()) |
| 320 return ERR_UNEXPECTED; | 320 return ERR_UNEXPECTED; |
| 321 #if !defined(OS_WIN) | 321 #if !defined(OS_MACOSX) && !defined(OS_WIN) |
| 322 // We must call EnsureOCSPInit() here, on the IO thread, to get the IO loop | 322 // We must call EnsureOCSPInit() here, on the IO thread, to get the IO loop |
| 323 // by MessageLoopForIO::current(). | 323 // by MessageLoopForIO::current(). |
| 324 // X509Certificate::Verify() runs on a worker thread of CertVerifier. | 324 // X509Certificate::Verify() runs on a worker thread of CertVerifier. |
| 325 EnsureOCSPInit(); | 325 EnsureOCSPInit(); |
| 326 #endif | 326 #endif |
| 327 | 327 |
| 328 LeaveFunction(""); | 328 LeaveFunction(""); |
| 329 return OK; | 329 return OK; |
| 330 } | 330 } |
| 331 | 331 |
| (...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 656 return transport_->SetSendBufferSize(size); | 656 return transport_->SetSendBufferSize(size); |
| 657 } | 657 } |
| 658 | 658 |
| 659 X509Certificate *SSLClientSocketNSS::UpdateServerCert() { | 659 X509Certificate *SSLClientSocketNSS::UpdateServerCert() { |
| 660 // We set the server_cert_ from OwnAuthCertHandler(), but this handler | 660 // We set the server_cert_ from OwnAuthCertHandler(), but this handler |
| 661 // does not necessarily get called if we are continuing a cached SSL | 661 // does not necessarily get called if we are continuing a cached SSL |
| 662 // session. | 662 // session. |
| 663 if (server_cert_ == NULL) { | 663 if (server_cert_ == NULL) { |
| 664 server_cert_nss_ = SSL_PeerCertificate(nss_fd_); | 664 server_cert_nss_ = SSL_PeerCertificate(nss_fd_); |
| 665 if (server_cert_nss_) { | 665 if (server_cert_nss_) { |
| 666 #if defined(OS_WIN) | 666 #if defined(OS_MACOSX) || defined(OS_WIN) |
| 667 // TODO(wtc): close cert_store_ at shutdown. | |
| 668 if (!cert_store_) | |
| 669 cert_store_ = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, NULL, 0, NULL); | |
| 670 | |
| 671 // Get each of the intermediate certificates in the server's chain. | 667 // Get each of the intermediate certificates in the server's chain. |
| 672 // These will be added to the server's X509Certificate object, making | 668 // These will be added to the server's X509Certificate object, making |
| 673 // them available to X509Certificate::Verify() for chain building. | 669 // them available to X509Certificate::Verify() for chain building. |
| 674 X509Certificate::OSCertHandles intermediate_ca_certs; | 670 X509Certificate::OSCertHandles intermediate_ca_certs; |
| 675 PCCERT_CONTEXT cert_context = NULL; | 671 X509Certificate::OSCertHandle cert_handle = NULL; |
| 676 CERTCertList* cert_list = CERT_GetCertChainFromCert( | 672 CERTCertList* cert_list = CERT_GetCertChainFromCert( |
| 677 server_cert_nss_, PR_Now(), certUsageSSLCA); | 673 server_cert_nss_, PR_Now(), certUsageSSLCA); |
| 678 if (cert_list) { | 674 if (cert_list) { |
| 679 for (CERTCertListNode* node = CERT_LIST_HEAD(cert_list); | 675 for (CERTCertListNode* node = CERT_LIST_HEAD(cert_list); |
| 680 !CERT_LIST_END(node, cert_list); | 676 !CERT_LIST_END(node, cert_list); |
| 681 node = CERT_LIST_NEXT(node)) { | 677 node = CERT_LIST_NEXT(node)) { |
| 682 if (node->cert == server_cert_nss_) | 678 if (node->cert == server_cert_nss_) |
| 683 continue; | 679 continue; |
| 680 #if defined(OS_WIN) |
| 684 // Work around http://crbug.com/43538 by not importing the | 681 // Work around http://crbug.com/43538 by not importing the |
| 685 // problematic COMODO EV SGC CA certificate. CryptoAPI will | 682 // problematic COMODO EV SGC CA certificate. CryptoAPI will |
| 686 // download a good certificate for that CA, issued by COMODO | 683 // download a good certificate for that CA, issued by COMODO |
| 687 // Certification Authority, using the AIA extension in the server | 684 // Certification Authority, using the AIA extension in the server |
| 688 // certificate. | 685 // certificate. |
| 689 if (IsProblematicComodoEVCACert(*node->cert)) | 686 if (IsProblematicComodoEVCACert(*node->cert)) |
| 690 continue; | 687 continue; |
| 691 cert_context = NULL; | 688 #endif |
| 692 BOOL ok = CertAddEncodedCertificateToStore( | 689 cert_handle = X509Certificate::CreateOSCertHandleFromBytes( |
| 693 cert_store_, | 690 reinterpret_cast<char*>(node->cert->derCert.data), |
| 694 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, | 691 node->cert->derCert.len); |
| 695 node->cert->derCert.data, | 692 DCHECK(cert_handle); |
| 696 node->cert->derCert.len, | 693 intermediate_ca_certs.push_back(cert_handle); |
| 697 CERT_STORE_ADD_USE_EXISTING, | |
| 698 &cert_context); | |
| 699 DCHECK(ok); | |
| 700 intermediate_ca_certs.push_back(cert_context); | |
| 701 } | 694 } |
| 702 CERT_DestroyCertList(cert_list); | 695 CERT_DestroyCertList(cert_list); |
| 703 } | 696 } |
| 704 | 697 |
| 705 // Finally create the X509Certificate object. | 698 // Finally create the X509Certificate object. |
| 706 BOOL ok = CertAddEncodedCertificateToStore( | 699 cert_handle = X509Certificate::CreateOSCertHandleFromBytes( |
| 707 cert_store_, | 700 reinterpret_cast<char*>(server_cert_nss_->derCert.data), |
| 708 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, | 701 server_cert_nss_->derCert.len); |
| 709 server_cert_nss_->derCert.data, | 702 DCHECK(cert_handle); |
| 710 server_cert_nss_->derCert.len, | |
| 711 CERT_STORE_ADD_USE_EXISTING, | |
| 712 &cert_context); | |
| 713 DCHECK(ok); | |
| 714 server_cert_ = X509Certificate::CreateFromHandle( | 703 server_cert_ = X509Certificate::CreateFromHandle( |
| 715 cert_context, | 704 cert_handle, |
| 716 X509Certificate::SOURCE_FROM_NETWORK, | 705 X509Certificate::SOURCE_FROM_NETWORK, |
| 717 intermediate_ca_certs); | 706 intermediate_ca_certs); |
| 718 for (size_t i = 0; i < intermediate_ca_certs.size(); ++i) | 707 for (size_t i = 0; i < intermediate_ca_certs.size(); ++i) |
| 719 CertFreeCertificateContext(intermediate_ca_certs[i]); | 708 X509Certificate::FreeOSCertHandle(intermediate_ca_certs[i]); |
| 720 #else | 709 #else |
| 721 server_cert_ = X509Certificate::CreateFromHandle( | 710 server_cert_ = X509Certificate::CreateFromHandle( |
| 722 CERT_DupCertificate(server_cert_nss_), | 711 CERT_DupCertificate(server_cert_nss_), |
| 723 X509Certificate::SOURCE_FROM_NETWORK, | 712 X509Certificate::SOURCE_FROM_NETWORK, |
| 724 X509Certificate::OSCertHandles()); | 713 X509Certificate::OSCertHandles()); |
| 725 #endif | 714 #endif |
| 726 } | 715 } |
| 727 } | 716 } |
| 728 return server_cert_; | 717 return server_cert_; |
| 729 } | 718 } |
| (...skipping 478 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1208 // Enumerate the client certificates. | 1197 // Enumerate the client certificates. |
| 1209 CERT_CHAIN_FIND_BY_ISSUER_PARA find_by_issuer_para; | 1198 CERT_CHAIN_FIND_BY_ISSUER_PARA find_by_issuer_para; |
| 1210 memset(&find_by_issuer_para, 0, sizeof(find_by_issuer_para)); | 1199 memset(&find_by_issuer_para, 0, sizeof(find_by_issuer_para)); |
| 1211 find_by_issuer_para.cbSize = sizeof(find_by_issuer_para); | 1200 find_by_issuer_para.cbSize = sizeof(find_by_issuer_para); |
| 1212 find_by_issuer_para.pszUsageIdentifier = szOID_PKIX_KP_CLIENT_AUTH; | 1201 find_by_issuer_para.pszUsageIdentifier = szOID_PKIX_KP_CLIENT_AUTH; |
| 1213 find_by_issuer_para.cIssuer = ca_names->nnames; | 1202 find_by_issuer_para.cIssuer = ca_names->nnames; |
| 1214 find_by_issuer_para.rgIssuer = ca_names->nnames ? &issuer_list[0] : NULL; | 1203 find_by_issuer_para.rgIssuer = ca_names->nnames ? &issuer_list[0] : NULL; |
| 1215 | 1204 |
| 1216 PCCERT_CHAIN_CONTEXT chain_context = NULL; | 1205 PCCERT_CHAIN_CONTEXT chain_context = NULL; |
| 1217 | 1206 |
| 1207 // TODO(wtc): close cert_store_ at shutdown. |
| 1208 if (!cert_store_) |
| 1209 cert_store_ = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, NULL, 0, NULL); |
| 1210 |
| 1218 for (;;) { | 1211 for (;;) { |
| 1219 // Find a certificate chain. | 1212 // Find a certificate chain. |
| 1220 chain_context = CertFindChainInStore(my_cert_store, | 1213 chain_context = CertFindChainInStore(my_cert_store, |
| 1221 X509_ASN_ENCODING, | 1214 X509_ASN_ENCODING, |
| 1222 0, | 1215 0, |
| 1223 CERT_CHAIN_FIND_BY_ISSUER, | 1216 CERT_CHAIN_FIND_BY_ISSUER, |
| 1224 &find_by_issuer_para, | 1217 &find_by_issuer_para, |
| 1225 chain_context); | 1218 chain_context); |
| 1226 if (!chain_context) { | 1219 if (!chain_context) { |
| 1227 DWORD err = GetLastError(); | 1220 DWORD err = GetLastError(); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1248 net::X509Certificate::OSCertHandles()); | 1241 net::X509Certificate::OSCertHandles()); |
| 1249 that->client_certs_.push_back(cert); | 1242 that->client_certs_.push_back(cert); |
| 1250 } | 1243 } |
| 1251 | 1244 |
| 1252 BOOL ok = CertCloseStore(my_cert_store, CERT_CLOSE_STORE_CHECK_FLAG); | 1245 BOOL ok = CertCloseStore(my_cert_store, CERT_CLOSE_STORE_CHECK_FLAG); |
| 1253 DCHECK(ok); | 1246 DCHECK(ok); |
| 1254 | 1247 |
| 1255 // Tell NSS to suspend the client authentication. We will then abort the | 1248 // Tell NSS to suspend the client authentication. We will then abort the |
| 1256 // handshake by returning ERR_SSL_CLIENT_AUTH_CERT_NEEDED. | 1249 // handshake by returning ERR_SSL_CLIENT_AUTH_CERT_NEEDED. |
| 1257 return SECWouldBlock; | 1250 return SECWouldBlock; |
| 1251 #elif defined(OS_MACOSX) |
| 1252 // TODO(wtc): see http://crbug.com/45369. |
| 1253 // Not implemented. Send no client certificate. |
| 1254 PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); |
| 1255 return SECFailure; |
| 1258 #else | 1256 #else |
| 1259 CERTCertificate* cert = NULL; | 1257 CERTCertificate* cert = NULL; |
| 1260 SECKEYPrivateKey* privkey = NULL; | 1258 SECKEYPrivateKey* privkey = NULL; |
| 1261 void* wincx = SSL_RevealPinArg(socket); | 1259 void* wincx = SSL_RevealPinArg(socket); |
| 1262 | 1260 |
| 1263 // Second pass: a client certificate should have been selected. | 1261 // Second pass: a client certificate should have been selected. |
| 1264 if (that->ssl_config_.send_client_cert) { | 1262 if (that->ssl_config_.send_client_cert) { |
| 1265 if (that->ssl_config_.client_cert) { | 1263 if (that->ssl_config_.client_cert) { |
| 1266 cert = CERT_DupCertificate( | 1264 cert = CERT_DupCertificate( |
| 1267 that->ssl_config_.client_cert->os_cert_handle()); | 1265 that->ssl_config_.client_cert->os_cert_handle()); |
| (...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1499 PRErrorCode prerr = PR_GetError(); | 1497 PRErrorCode prerr = PR_GetError(); |
| 1500 if (prerr == PR_WOULD_BLOCK_ERROR) { | 1498 if (prerr == PR_WOULD_BLOCK_ERROR) { |
| 1501 LeaveFunction(""); | 1499 LeaveFunction(""); |
| 1502 return ERR_IO_PENDING; | 1500 return ERR_IO_PENDING; |
| 1503 } | 1501 } |
| 1504 LeaveFunction(""); | 1502 LeaveFunction(""); |
| 1505 return MapNSPRError(prerr); | 1503 return MapNSPRError(prerr); |
| 1506 } | 1504 } |
| 1507 | 1505 |
| 1508 } // namespace net | 1506 } // namespace net |
| OLD | NEW |