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/logging.h" |
| 8 #include "base/string_piece.h" |
| 9 #include "crypto/ec_private_key.h" |
| 10 #include "crypto/ec_signature_creator.h" |
| 11 #include "crypto/signature_creator.h" |
| 12 #include "net/base/asn1_util.h" |
| 13 #include "net/base/server_bound_cert_service.h" |
| 14 #include "net/base/net_errors.h" |
| 15 #include "net/socket/ssl_client_socket.h" |
| 16 #include "net/spdy/spdy_framer.h" |
| 17 |
| 18 namespace net { |
| 19 |
| 20 namespace { |
| 21 |
| 22 std::vector<uint8> ToVector(base::StringPiece piece) { |
| 23 return std::vector<uint8>(piece.data(), piece.data() + piece.length()); |
| 24 } |
| 25 |
| 26 } // namespace |
| 27 |
| 28 // static |
| 29 int SpdyCredentialBuilder::Build(std::string tls_unique, |
| 30 SSLClientCertType type, |
| 31 const std::string& key, |
| 32 const std::string& cert, |
| 33 size_t slot, |
| 34 SpdyCredential* credential) { |
| 35 DCHECK(type == CLIENT_CERT_ECDSA_SIGN); |
| 36 if (type != CLIENT_CERT_ECDSA_SIGN) |
| 37 return ERR_BAD_SSL_CLIENT_AUTH_CERT; |
| 38 |
| 39 std::string secret = SpdyCredentialBuilder::GetCredentialSecret(tls_unique); |
| 40 |
| 41 // Extract the SubjectPublicKeyInfo from the certificate. |
| 42 base::StringPiece public_key_info; |
| 43 if(!asn1::ExtractSPKIFromDERCert(cert, &public_key_info)) |
| 44 return ERR_BAD_SSL_CLIENT_AUTH_CERT; |
| 45 |
| 46 // Next, extract the SubjectPublicKey data, which will actually |
| 47 // be stored in the cert field of the credential frame. |
| 48 base::StringPiece public_key; |
| 49 if (!asn1::ExtractSubjectPublicKeyFromSPKI(public_key_info, &public_key)) |
| 50 return ERR_BAD_SSL_CLIENT_AUTH_CERT; |
| 51 // Drop one byte of padding bits count from the BIT STRING |
| 52 // (this will always be zero). Drop one byte of X9.62 format specification |
| 53 // (this will always be 4 to indicated an uncompressed point). |
| 54 DCHECK_GT(public_key.length(), 2u); |
| 55 DCHECK_EQ(0, static_cast<int>(public_key[0])); |
| 56 DCHECK_EQ(4, static_cast<int>(public_key[1])); |
| 57 public_key = public_key.substr(2, public_key.length()); |
| 58 |
| 59 // Convert the strings into a vector<unit8> |
| 60 std::vector<uint8> proof_vector; |
| 61 scoped_ptr<crypto::ECPrivateKey> private_key( |
| 62 crypto::ECPrivateKey::CreateFromEncryptedPrivateKeyInfo( |
| 63 ServerBoundCertService::kEPKIPassword, |
| 64 ToVector(key), ToVector(public_key_info))); |
| 65 scoped_ptr<crypto::ECSignatureCreator> creator( |
| 66 crypto::ECSignatureCreator::Create(private_key.get())); |
| 67 creator->Sign(reinterpret_cast<const unsigned char *>(secret.data()), |
| 68 secret.length(), &proof_vector); |
| 69 |
| 70 credential->slot = slot; |
| 71 credential->certs.push_back(public_key.as_string()); |
| 72 credential->proof.assign(proof_vector.begin(), proof_vector.end()); |
| 73 return OK; |
| 74 } |
| 75 |
| 76 // static |
| 77 std::string SpdyCredentialBuilder::GetCredentialSecret(std::string tls_unique) { |
| 78 const char prefix[] = "SPDY CREDENTIAL ChannelID\0client -> server"; |
| 79 std::string secret(prefix, arraysize(prefix)); |
| 80 secret.append(tls_unique); |
| 81 |
| 82 return secret; |
| 83 } |
| 84 |
| 85 } // namespace net |
OLD | NEW |