blob: 9844e1652d58140d5dd8432a40620d69da4db362 [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/pem.h"
#include <cstdint>
#include <memory>
#include <string>
#include <utility>
#include "absl/status/status.h"
#include "absl/status/status_macros.h"
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "openssl/bio.h"
#include "openssl/ec.h"
#include "openssl/ec_key.h"
#include "openssl/evp.h"
#include "openssl/mem.h"
#include "openssl/nid.h"
#include "openssl/obj.h"
#include "openssl/pem.h"
#include "openssl/x509.h"
#include "proto/common.pb.h"
#include "tink/cleartext_keyset_handle.h"
#include "tink/keyset_handle.h"
#include "tink/public_key_sign.h"
#include "tink/signature/config_v0.h"
#include "tink/signature/signature_pem_keyset_reader.h"
namespace credentio {
using ::crypto::tink::PemKeyParams;
using ::crypto::tink::PublicKeySign;
using ::crypto::tink::SignaturePemKeysetReaderBuilder;
absl::StatusOr<std::unique_ptr<crypto::tink::PublicKeySign>> LoadTestKeyFromPem(
absl::string_view pem, const PemKeyParams& key_params) {
crypto::tink::SignaturePemKeysetReaderBuilder builder(
SignaturePemKeysetReaderBuilder::PemReaderType::PUBLIC_KEY_SIGN);
builder.Add({
.serialized_key = std::string(pem),
.parameters = key_params,
});
ABSL_ASSIGN_OR_RETURN(auto reader, builder.Build());
ABSL_ASSIGN_OR_RETURN(auto handle, crypto::tink::CleartextKeysetHandle::Read(
std::move(reader)));
return handle->GetPrimitive<crypto::tink::PublicKeySign>(
crypto::tink::ConfigSignatureV0());
}
absl::StatusOr<std::string> LoadOcspResponseFromPem(absl::string_view pem) {
bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(pem.data(), pem.size()));
if (bio == nullptr) {
return absl::InternalError("Failed to create BIO.");
}
std::string response;
bool found = false;
while (true) {
char* name = nullptr;
char* header = nullptr;
unsigned char* data = nullptr;
int64_t len = 0;
if (!PEM_read_bio(bio.get(), &name, &header, &data, &len)) {
break;
}
bssl::UniquePtr<char> name_ptr(name);
bssl::UniquePtr<char> header_ptr(header);
bssl::UniquePtr<unsigned char> data_ptr(data);
if (absl::string_view(name) == "OCSP RESPONSE") {
if (found) {
return absl::InvalidArgumentError(
"Multiple OCSP RESPONSE blocks found; expected only one.");
}
response = std::string(reinterpret_cast<char*>(data), len);
found = true;
}
}
if (!found) {
return absl::InvalidArgumentError("No OCSP RESPONSE block found.");
}
return response;
}
} // namespace credentio