summaryrefslogtreecommitdiff
path: root/chromium/net/cert/x509_util_openssl_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/net/cert/x509_util_openssl_unittest.cc')
-rw-r--r--chromium/net/cert/x509_util_openssl_unittest.cc105
1 files changed, 94 insertions, 11 deletions
diff --git a/chromium/net/cert/x509_util_openssl_unittest.cc b/chromium/net/cert/x509_util_openssl_unittest.cc
index f237602ecbd..c99f811705d 100644
--- a/chromium/net/cert/x509_util_openssl_unittest.cc
+++ b/chromium/net/cert/x509_util_openssl_unittest.cc
@@ -4,12 +4,89 @@
#include "base/memory/scoped_ptr.h"
#include "crypto/ec_private_key.h"
+#include "crypto/openssl_util.h"
#include "net/cert/x509_util.h"
#include "net/cert/x509_util_openssl.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace net {
+namespace {
+
+// Verify that a given certificate was signed with the private key corresponding
+// to a given public key.
+// |der_cert| is the DER-encoded X.509 certificate.
+// |der_spki| is the DER-encoded public key of the signer.
+void VerifyCertificateSignature(const std::string& der_cert,
+ const std::vector<uint8>& der_spki) {
+ const unsigned char* cert_data =
+ reinterpret_cast<const unsigned char*>(der_cert.data());
+ int cert_data_len = static_cast<int>(der_cert.size());
+ crypto::ScopedOpenSSL<X509, X509_free> cert(
+ d2i_X509(NULL, &cert_data, cert_data_len));
+ ASSERT_TRUE(cert.get());
+
+ // NOTE: SignatureVerifier wants the DER-encoded ASN.1 AlgorithmIdentifier
+ // but there is no OpenSSL API to extract it from an X509 object (!?)
+ // Use X509_verify() directly instead, which takes an EVP_PKEY.
+ const unsigned char* pub_key_data = &der_spki.front();
+ int pub_key_len = static_cast<int>(der_spki.size());
+ crypto::ScopedOpenSSL<EVP_PKEY, EVP_PKEY_free> pub_key(
+ d2i_PUBKEY(NULL, &pub_key_data, pub_key_len));
+ ASSERT_TRUE(pub_key.get());
+
+ // NOTE: X509_verify() returns 1 in case of succes, 0 or -1 on error.
+ EXPECT_EQ(1, X509_verify(cert.get(), pub_key.get()));
+}
+
+// Verify the attributes of a domain-bound certificate.
+// |domain| is the bound domain name.
+// |der_cert| is the DER-encoded X.509 certificate.
+void VerifyDomainBoundCert(const std::string& domain,
+ const std::string& der_cert) {
+ // Origin Bound Cert OID.
+ static const char oid_string[] = "1.3.6.1.4.1.11129.2.1.6";
+ crypto::ScopedOpenSSL<ASN1_OBJECT, ASN1_OBJECT_free> oid_obj(
+ OBJ_txt2obj(oid_string, 0));
+ ASSERT_TRUE(oid_obj.get());
+
+ const unsigned char* cert_data =
+ reinterpret_cast<const unsigned char*>(der_cert.data());
+ int cert_data_len = static_cast<int>(der_cert.size());
+ crypto::ScopedOpenSSL<X509, X509_free> cert(
+ d2i_X509(NULL, &cert_data, cert_data_len));
+ ASSERT_TRUE(cert.get());
+
+ // Find the extension.
+ int ext_pos = X509_get_ext_by_OBJ(cert.get(), oid_obj.get(), -1);
+ ASSERT_NE(-1, ext_pos);
+ X509_EXTENSION* ext = X509_get_ext(cert.get(), ext_pos);
+ ASSERT_TRUE(ext);
+
+ // Check its value, it must be an ASN.1 IA5STRING
+ // Which means <tag> <length> <domain>, with:
+ // <tag> == 22
+ // <length> is the domain length, a single byte for short forms.
+ // <domain> are the domain characters.
+ // See http://en.wikipedia.org/wiki/X.690
+ ASN1_STRING* value_asn1 = X509_EXTENSION_get_data(ext);
+ ASSERT_TRUE(value_asn1);
+ std::string value_str(reinterpret_cast<const char*>(value_asn1->data),
+ value_asn1->length);
+
+ // Check that the domain size is small enough for short form.
+ ASSERT_LE(domain.size(), 127U) << "Domain is too long!";
+ std::string value_expected;
+ value_expected.resize(2);
+ value_expected[0] = 22;
+ value_expected[1] = static_cast<char>(domain.size());
+ value_expected += domain;
+
+ EXPECT_EQ(value_expected, value_str);
+}
+
+} // namespace
+
TEST(X509UtilOpenSSLTest, IsSupportedValidityRange) {
base::Time now = base::Time::Now();
EXPECT_TRUE(x509_util::IsSupportedValidityRange(now, now));
@@ -35,23 +112,29 @@ TEST(X509UtilOpenSSLTest, IsSupportedValidityRange) {
EXPECT_FALSE(x509_util::IsSupportedValidityRange(too_late, too_late));
}
-// For OpenSSL, x509_util::CreateDomainBoundCertEC() is not yet implemented
-// and should return false. This unit test ensures that a stub implementation
-// is present.
-TEST(X509UtilOpenSSLTest, CreateDomainBoundCertNotImplemented) {
+TEST(X509UtilOpenSSLTest, CreateDomainBoundCertEC) {
+ // Create a sample ASCII weborigin.
std::string domain = "weborigin.com";
base::Time now = base::Time::Now();
+
scoped_ptr<crypto::ECPrivateKey> private_key(
crypto::ECPrivateKey::Create());
std::string der_cert;
- EXPECT_FALSE(x509_util::CreateDomainBoundCertEC(
- private_key.get(),
- domain, 1,
- now,
- now + base::TimeDelta::FromDays(1),
- &der_cert));
- EXPECT_TRUE(der_cert.empty());
+ ASSERT_TRUE(
+ x509_util::CreateDomainBoundCertEC(private_key.get(),
+ x509_util::DIGEST_SHA1,
+ domain,
+ 1,
+ now,
+ now + base::TimeDelta::FromDays(1),
+ &der_cert));
+
+ VerifyDomainBoundCert(domain, der_cert);
+ // signature_verifier_win and signature_verifier_mac can't handle EC certs.
+ std::vector<uint8> spki;
+ ASSERT_TRUE(private_key->ExportPublicKey(&spki));
+ VerifyCertificateSignature(der_cert, spki);
}
} // namespace net