]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
unit-tests: Update test_serial_gen suite
authorAndreas Steffen <andreas.steffen@strongswan.org>
Thu, 15 Jun 2023 14:39:25 +0000 (16:39 +0200)
committerTobias Brunner <tobias@strongswan.org>
Mon, 13 Nov 2023 11:40:55 +0000 (12:40 +0100)
src/libstrongswan/tests/suites/test_serial_gen.c

index 65846fd8579d87519530021e6ef46bdaeb61743b..696396175c03c4553695122cae79e1223ac53a01 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2022 Andreas Steffen, strongSec GmbH
+ * Copyright (C) 2022-2023 Andreas Steffen, strongSec GmbH
  *
  * Copyright (C) secunet Security Networks AG
  *
@@ -18,7 +18,9 @@
 
 #include <credentials/certificates/x509.h>
 #include <credentials/certificates/crl.h>
+#include <credentials/certificates/ocsp_request.h>
 #include <credentials/certificates/ocsp_response.h>
+#include <credentials/certificates/ocsp_single_response.h>
 #include <credentials/certificates/ac.h>
 
 #include <time.h>
@@ -182,6 +184,83 @@ static certificate_t* create_ocsp_request(certificate_t *cert)
        return ocsp_req;
 }
 
+/**
+ * Parse an ASN.1 encoded OCSP request
+ */
+static certificate_t* parse_ocsp_request(chunk_t encoding)
+{
+       certificate_t *ocsp_req;
+
+       ocsp_req = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509_OCSP_REQUEST,
+                                               BUILD_BLOB_ASN1_DER, encoding,
+                                               BUILD_END);
+       ck_assert(ocsp_req);
+
+       return ocsp_req;
+}
+
+/**
+ * Create an OCSP response based on an OCSP request
+ */
+static certificate_t* create_ocsp_response(ocsp_request_t *ocsp_request,
+                                                                                  cert_validation_t status,
+                                                                                  certificate_t *cert)
+{
+       private_key_t *privkey;
+       certificate_t *ocsp_rsp;
+       ocsp_status_t ocsp_status = OCSP_SUCCESSFUL;
+       ocsp_single_response_t *response;
+       chunk_t issuerNameHash, issuerKeyHash, serialNumber, nonce;
+       hash_algorithm_t hashAlgorithm;
+       linked_list_t *responses = linked_list_create();
+       enumerator_t *enumerator;
+
+       privkey = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
+                                                                BUILD_BLOB_ASN1_DER, chunk_from_thing(keydata),
+                                                                BUILD_END);
+       ck_assert(privkey);
+
+       /* generate OCSP single response */
+       enumerator = ocsp_request->create_request_enumerator(ocsp_request);
+       ck_assert(enumerator->enumerate(enumerator, &hashAlgorithm, &issuerNameHash,
+                                                                                               &issuerKeyHash, &serialNumber));
+       response = ocsp_single_response_create();
+       response->hashAlgorithm  = hashAlgorithm;
+       response->issuerNameHash = chunk_clone(issuerNameHash);
+       response->issuerKeyHash  = chunk_clone(issuerKeyHash);
+       response->serialNumber   = chunk_clone(serialNumber);
+       response->thisUpdate     = time(NULL);
+       response->status         = status;
+       if (status == VALIDATION_REVOKED)
+       {
+               response->revocationReason = CRL_REASON_KEY_COMPROMISE;
+               response->revocationTime   = time(NULL);
+       }
+       responses->insert_last(responses, response);
+       enumerator->destroy(enumerator);
+
+       nonce = ocsp_request->get_nonce(ocsp_request);
+
+       /* generate OCSP response */
+       enumerator = responses->create_enumerator(responses);
+       ocsp_rsp = lib->creds->create(lib->creds, CRED_CERTIFICATE,
+                                               CERT_X509_OCSP_RESPONSE,
+                                               BUILD_OCSP_STATUS, ocsp_status,
+                                               BUILD_OCSP_RESPONSES, enumerator,
+                                               BUILD_SIGNING_KEY, privkey,
+                                               BUILD_SIGNING_CERT, cert,
+                                               BUILD_NONCE, nonce,
+                                               BUILD_END);
+       enumerator->destroy(enumerator);
+
+       ck_assert(ocsp_rsp);
+
+       privkey->destroy(privkey);
+       responses->destroy_offset(responses, offsetof(ocsp_single_response_t, destroy));
+
+       return ocsp_rsp;
+}
+
 /**
  * Parse an ASN.1 encoded OCSP response
  */
