diff options
author | btolsch <btolsch@chromium.org> | 2019-12-17 18:23:10 -0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2019-12-18 02:36:32 +0000 |
commit | 3fb84816856bd15c694fb275b40e609472064c4f (patch) | |
tree | 81c786d9a305a4ec72366b51ba3be57a7a4ae2f9 /cast/sender | |
parent | c310e1bbcb8df5802ea9ea7598a16ea82e122cf9 (diff) | |
download | openscreen-3fb84816856bd15c694fb275b40e609472064c4f.tar.gz |
Add receiver authentication steps
This change adds the necessary crypto + messaging steps for a Cast
receiver to authenticate itself as such. It also adds an integration
test that checks our sender authentication code against this receiver
authentication code.
Bug: openscreen:91
Change-Id: If298b8781bc95116714eb36fa68ef96ba82742a3
Reviewed-on: https://chromium-review.googlesource.com/c/openscreen/+/1954745
Commit-Queue: Brandon Tolsch <btolsch@chromium.org>
Reviewed-by: mark a. foltz <mfoltz@chromium.org>
Diffstat (limited to 'cast/sender')
-rw-r--r-- | cast/sender/BUILD.gn | 3 | ||||
-rw-r--r-- | cast/sender/channel/cast_auth_util.cc | 56 | ||||
-rw-r--r-- | cast/sender/channel/cast_auth_util.h | 19 | ||||
-rw-r--r-- | cast/sender/channel/cast_auth_util_unittest.cc | 15 |
4 files changed, 77 insertions, 16 deletions
diff --git a/cast/sender/BUILD.gn b/cast/sender/BUILD.gn index f42d555c..ae36bf27 100644 --- a/cast/sender/BUILD.gn +++ b/cast/sender/BUILD.gn @@ -22,6 +22,8 @@ source_set("channel") { public_deps = [ "../../platform", "../../third_party/boringssl", + "../common:certificate", + "../common:channel", ] } @@ -34,6 +36,7 @@ source_set("unittests") { deps = [ ":channel", "../../platform", + "../../testing/util", "../../third_party/googletest:gtest", "../common/certificate/proto:certificate_proto", "../common/certificate/proto:certificate_unittest_proto", diff --git a/cast/sender/channel/cast_auth_util.cc b/cast/sender/channel/cast_auth_util.cc index 90d63f77..44a75b98 100644 --- a/cast/sender/channel/cast_auth_util.cc +++ b/cast/sender/channel/cast_auth_util.cc @@ -11,6 +11,7 @@ #include "cast/common/certificate/cast_cert_validator.h" #include "cast/common/certificate/cast_cert_validator_internal.h" #include "cast/common/certificate/cast_crl.h" +#include "cast/common/channel/proto/cast_channel.pb.h" #include "platform/api/time.h" #include "platform/base/error.h" #include "util/logging.h" @@ -222,18 +223,31 @@ openscreen::Error VerifyTLSCertificateValidity( return openscreen::Error::None(); } -ErrorOr<CastDeviceCertPolicy> AuthenticateChallengeReply( +ErrorOr<CastDeviceCertPolicy> VerifyCredentialsImpl( + const AuthResponse& response, + const std::string& signature_input, + const certificate::CRLPolicy& crl_policy, + certificate::TrustStore* cast_trust_store, + certificate::TrustStore* crl_trust_store, + const certificate::DateTime& verification_time, + bool enforce_sha256_checking); + +ErrorOr<CastDeviceCertPolicy> AuthenticateChallengeReplyImpl( const CastMessage& challenge_reply, X509* peer_cert, - const AuthContext& auth_context) { + const AuthContext& auth_context, + const certificate::CRLPolicy& crl_policy, + certificate::TrustStore* cast_trust_store, + certificate::TrustStore* crl_trust_store, + const certificate::DateTime& verification_time) { DeviceAuthMessage auth_message; openscreen::Error result = ParseAuthMessage(challenge_reply, &auth_message); if (!result.ok()) { return result; } - result = VerifyTLSCertificateValidity( - peer_cert, openscreen::GetWallTimeSinceUnixEpoch()); + result = VerifyTLSCertificateValidity(peer_cert, + DateTimeToSeconds(verification_time)); if (!result.ok()) { return result; } @@ -261,7 +275,35 @@ ErrorOr<CastDeviceCertPolicy> AuthenticateChallengeReply( OSP_DCHECK_EQ(actual_size, peer_cert_der.size()); peer_cert_der.resize(actual_size); - return VerifyCredentials(response, nonce_response + peer_cert_der); + return VerifyCredentialsImpl(response, nonce_response + peer_cert_der, + crl_policy, cast_trust_store, crl_trust_store, + verification_time, false); +} + +ErrorOr<CastDeviceCertPolicy> AuthenticateChallengeReply( + const CastMessage& challenge_reply, + X509* peer_cert, + const AuthContext& auth_context) { + certificate::DateTime now = {}; + OSP_CHECK(certificate::DateTimeFromSeconds( + openscreen::GetWallTimeSinceUnixEpoch().count(), &now)); + certificate::CRLPolicy policy = certificate::CRLPolicy::kCrlOptional; + return AuthenticateChallengeReplyImpl( + challenge_reply, peer_cert, auth_context, policy, + /* cast_trust_store */ nullptr, /* crl_trust_store */ nullptr, now); +} + +ErrorOr<CastDeviceCertPolicy> AuthenticateChallengeReplyForTest( + const CastMessage& challenge_reply, + X509* peer_cert, + const AuthContext& auth_context, + certificate::CRLPolicy crl_policy, + certificate::TrustStore* cast_trust_store, + certificate::TrustStore* crl_trust_store, + const certificate::DateTime& verification_time) { + return AuthenticateChallengeReplyImpl( + challenge_reply, peer_cert, auth_context, crl_policy, cast_trust_store, + crl_trust_store, verification_time); } // This function does the following @@ -301,8 +343,8 @@ ErrorOr<CastDeviceCertPolicy> VerifyCredentialsImpl( std::vector<std::string> cert_chain; cert_chain.push_back(response.client_auth_certificate()); cert_chain.insert(cert_chain.end(), - response.intermediate_certificate().begin(), - response.intermediate_certificate().end()); + response.intermediate_certificates().begin(), + response.intermediate_certificates().end()); // Parse the CRL. std::unique_ptr<certificate::CastCRL> crl; diff --git a/cast/sender/channel/cast_auth_util.h b/cast/sender/channel/cast_auth_util.h index 35f1d028..b3ea452f 100644 --- a/cast/sender/channel/cast_auth_util.h +++ b/cast/sender/channel/cast_auth_util.h @@ -7,10 +7,10 @@ #include <openssl/x509.h> +#include <chrono> #include <string> #include "cast/common/certificate/cast_cert_validator.h" -#include "cast/common/channel/proto/cast_channel.pb.h" #include "platform/base/error.h" namespace cast { @@ -61,6 +61,19 @@ ErrorOr<CastDeviceCertPolicy> AuthenticateChallengeReply( X509* peer_cert, const AuthContext& auth_context); +// Exposed for testing only. +// +// Overloaded version of AuthenticateChallengeReply that allows modifying the +// crl policy, trust stores, and verification times. +ErrorOr<CastDeviceCertPolicy> AuthenticateChallengeReplyForTest( + const CastMessage& challenge_reply, + X509* peer_cert, + const AuthContext& auth_context, + certificate::CRLPolicy crl_policy, + certificate::TrustStore* cast_trust_store, + certificate::TrustStore* crl_trust_store, + const certificate::DateTime& verification_time); + // Performs a quick check of the TLS certificate for time validity requirements. openscreen::Error VerifyTLSCertificateValidity( X509* peer_cert, @@ -77,8 +90,8 @@ ErrorOr<CastDeviceCertPolicy> VerifyCredentials( // Exposed for testing only. // -// Overloaded version of VerifyCredentials that allows modifying -// the crl policy, trust stores, and verification times. +// Overloaded version of VerifyCredentials that allows modifying the crl policy, +// trust stores, and verification times. ErrorOr<CastDeviceCertPolicy> VerifyCredentialsForTest( const AuthResponse& response, const std::string& signature_input, diff --git a/cast/sender/channel/cast_auth_util_unittest.cc b/cast/sender/channel/cast_auth_util_unittest.cc index b8a8e90c..a4b341e2 100644 --- a/cast/sender/channel/cast_auth_util_unittest.cc +++ b/cast/sender/channel/cast_auth_util_unittest.cc @@ -13,6 +13,7 @@ #include "cast/common/channel/proto/cast_channel.pb.h" #include "gtest/gtest.h" #include "platform/api/time.h" +#include "testing/util/read_file.h" #include "util/logging.h" namespace cast { @@ -123,8 +124,9 @@ class CastAuthUtilTest : public testing::Test { AuthResponse response; response.set_client_auth_certificate(chain[0]); - for (size_t i = 1; i < chain.size(); ++i) - response.add_intermediate_certificate(chain[i]); + for (size_t i = 1; i < chain.size(); ++i) { + response.add_intermediate_certificates(chain[i]); + } response.set_hash_algorithm(digest_algorithm); switch (digest_algorithm) { @@ -168,7 +170,7 @@ TEST_F(CastAuthUtilTest, VerifySuccess) { TEST_F(CastAuthUtilTest, VerifyBadCA) { std::string signed_data; AuthResponse auth_response = CreateAuthResponse(&signed_data, SHA256); - MangleString(auth_response.mutable_intermediate_certificate(0)); + MangleString(auth_response.mutable_intermediate_certificates(0)); ErrorOr<CastDeviceCertPolicy> result = VerifyCredentials(auth_response, signed_data); EXPECT_FALSE(result); @@ -354,8 +356,9 @@ ErrorOr<CastDeviceCertPolicy> TestVerifyRevocation( if (certificate_chain.size() > 0) { response.set_client_auth_certificate(certificate_chain[0]); - for (size_t i = 1; i < certificate_chain.size(); ++i) - response.add_intermediate_certificate(certificate_chain[i]); + for (size_t i = 1; i < certificate_chain.size(); ++i) { + response.add_intermediate_certificates(certificate_chain[i]); + } } response.set_crl(crl_bundle); @@ -447,7 +450,7 @@ bool RunTest(const certificate::DeviceCertTest& test_case) { // These tests are generated by a test generator in google3. void RunTestSuite(const std::string& test_suite_file_name) { std::string testsuite_raw = - certificate::testing::ReadEntireFileToString(test_suite_file_name); + openscreen::ReadEntireFileToString(test_suite_file_name); certificate::DeviceCertTestSuite test_suite; EXPECT_TRUE(test_suite.ParseFromString(testsuite_raw)); uint16_t successes = 0; |