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_private_key.h" 9 #include "crypto/ec_signature_creator.h" 10 #include "net/cert/asn1_util.h" 11 #include "net/spdy/spdy_test_util_common.h" 12 #include "net/ssl/default_server_bound_cert_store.h" 13 #include "net/ssl/server_bound_cert_service.h" 14 #include "testing/platform_test.h" 15 16 namespace net { 17 18 namespace { 19 20 const static size_t kSlot = 2; 21 const static char kSecretPrefix[] = 22 "SPDY CREDENTIAL ChannelID\0client -> server"; 23 24 void 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; 33 ServerBoundCertService::RequestHandle request_handle; 34 int rv = server_bound_cert_service->GetDomainBoundCert( 35 "www.google.com", key, cert, 36 callback.callback(), &request_handle); 37 EXPECT_EQ(ERR_IO_PENDING, rv); 38 EXPECT_EQ(OK, callback.WaitForResult()); 39 40 sequenced_worker_pool->Shutdown(); 41 } 42 43 } // namespace 44 45 class SpdyCredentialBuilderTest : public testing::Test { 46 public: 47 SpdyCredentialBuilderTest() { 48 CreateCertAndKey(&cert_, &key_); 49 } 50 51 protected: 52 int Build() { 53 return SpdyCredentialBuilder::Build( 54 MockClientSocket::kTlsUnique, key_, cert_, kSlot, &credential_); 55 } 56 57 std::string GetCredentialSecret() { 58 return SpdyCredentialBuilder::GetCredentialSecret( 59 MockClientSocket::kTlsUnique); 60 } 61 62 std::string cert_; 63 std::string key_; 64 SpdyCredential credential_; 65 MockECSignatureCreatorFactory ec_signature_creator_factory_; 66 }; 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 76 TEST_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) 84 #define MAYBE_Succeeds DISABLED_Succeeds 85 #else 86 #define MAYBE_Succeeds Succeeds 87 #endif 88 89 TEST_F(SpdyCredentialBuilderTest, MAYBE_Succeeds) { 90 EXPECT_EQ(OK, Build()); 91 } 92 93 #if defined(USE_OPENSSL) 94 #define MAYBE_SetsSlotCorrectly DISABLED_SetsSlotCorrectly 95 #else 96 #define MAYBE_SetsSlotCorrectly SetsSlotCorrectly 97 #endif 98 99 TEST_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 110 TEST_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 128 TEST_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 151