blob: 7df4c10974a54c2d29367b021bef0e44c3e70882 [file]
// Copyright 2026 Google LLC
//
// 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
//
// https://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 "testing/crypto_testing.h"
#include <cstddef>
#include <string>
#include "absl/log/check.h"
#include "absl/time/time.h"
#include "openssl/asn1.h"
#include "openssl/base.h"
#include "openssl/bn.h"
#include "openssl/digest.h"
#include "openssl/ec_key.h"
#include "openssl/evp.h"
#include "openssl/rsa.h"
#include "openssl/x509.h"
namespace credentio {
bssl::UniquePtr<EVP_PKEY> CreateTestEcKey(int nid) {
bssl::UniquePtr<EC_KEY> key(EC_KEY_new_by_curve_name(nid));
CHECK_NE(key, nullptr);
CHECK(EC_KEY_generate_key(key.get()));
bssl::UniquePtr<EVP_PKEY> pkey(EVP_PKEY_new());
CHECK_NE(pkey, nullptr);
CHECK(EVP_PKEY_set1_EC_KEY(pkey.get(), key.get()));
return pkey;
}
bssl::UniquePtr<EVP_PKEY> CreateTestRsaKey(size_t num_bits) {
bssl::UniquePtr<BIGNUM> rsa_f4(BN_new());
CHECK_NE(rsa_f4, nullptr);
CHECK(BN_set_word(rsa_f4.get(), RSA_F4));
bssl::UniquePtr<RSA> rsa(RSA_new());
CHECK_NE(rsa, nullptr);
CHECK(RSA_generate_key_ex(rsa.get(), num_bits, rsa_f4.get(), nullptr));
bssl::UniquePtr<EVP_PKEY> pkey(EVP_PKEY_new());
CHECK_NE(pkey, nullptr);
CHECK(EVP_PKEY_set1_RSA(pkey.get(), rsa.get()));
return pkey;
}
bssl::UniquePtr<EVP_PKEY> CreateTestEdKey() {
bssl::UniquePtr<EVP_PKEY_CTX> ctx(
EVP_PKEY_CTX_new_id(EVP_PKEY_ED25519, nullptr));
CHECK_NE(ctx, nullptr);
CHECK(EVP_PKEY_keygen_init(ctx.get()));
EVP_PKEY* pkey = nullptr;
CHECK(EVP_PKEY_keygen(ctx.get(), &pkey));
return bssl::UniquePtr<EVP_PKEY>(pkey);
}
bssl::UniquePtr<X509> CreateTestCertificate(
const TestCertificateOptions& options) {
// Options validation.
CHECK(!options.subject_common_name.empty());
CHECK(!options.issuer_common_name.empty());
CHECK(options.signing_key != nullptr);
CHECK(options.private_key != nullptr);
// Create the X509 object.
bssl::UniquePtr<X509> x509(X509_new());
CHECK(X509_set_version(x509.get(), 2));
// Set the not_before/not_after fields.
bssl::UniquePtr<ASN1_TIME> not_before(ASN1_TIME_new());
CHECK(ASN1_TIME_set(not_before.get(), absl::ToTimeT(options.not_before)));
CHECK(X509_set1_notBefore(x509.get(), not_before.get()));
bssl::UniquePtr<ASN1_TIME> not_after(ASN1_TIME_new());
CHECK(ASN1_TIME_set(not_after.get(), absl::ToTimeT(options.not_after)));
CHECK(X509_set1_notAfter(x509.get(), not_after.get()));
// Set the subject DN.
bssl::UniquePtr<X509_NAME> subject_name(X509_NAME_new());
CHECK(X509_NAME_add_entry_by_txt(subject_name.get(), /*field=*/"CN",
MBSTRING_ASC,
reinterpret_cast<const unsigned char*>(
options.subject_common_name.c_str()),
/*len=*/-1, /*loc=*/-1,
/*set=*/0));
CHECK(X509_NAME_add_entry_by_txt(
subject_name.get(), /*field=*/"O", MBSTRING_ASC,
reinterpret_cast<const unsigned char*>("Google"),
/*len=*/-1, /*loc=*/-1,
/*set=*/0));
CHECK(X509_NAME_add_entry_by_txt(
subject_name.get(), /*field=*/"OU", MBSTRING_ASC,
reinterpret_cast<const unsigned char*>("Google OU"),
/*len=*/-1, /*loc=*/-1,
/*set=*/0));
CHECK(X509_set_subject_name(x509.get(), subject_name.get()));
// Set the issuer DN.
bssl::UniquePtr<X509_NAME> issuer_name(X509_NAME_new());
CHECK(X509_NAME_add_entry_by_txt(issuer_name.get(), /*field=*/"CN",
MBSTRING_ASC,
reinterpret_cast<const unsigned char*>(
options.issuer_common_name.c_str()),
/*len=*/-1, /*loc=*/-1,
/*set=*/0));
CHECK(X509_NAME_add_entry_by_txt(
issuer_name.get(), /*field=*/"O", MBSTRING_ASC,
reinterpret_cast<const unsigned char*>("Google"),
/*len=*/-1, /*loc=*/-1,
/*set=*/0));
CHECK(X509_NAME_add_entry_by_txt(
issuer_name.get(), /*field=*/"OU", MBSTRING_ASC,
reinterpret_cast<const unsigned char*>("Google OU"),
/*len=*/-1, /*loc=*/-1,
/*set=*/0));
CHECK(X509_set_issuer_name(x509.get(), issuer_name.get()));
// Set the public key and sign the certificate.
CHECK(X509_set_pubkey(x509.get(), options.private_key));
CHECK(X509_sign(x509.get(), options.signing_key, EVP_sha256()));
return x509;
}
} // namespace credentio