mirror of https://github.com/grpc/grpc.git
The C based gRPC (C++, Python, Ruby, Objective-C, PHP, C#)
https://grpc.io/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
222 lines
9.0 KiB
222 lines
9.0 KiB
// |
|
// Copyright 2021 gRPC authors. |
|
// |
|
// Licensed under the Apache License, Version 2.0 (the "License"); |
|
// you may not use this file except in compliance with the License. |
|
// You may obtain a copy of the License at |
|
// |
|
// http://www.apache.org/licenses/LICENSE-2.0 |
|
// |
|
// Unless required by applicable law or agreed to in writing, software |
|
// distributed under the License is distributed on an "AS IS" BASIS, |
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
// See the License for the specific language governing permissions and |
|
// limitations under the License. |
|
// |
|
|
|
#include <memory> |
|
|
|
#include <gmock/gmock.h> |
|
#include <gtest/gtest.h> |
|
|
|
#include <grpc/grpc.h> |
|
#include <grpc/grpc_security.h> |
|
#include <grpcpp/security/server_credentials.h> |
|
#include <grpcpp/security/tls_credentials_options.h> |
|
|
|
#include "src/cpp/client/secure_credentials.h" |
|
#include "test/core/test_util/port.h" |
|
#include "test/core/test_util/test_config.h" |
|
#include "test/cpp/util/tls_test_utils.h" |
|
|
|
namespace { |
|
|
|
using ::grpc::experimental::ExternalCertificateVerifier; |
|
using ::grpc::experimental::HostNameCertificateVerifier; |
|
using ::grpc::experimental::NoOpCertificateVerifier; |
|
using ::grpc::experimental::TlsCustomVerificationCheckRequest; |
|
|
|
} // namespace |
|
|
|
namespace grpc { |
|
namespace testing { |
|
namespace { |
|
|
|
TEST(TlsCertificateVerifierTest, SyncCertificateVerifierSucceeds) { |
|
grpc_tls_custom_verification_check_request request; |
|
auto verifier = |
|
ExternalCertificateVerifier::Create<SyncCertificateVerifier>(true); |
|
TlsCustomVerificationCheckRequest cpp_request(&request); |
|
grpc::Status sync_status; |
|
verifier->Verify(&cpp_request, nullptr, &sync_status); |
|
EXPECT_TRUE(sync_status.ok()) |
|
<< sync_status.error_code() << " " << sync_status.error_message(); |
|
} |
|
|
|
TEST(TlsCertificateVerifierTest, SyncCertificateVerifierFails) { |
|
grpc_tls_custom_verification_check_request request; |
|
auto verifier = |
|
ExternalCertificateVerifier::Create<SyncCertificateVerifier>(false); |
|
TlsCustomVerificationCheckRequest cpp_request(&request); |
|
grpc::Status sync_status; |
|
verifier->Verify(&cpp_request, nullptr, &sync_status); |
|
EXPECT_EQ(sync_status.error_code(), grpc::StatusCode::UNAUTHENTICATED); |
|
EXPECT_EQ(sync_status.error_message(), "SyncCertificateVerifier failed"); |
|
} |
|
|
|
TEST(TlsCertificateVerifierTest, AsyncCertificateVerifierSucceeds) { |
|
grpc_tls_custom_verification_check_request request; |
|
auto verifier = |
|
ExternalCertificateVerifier::Create<AsyncCertificateVerifier>(true); |
|
TlsCustomVerificationCheckRequest cpp_request(&request); |
|
std::function<void(grpc::Status)> callback = [](grpc::Status async_status) { |
|
EXPECT_TRUE(async_status.ok()) |
|
<< async_status.error_code() << " " << async_status.error_message(); |
|
}; |
|
grpc::Status sync_status; |
|
EXPECT_FALSE(verifier->Verify(&cpp_request, callback, &sync_status)); |
|
} |
|
|
|
TEST(TlsCertificateVerifierTest, AsyncCertificateVerifierFails) { |
|
grpc_tls_custom_verification_check_request request; |
|
auto verifier = |
|
ExternalCertificateVerifier::Create<AsyncCertificateVerifier>(false); |
|
TlsCustomVerificationCheckRequest cpp_request(&request); |
|
std::function<void(grpc::Status)> callback = [](grpc::Status async_status) { |
|
EXPECT_EQ(async_status.error_code(), grpc::StatusCode::UNAUTHENTICATED); |
|
EXPECT_EQ(async_status.error_message(), "AsyncCertificateVerifier failed"); |
|
}; |
|
grpc::Status sync_status; |
|
EXPECT_FALSE(verifier->Verify(&cpp_request, callback, &sync_status)); |
|
} |
|
|
|
TEST(TlsCertificateVerifierTest, NoOpCertificateVerifierSucceeds) { |
|
grpc_tls_custom_verification_check_request request; |
|
memset(&request, 0, sizeof(request)); |
|
auto verifier = std::make_shared<NoOpCertificateVerifier>(); |
|
TlsCustomVerificationCheckRequest cpp_request(&request); |
|
grpc::Status sync_status; |
|
verifier->Verify(&cpp_request, nullptr, &sync_status); |
|
EXPECT_TRUE(sync_status.ok()) |
|
<< sync_status.error_code() << " " << sync_status.error_message(); |
|
} |
|
|
|
TEST(TlsCertificateVerifierTest, HostNameCertificateVerifierSucceeds) { |
|
grpc_tls_custom_verification_check_request request; |
|
memset(&request, 0, sizeof(request)); |
|
request.target_name = "foo.bar.com"; |
|
request.peer_info.common_name = "foo.bar.com"; |
|
auto verifier = std::make_shared<HostNameCertificateVerifier>(); |
|
TlsCustomVerificationCheckRequest cpp_request(&request); |
|
grpc::Status sync_status; |
|
verifier->Verify(&cpp_request, nullptr, &sync_status); |
|
EXPECT_TRUE(sync_status.ok()) |
|
<< sync_status.error_code() << " " << sync_status.error_message(); |
|
} |
|
|
|
TEST(TlsCertificateVerifierTest, HostNameCertificateVerifierFails) { |
|
grpc_tls_custom_verification_check_request request; |
|
memset(&request, 0, sizeof(request)); |
|
request.target_name = "foo.bar.com"; |
|
request.peer_info.common_name = "foo.baz.com"; |
|
auto verifier = std::make_shared<HostNameCertificateVerifier>(); |
|
TlsCustomVerificationCheckRequest cpp_request(&request); |
|
grpc::Status sync_status; |
|
verifier->Verify(&cpp_request, nullptr, &sync_status); |
|
EXPECT_EQ(sync_status.error_code(), grpc::StatusCode::UNAUTHENTICATED); |
|
EXPECT_EQ(sync_status.error_message(), "Hostname Verification Check failed."); |
|
} |
|
|
|
TEST(TlsCertificateVerifierTest, |
|
HostNameCertificateVerifierSucceedsMultipleFields) { |
|
grpc_tls_custom_verification_check_request request; |
|
memset(&request, 0, sizeof(request)); |
|
request.target_name = "foo.bar.com"; |
|
request.peer_info.common_name = "foo.baz.com"; |
|
char* dns_names[] = {const_cast<char*>("*.bar.com")}; |
|
request.peer_info.san_names.dns_names = dns_names; |
|
request.peer_info.san_names.dns_names_size = 1; |
|
auto verifier = std::make_shared<HostNameCertificateVerifier>(); |
|
TlsCustomVerificationCheckRequest cpp_request(&request); |
|
grpc::Status sync_status; |
|
verifier->Verify(&cpp_request, nullptr, &sync_status); |
|
EXPECT_TRUE(sync_status.ok()) |
|
<< sync_status.error_code() << " " << sync_status.error_message(); |
|
} |
|
|
|
TEST(TlsCertificateVerifierTest, |
|
HostNameCertificateVerifierFailsMultipleFields) { |
|
grpc_tls_custom_verification_check_request request; |
|
memset(&request, 0, sizeof(request)); |
|
request.target_name = "foo.bar.com"; |
|
request.peer_info.common_name = "foo.baz.com"; |
|
char* dns_names[] = {const_cast<char*>("*.")}; |
|
request.peer_info.san_names.dns_names = dns_names; |
|
request.peer_info.san_names.dns_names_size = 1; |
|
auto verifier = std::make_shared<HostNameCertificateVerifier>(); |
|
TlsCustomVerificationCheckRequest cpp_request(&request); |
|
grpc::Status sync_status; |
|
verifier->Verify(&cpp_request, nullptr, &sync_status); |
|
EXPECT_EQ(sync_status.error_code(), grpc::StatusCode::UNAUTHENTICATED); |
|
EXPECT_EQ(sync_status.error_message(), "Hostname Verification Check failed."); |
|
} |
|
|
|
TEST(TlsCertificateVerifierTest, VerifiedRootCertSubjectVerifierSucceeds) { |
|
grpc_tls_custom_verification_check_request request; |
|
constexpr char kExpectedSubject[] = |
|
"CN=testca,O=Internet Widgits Pty Ltd,ST=Some-State,C=AU"; |
|
request.peer_info.verified_root_cert_subject = kExpectedSubject; |
|
auto verifier = |
|
ExternalCertificateVerifier::Create<VerifiedRootCertSubjectVerifier>( |
|
kExpectedSubject); |
|
TlsCustomVerificationCheckRequest cpp_request(&request); |
|
grpc::Status sync_status; |
|
bool is_sync = verifier->Verify(&cpp_request, nullptr, &sync_status); |
|
EXPECT_TRUE(is_sync); |
|
EXPECT_TRUE(sync_status.ok()) |
|
<< sync_status.error_code() << " " << sync_status.error_message(); |
|
} |
|
|
|
TEST(TlsCertificateVerifierTest, VerifiedRootCertSubjectVerifierFailsNull) { |
|
grpc_tls_custom_verification_check_request request; |
|
constexpr char kExpectedSubject[] = |
|
"CN=testca,O=Internet Widgits Pty Ltd,ST=Some-State,C=AU"; |
|
request.peer_info.verified_root_cert_subject = nullptr; |
|
auto verifier = |
|
ExternalCertificateVerifier::Create<VerifiedRootCertSubjectVerifier>( |
|
kExpectedSubject); |
|
TlsCustomVerificationCheckRequest cpp_request(&request); |
|
EXPECT_EQ(cpp_request.verified_root_cert_subject(), ""); |
|
grpc::Status sync_status; |
|
verifier->Verify(&cpp_request, nullptr, &sync_status); |
|
EXPECT_EQ(sync_status.error_code(), grpc::StatusCode::UNAUTHENTICATED); |
|
EXPECT_EQ(sync_status.error_message(), |
|
"VerifiedRootCertSubjectVerifier failed"); |
|
} |
|
|
|
TEST(TlsCertificateVerifierTest, VerifiedRootCertSubjectVerifierFailsMismatch) { |
|
grpc_tls_custom_verification_check_request request; |
|
constexpr char kExpectedSubject[] = |
|
"CN=testca,O=Internet Widgits Pty Ltd,ST=Some-State,C=AU"; |
|
request.peer_info.verified_root_cert_subject = "BAD_SUBJECT"; |
|
auto verifier = |
|
ExternalCertificateVerifier::Create<VerifiedRootCertSubjectVerifier>( |
|
kExpectedSubject); |
|
TlsCustomVerificationCheckRequest cpp_request(&request); |
|
grpc::Status sync_status; |
|
verifier->Verify(&cpp_request, nullptr, &sync_status); |
|
EXPECT_EQ(sync_status.error_code(), grpc::StatusCode::UNAUTHENTICATED); |
|
EXPECT_EQ(sync_status.error_message(), |
|
"VerifiedRootCertSubjectVerifier failed"); |
|
} |
|
|
|
} // namespace |
|
} // namespace testing |
|
} // namespace grpc |
|
|
|
int main(int argc, char** argv) { |
|
::testing::InitGoogleTest(&argc, argv); |
|
grpc::testing::TestEnvironment env(&argc, argv); |
|
int ret = RUN_ALL_TESTS(); |
|
return ret; |
|
}
|
|
|