@@ -290,72 +369,22 @@ static serial_number_t serial_numbers[] = {
          chunk_from_chars(0x05,0x00,0xff,0xff,0xff,0xff) },
 };
 
-static chunk_t ocsp_responses[] = {
-       chunk_from_chars(
-               0x30,0x82,0x01,0x85,0x0a,0x01,0x00,0xa0,0x82,0x01,0x7e,0x30,0x82,0x01,0x7a,0x06,
-               0x09,0x2b,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x01,0x04,0x82,0x01,0x6b,0x30,0x82,
-               0x01,0x67,0x30,0x81,0xd1,0xa1,0x33,0x30,0x31,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,
-               0x04,0x06,0x13,0x02,0x43,0x48,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x0a,0x13,
-               0x0a,0x73,0x74,0x72,0x6f,0x6e,0x67,0x53,0x77,0x61,0x6e,0x31,0x0d,0x30,0x0b,0x06,
-               0x03,0x55,0x04,0x03,0x13,0x04,0x74,0x65,0x73,0x74,0x18,0x0f,0x32,0x30,0x32,0x32,
-               0x31,0x31,0x32,0x32,0x30,0x39,0x31,0x36,0x34,0x37,0x5a,0x30,0x64,0x30,0x62,0x30,
-               0x3a,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1a,0x05,0x00,0x04,0x14,0xbd,0x25,
-               0xa0,0xdf,0xc3,0x21,0xf2,0xd8,0xed,0x19,0x63,0x0a,0x4b,0x90,0x6d,0xc3,0x0f,0xe7,
-               0x79,0x20,0x04,0x14,0xe2,0x6d,0x1e,0xdf,0x83,0x8e,0xa2,0x1f,0xc3,0x00,0xdd,0x44,
-               0x6f,0x8a,0x4d,0x70,0x0c,0x02,0xe3,0x1f,0x02,0x01,0x7f,0x80,0x00,0x18,0x0f,0x32,
-               0x30,0x32,0x32,0x31,0x31,0x32,0x32,0x30,0x39,0x31,0x36,0x34,0x37,0x5a,0xa0,0x11,
-               0x18,0x0f,0x32,0x30,0x32,0x32,0x31,0x31,0x32,0x32,0x31,0x39,0x31,0x36,0x34,0x37,
-               0x5a,0xa1,0x23,0x30,0x21,0x30,0x1f,0x06,0x09,0x2b,0x06,0x01,0x05,0x05,0x07,0x30,
-               0x01,0x02,0x04,0x12,0x04,0x10,0x86,0x45,0x82,0x11,0xe6,0x62,0x43,0x83,0xbc,0x01,
-               0xe4,0x5c,0x48,0x87,0xcd,0x2e,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
-               0x01,0x01,0x0b,0x05,0x00,0x03,0x81,0x81,0x00,0x42,0x32,0xa9,0x24,0x97,0x8c,0xc5,
-               0x35,0x37,0xe7,0x14,0xf0,0x84,0x7e,0x69,0xf1,0x99,0xf8,0xf0,0x02,0x7d,0xe4,0xd8,
-               0x25,0x78,0x65,0x86,0x40,0xf6,0x30,0xc1,0x50,0x57,0x16,0x13,0xe9,0xe5,0xbc,0xa9,
-               0xbb,0x87,0xce,0xb8,0x0d,0x35,0x5d,0xad,0x68,0x3b,0x34,0x9f,0x82,0x2b,0xe5,0x1f,
-               0xcc,0xd5,0x54,0x8a,0xe3,0xd7,0xed,0xc9,0x7d,0xb6,0x50,0xd2,0xcb,0xc2,0xff,0x03,
-               0x24,0x8c,0xcf,0x49,0x40,0xd4,0x7f,0xcb,0xc0,0x20,0x75,0x78,0x45,0xb8,0x50,0x3c,
-               0x84,0xdd,0xdc,0xb7,0xfc,0xcd,0x64,0xc3,0x81,0xc6,0xb6,0xcd,0xc5,0xe9,0xc4,0x70,
-               0x31,0x30,0x7c,0xff,0x93,0xc3,0x9d,0x55,0x7b,0x32,0x77,0x53,0x07,0x45,0xc2,0x80,
-               0x7b,0x9b,0xfb,0x0e,0x45,0x27,0xf2,0xc5,0x16),
-       chunk_from_chars(
-               0x30,0x82,0x01,0x9c,0x0a,0x01,0x00,0xa0,0x82,0x01,0x95,0x30,0x82,0x01,0x91,0x06,
-               0x09,0x2b,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x01,0x04,0x82,0x01,0x82,0x30,0x82,
-               0x01,0x7e,0x30,0x81,0xe8,0xa1,0x33,0x30,0x31,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,
-               0x04,0x06,0x13,0x02,0x43,0x48,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x0a,0x13,
-               0x0a,0x73,0x74,0x72,0x6f,0x6e,0x67,0x53,0x77,0x61,0x6e,0x31,0x0d,0x30,0x0b,0x06,
-               0x03,0x55,0x04,0x03,0x13,0x04,0x74,0x65,0x73,0x74,0x18,0x0f,0x32,0x30,0x32,0x32,
-               0x31,0x31,0x32,0x32,0x30,0x39,0x32,0x32,0x32,0x34,0x5a,0x30,0x7b,0x30,0x79,0x30,
-               0x3b,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1a,0x05,0x00,0x04,0x14,0xbd,0x25,
-               0xa0,0xdf,0xc3,0x21,0xf2,0xd8,0xed,0x19,0x63,0x0a,0x4b,0x90,0x6d,0xc3,0x0f,0xe7,
-               0x79,0x20,0x04,0x14,0xe2,0x6d,0x1e,0xdf,0x83,0x8e,0xa2,0x1f,0xc3,0x00,0xdd,0x44,
-               0x6f,0x8a,0x4d,0x70,0x0c,0x02,0xe3,0x1f,0x02,0x02,0x00,0x80,0xa1,0x16,0x18,0x0f,
-               0x32,0x30,0x32,0x32,0x31,0x31,0x31,0x35,0x31,0x38,0x34,0x30,0x35,0x34,0x5a,0xa0,
-               0x03,0x0a,0x01,0x01,0x18,0x0f,0x32,0x30,0x32,0x32,0x31,0x31,0x32,0x32,0x30,0x39,
-               0x32,0x32,0x32,0x34,0x5a,0xa0,0x11,0x18,0x0f,0x32,0x30,0x32,0x32,0x31,0x31,0x32,
-               0x32,0x31,0x39,0x32,0x32,0x32,0x34,0x5a,0xa1,0x23,0x30,0x21,0x30,0x1f,0x06,0x09,
-               0x2b,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x02,0x04,0x12,0x04,0x10,0xf2,0x47,0xbd,
-               0xd2,0xdd,0x6d,0x58,0xba,0xa4,0x6f,0xa5,0xed,0x31,0xb1,0x37,0x89,0x30,0x0d,0x06,
-               0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x0b,0x05,0x00,0x03,0x81,0x81,0x00,
-               0x17,0x96,0x3b,0x5a,0x4d,0x4e,0x90,0x8a,0xdf,0xe9,0x2b,0x1c,0x48,0x15,0x5d,0x8e,
-               0xed,0xf0,0xa6,0x42,0x3a,0x9c,0x71,0xd9,0x6a,0xa6,0xc1,0xfd,0xef,0xe8,0x0a,0xa1,
-               0x61,0x46,0xe4,0x04,0x5c,0x64,0xaf,0x47,0x95,0xdd,0x4c,0xba,0x8e,0x53,0xf6,0x9b,
-               0xbc,0x16,0xcb,0xeb,0xfe,0x80,0x6a,0x70,0x54,0x10,0x59,0x40,0x5b,0xa0,0x2b,0xb3,
-               0x62,0x27,0x9e,0x5d,0xd2,0xd6,0x15,0x2a,0x9d,0xa3,0xb1,0xcb,0x44,0x09,0xd8,0x29,
-               0xb5,0x55,0xd9,0x63,0x86,0xd5,0xb3,0x3c,0x4b,0x78,0x14,0x5a,0x27,0x37,0x3a,0x28,
-               0xd8,0xae,0x69,0x51,0x2e,0x7d,0xf1,0x06,0xc1,0xac,0x4e,0x5d,0x25,0x7a,0xd2,0xf4,
-               0x41,0xfd,0x9f,0xbf,0x05,0xc1,0x70,0xa5,0x3f,0x7a,0x53,0x06,0x85,0x7b,0xeb,0x94)
-};
 
 START_TEST(test_gen_serial_numbers)
 {
        chunk_t encoding, serial, serial_asn1;
-       certificate_t *cert, *crl, *ocsp_req, *acert, *acert1;
-       enumerator_t *enumerator;
+       certificate_t *cert, *crl, *ocsp_req, *ocsp_rsp, *acert, *acert1;
+       time_t revocation_time, this_update, next_update;
+       ocsp_request_t *ocsp_request;
+       ocsp_response_t *ocsp_resp;
+       cert_validation_t status;
+       crl_reason_t revocation_reason;
        crl_t *x509_crl;
        x509_t *x509;
        ac_t *ac;
        size_t offset;
        u_char *pos;
+       enumerator_t *enumerator;
 
        /**
         * Use serial number with canonical encoding (no leading zeroes)
@@ -502,51 +531,93 @@ START_TEST(test_gen_serial_numbers)
        pos = encoding.ptr + 68;
        serial_asn1 = chunk_create(pos, 1 + *pos);
        ck_assert_chunk_eq(serial_asn1, serial_numbers[_i].serial_asn1);
+       ocsp_req->destroy(ocsp_req);
+
+       /* parse ocsp request */
+       ocsp_req = parse_ocsp_request(encoding);
+       ocsp_request = (ocsp_request_t*)ocsp_req;
+
+       /* test ocsp request */
+       enumerator = ocsp_request->create_request_enumerator(ocsp_request);
+       ck_assert(enumerator->enumerate(enumerator, NULL, NULL, NULL, &serial));
+       ck_assert_chunk_eq(serial, serial_numbers[_i].serial);
+       enumerator->destroy(enumerator);
        chunk_free(&encoding);
 
+       /* create ocsp response */
+       status = (_i % 2) ? VALIDATION_GOOD : VALIDATION_REVOKED;
+       ocsp_rsp = create_ocsp_response(ocsp_request, status, cert);
+
+       /* the ASN.1 TLV (Type-Length-Value) encoding of an OCSP response is
+        *
+        * 0 "OCSPResponse",                     ASN1_SEQUENCE
+        * 1   "responseStatus",                 ASN1_ENUMERATED
+        * 1   "responseBytesContext",           ASN1_CONTEXT_C_0
+        * 2     "responseBytes",                ASN1_SEQUENCE
+        * 3       "responseType",               ASN1_OID
+        * 3       "response",                   ASN1_OCTET_STRING
+        * 4         "BasicOCSPResponse",        ASN1_SEQUENCE
+        * 5           "tbsResponseData",        ASN1_SEQUENCE
+        * 6             "responderIdContext",   ASN1_CONTEXT_C_1
+        * 6             "producedAt",           ASN1_GENERALIZEDTIME
+        * 6             "responses",            ASN1_SEQUENCE
+        * 7               "singleResponse",     ASN1_SEQUENCE
+        * 8                 "certID",           ASN1_SEQUENCE
+        * 9                   "algorithm",      ASN1_SEQUENCE
+        * 9                   "issuerNameHash", ASN1_OCTET_STRING
+        * 9                   "issuerKeyHash",  ASN1_OCTET_STRING
+        * 9                   "serialNumber",   ASN1_INTEGER
+        *
+        * The one octet length field of the serialNumber (8) is at
+     * pos = 4 (TL0) + 3 (TLV1) + 4 (TL1) + 4 (TL2) + 11 (TLV3) + 4 (TL3) +
+             4 (TL4) + 3 (TL5) + 53 (TLV6) + 17 (TVL6) + 2 (TL6) + 2 (TL7) +
+             2 (TL8) + 11 (TLV9) + 22 (TLV9) + 22 (TLV9) + 1 (T9) = 169
+     */
+       ck_assert(ocsp_rsp->get_encoding(ocsp_rsp, CERT_ASN1_DER, &encoding));
+       DBG2(DBG_LIB, "ocsp response: %B", &encoding);
+
+       /* check ASN.1 integer encoding of requested serial number */
+       pos = encoding.ptr + 169;
+       serial_asn1 = chunk_create(pos, 1 + *pos);
+       ck_assert_chunk_eq(serial_asn1, serial_numbers[_i].serial_asn1);
+       ocsp_rsp->destroy(ocsp_rsp);
+
+       /* parse ocsp response */
+       ocsp_rsp = parse_ocsp_response(encoding);
+       ocsp_resp = (ocsp_response_t*)ocsp_rsp;
+
        /* test ocsp response */
-       if (_i == 2 || _i == 3)
+       ck_assert_chunk_eq(ocsp_request->get_nonce(ocsp_request),
+                                          ocsp_resp->get_nonce(ocsp_resp));
+
+       status = ocsp_resp->get_status(ocsp_resp, x509, x509, &revocation_time,
+                                                               &revocation_reason, &this_update, &next_update);
+       if (_i % 2)
        {
-               certificate_t *ocsp_rsp;
-               ocsp_response_t *ocsp_resp;
-               cert_validation_t status;
-               crl_reason_t revocation_reason;
-               time_t revocation_time, this_update, next_update;
-               enumerator_t *enumerator;
-
-               ocsp_rsp = parse_ocsp_response(ocsp_responses[_i-2]);
-               ocsp_resp = (ocsp_response_t*)ocsp_rsp;
-
-               status = ocsp_resp->get_status(ocsp_resp, x509, x509, &revocation_time,
-                                                        &revocation_reason, &this_update, &next_update);
-               if (_i == 2)
-               {
-                       ck_assert(status == VALIDATION_GOOD);
-               }
-               else
-               {
-                       ck_assert(status == VALIDATION_REVOKED);
-                       ck_assert(revocation_reason == CRL_REASON_KEY_COMPROMISE);
-               }
-
-               enumerator = ocsp_resp->create_response_enumerator(ocsp_resp);
-               ck_assert(enumerator->enumerate(enumerator, &serial, &status,
-                                                                           &revocation_time, &revocation_reason));
-               ck_assert_chunk_eq(serial, serial_numbers[_i].serial);
-               if (_i == 2)
-               {
-                       ck_assert(status == VALIDATION_GOOD);
-               }
-               else
-               {
-                       ck_assert(status == VALIDATION_REVOKED);
-                       ck_assert(revocation_reason == CRL_REASON_KEY_COMPROMISE);
-               }
-               enumerator->destroy(enumerator);
-
-               ocsp_rsp->destroy(ocsp_rsp);
+               ck_assert(status == VALIDATION_GOOD);
+       }
+       else
+       {
+               ck_assert(status == VALIDATION_REVOKED);
+               ck_assert(revocation_reason == CRL_REASON_KEY_COMPROMISE);
        }
 
+       enumerator = ocsp_resp->create_response_enumerator(ocsp_resp);
+       ck_assert(enumerator->enumerate(enumerator, &serial, &status,
+                                                                       &revocation_time, &revocation_reason));
+       ck_assert_chunk_eq(serial, serial_numbers[_i].serial);
+       if (_i % 2)
+       {
+               ck_assert(status == VALIDATION_GOOD);
+       }
+       else
+       {
+               ck_assert(status == VALIDATION_REVOKED);
+               ck_assert(revocation_reason == CRL_REASON_KEY_COMPROMISE);
+       }
+       enumerator->destroy(enumerator);
+       chunk_free(&encoding);
+
        /* create attribute certificate */
        acert = create_acert(serial_numbers[_i].serial, cert);
 
@@ -633,6 +704,7 @@ START_TEST(test_gen_serial_numbers)
        cert->destroy(cert);
        crl->destroy(crl);
        ocsp_req->destroy(ocsp_req);
+       ocsp_rsp->destroy(ocsp_rsp);
        acert->destroy(acert);
        acert1->destroy(acert1);