Roll src/third_party/WebKit eac3800:0237a66 (svn 202606:202607)
[chromium-blink-merge.git] / net / quic / crypto / proof_source_chromium_openssl.cc
blobe122687dc932038ffa28236a0141c15a4798a005
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"
16 using std::string;
17 using std::vector;
19 namespace net {
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.";
32 return false;
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.";
41 return false;
44 for (const scoped_refptr<X509Certificate>& cert : certs_in_file) {
45 std::string der_encoded_cert;
46 if (!X509Certificate::GetDEREncoded(cert->os_cert_handle(),
47 &der_encoded_cert)) {
48 return false;
50 certificates_.push_back(der_encoded_cert);
53 std::string key_data;
54 if (!base::ReadFileToString(key_path, &key_data)) {
55 DLOG(FATAL) << "Unable to read key.";
56 return false;
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.";
64 return false;
66 return true;
69 bool ProofSourceChromium::GetProof(const IPAddressNumber& server_ip,
70 const string& hostname,
71 const string& server_config,
72 bool ecdsa_ok,
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())) {
90 return false;
93 // Determine the maximum length of the signature.
94 size_t len = 0;
95 if (!EVP_DigestSignFinal(sign_context.get(), nullptr, &len)) {
96 return false;
98 std::vector<uint8_t> signature(len);
99 // Sign it.
100 if (!EVP_DigestSignFinal(sign_context.get(), vector_as_array(&signature),
101 &len)) {
102 return false;
104 signature.resize(len);
105 out_signature->assign(reinterpret_cast<const char*>(&signature[0]),
106 signature.size());
107 *out_certs = &certificates_;
108 VLOG(1) << "signature: "
109 << base::HexEncode(out_signature->data(), out_signature->size());
110 return true;
113 } // namespace net