Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 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. | |
| 4 | |
| 5 #include "net/quic/crypto/proof_source_chromium.h" | |
| 6 | |
| 7 #include "base/strings/string_number_conversions.h" | |
| 8 #include "crypto/openssl_util.h" | |
| 9 #include "net/quic/crypto/crypto_protocol.h" | |
| 10 #include "net/ssl/scoped_openssl_types.h" | |
| 11 | |
| 12 using std::string; | |
| 13 using std::vector; | |
| 14 | |
| 15 namespace net { | |
| 16 | |
| 17 ProofSourceChromium::ProofSourceChromium() {} | |
| 18 | |
| 19 ProofSourceChromium::~ProofSourceChromium() {} | |
| 20 | |
| 21 bool ProofSourceChromium::Initialize(const base::FilePath& cert_path, | |
| 22 const base::FilePath& key_path) { | |
| 23 crypto::EnsureOpenSSLInit(); | |
| 24 | |
| 25 std::string cert_data; | |
| 26 if (!base::ReadFileToString(cert_path, &cert_data)) { | |
| 27 DLOG(FATAL) << "Unable to read certificates"; | |
| 28 return false; | |
| 29 } | |
| 30 | |
| 31 CertificateList certs_in_file = | |
| 32 X509Certificate::CreateCertificateListFromBytes( | |
| 33 cert_data.data(), cert_data.size(), X509Certificate::FORMAT_AUTO); | |
| 34 | |
| 35 if (certs_in_file.empty()) { | |
| 36 DLOG(FATAL) << "No certificates"; | |
| 37 return false; | |
| 38 } | |
| 39 | |
| 40 for (const scoped_refptr<X509Certificate>& cert : certs_in_file) { | |
| 41 std::string der_encoded_cert; | |
| 42 X509Certificate::GetDEREncoded(cert->os_cert_handle(), &der_encoded_cert); | |
|
ramant (doing other things)
2015/08/24 22:31:30
overly nit: should we consider checking the return
Ryan Hamilton
2015/08/24 23:29:55
Done.
| |
| 43 certificates_.push_back(der_encoded_cert); | |
| 44 } | |
| 45 | |
| 46 std::string key_data; | |
| 47 if (!base::ReadFileToString(key_path, &key_data)) { | |
| 48 DLOG(FATAL) << "Unable to read key"; | |
| 49 return false; | |
| 50 } | |
| 51 | |
| 52 const uint8_t* p = reinterpret_cast<const uint8_t*>(key_data.data()); | |
| 53 std::vector<uint8_t> input(p, p + key_data.size()); | |
| 54 private_key_.reset(crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(input)); | |
|
ramant (doing other things)
2015/08/24 22:31:30
overly nit:
Consider adding after DCHECK (ala gige
Ryan Hamilton
2015/08/24 23:29:55
Done.
| |
| 55 DCHECK(private_key_.get()) << " this: " << this; | |
| 56 return true; | |
| 57 } | |
| 58 | |
| 59 bool ProofSourceChromium::GetProof(const IPAddressNumber& server_ip, | |
| 60 const string& hostname, | |
| 61 const string& server_config, | |
| 62 bool ecdsa_ok, | |
| 63 const vector<string>** out_certs, | |
| 64 string* out_signature) { | |
| 65 DCHECK(private_key_.get()) << " this: " << this; | |
| 66 | |
| 67 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); | |
| 68 const EVP_MD* const digest = EVP_sha256(); | |
| 69 DCHECK(digest); | |
| 70 if (!digest) { | |
|
davidben
2015/08/24 22:50:24
Doesn't happen.
Ryan Hamilton
2015/08/24 23:29:55
Done.
| |
| 71 return false; | |
| 72 } | |
| 73 crypto::ScopedEVP_MD_CTX sign_context(EVP_MD_CTX_create()); | |
| 74 EVP_PKEY_CTX* pkey_ctx; | |
| 75 if (!EVP_DigestSignInit(sign_context.get(), &pkey_ctx, digest, NULL, | |
| 76 private_key_->key())) { | |
|
davidben
2015/08/24 22:50:24
If I were you, I'd just chain all these with ||s.
Ryan Hamilton
2015/08/24 23:29:55
Ah, great, thanks! I think I did what you proposed
| |
| 77 return false; | |
| 78 } | |
| 79 if (!EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING)) { | |
|
ramant (doing other things)
2015/08/24 22:31:30
overly nit: 1 != EVP_PKEY_CTX_set_rsa_padding ala
davidben
2015/08/24 22:50:24
It's an OpenSSL vs BoringSSL thing. If this code w
Ryan Hamilton
2015/08/24 23:29:55
Ah, actually davidben said that boringssl has fixe
| |
| 80 LOG(FATAL) << "EVP_PKEY_CTX_set_rsa_padding"; | |
| 81 return false; | |
| 82 } | |
| 83 // -1 sets the salt length to the digest length. | |
| 84 if (1 != EVP_PKEY_CTX_set_rsa_pss_saltlen(pkey_ctx, -1)) { | |
|
davidben
2015/08/24 22:50:24
This can be ! as well.
Ryan Hamilton
2015/08/24 23:29:55
Whoops, done!
| |
| 85 LOG(FATAL) << "EVP_PKEY_CTX_set_rsa_pss_saltlen"; | |
| 86 return false; | |
| 87 } | |
| 88 | |
| 89 if (!EVP_DigestSignUpdate(sign_context.get(), reinterpret_cast<const uint8*>( | |
| 90 kProofSignatureLabel), | |
| 91 sizeof(kProofSignatureLabel))) { | |
| 92 DLOG(ERROR) << "Unable to sign lable."; | |
|
ramant (doing other things)
2015/08/24 22:31:30
overly nit: lable -> label?
Ryan Hamilton
2015/08/24 23:29:55
Done.
| |
| 93 return false; | |
| 94 } | |
| 95 | |
| 96 if (!EVP_DigestSignUpdate(sign_context.get(), reinterpret_cast<const uint8*>( | |
| 97 server_config.data()), | |
| 98 server_config.size())) { | |
| 99 DLOG(ERROR) << "Unable to sign server config."; | |
| 100 return false; | |
| 101 } | |
| 102 | |
| 103 // Determine the maximum length of the signature. | |
| 104 size_t len = 0; | |
| 105 if (!EVP_DigestSignFinal(sign_context.get(), NULL, &len)) { | |
| 106 DLOG(ERROR) << "Unable to finalize signature."; | |
| 107 return false; | |
| 108 } | |
| 109 std::vector<uint8> signature(len); | |
|
davidben
2015/08/24 22:50:24
Nit: uint8_t
Ryan Hamilton
2015/08/24 23:29:55
Done.
| |
| 110 // Sign it. | |
| 111 if (!EVP_DigestSignFinal(sign_context.get(), vector_as_array(&signature), | |
| 112 &len)) { | |
| 113 return false; | |
| 114 } | |
|
davidben
2015/08/24 22:50:24
This should have a:
signature.resize(len);
EVP_
Ryan Hamilton
2015/08/24 23:29:55
Done.
| |
| 115 | |
| 116 out_signature->assign(reinterpret_cast<const char*>(&signature[0]), | |
| 117 signature.size()); | |
| 118 *out_certs = &certificates_; | |
| 119 VLOG(1) << "signature: " | |
| 120 << base::HexEncode(out_signature->data(), out_signature->size()); | |
| 121 return true; | |
| 122 } | |
| 123 | |
| 124 } // namespace net | |
| OLD | NEW |