OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 // OpenSSL binding for SSLClientSocket. The class layout and general principle | 5 // OpenSSL binding for SSLClientSocket. The class layout and general principle |
6 // of operation is derived from SSLClientSocketNSS. | 6 // of operation is derived from SSLClientSocketNSS. |
7 | 7 |
8 #include "net/socket/ssl_client_socket_openssl.h" | 8 #include "net/socket/ssl_client_socket_openssl.h" |
9 | 9 |
10 #include <openssl/err.h> | 10 #include <openssl/err.h> |
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
382 | 382 |
383 // Must increase the reference count manually for sk_X509_dup | 383 // Must increase the reference count manually for sk_X509_dup |
384 openssl_chain_.reset(sk_X509_dup(other.openssl_chain_.get())); | 384 openssl_chain_.reset(sk_X509_dup(other.openssl_chain_.get())); |
385 for (int i = 0; i < sk_X509_num(openssl_chain_.get()); ++i) { | 385 for (int i = 0; i < sk_X509_num(openssl_chain_.get()); ++i) { |
386 X509* x = sk_X509_value(openssl_chain_.get(), i); | 386 X509* x = sk_X509_value(openssl_chain_.get(), i); |
387 CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); | 387 CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); |
388 } | 388 } |
389 return *this; | 389 return *this; |
390 } | 390 } |
391 | 391 |
392 #if defined(USE_OPENSSL) | 392 #if defined(USE_OPENSSL_CERTS) |
393 // When OSCertHandle is typedef'ed to X509, this implementation does a short cut | 393 // When OSCertHandle is typedef'ed to X509, this implementation does a short cut |
394 // to avoid converting back and forth between der and X509 struct. | 394 // to avoid converting back and forth between der and X509 struct. |
395 void SSLClientSocketOpenSSL::PeerCertificateChain::Reset( | 395 void SSLClientSocketOpenSSL::PeerCertificateChain::Reset( |
396 STACK_OF(X509)* chain) { | 396 STACK_OF(X509)* chain) { |
397 openssl_chain_.reset(NULL); | 397 openssl_chain_.reset(NULL); |
398 os_chain_ = NULL; | 398 os_chain_ = NULL; |
399 | 399 |
400 if (!chain) | 400 if (!chain) |
401 return; | 401 return; |
402 | 402 |
403 X509Certificate::OSCertHandles intermediates; | 403 X509Certificate::OSCertHandles intermediates; |
404 for (int i = 1; i < sk_X509_num(chain); ++i) | 404 for (int i = 1; i < sk_X509_num(chain); ++i) |
405 intermediates.push_back(sk_X509_value(chain, i)); | 405 intermediates.push_back(sk_X509_value(chain, i)); |
406 | 406 |
407 os_chain_ = | 407 os_chain_ = |
408 X509Certificate::CreateFromHandle(sk_X509_value(chain, 0), intermediates); | 408 X509Certificate::CreateFromHandle(sk_X509_value(chain, 0), intermediates); |
409 | 409 |
410 // sk_X509_dup does not increase reference count on the certs in the stack. | 410 // sk_X509_dup does not increase reference count on the certs in the stack. |
411 openssl_chain_.reset(sk_X509_dup(chain)); | 411 openssl_chain_.reset(sk_X509_dup(chain)); |
412 | 412 |
413 std::vector<base::StringPiece> der_chain; | 413 std::vector<base::StringPiece> der_chain; |
414 for (int i = 0; i < sk_X509_num(openssl_chain_.get()); ++i) { | 414 for (int i = 0; i < sk_X509_num(openssl_chain_.get()); ++i) { |
415 X509* x = sk_X509_value(openssl_chain_.get(), i); | 415 X509* x = sk_X509_value(openssl_chain_.get(), i); |
416 // Increase the reference count for the certs in openssl_chain_. | 416 // Increase the reference count for the certs in openssl_chain_. |
417 CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); | 417 CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); |
418 } | 418 } |
419 } | 419 } |
420 #else // !defined(USE_OPENSSL) | 420 #else // !defined(USE_OPENSSL_CERTS) |
421 void SSLClientSocketOpenSSL::PeerCertificateChain::Reset( | 421 void SSLClientSocketOpenSSL::PeerCertificateChain::Reset( |
422 STACK_OF(X509)* chain) { | 422 STACK_OF(X509)* chain) { |
423 openssl_chain_.reset(NULL); | 423 openssl_chain_.reset(NULL); |
424 os_chain_ = NULL; | 424 os_chain_ = NULL; |
425 | 425 |
426 if (!chain) | 426 if (!chain) |
427 return; | 427 return; |
428 | 428 |
429 // sk_X509_dup does not increase reference count on the certs in the stack. | 429 // sk_X509_dup does not increase reference count on the certs in the stack. |
430 openssl_chain_.reset(sk_X509_dup(chain)); | 430 openssl_chain_.reset(sk_X509_dup(chain)); |
(...skipping 17 matching lines...) Expand all Loading... |
448 for (size_t i = 0; i < der_chain.size(); ++i) { | 448 for (size_t i = 0; i < der_chain.size(); ++i) { |
449 OPENSSL_free(const_cast<char*>(der_chain[i].data())); | 449 OPENSSL_free(const_cast<char*>(der_chain[i].data())); |
450 } | 450 } |
451 | 451 |
452 if (der_chain.size() != | 452 if (der_chain.size() != |
453 static_cast<size_t>(sk_X509_num(openssl_chain_.get()))) { | 453 static_cast<size_t>(sk_X509_num(openssl_chain_.get()))) { |
454 openssl_chain_.reset(NULL); | 454 openssl_chain_.reset(NULL); |
455 os_chain_ = NULL; | 455 os_chain_ = NULL; |
456 } | 456 } |
457 } | 457 } |
458 #endif // USE_OPENSSL | 458 #endif // defined(USE_OPENSSL_CERTS) |
459 | 459 |
460 // static | 460 // static |
461 SSLSessionCacheOpenSSL::Config | 461 SSLSessionCacheOpenSSL::Config |
462 SSLClientSocketOpenSSL::SSLContext::kDefaultSessionCacheConfig = { | 462 SSLClientSocketOpenSSL::SSLContext::kDefaultSessionCacheConfig = { |
463 &GetSessionCacheKey, // key_func | 463 &GetSessionCacheKey, // key_func |
464 1024, // max_entries | 464 1024, // max_entries |
465 256, // expiration_check_count | 465 256, // expiration_check_count |
466 60 * 60, // timeout_seconds | 466 60 * 60, // timeout_seconds |
467 }; | 467 }; |
468 | 468 |
469 // static | 469 // static |
470 void SSLClientSocket::ClearSessionCache() { | 470 void SSLClientSocket::ClearSessionCache() { |
471 SSLClientSocketOpenSSL::SSLContext* context = | 471 SSLClientSocketOpenSSL::SSLContext* context = |
472 SSLClientSocketOpenSSL::SSLContext::GetInstance(); | 472 SSLClientSocketOpenSSL::SSLContext::GetInstance(); |
473 context->session_cache()->Flush(); | 473 context->session_cache()->Flush(); |
| 474 #if defined(USE_OPENSSL_CERTS) |
474 OpenSSLClientKeyStore::GetInstance()->Flush(); | 475 OpenSSLClientKeyStore::GetInstance()->Flush(); |
| 476 #endif |
475 } | 477 } |
476 | 478 |
477 SSLClientSocketOpenSSL::SSLClientSocketOpenSSL( | 479 SSLClientSocketOpenSSL::SSLClientSocketOpenSSL( |
478 scoped_ptr<ClientSocketHandle> transport_socket, | 480 scoped_ptr<ClientSocketHandle> transport_socket, |
479 const HostPortPair& host_and_port, | 481 const HostPortPair& host_and_port, |
480 const SSLConfig& ssl_config, | 482 const SSLConfig& ssl_config, |
481 const SSLClientSocketContext& context) | 483 const SSLClientSocketContext& context) |
482 : transport_send_busy_(false), | 484 : transport_send_busy_(false), |
483 transport_recv_busy_(false), | 485 transport_recv_busy_(false), |
484 transport_recv_eof_(false), | 486 transport_recv_eof_(false), |
(...skipping 922 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1407 return result; | 1409 return result; |
1408 } | 1410 } |
1409 | 1411 |
1410 int SSLClientSocketOpenSSL::ClientCertRequestCallback(SSL* ssl, | 1412 int SSLClientSocketOpenSSL::ClientCertRequestCallback(SSL* ssl, |
1411 X509** x509, | 1413 X509** x509, |
1412 EVP_PKEY** pkey) { | 1414 EVP_PKEY** pkey) { |
1413 DVLOG(3) << "OpenSSL ClientCertRequestCallback called"; | 1415 DVLOG(3) << "OpenSSL ClientCertRequestCallback called"; |
1414 DCHECK(ssl == ssl_); | 1416 DCHECK(ssl == ssl_); |
1415 DCHECK(*x509 == NULL); | 1417 DCHECK(*x509 == NULL); |
1416 DCHECK(*pkey == NULL); | 1418 DCHECK(*pkey == NULL); |
1417 | 1419 #if defined(USE_OPENSSL_CERTS) |
1418 if (!ssl_config_.send_client_cert) { | 1420 if (!ssl_config_.send_client_cert) { |
1419 // First pass: we know that a client certificate is needed, but we do not | 1421 // First pass: we know that a client certificate is needed, but we do not |
1420 // have one at hand. | 1422 // have one at hand. |
1421 client_auth_cert_needed_ = true; | 1423 client_auth_cert_needed_ = true; |
1422 STACK_OF(X509_NAME) *authorities = SSL_get_client_CA_list(ssl); | 1424 STACK_OF(X509_NAME) *authorities = SSL_get_client_CA_list(ssl); |
1423 for (int i = 0; i < sk_X509_NAME_num(authorities); i++) { | 1425 for (int i = 0; i < sk_X509_NAME_num(authorities); i++) { |
1424 X509_NAME *ca_name = (X509_NAME *)sk_X509_NAME_value(authorities, i); | 1426 X509_NAME *ca_name = (X509_NAME *)sk_X509_NAME_value(authorities, i); |
1425 unsigned char* str = NULL; | 1427 unsigned char* str = NULL; |
1426 int length = i2d_X509_NAME(ca_name, &str); | 1428 int length = i2d_X509_NAME(ca_name, &str); |
1427 cert_authorities_.push_back(std::string( | 1429 cert_authorities_.push_back(std::string( |
(...skipping 16 matching lines...) Expand all Loading... |
1444 ssl_config_.client_cert.get(), &privkey)) { | 1446 ssl_config_.client_cert.get(), &privkey)) { |
1445 // TODO(joth): (copied from NSS) We should wait for server certificate | 1447 // TODO(joth): (copied from NSS) We should wait for server certificate |
1446 // verification before sending our credentials. See http://crbug.com/13934 | 1448 // verification before sending our credentials. See http://crbug.com/13934 |
1447 *x509 = X509Certificate::DupOSCertHandle( | 1449 *x509 = X509Certificate::DupOSCertHandle( |
1448 ssl_config_.client_cert->os_cert_handle()); | 1450 ssl_config_.client_cert->os_cert_handle()); |
1449 *pkey = privkey.release(); | 1451 *pkey = privkey.release(); |
1450 return 1; | 1452 return 1; |
1451 } | 1453 } |
1452 LOG(WARNING) << "Client cert found without private key"; | 1454 LOG(WARNING) << "Client cert found without private key"; |
1453 } | 1455 } |
| 1456 #else // !defined(USE_OPENSSL_CERTS) |
| 1457 // OS handling of client certificates is not yet implemented. |
| 1458 NOTIMPLEMENTED(); |
| 1459 #endif // defined(USE_OPENSSL_CERTS) |
1454 | 1460 |
1455 // Send no client certificate. | 1461 // Send no client certificate. |
1456 return 0; | 1462 return 0; |
1457 } | 1463 } |
1458 | 1464 |
1459 void SSLClientSocketOpenSSL::ChannelIDRequestCallback(SSL* ssl, | 1465 void SSLClientSocketOpenSSL::ChannelIDRequestCallback(SSL* ssl, |
1460 EVP_PKEY** pkey) { | 1466 EVP_PKEY** pkey) { |
1461 DVLOG(3) << "OpenSSL ChannelIDRequestCallback called"; | 1467 DVLOG(3) << "OpenSSL ChannelIDRequestCallback called"; |
1462 DCHECK_EQ(ssl, ssl_); | 1468 DCHECK_EQ(ssl, ssl_); |
1463 DCHECK(!*pkey); | 1469 DCHECK(!*pkey); |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1567 #endif | 1573 #endif |
1568 return SSL_TLSEXT_ERR_OK; | 1574 return SSL_TLSEXT_ERR_OK; |
1569 } | 1575 } |
1570 | 1576 |
1571 scoped_refptr<X509Certificate> | 1577 scoped_refptr<X509Certificate> |
1572 SSLClientSocketOpenSSL::GetUnverifiedServerCertificateChain() const { | 1578 SSLClientSocketOpenSSL::GetUnverifiedServerCertificateChain() const { |
1573 return server_cert_; | 1579 return server_cert_; |
1574 } | 1580 } |
1575 | 1581 |
1576 } // namespace net | 1582 } // namespace net |
OLD | NEW |