OLD | NEW |
(Empty) | |
| 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 |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "net/spdy/spdy_credential_builder.h" |
| 6 |
| 7 #include "base/threading/sequenced_worker_pool.h" |
| 8 #include "crypto/ec_signature_creator.h" |
| 9 #include "crypto/ec_private_key.h" |
| 10 #include "net/base/asn1_util.h" |
| 11 #include "net/base/default_server_bound_cert_store.h" |
| 12 #include "net/base/server_bound_cert_service.h" |
| 13 #include "net/spdy/spdy_test_util_spdy3.h" |
| 14 #include "testing/platform_test.h" |
| 15 |
| 16 using namespace net::test_spdy3; |
| 17 |
| 18 namespace net { |
| 19 |
| 20 namespace { |
| 21 |
| 22 const static size_t kSlot = 2; |
| 23 const static char kSecretPrefix[] = |
| 24 "SPDY CREDENTIAL ChannelID\0client -> server"; |
| 25 |
| 26 void CreateCertAndKey(std::string* cert, std::string* key) { |
| 27 // TODO(rch): Share this code with ServerBoundCertServiceTest. |
| 28 scoped_refptr<base::SequencedWorkerPool> sequenced_worker_pool = |
| 29 new base::SequencedWorkerPool(1, "CreateCertAndKey"); |
| 30 scoped_ptr<ServerBoundCertService> server_bound_cert_service( |
| 31 new ServerBoundCertService(new DefaultServerBoundCertStore(NULL), |
| 32 sequenced_worker_pool)); |
| 33 |
| 34 TestCompletionCallback callback; |
| 35 std::vector<uint8> requested_cert_types; |
| 36 requested_cert_types.push_back(CLIENT_CERT_ECDSA_SIGN); |
| 37 SSLClientCertType cert_type; |
| 38 ServerBoundCertService::RequestHandle request_handle; |
| 39 int rv = server_bound_cert_service->GetDomainBoundCert( |
| 40 "https://www.google.com", requested_cert_types, &cert_type, key, cert, |
| 41 callback.callback(), &request_handle); |
| 42 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 43 EXPECT_EQ(OK, callback.WaitForResult()); |
| 44 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, cert_type); |
| 45 |
| 46 sequenced_worker_pool->Shutdown(); |
| 47 } |
| 48 |
| 49 } // namespace |
| 50 |
| 51 class SpdyCredentialBuilderTest : public testing::Test { |
| 52 public: |
| 53 SpdyCredentialBuilderTest() { |
| 54 CreateCertAndKey(&cert_, &key_); |
| 55 } |
| 56 |
| 57 protected: |
| 58 int BuildWithType(SSLClientCertType type) { |
| 59 return SpdyCredentialBuilder::Build( |
| 60 MockClientSocket::kTlsUnique, type, key_, cert_, kSlot, &credential_); |
| 61 } |
| 62 |
| 63 int Build() { |
| 64 return BuildWithType(CLIENT_CERT_ECDSA_SIGN); |
| 65 } |
| 66 |
| 67 std::string GetCredentialSecret() { |
| 68 return SpdyCredentialBuilder::GetCredentialSecret( |
| 69 MockClientSocket::kTlsUnique); |
| 70 } |
| 71 |
| 72 SpdyTestStateHelper helper_; // Provides deterministic EC signatures. |
| 73 std::string cert_; |
| 74 std::string key_; |
| 75 SpdyCredential credential_; |
| 76 }; |
| 77 |
| 78 TEST_F(SpdyCredentialBuilderTest, GetCredentialSecret) { |
| 79 std::string secret_str(kSecretPrefix, arraysize(kSecretPrefix)); |
| 80 secret_str.append(MockClientSocket::kTlsUnique); |
| 81 |
| 82 EXPECT_EQ(secret_str, GetCredentialSecret()); |
| 83 } |
| 84 |
| 85 TEST_F(SpdyCredentialBuilderTest, SucceedsWithECDSACert) { |
| 86 EXPECT_EQ(OK, BuildWithType(CLIENT_CERT_ECDSA_SIGN)); |
| 87 } |
| 88 |
| 89 TEST_F(SpdyCredentialBuilderTest, FailsWithRSACert) { |
| 90 EXPECT_EQ(ERR_BAD_SSL_CLIENT_AUTH_CERT, |
| 91 BuildWithType(CLIENT_CERT_RSA_SIGN)); |
| 92 } |
| 93 |
| 94 TEST_F(SpdyCredentialBuilderTest, SetsSlotCorrectly) { |
| 95 ASSERT_EQ(OK, Build()); |
| 96 EXPECT_EQ(kSlot, credential_.slot); |
| 97 } |
| 98 |
| 99 TEST_F(SpdyCredentialBuilderTest, SetsCertCorrectly) { |
| 100 ASSERT_EQ(OK, Build()); |
| 101 base::StringPiece spki; |
| 102 ASSERT_TRUE(asn1::ExtractSPKIFromDERCert(cert_, &spki)); |
| 103 base::StringPiece spk; |
| 104 ASSERT_TRUE(asn1::ExtractSubjectPublicKeyFromSPKI(spki, &spk)); |
| 105 EXPECT_EQ(1u, credential_.certs.size()); |
| 106 EXPECT_EQ(0, (int)spk[0]); |
| 107 EXPECT_EQ(4, (int)spk[1]); |
| 108 EXPECT_EQ(spk.substr(2, spk.length()).as_string(), credential_.certs[0]); |
| 109 } |
| 110 |
| 111 TEST_F(SpdyCredentialBuilderTest, SetsProofCorrectly) { |
| 112 ASSERT_EQ(OK, Build()); |
| 113 base::StringPiece spki; |
| 114 ASSERT_TRUE(asn1::ExtractSPKIFromDERCert(cert_, &spki)); |
| 115 std::vector<uint8> spki_data(spki.data(), |
| 116 spki.data() + spki.size()); |
| 117 std::vector<uint8> key_data(key_.data(), |
| 118 key_.data() + key_.length()); |
| 119 std::vector<uint8> proof_data; |
| 120 scoped_ptr<crypto::ECPrivateKey> private_key( |
| 121 crypto::ECPrivateKey::CreateFromEncryptedPrivateKeyInfo( |
| 122 ServerBoundCertService::kEPKIPassword, key_data, spki_data)); |
| 123 scoped_ptr<crypto::ECSignatureCreator> creator( |
| 124 crypto::ECSignatureCreator::Create(private_key.get())); |
| 125 std::string secret = GetCredentialSecret(); |
| 126 creator->Sign(reinterpret_cast<const unsigned char *>(secret.data()), |
| 127 secret.length(), &proof_data); |
| 128 |
| 129 std::string proof(proof_data.begin(), proof_data.end()); |
| 130 EXPECT_EQ(proof, credential_.proof); |
| 131 } |
| 132 |
| 133 } // namespace net |
OLD | NEW |