Skip to content

Commit

Permalink
Revert of Encrypt certificate reports before uploading to HTTP URLs (…
Browse files Browse the repository at this point in the history
…patchset chromium#20 id:400001 of https://codereview.chromium.org/1083493003/)

Reason for revert:
This CL broke the Win8 GN bot:

http://build.chromium.org/p/chromium.win/builders/Win8%20GN/builds/6514

Original issue's description:
> Encrypt certificate reports before uploading to HTTP URLs
>
> This CL introduces a new protobuf to store encrypted
> CertLoggerRequests. Serialized certificate reports are encrypted with an
> AES-CTR-128-HMAC-SHA256 AEAD (from BoringSSL, thus encrypted reports are
> only supported on BoringSSL platforms) before being uploaded to HTTP
> endpoints. |CertificateErrorReporter::IsHttpUploadUrlSupported| allows
> users of the class to set an HTTP URL if supported.
>
> BUG=461590
>
> Committed: https://crrev.com/0a3351c2a7c81284f82e6531380a21d079f55056
> Cr-Commit-Position: refs/heads/master@{#326876}

TBR=agl@chromium.org,felt@chromium.org,mattm@chromium.org,estark@chromium.org
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=461590

Review URL: https://codereview.chromium.org/1073913004

Cr-Commit-Position: refs/heads/master@{#326878}
  • Loading branch information
justindonnelly authored and Commit bot committed Apr 24, 2015
1 parent f57a7bb commit 7f606b3
Show file tree
Hide file tree
Showing 10 changed files with 26 additions and 501 deletions.
19 changes: 1 addition & 18 deletions chrome/browser/net/cert_logger.proto
Original file line number Diff line number Diff line change
Expand Up @@ -41,24 +41,6 @@ message CertLoggerRequest {
repeated string pin = 5;
};

// A wrapper proto containing an encrypted CertLoggerRequest
message EncryptedCertLoggerRequest {
// An encrypted, serialized CertLoggerRequest
required bytes encrypted_report = 1;
// The server public key version that was used to derive the shared secret.
required uint32 server_public_key_version = 2;
// The client public key that corresponds to the private key that was used
// to derive the shared secret.
required bytes client_public_key = 3;
// The encryption algorithm used to encrypt the report.
enum Algorithm {
UNKNOWN_ALGORITHM = 0;
AEAD_ECDH_AES_128_CTR_HMAC_SHA256 = 1;
}
optional Algorithm algorithm = 4
[default = AEAD_ECDH_AES_128_CTR_HMAC_SHA256];
};

// The response sent back to the user.
message CertLoggerResponse {
enum ResponseCode {
Expand All @@ -71,3 +53,4 @@ message CertLoggerResponse {
};
required ResponseCode response = 1;
};

150 changes: 6 additions & 144 deletions chrome/browser/net/certificate_error_reporter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,6 @@
#include "base/stl_util.h"
#include "base/time/time.h"
#include "chrome/browser/net/cert_logger.pb.h"

#if defined(USE_OPENSSL)
#include "crypto/aead_openssl.h"
#endif

#include "crypto/curve25519.h"
#include "crypto/hkdf.h"
#include "crypto/random.h"
#include "net/base/elements_upload_data_stream.h"
#include "net/base/load_flags.h"
#include "net/base/request_priority.h"
Expand All @@ -26,87 +18,15 @@
#include "net/ssl/ssl_info.h"
#include "net/url_request/url_request_context.h"

namespace {

// Constants used for crypto
static const uint8 kServerPublicKey[] = {
0x51, 0xcc, 0x52, 0x67, 0x42, 0x47, 0x3b, 0x10, 0xe8, 0x63, 0x18,
0x3c, 0x61, 0xa7, 0x96, 0x76, 0x86, 0x91, 0x40, 0x71, 0x39, 0x5f,
0x31, 0x1a, 0x39, 0x5b, 0x76, 0xb1, 0x6b, 0x3d, 0x6a, 0x2b};
static const uint32 kServerPublicKeyVersion = 1;

#if defined(USE_OPENSSL)

static const char kHkdfLabel[] = "certificate report";

bool EncryptSerializedReport(
const uint8* server_public_key,
uint32 server_public_key_version,
const std::string& report,
chrome_browser_net::EncryptedCertLoggerRequest* encrypted_report) {
// Generate an ephemeral key pair to generate a shared secret.
uint8 public_key[crypto::curve25519::kBytes];
uint8 private_key[crypto::curve25519::kScalarBytes];
uint8 shared_secret[crypto::curve25519::kBytes];

crypto::RandBytes(private_key, sizeof(private_key));
crypto::curve25519::ScalarBaseMult(private_key, public_key);
crypto::curve25519::ScalarMult(private_key, server_public_key, shared_secret);

crypto::Aead aead(crypto::Aead::AES_128_CTR_HMAC_SHA256);
crypto::HKDF hkdf(std::string((char*)shared_secret, sizeof(shared_secret)),
kHkdfLabel, std::string(), 0, 0, aead.KeyLength());

const std::string key(hkdf.subkey_secret().data(),
hkdf.subkey_secret().size());
aead.Init(&key);

// Use an all-zero nonce because the key is random per-message.
std::string nonce(aead.NonceLength(), 0);

std::string ciphertext;
if (!aead.Seal(report, nonce, "", &ciphertext)) {
LOG(ERROR) << "Error sealing certificate report.";
return false;
}

encrypted_report->set_encrypted_report(ciphertext);
encrypted_report->set_server_public_key_version(server_public_key_version);
encrypted_report->set_client_public_key(
std::string((char*)public_key, sizeof(public_key)));
encrypted_report->set_algorithm(
chrome_browser_net::EncryptedCertLoggerRequest::
AEAD_ECDH_AES_128_CTR_HMAC_SHA256);
return true;
}
#endif

} // namespace

namespace chrome_browser_net {

CertificateErrorReporter::CertificateErrorReporter(
net::URLRequestContext* request_context,
const GURL& upload_url,
CookiesPreference cookies_preference)
: CertificateErrorReporter(request_context,
upload_url,
cookies_preference,
kServerPublicKey,
kServerPublicKeyVersion) {
}

CertificateErrorReporter::CertificateErrorReporter(
net::URLRequestContext* request_context,
const GURL& upload_url,
CookiesPreference cookies_preference,
const uint8 server_public_key[32],
const uint32 server_public_key_version)
: request_context_(request_context),
upload_url_(upload_url),
cookies_preference_(cookies_preference),
server_public_key_(server_public_key),
server_public_key_version_(server_public_key_version) {
cookies_preference_(cookies_preference) {
DCHECK(!upload_url.is_empty());
}

Expand All @@ -118,32 +38,18 @@ void CertificateErrorReporter::SendReport(ReportType type,
const std::string& hostname,
const net::SSLInfo& ssl_info) {
CertLoggerRequest request;
std::string out;

BuildReport(hostname, ssl_info, &request);

switch (type) {
case REPORT_TYPE_PINNING_VIOLATION:
SendCertLoggerRequest(request);
break;
case REPORT_TYPE_EXTENDED_REPORTING:
if (upload_url_.SchemeIsCryptographic()) {
SendCertLoggerRequest(request);
} else {
DCHECK(IsHttpUploadUrlSupported());
#if defined(USE_OPENSSL)
EncryptedCertLoggerRequest encrypted_report;
std::string serialized_report;
request.SerializeToString(&serialized_report);
if (!EncryptSerializedReport(server_public_key_,
server_public_key_version_,
serialized_report, &encrypted_report)) {
LOG(ERROR) << "Failed to encrypt serialized report.";
return;
}
std::string serialized_encrypted_report;
encrypted_report.SerializeToString(&serialized_encrypted_report);
SendSerializedRequest(serialized_encrypted_report);
#endif
}
// TODO(estark): Encrypt the report if not sending over HTTPS.
DCHECK(upload_url_.SchemeIsCryptographic());
SendCertLoggerRequest(request);
break;
default:
NOTREACHED();
Expand Down Expand Up @@ -178,55 +84,11 @@ scoped_ptr<net::URLRequest> CertificateErrorReporter::CreateURLRequest(
return request.Pass();
}

bool CertificateErrorReporter::IsHttpUploadUrlSupported() {
#if defined(USE_OPENSSL)
return true;
#else
return false;
#endif
}

// Used only by tests.
#if defined(USE_OPENSSL)
bool CertificateErrorReporter::DecryptCertificateErrorReport(
const uint8 server_private_key[32],
const EncryptedCertLoggerRequest& encrypted_report,
CertLoggerRequest* decrypted_report) {
uint8 shared_secret[crypto::curve25519::kBytes];
crypto::curve25519::ScalarMult(
server_private_key, (uint8*)encrypted_report.client_public_key().data(),
shared_secret);

crypto::Aead aead(crypto::Aead::AES_128_CTR_HMAC_SHA256);
crypto::HKDF hkdf(std::string((char*)shared_secret, sizeof(shared_secret)),
kHkdfLabel, std::string(), 0, 0, aead.KeyLength());

const std::string key(hkdf.subkey_secret().data(),
hkdf.subkey_secret().size());
aead.Init(&key);

// Use an all-zero nonce because the key is random per-message.
std::string nonce(aead.NonceLength(), 0);

std::string plaintext;
if (!aead.Open(encrypted_report.encrypted_report(), nonce, "", &plaintext)) {
LOG(ERROR) << "Error opening certificate report";
return false;
}

return decrypted_report->ParseFromString(plaintext);
}
#endif

void CertificateErrorReporter::SendCertLoggerRequest(
const CertLoggerRequest& request) {
std::string serialized_request;
request.SerializeToString(&serialized_request);
SendSerializedRequest(serialized_request);
}

void CertificateErrorReporter::SendSerializedRequest(
const std::string& serialized_request) {
scoped_ptr<net::URLRequest> url_request = CreateURLRequest(request_context_);
url_request->set_method("POST");

Expand Down
28 changes: 0 additions & 28 deletions chrome/browser/net/certificate_error_reporter.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ class SSLInfo;
namespace chrome_browser_net {

class CertLoggerRequest;
class EncryptedCertLoggerRequest;

// Provides functionality for sending reports about invalid SSL
// certificate chains to a report collection server.
Expand Down Expand Up @@ -49,13 +48,6 @@ class CertificateErrorReporter : public net::URLRequest::Delegate {
const GURL& upload_url,
CookiesPreference cookies_preference);

// Allows tests to use a server public key with known private key.
CertificateErrorReporter(net::URLRequestContext* request_context,
const GURL& upload_url,
CookiesPreference cookies_preference,
const uint8 server_public_key[32],
const uint32 server_public_key_version);

~CertificateErrorReporter() override;

// Construct, serialize, and send a certificate report to the report
Expand All @@ -66,11 +58,6 @@ class CertificateErrorReporter : public net::URLRequest::Delegate {
// responsible for enforcing any preconditions (such as obtaining user
// opt-in, only sending reports for certain hostnames, checking for
// incognito mode, etc.).
//
// On some platforms (but not all), CertificateErrorReporter can use
// an HTTP endpoint to send encrypted extended reporting reports. On
// unsupported platforms, callers must send extended reporting reports
// over SSL.
virtual void SendReport(ReportType type,
const std::string& hostname,
const net::SSLInfo& ssl_info);
Expand All @@ -79,16 +66,6 @@ class CertificateErrorReporter : public net::URLRequest::Delegate {
void OnResponseStarted(net::URLRequest* request) override;
void OnReadCompleted(net::URLRequest* request, int bytes_read) override;

// Callers can use this method to determine if sending reports over
// HTTP is supported.
static bool IsHttpUploadUrlSupported();

// Used by tests.
static bool DecryptCertificateErrorReport(
const uint8 server_private_key[32],
const EncryptedCertLoggerRequest& encrypted_report,
CertLoggerRequest* decrypted_report);

private:
// Create a URLRequest with which to send a certificate report to the
// server.
Expand All @@ -99,8 +76,6 @@ class CertificateErrorReporter : public net::URLRequest::Delegate {
// collection server.
void SendCertLoggerRequest(const CertLoggerRequest& request);

void SendSerializedRequest(const std::string& serialized_request);

// Populate the CertLoggerRequest for a report.
static void BuildReport(const std::string& hostname,
const net::SSLInfo& ssl_info,
Expand All @@ -117,9 +92,6 @@ class CertificateErrorReporter : public net::URLRequest::Delegate {

CookiesPreference cookies_preference_;

const uint8* server_public_key_;
const uint32 server_public_key_version_;

DISALLOW_COPY_AND_ASSIGN(CertificateErrorReporter);
};

Expand Down
Loading

0 comments on commit 7f606b3

Please sign in to comment.