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