summaryrefslogtreecommitdiffstats
path: root/extensions
diff options
context:
space:
mode:
authordavidben <davidben@chromium.org>2015-10-02 09:46:39 -0700
committerCommit bot <commit-bot@chromium.org>2015-10-02 16:47:29 +0000
commit9cd4b57584efba6ae7686e1b4689434e73543c96 (patch)
tree332895584a1fb755a3bd9b32bde605df88c1c760 /extensions
parentebf0bc25277c6a656337e442060fc51dfc201048 (diff)
downloadchromium_src-9cd4b57584efba6ae7686e1b4689434e73543c96.zip
chromium_src-9cd4b57584efba6ae7686e1b4689434e73543c96.tar.gz
chromium_src-9cd4b57584efba6ae7686e1b4689434e73543c96.tar.bz2
Fold away the NSS cast_cert_validator.cc path.
All platforms with extensions may assume OpenSSL. This removes the three-argument form of VerificationResult as it's no longer used. BUG=519504 Review URL: https://codereview.chromium.org/1365733004 Cr-Commit-Position: refs/heads/master@{#352054}
Diffstat (limited to 'extensions')
-rw-r--r--extensions/browser/api/cast_channel/cast_auth_util.cc24
-rw-r--r--extensions/browser/api/cast_channel/cast_auth_util.h12
-rw-r--r--extensions/browser/api/cast_channel/cast_channel_api.cc2
-rw-r--r--extensions/browser/api/cast_channel/logger.cc6
-rw-r--r--extensions/browser/api/cast_channel/logger_unittest.cc21
-rw-r--r--extensions/browser/api/cast_channel/logger_util.cc4
-rw-r--r--extensions/browser/api/cast_channel/logger_util.h3
-rw-r--r--extensions/common/BUILD.gn14
-rw-r--r--extensions/common/api/cast_channel/logging.proto1
-rw-r--r--extensions/common/cast/cast_cert_validator.cc151
-rw-r--r--extensions/common/cast/cast_cert_validator.h12
-rw-r--r--extensions/common/cast/cast_cert_validator_nss.cc155
-rw-r--r--extensions/common/cast/cast_cert_validator_openssl.cc158
-rw-r--r--extensions/extensions.gyp26
-rw-r--r--extensions/extensions.gypi6
15 files changed, 159 insertions, 436 deletions
diff --git a/extensions/browser/api/cast_channel/cast_auth_util.cc b/extensions/browser/api/cast_channel/cast_auth_util.cc
index 759ee7d..10c3775 100644
--- a/extensions/browser/api/cast_channel/cast_auth_util.cc
+++ b/extensions/browser/api/cast_channel/cast_auth_util.cc
@@ -64,7 +64,6 @@ AuthResult TranslateVerificationResult(
const cast_crypto::VerificationResult& result) {
AuthResult translated;
translated.error_message = result.error_message;
- translated.nss_error_code = result.library_error_code;
switch (result.error_type) {
case cast_crypto::VerificationResult::ERROR_NONE:
translated.error_type = AuthResult::ERROR_NONE;
@@ -90,8 +89,10 @@ AuthResult TranslateVerificationResult(
} // namespace
AuthResult::AuthResult()
- : error_type(ERROR_NONE), nss_error_code(0), channel_policies(POLICY_NONE) {
-}
+ : error_type(ERROR_NONE), channel_policies(POLICY_NONE) {}
+
+AuthResult::AuthResult(const std::string& error_message, ErrorType error_type)
+ : error_message(error_message), error_type(error_type) {}
AuthResult::~AuthResult() {
}
@@ -99,22 +100,7 @@ AuthResult::~AuthResult() {
// static
AuthResult AuthResult::CreateWithParseError(const std::string& error_message,
ErrorType error_type) {
- return AuthResult(kParseErrorPrefix + error_message, error_type, 0);
-}
-
-// static
-AuthResult AuthResult::CreateWithNSSError(const std::string& error_message,
- ErrorType error_type,
- int nss_error_code) {
- return AuthResult(error_message, error_type, nss_error_code);
-}
-
-AuthResult::AuthResult(const std::string& error_message,
- ErrorType error_type,
- int nss_error_code)
- : error_message(error_message),
- error_type(error_type),
- nss_error_code(nss_error_code) {
+ return AuthResult(kParseErrorPrefix + error_message, error_type);
}
AuthResult AuthenticateChallengeReply(const CastMessage& challenge_reply,
diff --git a/extensions/browser/api/cast_channel/cast_auth_util.h b/extensions/browser/api/cast_channel/cast_auth_util.h
index a500586..e1c07f4 100644
--- a/extensions/browser/api/cast_channel/cast_auth_util.h
+++ b/extensions/browser/api/cast_channel/cast_auth_util.h
@@ -37,25 +37,19 @@ struct AuthResult {
// Constructs a AuthResult that corresponds to success.
AuthResult();
+
+ AuthResult(const std::string& error_message, ErrorType error_type);
+
~AuthResult();
static AuthResult CreateWithParseError(const std::string& error_message,
ErrorType error_type);
- static AuthResult CreateWithNSSError(const std::string& error_message,
- ErrorType error_type,
- int nss_error_code);
bool success() const { return error_type == ERROR_NONE; }
std::string error_message;
ErrorType error_type;
- int nss_error_code;
unsigned int channel_policies;
-
- private:
- AuthResult(const std::string& error_message,
- ErrorType error_type,
- int nss_error_code);
};
// Authenticates the given |challenge_reply|:
diff --git a/extensions/browser/api/cast_channel/cast_channel_api.cc b/extensions/browser/api/cast_channel/cast_channel_api.cc
index 52c4d90..0b1fa2e 100644
--- a/extensions/browser/api/cast_channel/cast_channel_api.cc
+++ b/extensions/browser/api/cast_channel/cast_channel_api.cc
@@ -90,8 +90,6 @@ void FillErrorInfo(ChannelError error_state,
}
if (last_errors.net_return_value <= 0)
error_info->net_return_value.reset(new int(last_errors.net_return_value));
- if (last_errors.nss_error_code < 0)
- error_info->nss_error_code.reset(new int(last_errors.nss_error_code));
}
bool IsValidConnectInfoPort(const ConnectInfo& connect_info) {
diff --git a/extensions/browser/api/cast_channel/logger.cc b/extensions/browser/api/cast_channel/logger.cc
index 77b281f..e6d3a77 100644
--- a/extensions/browser/api/cast_channel/logger.cc
+++ b/extensions/browser/api/cast_channel/logger.cc
@@ -115,10 +115,6 @@ void MaybeSetLastErrors(const SocketEvent& event, LastErrors* last_errors) {
event.challenge_reply_error_type();
last_errors->event_type = event.type();
}
- if (event.has_nss_error_code()) {
- last_errors->nss_error_code = event.nss_error_code();
- last_errors->event_type = event.type();
- }
}
} // namespace
@@ -265,8 +261,6 @@ void Logger::LogSocketChallengeReplyEvent(int channel_id,
SocketEvent event = CreateEvent(proto::AUTH_CHALLENGE_REPLY);
event.set_challenge_reply_error_type(
ChallegeReplyErrorToProto(auth_result.error_type));
- if (auth_result.nss_error_code != 0)
- event.set_nss_error_code(auth_result.nss_error_code);
LogSocketEvent(channel_id, event);
}
diff --git a/extensions/browser/api/cast_channel/logger_unittest.cc b/extensions/browser/api/cast_channel/logger_unittest.cc
index b3a40ad..13e00b7 100644
--- a/extensions/browser/api/cast_channel/logger_unittest.cc
+++ b/extensions/browser/api/cast_channel/logger_unittest.cc
@@ -16,8 +16,6 @@ namespace extensions {
namespace api {
namespace cast_channel {
-const int kTestNssErrorCode = -8164;
-
using proto::AggregatedSocketEvent;
using proto::EventType;
using proto::Log;
@@ -107,9 +105,7 @@ TEST_F(CastChannelLoggerTest, BasicLogging) {
clock_->Advance(base::TimeDelta::FromMicroseconds(1));
auth_result =
- AuthResult::CreateWithNSSError("Parsing failed",
- AuthResult::ERROR_CERT_PARSING_FAILED,
- kTestNssErrorCode);
+ AuthResult("Parsing failed", AuthResult::ERROR_CERT_PARSING_FAILED);
logger_->LogSocketChallengeReplyEvent(2, auth_result);
LastErrors last_errors = logger_->GetLastErrors(2);
@@ -117,7 +113,6 @@ TEST_F(CastChannelLoggerTest, BasicLogging) {
EXPECT_EQ(last_errors.net_return_value, net::OK);
EXPECT_EQ(last_errors.challenge_reply_error_type,
proto::CHALLENGE_REPLY_ERROR_CERT_PARSING_FAILED);
- EXPECT_EQ(last_errors.nss_error_code, kTestNssErrorCode);
scoped_ptr<Log> log = GetLog();
ASSERT_TRUE(log);
@@ -179,7 +174,7 @@ TEST_F(CastChannelLoggerTest, BasicLogging) {
EXPECT_EQ(proto::CHALLENGE_REPLY_ERROR_CERT_PARSING_FAILED,
event.challenge_reply_error_type());
EXPECT_FALSE(event.has_net_return_value());
- EXPECT_EQ(kTestNssErrorCode, event.nss_error_code());
+ EXPECT_FALSE(event.has_nss_error_code());
}
}
}
@@ -212,21 +207,16 @@ TEST_F(CastChannelLoggerTest, LogLastErrorEvents) {
EXPECT_EQ(last_errors.net_return_value, net::OK);
EXPECT_EQ(last_errors.challenge_reply_error_type,
proto::CHALLENGE_REPLY_ERROR_NONE);
- EXPECT_EQ(last_errors.nss_error_code, 0);
- // Now log a challenge reply error with NSS error code. LastErrors will be
- // set.
+ // Now log a challenge reply error. LastErrors will be set.
clock_->Advance(base::TimeDelta::FromMicroseconds(1));
- auth_result = AuthResult::CreateWithNSSError(
- "Some error",
- AuthResult::ErrorType::ERROR_WRONG_PAYLOAD_TYPE,
- kTestNssErrorCode);
+ auth_result =
+ AuthResult("Some error failed", AuthResult::ERROR_WRONG_PAYLOAD_TYPE);
logger_->LogSocketChallengeReplyEvent(3, auth_result);
last_errors = logger_->GetLastErrors(3);
EXPECT_EQ(last_errors.event_type, proto::AUTH_CHALLENGE_REPLY);
EXPECT_EQ(last_errors.challenge_reply_error_type,
proto::CHALLENGE_REPLY_ERROR_WRONG_PAYLOAD_TYPE);
- EXPECT_EQ(last_errors.nss_error_code, kTestNssErrorCode);
// Logging a non-error event does not change the LastErrors for the channel.
clock_->Advance(base::TimeDelta::FromMicroseconds(1));
@@ -235,7 +225,6 @@ TEST_F(CastChannelLoggerTest, LogLastErrorEvents) {
EXPECT_EQ(last_errors.event_type, proto::AUTH_CHALLENGE_REPLY);
EXPECT_EQ(last_errors.challenge_reply_error_type,
proto::CHALLENGE_REPLY_ERROR_WRONG_PAYLOAD_TYPE);
- EXPECT_EQ(last_errors.nss_error_code, kTestNssErrorCode);
}
TEST_F(CastChannelLoggerTest, LogSocketReadWrite) {
diff --git a/extensions/browser/api/cast_channel/logger_util.cc b/extensions/browser/api/cast_channel/logger_util.cc
index db5f201..35e2c10 100644
--- a/extensions/browser/api/cast_channel/logger_util.cc
+++ b/extensions/browser/api/cast_channel/logger_util.cc
@@ -12,9 +12,7 @@ namespace cast_channel {
LastErrors::LastErrors()
: event_type(proto::EVENT_TYPE_UNKNOWN),
challenge_reply_error_type(proto::CHALLENGE_REPLY_ERROR_NONE),
- net_return_value(net::OK),
- nss_error_code(0) {
-}
+ net_return_value(net::OK) {}
LastErrors::~LastErrors() {
}
diff --git a/extensions/browser/api/cast_channel/logger_util.h b/extensions/browser/api/cast_channel/logger_util.h
index 2a9f293..2b5de5b 100644
--- a/extensions/browser/api/cast_channel/logger_util.h
+++ b/extensions/browser/api/cast_channel/logger_util.h
@@ -31,9 +31,6 @@ struct LastErrors {
// The most recent net_return_value logged for the socket.
int net_return_value;
-
- // The most recent NSS error logged for the socket.
- int nss_error_code;
};
} // namespace cast_channel
diff --git a/extensions/common/BUILD.gn b/extensions/common/BUILD.gn
index c76d9b1..3a557d3 100644
--- a/extensions/common/BUILD.gn
+++ b/extensions/common/BUILD.gn
@@ -60,6 +60,7 @@ if (enable_extensions) {
"//extensions:extensions_resources",
"//ipc",
"//net",
+ "//third_party/boringssl",
"//third_party/icu",
"//third_party/libxml",
"//third_party/re2",
@@ -69,19 +70,6 @@ if (enable_extensions) {
"//url",
]
- if (use_openssl) {
- sources +=
- rebase_path(extensions_gypi_values.extensions_common_sources_openssl,
- ".",
- "//extensions")
- deps += [ "//third_party/boringssl" ]
- } else {
- sources += rebase_path(
- extensions_gypi_values.extensions_common_sources_nonopenssl,
- ".",
- "//extensions")
- }
-
if (enable_nacl) {
nacl_sources =
rebase_path(extensions_gypi_values.extensions_common_sources_nacl,
diff --git a/extensions/common/api/cast_channel/logging.proto b/extensions/common/api/cast_channel/logging.proto
index a629aee..6ac52e4 100644
--- a/extensions/common/api/cast_channel/logging.proto
+++ b/extensions/common/api/cast_channel/logging.proto
@@ -142,6 +142,7 @@ message SocketEvent {
optional ErrorState error_state = 10;
optional ChallengeReplyErrorType challenge_reply_error_type = 11;
+ // No longer used.
optional int32 nss_error_code = 12;
}
diff --git a/extensions/common/cast/cast_cert_validator.cc b/extensions/common/cast/cast_cert_validator.cc
index cdd803a..5bf7300 100644
--- a/extensions/common/cast/cast_cert_validator.cc
+++ b/extensions/common/cast/cast_cert_validator.cc
@@ -4,27 +4,156 @@
#include "extensions/common/cast/cast_cert_validator.h"
+#include <openssl/digest.h>
+#include <openssl/evp.h>
+#include <openssl/rsa.h>
+#include <openssl/x509.h>
+
+#include "base/logging.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_util.h"
+#include "base/strings/stringprintf.h"
+#include "crypto/openssl_util.h"
+#include "crypto/scoped_openssl_types.h"
#include "extensions/browser/api/cast_channel/cast_auth_ica.h"
+#include "net/cert/x509_certificate.h"
+#include "net/cert/x509_util_openssl.h"
+#include "net/ssl/scoped_openssl_types.h"
namespace extensions {
namespace api {
namespace cast_crypto {
+namespace {
-VerificationResult::VerificationResult()
- : VerificationResult("", ERROR_NONE, 0) {
-}
+class CertVerificationContextImpl : public CertVerificationContext {
+ public:
+ // Takes ownership of the passed-in x509 object
+ explicit CertVerificationContextImpl(net::ScopedX509 x509)
+ : x509_(x509.Pass()) {}
+
+ VerificationResult VerifySignatureOverData(
+ const base::StringPiece& signature,
+ const base::StringPiece& data) const override {
+ // Retrieve public key object.
+ crypto::ScopedEVP_PKEY public_key(X509_get_pubkey(x509_.get()));
+ if (!public_key) {
+ return VerificationResult(
+ "Failed to extract device certificate public key.",
+ VerificationResult::ERROR_CERT_INVALID);
+ }
+ // Make sure the key is RSA.
+ const int public_key_type = EVP_PKEY_id(public_key.get());
+ if (public_key_type != EVP_PKEY_RSA) {
+ return VerificationResult(
+ std::string("Expected RSA key type for client certificate, got ") +
+ base::IntToString(public_key_type) + " instead.",
+ VerificationResult::ERROR_CERT_INVALID);
+ }
+ // Verify signature.
+ const crypto::ScopedEVP_MD_CTX ctx(EVP_MD_CTX_create());
+ if (!ctx ||
+ !EVP_DigestVerifyInit(ctx.get(), nullptr, EVP_sha1(), nullptr,
+ public_key.get()) ||
+ !EVP_DigestVerifyUpdate(ctx.get(), data.data(), data.size()) ||
+ !EVP_DigestVerifyFinal(
+ ctx.get(), reinterpret_cast<const uint8_t*>(signature.data()),
+ signature.size())) {
+ return VerificationResult("Signature verification failed.",
+ VerificationResult::ERROR_SIGNATURE_INVALID);
+ }
+ return VerificationResult();
+ }
+
+ std::string GetCommonName() const override {
+ int common_name_length = X509_NAME_get_text_by_NID(
+ x509_->cert_info->subject, NID_commonName, NULL, 0);
+ if (common_name_length < 0)
+ return std::string();
+ std::string common_name;
+ common_name_length = X509_NAME_get_text_by_NID(
+ x509_->cert_info->subject, NID_commonName,
+ base::WriteInto(&common_name,
+ static_cast<size_t>(common_name_length) + 1),
+ common_name_length + 1);
+ if (common_name_length < 0)
+ return std::string();
+ return common_name;
+ }
+
+ private:
+ net::ScopedX509 x509_;
+};
+
+} // namespace
+
+VerificationResult::VerificationResult() : VerificationResult("", ERROR_NONE) {}
VerificationResult::VerificationResult(const std::string& in_error_message,
ErrorType in_error_type)
- : VerificationResult(in_error_message, in_error_type, 0) {
-}
+ : error_type(in_error_type), error_message(in_error_message) {}
-VerificationResult::VerificationResult(const std::string& in_error_message,
- ErrorType in_error_type,
- int in_error_code)
- : error_type(in_error_type),
- error_message(in_error_message),
- library_error_code(in_error_code) {
+VerificationResult VerifyDeviceCert(
+ const base::StringPiece& device_cert,
+ const std::vector<std::string>& ica_certs,
+ scoped_ptr<CertVerificationContext>* context) {
+ crypto::EnsureOpenSSLInit();
+ crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
+
+ // If the list of intermediates is empty then use kPublicKeyICA1 as
+ // the trusted CA (legacy case).
+ // Otherwise, use the first intermediate in the list as long as it
+ // is in the allowed list of intermediates.
+ base::StringPiece ica_public_key_der =
+ (ica_certs.size() == 0)
+ ? cast_channel::GetDefaultTrustedICAPublicKey()
+ : cast_channel::GetTrustedICAPublicKey(ica_certs[0]);
+
+ if (ica_public_key_der.empty()) {
+ return VerificationResult(
+ "Device certificate is not signed by a trusted CA",
+ VerificationResult::ERROR_CERT_UNTRUSTED);
+ }
+
+ // Initialize the ICA public key.
+ const uint8_t* ica_public_key_der_ptr =
+ reinterpret_cast<const uint8_t*>(ica_public_key_der.data());
+ const uint8_t* ica_public_key_der_end =
+ ica_public_key_der_ptr + ica_public_key_der.size();
+ crypto::ScopedRSA ica_public_key_rsa(d2i_RSAPublicKey(
+ NULL, &ica_public_key_der_ptr, ica_public_key_der.size()));
+ if (!ica_public_key_rsa || ica_public_key_der_ptr != ica_public_key_der_end) {
+ return VerificationResult("Failed to import trusted public key.",
+ VerificationResult::ERROR_INTERNAL);
+ }
+ crypto::ScopedEVP_PKEY ica_public_key_evp(EVP_PKEY_new());
+ if (!ica_public_key_evp ||
+ !EVP_PKEY_set1_RSA(ica_public_key_evp.get(), ica_public_key_rsa.get())) {
+ return VerificationResult("Failed to import trusted public key.",
+ VerificationResult::ERROR_INTERNAL);
+ }
+
+ // Parse the device certificate.
+ const uint8_t* device_cert_der_ptr =
+ reinterpret_cast<const uint8_t*>(device_cert.data());
+ const uint8_t* device_cert_der_end = device_cert_der_ptr + device_cert.size();
+ net::ScopedX509 device_cert_x509(
+ d2i_X509(NULL, &device_cert_der_ptr, device_cert.size()));
+ if (!device_cert_x509 || device_cert_der_ptr != device_cert_der_end) {
+ return VerificationResult("Failed to parse device certificate.",
+ VerificationResult::ERROR_CERT_INVALID);
+ }
+
+ // Verify device certificate.
+ if (X509_verify(device_cert_x509.get(), ica_public_key_evp.get()) != 1) {
+ return VerificationResult(
+ "Device certificate signature verification failed.",
+ VerificationResult::ERROR_CERT_INVALID);
+ }
+
+ if (context)
+ context->reset(new CertVerificationContextImpl(device_cert_x509.Pass()));
+
+ return VerificationResult();
}
bool SetTrustedCertificateAuthoritiesForTest(const std::string& keys,
diff --git a/extensions/common/cast/cast_cert_validator.h b/extensions/common/cast/cast_cert_validator.h
index 720fff5..8a37fa1 100644
--- a/extensions/common/cast/cast_cert_validator.h
+++ b/extensions/common/cast/cast_cert_validator.h
@@ -39,25 +39,17 @@ struct VerificationResult {
// Construct error-related objects
VerificationResult(const std::string& error_message, ErrorType error_type);
- VerificationResult(const std::string& error_message,
- ErrorType error_type,
- int error_code);
bool Success() const { return error_type == ERROR_NONE; }
bool Failure() const { return error_type != ERROR_NONE; }
- // Generates a string representation of this object for logging.
- std::string GetLogString() const;
-
ErrorType error_type;
// Human-readable description of the problem if error_type != ERROR_NONE
std::string error_message;
- // May contain the underlying crypto library error code.
- int library_error_code;
};
-// An object of this type is returned by the VerifyCert function, and can be
-// used for additional certificate-related operations, using the verified
+// An object of this type is returned by the VerifyDeviceCert function, and can
+// be used for additional certificate-related operations, using the verified
// certificate.
class CertVerificationContext {
public:
diff --git a/extensions/common/cast/cast_cert_validator_nss.cc b/extensions/common/cast/cast_cert_validator_nss.cc
deleted file mode 100644
index 47b7648..0000000
--- a/extensions/common/cast/cast_cert_validator_nss.cc
+++ /dev/null
@@ -1,155 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "extensions/common/cast/cast_cert_validator.h"
-
-#include <cert.h>
-#include <cryptohi.h>
-#include <pk11pub.h>
-#include <seccomon.h>
-
-#include "base/logging.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/strings/string_number_conversions.h"
-#include "crypto/nss_util.h"
-#include "crypto/scoped_nss_types.h"
-#include "extensions/browser/api/cast_channel/cast_auth_ica.h"
-
-namespace extensions {
-namespace api {
-namespace cast_crypto {
-
-namespace {
-
-typedef scoped_ptr<
- CERTCertificate,
- crypto::NSSDestroyer<CERTCertificate, CERT_DestroyCertificate>>
- ScopedCERTCertificate;
-
-class CertVerificationContextNSS : public CertVerificationContext {
- public:
- explicit CertVerificationContextNSS(CERTCertificate* certificate)
- : certificate_(certificate) {}
-
- VerificationResult VerifySignatureOverData(
- const base::StringPiece& signature,
- const base::StringPiece& data) const override {
- // Retrieve public key object
- crypto::ScopedSECKEYPublicKey public_key_obj(
- CERT_ExtractPublicKey(certificate_.get()));
- if (!public_key_obj.get()) {
- return VerificationResult(
- "Failed to extract device certificate public key.",
- VerificationResult::ERROR_CERT_INVALID);
- }
- // Verify signature.
- SECItem signature_item;
- signature_item.type = siBuffer;
- signature_item.data =
- reinterpret_cast<unsigned char*>(const_cast<char*>(signature.data()));
- signature_item.len = signature.length();
- if (VFY_VerifyDataDirect(
- reinterpret_cast<unsigned char*>(const_cast<char*>(data.data())),
- data.size(), public_key_obj.get(), &signature_item,
- SEC_OID_PKCS1_RSA_ENCRYPTION, SEC_OID_SHA1, NULL,
- NULL) != SECSuccess) {
- return VerificationResult("Signature verification failed.",
- VerificationResult::ERROR_SIGNATURE_INVALID,
- PORT_GetError());
- }
- return VerificationResult();
- }
-
- std::string GetCommonName() const override {
- char* common_name = CERT_GetCommonName(&certificate_->subject);
- if (!common_name)
- return std::string();
-
- std::string result(common_name);
- PORT_Free(common_name);
- return result;
- }
-
- private:
- ScopedCERTCertificate certificate_;
-};
-
-} // namespace
-
-VerificationResult VerifyDeviceCert(
- const base::StringPiece& device_cert,
- const std::vector<std::string>& ica_certs,
- scoped_ptr<CertVerificationContext>* context) {
- crypto::EnsureNSSInit();
-
- // If the list of intermediates is empty then use kPublicKeyICA1 as
- // the trusted CA (legacy case).
- // Otherwise, use the first intermediate in the list as long as it
- // is in the allowed list of intermediates.
- base::StringPiece ica_public_key_der =
- (ica_certs.size() == 0)
- ? cast_channel::GetDefaultTrustedICAPublicKey()
- : cast_channel::GetTrustedICAPublicKey(ica_certs[0]);
-
- if (ica_public_key_der.empty()) {
- return VerificationResult(
- "Device certificate is not signed by a trusted CA",
- VerificationResult::ERROR_CERT_UNTRUSTED);
- }
- // Initialize the ICA public key.
- SECItem ica_public_key_der_item;
- ica_public_key_der_item.type = SECItemType::siDERCertBuffer;
- ica_public_key_der_item.data = const_cast<uint8_t*>(
- reinterpret_cast<const uint8_t*>(ica_public_key_der.data()));
- ica_public_key_der_item.len = ica_public_key_der.size();
-
- crypto::ScopedSECKEYPublicKey ica_public_key_obj(
- SECKEY_ImportDERPublicKey(&ica_public_key_der_item, CKK_RSA));
- if (!ica_public_key_obj) {
- return VerificationResult("Failed to import trusted public key.",
- VerificationResult::ERROR_INTERNAL,
- PORT_GetError());
- }
- SECItem device_cert_der_item;
- device_cert_der_item.type = siDERCertBuffer;
- // Make a copy of certificate string so it is safe to type cast.
- device_cert_der_item.data =
- reinterpret_cast<unsigned char*>(const_cast<char*>(device_cert.data()));
- device_cert_der_item.len = device_cert.length();
-
- // Parse into a certificate structure.
- ScopedCERTCertificate device_cert_obj(CERT_NewTempCertificate(
- CERT_GetDefaultCertDB(), &device_cert_der_item, NULL, PR_FALSE, PR_TRUE));
- if (!device_cert_obj.get()) {
- return VerificationResult("Failed to parse device certificate.",
- VerificationResult::ERROR_CERT_INVALID,
- PORT_GetError());
- }
- if (CERT_VerifySignedDataWithPublicKey(&device_cert_obj->signatureWrap,
- ica_public_key_obj.get(),
- NULL) != SECSuccess) {
- return VerificationResult("Signature verification failed.",
- VerificationResult::ERROR_SIGNATURE_INVALID,
- PORT_GetError());
- }
- if (context) {
- scoped_ptr<CertVerificationContext> tmp_context(
- new CertVerificationContextNSS(device_cert_obj.release()));
- tmp_context.swap(*context);
- }
-
- return VerificationResult();
-}
-
-std::string VerificationResult::GetLogString() const {
- std::string nssError = "NSS Error Code: ";
- nssError += base::IntToString(library_error_code);
- return error_message.size()
- ? std::string("Error: ") + error_message + ", " + nssError
- : nssError;
-}
-
-} // namespace cast_crypto
-} // namespace api
-} // namespace extensions
diff --git a/extensions/common/cast/cast_cert_validator_openssl.cc b/extensions/common/cast/cast_cert_validator_openssl.cc
deleted file mode 100644
index 4e0e08b..0000000
--- a/extensions/common/cast/cast_cert_validator_openssl.cc
+++ /dev/null
@@ -1,158 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "extensions/common/cast/cast_cert_validator.h"
-
-#include <openssl/digest.h>
-#include <openssl/evp.h>
-#include <openssl/rsa.h>
-#include <openssl/x509.h>
-
-#include "base/logging.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_util.h"
-#include "base/strings/stringprintf.h"
-#include "crypto/openssl_util.h"
-#include "crypto/scoped_openssl_types.h"
-#include "extensions/browser/api/cast_channel/cast_auth_ica.h"
-#include "net/cert/x509_certificate.h"
-#include "net/cert/x509_util_openssl.h"
-#include "net/ssl/scoped_openssl_types.h"
-
-namespace extensions {
-namespace api {
-namespace cast_crypto {
-namespace {
-
-class CertVerificationContextOpenSSL : public CertVerificationContext {
- public:
- // Takes ownership of the passed-in x509 object
- explicit CertVerificationContextOpenSSL(X509* x509) : x509_(x509) {}
-
- VerificationResult VerifySignatureOverData(
- const base::StringPiece& signature,
- const base::StringPiece& data) const override {
- // Retrieve public key object.
- crypto::ScopedEVP_PKEY public_key(X509_get_pubkey(x509_.get()));
- if (!public_key) {
- return VerificationResult(
- "Failed to extract device certificate public key.",
- VerificationResult::ERROR_CERT_INVALID);
- }
- // Make sure the key is RSA.
- const int public_key_type = EVP_PKEY_id(public_key.get());
- if (public_key_type != EVP_PKEY_RSA) {
- return VerificationResult(
- std::string("Expected RSA key type for client certificate, got ") +
- base::IntToString(public_key_type) + " instead.",
- VerificationResult::ERROR_CERT_INVALID);
- }
- // Verify signature.
- const crypto::ScopedEVP_MD_CTX ctx(EVP_MD_CTX_create());
- if (!ctx ||
- !EVP_DigestVerifyInit(ctx.get(), NULL, EVP_sha1(), NULL,
- public_key.get()) ||
- !EVP_DigestVerifyUpdate(ctx.get(), data.data(), data.size()) ||
- !EVP_DigestVerifyFinal(
- ctx.get(), reinterpret_cast<const uint8_t*>(signature.data()),
- signature.size())) {
- return VerificationResult("Signature verification failed.",
- VerificationResult::ERROR_SIGNATURE_INVALID);
- }
- return VerificationResult();
- }
-
- std::string GetCommonName() const override {
- int common_name_length = X509_NAME_get_text_by_NID(
- x509_->cert_info->subject, NID_commonName, NULL, 0);
- if (common_name_length < 0)
- return std::string();
- std::string common_name;
- common_name_length = X509_NAME_get_text_by_NID(
- x509_->cert_info->subject, NID_commonName,
- base::WriteInto(&common_name,
- static_cast<size_t>(common_name_length) + 1),
- common_name_length + 1);
- if (common_name_length < 0)
- return std::string();
- return common_name;
- }
-
- private:
- net::ScopedX509 x509_;
-};
-
-} // namespace
-
-VerificationResult VerifyDeviceCert(
- const base::StringPiece& device_cert,
- const std::vector<std::string>& ica_certs,
- scoped_ptr<CertVerificationContext>* context) {
- crypto::EnsureOpenSSLInit();
- crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
-
- // If the list of intermediates is empty then use kPublicKeyICA1 as
- // the trusted CA (legacy case).
- // Otherwise, use the first intermediate in the list as long as it
- // is in the allowed list of intermediates.
- base::StringPiece ica_public_key_der =
- (ica_certs.size() == 0)
- ? cast_channel::GetDefaultTrustedICAPublicKey()
- : cast_channel::GetTrustedICAPublicKey(ica_certs[0]);
-
- if (ica_public_key_der.empty()) {
- return VerificationResult(
- "Device certificate is not signed by a trusted CA",
- VerificationResult::ERROR_CERT_UNTRUSTED);
- }
- // Initialize the ICA public key.
- const uint8_t* ica_public_key_der_ptr =
- reinterpret_cast<const uint8_t*>(ica_public_key_der.data());
- const uint8_t* ica_public_key_der_end =
- ica_public_key_der_ptr + ica_public_key_der.size();
- crypto::ScopedRSA ica_public_key_rsa(d2i_RSAPublicKey(
- NULL, &ica_public_key_der_ptr, ica_public_key_der.size()));
- if (!ica_public_key_rsa || ica_public_key_der_ptr != ica_public_key_der_end) {
- return VerificationResult("Failed to import trusted public key.",
- VerificationResult::ERROR_INTERNAL);
- }
- crypto::ScopedEVP_PKEY ica_public_key_evp(EVP_PKEY_new());
- if (!ica_public_key_evp ||
- !EVP_PKEY_set1_RSA(ica_public_key_evp.get(), ica_public_key_rsa.get())) {
- return VerificationResult("Failed to import trusted public key.",
- VerificationResult::ERROR_INTERNAL);
- }
- // Parse the device certificate.
- const uint8_t* device_cert_der_ptr =
- reinterpret_cast<const uint8_t*>(device_cert.data());
- const uint8_t* device_cert_der_end = device_cert_der_ptr + device_cert.size();
- net::ScopedX509 device_cert_x509(
- d2i_X509(NULL, &device_cert_der_ptr, device_cert.size()));
- if (!device_cert_x509 || device_cert_der_ptr != device_cert_der_end) {
- return VerificationResult("Failed to parse device certificate.",
- VerificationResult::ERROR_CERT_INVALID);
- }
- // Verify device certificate.
- if (X509_verify(device_cert_x509.get(), ica_public_key_evp.get()) != 1) {
- return VerificationResult(
- "Device certificate signature verification failed.",
- VerificationResult::ERROR_CERT_INVALID);
- }
-
- if (context) {
- scoped_ptr<CertVerificationContext> tmp_context(
- new CertVerificationContextOpenSSL(device_cert_x509.release()));
- tmp_context.swap(*context);
- }
-
- return VerificationResult();
-}
-
-std::string VerificationResult::GetLogString() const {
- return error_message;
-}
-
-} // namespace cast_crypto
-} // namespace api
-} // namespace extensions
diff --git a/extensions/extensions.gyp b/extensions/extensions.gyp
index 6e807d4..c7976da 100644
--- a/extensions/extensions.gyp
+++ b/extensions/extensions.gyp
@@ -59,6 +59,7 @@
'../ui/gfx/gfx.gyp:gfx_geometry',
'../ui/gfx/ipc/gfx_ipc.gyp:gfx_ipc',
'../url/url.gyp:url_lib',
+ '../third_party/boringssl/boringssl.gyp:boringssl',
'../third_party/libxml/libxml.gyp:libxml',
'common/api/api.gyp:extensions_api',
'extensions_resources.gyp:extensions_resources',
@@ -90,31 +91,6 @@
'<@(extensions_common_sources_nacl)',
],
}],
- ['use_openssl==1', {
- 'sources': [
- '<@(extensions_common_sources_openssl)',
- ],
- 'dependencies': [
- '../third_party/boringssl/boringssl.gyp:boringssl',
- ],
- }, {
- 'sources': [
- '<@(extensions_common_sources_nonopenssl)'
- ],
- 'conditions': [
- ['os_posix == 1 and OS != "mac" and OS != "ios" and OS != "android"', {
- 'dependencies': [
- '../build/linux/system.gyp:ssl',
- ],
- }],
- ['OS == "mac" or OS == "ios" or OS == "win"', {
- 'dependencies': [
- '../third_party/nss/nss.gyp:nspr',
- '../third_party/nss/nss.gyp:nss',
- ],
- }],
- ],
- }],
],
},
{
diff --git a/extensions/extensions.gypi b/extensions/extensions.gypi
index 575ed02..68b1b80 100644
--- a/extensions/extensions.gypi
+++ b/extensions/extensions.gypi
@@ -228,12 +228,6 @@
'common/manifest_handlers/nacl_modules_handler.cc',
'common/manifest_handlers/nacl_modules_handler.h',
],
- 'extensions_common_sources_openssl': [
- 'common/cast/cast_cert_validator_openssl.cc',
- ],
- 'extensions_common_sources_nonopenssl': [
- 'common/cast/cast_cert_validator_nss.cc',
- ],
'extensions_browser_sources': [
# NOTE: When moving an API out of Chrome be sure to verify that the
# Android build still compiles. See conditions below.