1 // Copyright 2013 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/quic/crypto/proof_source_chromium.h"
7 #include <openssl/digest.h>
8 #include <openssl/evp.h>
9 #include <openssl/rsa.h>
11 #include "base/strings/string_number_conversions.h"
12 #include "crypto/openssl_util.h"
13 #include "net/quic/crypto/crypto_protocol.h"
14 #include "net/ssl/scoped_openssl_types.h"
21 ProofSourceChromium::ProofSourceChromium() {}
23 ProofSourceChromium::~ProofSourceChromium() {}
25 bool ProofSourceChromium::Initialize(const base::FilePath
& cert_path
,
26 const base::FilePath
& key_path
) {
27 crypto::EnsureOpenSSLInit();
29 std::string cert_data
;
30 if (!base::ReadFileToString(cert_path
, &cert_data
)) {
31 DLOG(FATAL
) << "Unable to read certificates.";
35 CertificateList certs_in_file
=
36 X509Certificate::CreateCertificateListFromBytes(
37 cert_data
.data(), cert_data
.size(), X509Certificate::FORMAT_AUTO
);
39 if (certs_in_file
.empty()) {
40 DLOG(FATAL
) << "No certificates.";
44 for (const scoped_refptr
<X509Certificate
>& cert
: certs_in_file
) {
45 std::string der_encoded_cert
;
46 if (!X509Certificate::GetDEREncoded(cert
->os_cert_handle(),
50 certificates_
.push_back(der_encoded_cert
);
54 if (!base::ReadFileToString(key_path
, &key_data
)) {
55 DLOG(FATAL
) << "Unable to read key.";
59 const uint8_t* p
= reinterpret_cast<const uint8_t*>(key_data
.data());
60 std::vector
<uint8_t> input(p
, p
+ key_data
.size());
61 private_key_
.reset(crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(input
));
62 if (private_key_
.get() == nullptr) {
63 DLOG(FATAL
) << "Unable to create private key.";
69 bool ProofSourceChromium::GetProof(const IPAddressNumber
& server_ip
,
70 const string
& hostname
,
71 const string
& server_config
,
73 const vector
<string
>** out_certs
,
74 string
* out_signature
) {
75 DCHECK(private_key_
.get()) << " this: " << this;
77 crypto::OpenSSLErrStackTracer
err_tracer(FROM_HERE
);
78 crypto::ScopedEVP_MD_CTX
sign_context(EVP_MD_CTX_create());
79 EVP_PKEY_CTX
* pkey_ctx
;
80 if (!EVP_DigestSignInit(sign_context
.get(), &pkey_ctx
, EVP_sha256(), nullptr,
81 private_key_
->key()) ||
82 !EVP_PKEY_CTX_set_rsa_padding(pkey_ctx
, RSA_PKCS1_PSS_PADDING
) ||
83 !EVP_PKEY_CTX_set_rsa_pss_saltlen(pkey_ctx
, -1) ||
84 !EVP_DigestSignUpdate(sign_context
.get(), reinterpret_cast<const uint8
*>(
85 kProofSignatureLabel
),
86 sizeof(kProofSignatureLabel
)) ||
87 !EVP_DigestSignUpdate(sign_context
.get(), reinterpret_cast<const uint8
*>(
88 server_config
.data()),
89 server_config
.size())) {
93 // Determine the maximum length of the signature.
95 if (!EVP_DigestSignFinal(sign_context
.get(), nullptr, &len
)) {
98 std::vector
<uint8_t> signature(len
);
100 if (!EVP_DigestSignFinal(sign_context
.get(), vector_as_array(&signature
),
104 signature
.resize(len
);
105 out_signature
->assign(reinterpret_cast<const char*>(&signature
[0]),
107 *out_certs
= &certificates_
;
108 VLOG(1) << "signature: "
109 << base::HexEncode(out_signature
->data(), out_signature
->size());