blob: bc67cc593ae21924770004bb5d8869293553bdc4 [file] [log] [blame]
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001// 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"
Torne (Richard Coles)58218062012-11-14 11:43:16 +00008#include "crypto/ec_private_key.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00009#include "crypto/ec_signature_creator.h"
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010010#include "net/cert/asn1_util.h"
Ben Murdocheb525c52013-07-10 11:40:50 +010011#include "net/spdy/spdy_test_util_common.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000012#include "net/ssl/default_server_bound_cert_store.h"
13#include "net/ssl/server_bound_cert_service.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000014#include "testing/platform_test.h"
15
Torne (Richard Coles)58218062012-11-14 11:43:16 +000016namespace net {
17
18namespace {
19
20const static size_t kSlot = 2;
21const static char kSecretPrefix[] =
22 "SPDY CREDENTIAL ChannelID\0client -> server";
23
24void CreateCertAndKey(std::string* cert, std::string* key) {
25 // TODO(rch): Share this code with ServerBoundCertServiceTest.
26 scoped_refptr<base::SequencedWorkerPool> sequenced_worker_pool =
27 new base::SequencedWorkerPool(1, "CreateCertAndKey");
28 scoped_ptr<ServerBoundCertService> server_bound_cert_service(
29 new ServerBoundCertService(new DefaultServerBoundCertStore(NULL),
30 sequenced_worker_pool));
31
32 TestCompletionCallback callback;
Torne (Richard Coles)58218062012-11-14 11:43:16 +000033 ServerBoundCertService::RequestHandle request_handle;
34 int rv = server_bound_cert_service->GetDomainBoundCert(
Ben Murdochbb1529c2013-08-08 10:24:53 +010035 "www.google.com", key, cert,
Torne (Richard Coles)58218062012-11-14 11:43:16 +000036 callback.callback(), &request_handle);
37 EXPECT_EQ(ERR_IO_PENDING, rv);
38 EXPECT_EQ(OK, callback.WaitForResult());
Torne (Richard Coles)58218062012-11-14 11:43:16 +000039
40 sequenced_worker_pool->Shutdown();
41}
42
43} // namespace
44
45class SpdyCredentialBuilderTest : public testing::Test {
46 public:
47 SpdyCredentialBuilderTest() {
48 CreateCertAndKey(&cert_, &key_);
49 }
50
51 protected:
Torne (Richard Coles)58218062012-11-14 11:43:16 +000052 int Build() {
Ben Murdochbb1529c2013-08-08 10:24:53 +010053 return SpdyCredentialBuilder::Build(
54 MockClientSocket::kTlsUnique, key_, cert_, kSlot, &credential_);
Torne (Richard Coles)58218062012-11-14 11:43:16 +000055 }
56
57 std::string GetCredentialSecret() {
58 return SpdyCredentialBuilder::GetCredentialSecret(
59 MockClientSocket::kTlsUnique);
60 }
61
Torne (Richard Coles)58218062012-11-14 11:43:16 +000062 std::string cert_;
63 std::string key_;
64 SpdyCredential credential_;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000065 MockECSignatureCreatorFactory ec_signature_creator_factory_;
Torne (Richard Coles)58218062012-11-14 11:43:16 +000066};
67
68// http://crbug.com/142833, http://crbug.com/140991. The following tests fail
69// with OpenSSL due to the unimplemented ec_private_key_openssl.cc.
70#if defined(USE_OPENSSL)
71#define MAYBE_GetCredentialSecret DISABLED_GetCredentialSecret
72#else
73#define MAYBE_GetCredentialSecret GetCredentialSecret
74#endif
75
76TEST_F(SpdyCredentialBuilderTest, MAYBE_GetCredentialSecret) {
77 std::string secret_str(kSecretPrefix, arraysize(kSecretPrefix));
78 secret_str.append(MockClientSocket::kTlsUnique);
79
80 EXPECT_EQ(secret_str, GetCredentialSecret());
81}
82
83#if defined(USE_OPENSSL)
Ben Murdochbb1529c2013-08-08 10:24:53 +010084#define MAYBE_Succeeds DISABLED_Succeeds
Torne (Richard Coles)58218062012-11-14 11:43:16 +000085#else
Ben Murdochbb1529c2013-08-08 10:24:53 +010086#define MAYBE_Succeeds Succeeds
Torne (Richard Coles)58218062012-11-14 11:43:16 +000087#endif
88
Ben Murdochbb1529c2013-08-08 10:24:53 +010089TEST_F(SpdyCredentialBuilderTest, MAYBE_Succeeds) {
90 EXPECT_EQ(OK, Build());
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000091}
92
93#if defined(USE_OPENSSL)
Torne (Richard Coles)58218062012-11-14 11:43:16 +000094#define MAYBE_SetsSlotCorrectly DISABLED_SetsSlotCorrectly
95#else
96#define MAYBE_SetsSlotCorrectly SetsSlotCorrectly
97#endif
98
99TEST_F(SpdyCredentialBuilderTest, MAYBE_SetsSlotCorrectly) {
100 ASSERT_EQ(OK, Build());
101 EXPECT_EQ(kSlot, credential_.slot);
102}
103
104#if defined(USE_OPENSSL)
105#define MAYBE_SetsCertCorrectly DISABLED_SetsCertCorrectly
106#else
107#define MAYBE_SetsCertCorrectly SetsCertCorrectly
108#endif
109
110TEST_F(SpdyCredentialBuilderTest, MAYBE_SetsCertCorrectly) {
111 ASSERT_EQ(OK, Build());
112 base::StringPiece spki;
113 ASSERT_TRUE(asn1::ExtractSPKIFromDERCert(cert_, &spki));
114 base::StringPiece spk;
115 ASSERT_TRUE(asn1::ExtractSubjectPublicKeyFromSPKI(spki, &spk));
116 EXPECT_EQ(1u, credential_.certs.size());
117 EXPECT_EQ(0, (int)spk[0]);
118 EXPECT_EQ(4, (int)spk[1]);
119 EXPECT_EQ(spk.substr(2, spk.length()).as_string(), credential_.certs[0]);
120}
121
122#if defined(USE_OPENSSL)
123#define MAYBE_SetsProofCorrectly DISABLED_SetsProofCorrectly
124#else
125#define MAYBE_SetsProofCorrectly SetsProofCorrectly
126#endif
127
128TEST_F(SpdyCredentialBuilderTest, MAYBE_SetsProofCorrectly) {
129 ASSERT_EQ(OK, Build());
130 base::StringPiece spki;
131 ASSERT_TRUE(asn1::ExtractSPKIFromDERCert(cert_, &spki));
132 std::vector<uint8> spki_data(spki.data(),
133 spki.data() + spki.size());
134 std::vector<uint8> key_data(key_.data(),
135 key_.data() + key_.length());
136 std::vector<uint8> proof_data;
137 scoped_ptr<crypto::ECPrivateKey> private_key(
138 crypto::ECPrivateKey::CreateFromEncryptedPrivateKeyInfo(
139 ServerBoundCertService::kEPKIPassword, key_data, spki_data));
140 scoped_ptr<crypto::ECSignatureCreator> creator(
141 crypto::ECSignatureCreator::Create(private_key.get()));
142 std::string secret = GetCredentialSecret();
143 creator->Sign(reinterpret_cast<const unsigned char *>(secret.data()),
144 secret.length(), &proof_data);
145
146 std::string proof(proof_data.begin(), proof_data.end());
147 EXPECT_EQ(proof, credential_.proof);
148}
149
150} // namespace net