Chromium Code Reviews| 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 class MockBuilder : public SpdyCredentialBuilder { | |
|
ramant (doing other things)
2012/08/02 00:03:05
overly nit: do we need this class? Can we call Spd
Ryan Hamilton
2012/08/02 15:53:49
As I've moved GetCredentialSecret from protected t
| |
| 27 public: | |
| 28 std::string GetCredentialSecret() { | |
|
ramant (doing other things)
2012/08/02 00:03:05
nit: why GetCredentialSecret public?
ramant (doing other things)
2012/08/02 00:54:20
Please ignore this.
| |
| 29 return SpdyCredentialBuilder::GetCredentialSecret( | |
| 30 MockClientSocket::kTlsUnique); | |
| 31 } | |
| 32 }; | |
| 33 | |
| 34 void CreateCertAndKey(std::string* cert, std::string* key) { | |
| 35 scoped_refptr<base::SequencedWorkerPool> sequenced_worker_pool = | |
| 36 new base::SequencedWorkerPool(1, "SpdyHttpStreamSpdy3Test"); | |
|
ramant (doing other things)
2012/08/02 00:03:05
nit: consider using "CreateCertAndKey" or "SpdyCre
Ryan Hamilton
2012/08/02 15:53:49
I don't know what you mean? The method is already
| |
| 37 scoped_ptr<ServerBoundCertService> server_bound_cert_service( | |
|
ramant (doing other things)
2012/08/02 00:03:05
overly nit: It would be really awesome to share co
Ryan Hamilton
2012/08/02 15:53:49
Done.
| |
| 38 new ServerBoundCertService(new DefaultServerBoundCertStore(NULL), | |
| 39 sequenced_worker_pool)); | |
| 40 | |
| 41 TestCompletionCallback callback; | |
| 42 std::vector<uint8> requested_cert_types; | |
| 43 requested_cert_types.push_back(CLIENT_CERT_ECDSA_SIGN); | |
| 44 SSLClientCertType cert_type; | |
| 45 ServerBoundCertService::RequestHandle request_handle; | |
| 46 int rv = server_bound_cert_service->GetDomainBoundCert( | |
| 47 "https://www.google.com", requested_cert_types, &cert_type, key, cert, | |
| 48 callback.callback(), &request_handle); | |
| 49 EXPECT_EQ(ERR_IO_PENDING, rv); | |
| 50 EXPECT_EQ(OK, callback.WaitForResult()); | |
| 51 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, cert_type); | |
| 52 | |
| 53 sequenced_worker_pool->Shutdown(); | |
| 54 } | |
| 55 | |
| 56 } // namespace | |
| 57 | |
| 58 class SpdyCredentialBuilderTest : public testing::Test { | |
| 59 public: | |
| 60 SpdyCredentialBuilderTest() { | |
| 61 CreateCertAndKey(&cert_, &key_); | |
| 62 } | |
| 63 | |
| 64 protected: | |
| 65 int BuildWithType(SSLClientCertType type) { | |
| 66 return builder_.Build( | |
| 67 MockClientSocket::kTlsUnique, type, key_, cert_, kSlot, &credential_); | |
| 68 } | |
| 69 | |
| 70 int Build() { | |
| 71 return BuildWithType(CLIENT_CERT_ECDSA_SIGN); | |
| 72 } | |
| 73 | |
| 74 SpdyTestStateHelper helper_; | |
|
jar (doing other things)
2012/08/02 02:23:04
nit: all members should be private.
Ryan Hamilton
2012/08/02 15:53:49
Normally, this is true, but the style guide specif
| |
| 75 std::string cert_; | |
|
ramant (doing other things)
2012/08/02 00:03:05
nit: do we need helper_?
Ryan Hamilton
2012/08/02 15:53:49
(you comment seems to be one line below the line y
| |
| 76 std::string key_; | |
| 77 MockBuilder builder_; | |
| 78 SpdyCredential credential_; | |
| 79 }; | |
| 80 | |
| 81 TEST_F(SpdyCredentialBuilderTest, GetCredentialSecret) { | |
| 82 std::string secret_str(kSecretPrefix, arraysize(kSecretPrefix)); | |
| 83 secret_str.append(MockClientSocket::kTlsUnique); | |
| 84 | |
| 85 EXPECT_EQ(secret_str, builder_.GetCredentialSecret()); | |
| 86 } | |
| 87 | |
| 88 TEST_F(SpdyCredentialBuilderTest, SucceedsWithECDSACert) { | |
| 89 EXPECT_EQ(OK, BuildWithType(CLIENT_CERT_ECDSA_SIGN)); | |
| 90 } | |
| 91 | |
| 92 TEST_F(SpdyCredentialBuilderTest, FailsWithRSACert) { | |
| 93 #if !defined(DCHECK_ALWAYS_ON) | |
| 94 EXPECT_DEBUG_DEATH(BuildWithType(CLIENT_CERT_RSA_SIGN), ""); | |
| 95 #else | |
| 96 EXPECT_EQ(ERR_BAD_SSL_CLIENT_AUTH_CERT, | |
| 97 BuildWithType(CLIENT_CERT_RSA_SIGN)); | |
| 98 #endif | |
| 99 } | |
| 100 | |
| 101 TEST_F(SpdyCredentialBuilderTest, SetsSlotCorrectly) { | |
| 102 ASSERT_EQ(OK, Build()); | |
| 103 EXPECT_EQ(kSlot, credential_.slot); | |
| 104 } | |
| 105 | |
| 106 TEST_F(SpdyCredentialBuilderTest, SetsCertCorrectly) { | |
| 107 ASSERT_EQ(OK, Build()); | |
| 108 base::StringPiece spki; | |
| 109 ASSERT_TRUE(asn1::ExtractSPKIFromDERCert(cert_, &spki)); | |
| 110 base::StringPiece spk; | |
| 111 ASSERT_TRUE(asn1::ExtractSubjectPublicKeyFromSPKI(spki, &spk)); | |
| 112 EXPECT_EQ(1u, credential_.certs.size()); | |
| 113 EXPECT_EQ(0, (int)spk[0]); | |
| 114 EXPECT_EQ(4, (int)spk[1]); | |
| 115 EXPECT_EQ(spk.substr(2, spk.length()).as_string(), credential_.certs[0]); | |
| 116 } | |
| 117 | |
| 118 TEST_F(SpdyCredentialBuilderTest, SetsProofCorrectly) { | |
| 119 ASSERT_EQ(OK, Build()); | |
| 120 base::StringPiece spki; | |
| 121 ASSERT_TRUE(asn1::ExtractSPKIFromDERCert(cert_, &spki)); | |
| 122 std::vector<uint8> spki_data(spki.data(), | |
| 123 spki.data() + spki.size()); | |
| 124 std::vector<uint8> key_data(key_.data(), | |
| 125 key_.data() + key_.length()); | |
| 126 std::vector<uint8> proof_data; | |
| 127 scoped_ptr<crypto::ECPrivateKey> private_key( | |
| 128 crypto::ECPrivateKey::CreateFromEncryptedPrivateKeyInfo( | |
| 129 ServerBoundCertService::kEPKIPassword, key_data, spki_data)); | |
| 130 scoped_ptr<crypto::ECSignatureCreator> creator( | |
| 131 crypto::ECSignatureCreator::Create(private_key.get())); | |
| 132 std::string secret = builder_.GetCredentialSecret(); | |
| 133 creator->Sign(reinterpret_cast<const unsigned char *>(secret.data()), | |
| 134 secret.length(), &proof_data); | |
| 135 | |
| 136 std::string proof(proof_data.begin(), proof_data.end()); | |
| 137 EXPECT_EQ(proof, credential_.proof); | |
| 138 } | |
| 139 | |
| 140 } // namespace net | |
| OLD | NEW |