From 518df309b138936671e445737eb3a944e2e13583 Mon Sep 17 00:00:00 2001 From: Samuel Chiang Date: Tue, 30 Jul 2024 16:39:55 -0700 Subject: [PATCH] Support utility OCSP request functions (#1708) There are a few easier `OCSP_REQUEST` utility functions Ruby uses. We initially didn't support these as they made more sense as supporting functions for OCSP responders. `OCSP_id_issuer_cmp` was also pulled out of `internal.h` since it's needed. By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license and the ISC license. --- crypto/ocsp/internal.h | 4 ---- crypto/ocsp/ocsp_server.c | 24 +++++++++++++++++++++--- crypto/ocsp/ocsp_test.cc | 10 +++++++++- include/openssl/ocsp.h | 17 ++++++++++++++++- 4 files changed, 46 insertions(+), 9 deletions(-) diff --git a/crypto/ocsp/internal.h b/crypto/ocsp/internal.h index eaa7d92474..cbc44bc164 100644 --- a/crypto/ocsp/internal.h +++ b/crypto/ocsp/internal.h @@ -269,10 +269,6 @@ int OCSP_REQ_CTX_nbio_d2i(OCSP_REQ_CTX *rctx, ASN1_VALUE **pval, // correctly. OPENSSL_EXPORT BIO *OCSP_REQ_CTX_get0_mem_bio(OCSP_REQ_CTX *rctx); -// --- OCSP compare functions --- -// Compares certificate id issuers, returns 0 on equal. -int OCSP_id_issuer_cmp(const OCSP_CERTID *a, const OCSP_CERTID *b); - // OCSP extension functions diff --git a/crypto/ocsp/ocsp_server.c b/crypto/ocsp/ocsp_server.c index 31afb710da..02c33ca415 100644 --- a/crypto/ocsp/ocsp_server.c +++ b/crypto/ocsp/ocsp_server.c @@ -10,8 +10,20 @@ // SPDX-License-Identifier: Apache-2.0 OR ISC // Modifications Copyright Amazon.com, Inc. or its affiliates. +#include "../internal.h" #include "internal.h" +int OCSP_request_onereq_count(OCSP_REQUEST *req) { + GUARD_PTR(req); + GUARD_PTR(req->tbsRequest); + return (int)sk_OCSP_ONEREQ_num(req->tbsRequest->requestList); +} + +OCSP_ONEREQ *OCSP_request_onereq_get0(OCSP_REQUEST *req, int i) { + GUARD_PTR(req); + GUARD_PTR(req->tbsRequest); + return sk_OCSP_ONEREQ_value(req->tbsRequest->requestList, i); +} int OCSP_id_get0_info(ASN1_OCTET_STRING **nameHash, ASN1_OBJECT **algor, ASN1_OCTET_STRING **keyHash, ASN1_INTEGER **serial, @@ -34,10 +46,16 @@ int OCSP_id_get0_info(ASN1_OCTET_STRING **nameHash, ASN1_OBJECT **algor, return 1; } -OCSP_CERTID *OCSP_onereq_get0_id(OCSP_ONEREQ *one) { - if(one == NULL) { - return NULL; +int OCSP_request_is_signed(OCSP_REQUEST *req) { + GUARD_PTR(req); + if (req->optionalSignature != NULL) { + return 1; } + return 0; +} + +OCSP_CERTID *OCSP_onereq_get0_id(OCSP_ONEREQ *one) { + GUARD_PTR(one); return one->reqCert; } diff --git a/crypto/ocsp/ocsp_test.cc b/crypto/ocsp/ocsp_test.cc index cf591d4b65..a58995b5da 100644 --- a/crypto/ocsp/ocsp_test.cc +++ b/crypto/ocsp/ocsp_test.cc @@ -946,8 +946,10 @@ TEST_P(OCSPRequestTest, OCSPRequestSign) { pkey.get(), t.dgst, additional_cert.get(), 0); if (t.expected_sign_status == OCSP_REQUEST_SIGN_SUCCESS) { ASSERT_TRUE(ret); + EXPECT_TRUE(OCSP_request_is_signed(ocspRequest.get())); } else { ASSERT_FALSE(ret); + EXPECT_FALSE(OCSP_request_is_signed(ocspRequest.get())); } } } @@ -1582,7 +1584,7 @@ TEST(OCSPTest, OCSPRequestPrint) { } } -TEST(OCSPTest, OCSPGetID) { +TEST(OCSPTest, OCSPUtilityFunctions) { // Create new OCSP_CERTID OCSP_CERTID *cert_id = OCSP_CERTID_new(); ASSERT_TRUE(cert_id); @@ -1590,8 +1592,14 @@ TEST(OCSPTest, OCSPGetID) { bssl::UniquePtr request(OCSP_REQUEST_new()); ASSERT_TRUE(request); + // Test that an |OCSP_ONEREQ| does not exist yet. + EXPECT_EQ(OCSP_request_onereq_count(request.get()), 0); + EXPECT_FALSE(OCSP_request_onereq_get0(request.get(), 0)); + OCSP_ONEREQ *one = OCSP_request_add0_id(request.get(), cert_id); ASSERT_TRUE(one); + EXPECT_EQ(OCSP_request_onereq_count(request.get()), 1); + EXPECT_TRUE(OCSP_request_onereq_get0(request.get(), 0)); // Call function to get OCSP_CERTID OCSP_CERTID *returned_id = OCSP_onereq_get0_id(one); diff --git a/include/openssl/ocsp.h b/include/openssl/ocsp.h index 3cc9a83005..21d00863b8 100644 --- a/include/openssl/ocsp.h +++ b/include/openssl/ocsp.h @@ -200,6 +200,16 @@ OPENSSL_EXPORT int OCSP_request_set1_name(OCSP_REQUEST *req, X509_NAME *nm); // OCSP_request_add1_cert adds a certificate to an |OCSP_REQUEST|. OPENSSL_EXPORT int OCSP_request_add1_cert(OCSP_REQUEST *req, X509 *cert); +// OCSP_request_is_signed checks if the optional signature exists for |req|. +OPENSSL_EXPORT int OCSP_request_is_signed(OCSP_REQUEST *req); + +// OCSP_request_onereq_count returns the number of |OCSP_ONEREQ|s in |req|. +OPENSSL_EXPORT int OCSP_request_onereq_count(OCSP_REQUEST *req); + +// OCSP_request_onereq_get0 returns the |OCSP_ONEREQ| in |req| at index |i| or +// NULL if |i| is out of bounds. +OPENSSL_EXPORT OCSP_ONEREQ *OCSP_request_onereq_get0(OCSP_REQUEST *req, int i); + // OCSP_request_sign signs an |OCSP_REQUEST|. Signing also sets the // |requestorName| to the subject name of an optional signers certificate and // includes one or more optional certificates in the request. @@ -339,7 +349,12 @@ OPENSSL_EXPORT OCSP_CERTID *OCSP_cert_to_id(const EVP_MD *dgst, OPENSSL_EXPORT int OCSP_parse_url(const char *url, char **phost, char **pport, char **ppath, int *pssl); -// OCSP_id_cmp compares the contents of |OCSP_CERTID|, returns 0 on equal. +// OCSP_id_issuer_cmp compares the issuers' name and key hash of |a| and |b|. It +// returns 0 on equal. +OPENSSL_EXPORT int OCSP_id_issuer_cmp(const OCSP_CERTID *a, const OCSP_CERTID *b); + +// OCSP_id_cmp calls |OCSP_id_issuer_cmp| and additionally compares the +// |serialNumber| of |a| and |b|. It returns 0 on equal. OPENSSL_EXPORT int OCSP_id_cmp(const OCSP_CERTID *a, const OCSP_CERTID *b); // OCSP_id_get0_info returns the issuer name hash, hash OID, issuer key hash,