Fix media_cas_proxy_sdk build issue.
Add example binary for testing building the SDK after 'git clone' from our repo. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=227583629
This commit is contained in:
@@ -67,22 +67,20 @@ X509Cert::~X509Cert() {
|
||||
|
||||
X509Cert::X509Cert(X509* openssl_cert) : openssl_cert_(openssl_cert) {}
|
||||
|
||||
util::Status X509Cert::LoadPem(const std::string& pem_cert) {
|
||||
Status X509Cert::LoadPem(const std::string& pem_cert) {
|
||||
if (pem_cert.empty()) {
|
||||
return util::Status(util::error::INVALID_ARGUMENT, "Empty PEM certificate");
|
||||
return Status(error::INVALID_ARGUMENT, "Empty PEM certificate");
|
||||
}
|
||||
BIO* bio(NULL);
|
||||
X509* new_cert(NULL);
|
||||
bio = BIO_new_mem_buf(const_cast<char*>(pem_cert.data()), pem_cert.size());
|
||||
if (bio == NULL) {
|
||||
return util::Status(util::error::INTERNAL, "BIO allocation failed");
|
||||
return Status(error::INTERNAL, "BIO allocation failed");
|
||||
}
|
||||
util::Status status;
|
||||
Status status;
|
||||
new_cert = PEM_read_bio_X509_AUX(bio, NULL, NULL, NULL);
|
||||
if (new_cert == NULL) {
|
||||
status = util::Status(util::Status::canonical_space(),
|
||||
util::error::INVALID_ARGUMENT,
|
||||
"PEM certificate load failed");
|
||||
status = Status(error::INVALID_ARGUMENT, "PEM certificate load failed");
|
||||
goto cleanup;
|
||||
}
|
||||
if (openssl_cert_ != NULL) {
|
||||
@@ -97,22 +95,21 @@ cleanup:
|
||||
return status;
|
||||
}
|
||||
|
||||
util::Status X509Cert::LoadDer(const std::string& der_cert) {
|
||||
Status X509Cert::LoadDer(const std::string& der_cert) {
|
||||
if (der_cert.empty()) {
|
||||
return util::Status(util::error::INVALID_ARGUMENT, "Empty DER certificate");
|
||||
return Status(error::INVALID_ARGUMENT, "Empty DER certificate");
|
||||
}
|
||||
const unsigned char* cert_data =
|
||||
reinterpret_cast<const unsigned char*>(der_cert.data());
|
||||
X509* new_cert = d2i_X509(NULL, &cert_data, der_cert.size());
|
||||
if (new_cert == NULL) {
|
||||
return util::Status(util::error::INVALID_ARGUMENT,
|
||||
"DER certificate load failed");
|
||||
return Status(error::INVALID_ARGUMENT, "DER certificate load failed");
|
||||
}
|
||||
if (openssl_cert_ != NULL) {
|
||||
X509_free(openssl_cert_);
|
||||
}
|
||||
openssl_cert_ = new_cert;
|
||||
return util::OkStatus();
|
||||
return OkStatus();
|
||||
}
|
||||
|
||||
std::string X509Cert::GetPem() const {
|
||||
@@ -184,6 +181,24 @@ std::string X509Cert::GetSerialNumber() const {
|
||||
return result;
|
||||
}
|
||||
|
||||
bool X509Cert::GetNotBeforeSeconds(int64_t* valid_start_seconds) const {
|
||||
if (openssl_cert_ == nullptr) {
|
||||
return false;
|
||||
}
|
||||
return Asn1TimeToEpochSeconds(X509_get0_notBefore(openssl_cert_),
|
||||
valid_start_seconds)
|
||||
.ok();
|
||||
}
|
||||
|
||||
bool X509Cert::GetNotAfterSeconds(int64_t* valid_end_seconds) const {
|
||||
if (openssl_cert_ == nullptr) {
|
||||
return false;
|
||||
}
|
||||
return Asn1TimeToEpochSeconds(X509_get0_notAfter(openssl_cert_),
|
||||
valid_end_seconds)
|
||||
.ok();
|
||||
}
|
||||
|
||||
bool X509Cert::IsCaCertificate() const {
|
||||
return X509_check_ca(openssl_cert_) != 0;
|
||||
}
|
||||
@@ -204,6 +219,38 @@ bool X509Cert::GetV3BooleanExtension(const std::string& oid, bool* value) const
|
||||
return true;
|
||||
}
|
||||
|
||||
Status X509Cert::Asn1TimeToEpochSeconds(const ASN1_TIME* asn1_time,
|
||||
int64_t* epoch_seconds) const {
|
||||
if (asn1_time == nullptr) {
|
||||
// This code is exported to shared source. The exported code does not yet
|
||||
// support MakeStatus.
|
||||
// NOLINTNEXTLINE
|
||||
return Status(error::INVALID_ARGUMENT, "asn1_time cannot be null.");
|
||||
}
|
||||
|
||||
if (epoch_seconds == nullptr) {
|
||||
// NOLINTNEXTLINE
|
||||
return Status(error::INVALID_ARGUMENT, "epoch_seconds cannot be null.");
|
||||
}
|
||||
|
||||
ScopedAsn1Time epoch_time(ASN1_TIME_new());
|
||||
if (!ASN1_TIME_set(epoch_time.get(), 0)) {
|
||||
// NOLINTNEXTLINE
|
||||
return Status(error::INTERNAL, "Failed to set epoch time.");
|
||||
}
|
||||
|
||||
int day = 0;
|
||||
int seconds = 0;
|
||||
if (!ASN1_TIME_diff(&day, &seconds, epoch_time.get(), asn1_time)) {
|
||||
// NOLINTNEXTLINE
|
||||
return Status(error::INTERNAL,
|
||||
"Failed to convert asn1 time to epoch time.");
|
||||
}
|
||||
|
||||
*epoch_seconds = 24L * 3600L * day + seconds;
|
||||
return OkStatus();
|
||||
}
|
||||
|
||||
X509CertChain::~X509CertChain() { Reset(); }
|
||||
|
||||
void X509CertChain::Reset() {
|
||||
@@ -213,7 +260,7 @@ void X509CertChain::Reset() {
|
||||
cert_chain_.clear();
|
||||
}
|
||||
|
||||
util::Status X509CertChain::LoadPem(const std::string& pem_cert_chain) {
|
||||
Status X509CertChain::LoadPem(const std::string& pem_cert_chain) {
|
||||
static const char kBeginCertificate[] = "-----BEGIN CERTIFICATE-----";
|
||||
static const char kEndCertificate[] = "-----END CERTIFICATE-----";
|
||||
|
||||
@@ -225,7 +272,7 @@ util::Status X509CertChain::LoadPem(const std::string& pem_cert_chain) {
|
||||
if (end_pos != std::string::npos) {
|
||||
end_pos += sizeof(kEndCertificate) - 1;
|
||||
std::unique_ptr<X509Cert> new_cert(new X509Cert);
|
||||
util::Status status = new_cert->LoadPem(
|
||||
Status status = new_cert->LoadPem(
|
||||
pem_cert_chain.substr(begin_pos, end_pos - begin_pos));
|
||||
if (!status.ok()) {
|
||||
return status;
|
||||
@@ -234,17 +281,17 @@ util::Status X509CertChain::LoadPem(const std::string& pem_cert_chain) {
|
||||
begin_pos = pem_cert_chain.find(kBeginCertificate, end_pos);
|
||||
}
|
||||
}
|
||||
return util::OkStatus();
|
||||
return OkStatus();
|
||||
}
|
||||
|
||||
util::Status X509CertChain::LoadPkcs7(const std::string& pk7_cert_chain) {
|
||||
Status X509CertChain::LoadPkcs7(const std::string& pk7_cert_chain) {
|
||||
ScopedX509Stack cert_stack(sk_X509_new_null());
|
||||
CBS cbs;
|
||||
CBS_init(&cbs, reinterpret_cast<const uint8_t*>(pk7_cert_chain.data()),
|
||||
pk7_cert_chain.size());
|
||||
if (!PKCS7_get_certificates(cert_stack.get(), &cbs)) {
|
||||
return util::Status(util::error::INVALID_ARGUMENT,
|
||||
"Unable to load PKCS#7 certificate chain");
|
||||
return Status(error::INVALID_ARGUMENT,
|
||||
"Unable to load PKCS#7 certificate chain");
|
||||
}
|
||||
|
||||
while (sk_X509_num(cert_stack.get()) > 0) {
|
||||
@@ -252,7 +299,7 @@ util::Status X509CertChain::LoadPkcs7(const std::string& pk7_cert_chain) {
|
||||
new X509Cert(sk_X509_pop(cert_stack.get())));
|
||||
}
|
||||
|
||||
return util::OkStatus();
|
||||
return OkStatus();
|
||||
}
|
||||
|
||||
std::string X509CertChain::GetPkcs7() {
|
||||
@@ -305,44 +352,42 @@ X509CA::~X509CA() {
|
||||
}
|
||||
}
|
||||
|
||||
util::Status X509CA::InitializeStore() {
|
||||
Status X509CA::InitializeStore() {
|
||||
absl::WriterMutexLock lock(&openssl_store_mutex_);
|
||||
if (openssl_store_ == NULL) {
|
||||
if (ca_cert_ == NULL) {
|
||||
return util::Status(util::error::INTERNAL, "CA X.509Cert is NULL");
|
||||
return Status(error::INTERNAL, "CA X.509Cert is NULL");
|
||||
}
|
||||
openssl_store_ = X509_STORE_new();
|
||||
if (openssl_store_ == NULL) {
|
||||
return util::Status(util::error::INTERNAL,
|
||||
"Failed to allocate X.509 store");
|
||||
return Status(error::INTERNAL, "Failed to allocate X.509 store");
|
||||
}
|
||||
if (X509_STORE_add_cert(openssl_store_,
|
||||
const_cast<X509*>(ca_cert_->openssl_cert())) == 0) {
|
||||
X509_STORE_free(openssl_store_);
|
||||
openssl_store_ = NULL;
|
||||
|
||||
return util::Status(util::error::INTERNAL,
|
||||
"Failed to add X.509 CA certificate to store");
|
||||
return Status(error::INTERNAL,
|
||||
"Failed to add X.509 CA certificate to store");
|
||||
}
|
||||
}
|
||||
return util::OkStatus();
|
||||
return OkStatus();
|
||||
}
|
||||
|
||||
util::Status X509CA::VerifyCert(const X509Cert& cert) {
|
||||
Status X509CA::VerifyCert(const X509Cert& cert) {
|
||||
return OpenSslX509Verify(cert.openssl_cert(), nullptr);
|
||||
}
|
||||
|
||||
util::Status X509CA::VerifyCertChain(const X509CertChain& cert_chain) {
|
||||
Status X509CA::VerifyCertChain(const X509CertChain& cert_chain) {
|
||||
if (cert_chain.GetNumCerts() < 1) {
|
||||
return util::Status(util::error::INVALID_ARGUMENT,
|
||||
"Cannot verify empty certificate chain");
|
||||
return Status(error::INVALID_ARGUMENT,
|
||||
"Cannot verify empty certificate chain");
|
||||
}
|
||||
|
||||
ScopedX509StackOnly intermediates(sk_X509_new_null());
|
||||
if (!intermediates) {
|
||||
return util::Status(
|
||||
util::Status::canonical_space(), util::error::INTERNAL,
|
||||
"Failed to allocate X.509 intermediate certificate stack");
|
||||
return Status(error::INTERNAL,
|
||||
"Failed to allocate X.509 intermediate certificate stack");
|
||||
}
|
||||
const X509Cert* leaf_cert(nullptr);
|
||||
for (size_t idx = 0; idx < cert_chain.GetNumCerts(); ++idx) {
|
||||
@@ -354,23 +399,21 @@ util::Status X509CA::VerifyCertChain(const X509CertChain& cert_chain) {
|
||||
}
|
||||
}
|
||||
if (!leaf_cert) {
|
||||
return util::Status(util::Status::canonical_space(),
|
||||
util::error::INVALID_ARGUMENT,
|
||||
"X.509 certificate chain without leaf certificate.");
|
||||
return Status(error::INVALID_ARGUMENT,
|
||||
"X.509 certificate chain without leaf certificate.");
|
||||
}
|
||||
return OpenSslX509Verify(leaf_cert->openssl_cert(), intermediates.get());
|
||||
}
|
||||
|
||||
util::Status X509CA::VerifyCertWithChain(const X509Cert& cert,
|
||||
const X509CertChain& cert_chain) {
|
||||
Status X509CA::VerifyCertWithChain(const X509Cert& cert,
|
||||
const X509CertChain& cert_chain) {
|
||||
ScopedX509StackOnly intermediates(sk_X509_new_null());
|
||||
if (!intermediates) {
|
||||
// MakeStatus is now preferred. But we don't support it in the exported
|
||||
// version, yet. So, ignore lint here.
|
||||
// NOLINTNEXTLINE
|
||||
return util::Status(
|
||||
util::Status::canonical_space(), util::error::INTERNAL,
|
||||
"Failed to allocate X.509 intermediate certificate stack");
|
||||
return Status(error::INTERNAL,
|
||||
"Failed to allocate X.509 intermediate certificate stack");
|
||||
}
|
||||
for (size_t idx = 0; idx < cert_chain.GetNumCerts(); ++idx) {
|
||||
sk_X509_push(intermediates.get(),
|
||||
@@ -380,14 +423,14 @@ util::Status X509CA::VerifyCertWithChain(const X509Cert& cert,
|
||||
return OpenSslX509Verify(cert.openssl_cert(), intermediates.get());
|
||||
}
|
||||
|
||||
util::Status X509CA::OpenSslX509Verify(const X509* cert,
|
||||
STACK_OF(X509) * intermediates) {
|
||||
Status X509CA::OpenSslX509Verify(const X509* cert,
|
||||
STACK_OF(X509) * intermediates) {
|
||||
DCHECK(cert);
|
||||
|
||||
absl::ReaderMutexLock lock(&openssl_store_mutex_);
|
||||
if (openssl_store_ == NULL) {
|
||||
openssl_store_mutex_.ReaderUnlock();
|
||||
util::Status status = InitializeStore();
|
||||
Status status = InitializeStore();
|
||||
if (!status.ok()) {
|
||||
return status;
|
||||
}
|
||||
@@ -395,23 +438,21 @@ util::Status X509CA::OpenSslX509Verify(const X509* cert,
|
||||
}
|
||||
ScopedX509StoreCtx store_ctx(X509_STORE_CTX_new());
|
||||
if (!store_ctx) {
|
||||
return util::Status(util::Status::canonical_space(), util::error::INTERNAL,
|
||||
"Failed to allocate X.509 store context");
|
||||
return Status(error::INTERNAL, "Failed to allocate X.509 store context");
|
||||
}
|
||||
if (X509_STORE_CTX_init(store_ctx.get(), openssl_store_,
|
||||
const_cast<X509*>(cert), intermediates) == 0) {
|
||||
return util::Status(util::Status::canonical_space(), util::error::INTERNAL,
|
||||
"Failed to initialize X.509 store context");
|
||||
return Status(error::INTERNAL, "Failed to initialize X.509 store context");
|
||||
}
|
||||
int x509_status = X509_verify_cert(store_ctx.get());
|
||||
if (x509_status != 1) {
|
||||
return util::Status(util::Status::canonical_space(), util::error::INTERNAL,
|
||||
std::string("X.509 certificate chain validation failed: ") +
|
||||
X509_verify_cert_error_string(
|
||||
X509_STORE_CTX_get_error(store_ctx.get())));
|
||||
return Status(error::INTERNAL,
|
||||
std::string("X.509 certificate chain validation failed: ") +
|
||||
X509_verify_cert_error_string(
|
||||
X509_STORE_CTX_get_error(store_ctx.get())));
|
||||
}
|
||||
|
||||
return util::OkStatus();
|
||||
return OkStatus();
|
||||
}
|
||||
|
||||
} // namespace widevine
|
||||
|
||||
Reference in New Issue
Block a user