diff options
author | hclam@chromium.org <hclam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-12-22 21:21:09 +0000 |
---|---|---|
committer | hclam@chromium.org <hclam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-12-22 21:21:09 +0000 |
commit | 3a50f8a87d43c111e58d6e5e0cea5a4ee3c08265 (patch) | |
tree | f3f4907bcc7087e11f7583228d1f67914d054074 | |
parent | b7ff596d84cc3f65463e0b026a3f41402c80dd99 (diff) | |
download | chromium_src-3a50f8a87d43c111e58d6e5e0cea5a4ee3c08265.zip chromium_src-3a50f8a87d43c111e58d6e5e0cea5a4ee3c08265.tar.gz chromium_src-3a50f8a87d43c111e58d6e5e0cea5a4ee3c08265.tar.bz2 |
Implement X509Certificate::CreateSelfSigned on Windows
In order to run SSLServerSocketNSS on windows a self signed certificate is
needed.
BUG=None
TEST=net_unittests --gtest_filter=X509*
Review URL: http://codereview.chromium.org/6002003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@69984 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | net/base/x509_certificate.h | 2 | ||||
-rw-r--r-- | net/base/x509_certificate_mac.cc | 10 | ||||
-rw-r--r-- | net/base/x509_certificate_openssl.cc | 10 | ||||
-rw-r--r-- | net/base/x509_certificate_unittest.cc | 6 | ||||
-rw-r--r-- | net/base/x509_certificate_win.cc | 65 |
5 files changed, 88 insertions, 5 deletions
diff --git a/net/base/x509_certificate.h b/net/base/x509_certificate.h index 349a08c..3ee7304 100644 --- a/net/base/x509_certificate.h +++ b/net/base/x509_certificate.h @@ -152,7 +152,6 @@ class X509Certificate : public base::RefCountedThreadSafe<X509Certificate> { int length, int format); -#if defined(USE_NSS) // Create a self-signed certificate containing the public key in |key|. // Subject, serial number and validity period are given as parameters. // The certificate is signed by the private key in |key|. The hashing @@ -175,7 +174,6 @@ class X509Certificate : public base::RefCountedThreadSafe<X509Certificate> { const std::string& subject, uint32 serial_number, base::TimeDelta valid_duration); -#endif // Creates a X509Certificate from the ground up. Used by tests that simulate // SSL connections. diff --git a/net/base/x509_certificate_mac.cc b/net/base/x509_certificate_mac.cc index 2187cd3..f7c89e4 100644 --- a/net/base/x509_certificate_mac.cc +++ b/net/base/x509_certificate_mac.cc @@ -400,6 +400,16 @@ X509Certificate* X509Certificate::CreateFromPickle(const Pickle& pickle, return CreateFromBytes(data, length); } +// static +X509Certificate* X509Certificate::CreateSelfSigned( + base::RSAPrivateKey* key, + const std::string& subject, + uint32 serial_number, + base::TimeDelta valid_duration) { + // TODO(port): Implement. + return NULL; +} + void X509Certificate::Persist(Pickle* pickle) { CSSM_DATA cert_data; OSStatus status = SecCertificateGetData(cert_handle_, &cert_data); diff --git a/net/base/x509_certificate_openssl.cc b/net/base/x509_certificate_openssl.cc index 44f276b..c6ffb2c 100644 --- a/net/base/x509_certificate_openssl.cc +++ b/net/base/x509_certificate_openssl.cc @@ -382,6 +382,16 @@ X509Certificate* X509Certificate::CreateFromPickle(const Pickle& pickle, return CreateFromBytes(data, length); } +// static +X509Certificate* X509Certificate::CreateSelfSigned( + base::RSAPrivateKey* key, + const std::string& subject, + uint32 serial_number, + base::TimeDelta valid_duration) { + // TODO(port): Implement. + return NULL; +} + void X509Certificate::Persist(Pickle* pickle) { DERCache der_cache; if (!GetDERAndCacheIfNeeded(cert_handle_, &der_cache)) diff --git a/net/base/x509_certificate_unittest.cc b/net/base/x509_certificate_unittest.cc index 893f849..83c11fa 100644 --- a/net/base/x509_certificate_unittest.cc +++ b/net/base/x509_certificate_unittest.cc @@ -659,9 +659,9 @@ TEST(X509CertificateTest, IsIssuedBy) { } #endif // defined(OS_MACOSX) -#if defined(USE_NSS) -// CreateSelfSigned() is only implemented using NSS. -// This test creates a signed cert from a private key and then +#if defined(USE_NSS) || defined(OS_WIN) +// This test creates a signed cert from a private key and then verify content +// of the certificate. TEST(X509CertificateTest, CreateSelfSigned) { scoped_ptr<base::RSAPrivateKey> private_key( base::RSAPrivateKey::Create(1024)); diff --git a/net/base/x509_certificate_win.cc b/net/base/x509_certificate_win.cc index 509c6c9..568c1fd 100644 --- a/net/base/x509_certificate_win.cc +++ b/net/base/x509_certificate_win.cc @@ -4,6 +4,7 @@ #include "net/base/x509_certificate.h" +#include "base/crypto/rsa_private_key.h" #include "base/crypto/scoped_capi_types.h" #include "base/lazy_instance.h" #include "base/logging.h" @@ -501,6 +502,70 @@ X509Certificate* X509Certificate::CreateFromPickle(const Pickle& pickle, return cert; } +// static +X509Certificate* X509Certificate::CreateSelfSigned( + base::RSAPrivateKey* key, + const std::string& subject, + uint32 serial_number, + base::TimeDelta valid_duration) { + // Get the ASN.1 encoding of the certificate subject. + std::wstring w_subject = ASCIIToWide(subject); + DWORD encoded_subject_length = 0; + if (!CertStrToName( + X509_ASN_ENCODING, + const_cast<wchar_t*>(w_subject.c_str()), + CERT_X500_NAME_STR, NULL, NULL, &encoded_subject_length, NULL)) { + return NULL; + } + + scoped_array<char> encoded_subject(new char[encoded_subject_length]); + if (!CertStrToName( + X509_ASN_ENCODING, + const_cast<wchar_t*>(w_subject.c_str()), + CERT_X500_NAME_STR, NULL, + reinterpret_cast<BYTE*>(encoded_subject.get()), + &encoded_subject_length, NULL)) { + return NULL; + } + + CERT_NAME_BLOB subject_name; + memset(&subject_name, 0, sizeof(subject_name)); + subject_name.cbData = encoded_subject_length; + subject_name.pbData = reinterpret_cast<BYTE*>(encoded_subject.get()); + + CRYPT_ALGORITHM_IDENTIFIER sign_algo; + memset(&sign_algo, 0, sizeof(sign_algo)); + sign_algo.pszObjId = szOID_RSA_SHA1RSA; + + base::Time not_valid = base::Time::Now() + valid_duration; + base::Time::Exploded exploded; + not_valid.UTCExplode(&exploded); + + // Create the system time struct representing our exploded time. + SYSTEMTIME system_time; + system_time.wYear = exploded.year; + system_time.wMonth = exploded.month; + system_time.wDayOfWeek = exploded.day_of_week; + system_time.wDay = exploded.day_of_month; + system_time.wHour = exploded.hour; + system_time.wMinute = exploded.minute; + system_time.wSecond = exploded.second; + system_time.wMilliseconds = exploded.millisecond; + + PCCERT_CONTEXT cert_handle = + CertCreateSelfSignCertificate(key->provider(), &subject_name, + CERT_CREATE_SELFSIGN_NO_KEY_INFO, + NULL, &sign_algo, 0, &system_time, 0); + DCHECK(cert_handle) << "Failed to create self-signed certificate: " + << logging::GetLastSystemErrorCode(); + + X509Certificate* cert = CreateFromHandle(cert_handle, + SOURCE_LONE_CERT_IMPORT, + OSCertHandles()); + FreeOSCertHandle(cert_handle); + return cert; +} + void X509Certificate::Persist(Pickle* pickle) { DCHECK(cert_handle_); DWORD length; |