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, "SpdyHttpStreamSpdy3Test"); | |
ramant (doing other things)
2012/08/02 16:54:19
nit: was suggesting 'new base::SequencedWorkerPool
Ryan Hamilton
2012/08/02 17:00:25
Oh, I see. I totally missed that. Done.
| |
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 #if !defined(DCHECK_ALWAYS_ON) | |
91 EXPECT_DEBUG_DEATH(BuildWithType(CLIENT_CERT_RSA_SIGN), ""); | |
92 #else | |
93 EXPECT_EQ(ERR_BAD_SSL_CLIENT_AUTH_CERT, | |
94 BuildWithType(CLIENT_CERT_RSA_SIGN)); | |
95 #endif | |
96 } | |
97 | |
98 TEST_F(SpdyCredentialBuilderTest, SetsSlotCorrectly) { | |
99 ASSERT_EQ(OK, Build()); | |
100 EXPECT_EQ(kSlot, credential_.slot); | |
101 } | |
102 | |
103 TEST_F(SpdyCredentialBuilderTest, SetsCertCorrectly) { | |
104 ASSERT_EQ(OK, Build()); | |
105 base::StringPiece spki; | |
106 ASSERT_TRUE(asn1::ExtractSPKIFromDERCert(cert_, &spki)); | |
107 base::StringPiece spk; | |
108 ASSERT_TRUE(asn1::ExtractSubjectPublicKeyFromSPKI(spki, &spk)); | |
109 EXPECT_EQ(1u, credential_.certs.size()); | |
110 EXPECT_EQ(0, (int)spk[0]); | |
111 EXPECT_EQ(4, (int)spk[1]); | |
112 EXPECT_EQ(spk.substr(2, spk.length()).as_string(), credential_.certs[0]); | |
113 } | |
114 | |
115 TEST_F(SpdyCredentialBuilderTest, SetsProofCorrectly) { | |
116 ASSERT_EQ(OK, Build()); | |
117 base::StringPiece spki; | |
118 ASSERT_TRUE(asn1::ExtractSPKIFromDERCert(cert_, &spki)); | |
119 std::vector<uint8> spki_data(spki.data(), | |
120 spki.data() + spki.size()); | |
121 std::vector<uint8> key_data(key_.data(), | |
122 key_.data() + key_.length()); | |
123 std::vector<uint8> proof_data; | |
124 scoped_ptr<crypto::ECPrivateKey> private_key( | |
125 crypto::ECPrivateKey::CreateFromEncryptedPrivateKeyInfo( | |
126 ServerBoundCertService::kEPKIPassword, key_data, spki_data)); | |
127 scoped_ptr<crypto::ECSignatureCreator> creator( | |
128 crypto::ECSignatureCreator::Create(private_key.get())); | |
129 std::string secret = GetCredentialSecret(); | |
130 creator->Sign(reinterpret_cast<const unsigned char *>(secret.data()), | |
131 secret.length(), &proof_data); | |
132 | |
133 std::string proof(proof_data.begin(), proof_data.end()); | |
134 EXPECT_EQ(proof, credential_.proof); | |
135 } | |
136 | |
137 } // namespace net | |
OLD | NEW |