summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhclam@chromium.org <hclam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-12-22 21:21:09 +0000
committerhclam@chromium.org <hclam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-12-22 21:21:09 +0000
commit3a50f8a87d43c111e58d6e5e0cea5a4ee3c08265 (patch)
treef3f4907bcc7087e11f7583228d1f67914d054074
parentb7ff596d84cc3f65463e0b026a3f41402c80dd99 (diff)
downloadchromium_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.h2
-rw-r--r--net/base/x509_certificate_mac.cc10
-rw-r--r--net/base/x509_certificate_openssl.cc10
-rw-r--r--net/base/x509_certificate_unittest.cc6
-rw-r--r--net/base/x509_certificate_win.cc65
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;