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 |