From: Andreas Steffen Date: Thu, 15 Jun 2023 14:39:25 +0000 (+0200) Subject: unit-tests: Update test_serial_gen suite X-Git-Tag: 5.9.12rc1~3^2~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a0f672d3d198accccbb3fb907d54561b2f48e650;p=thirdparty%2Fstrongswan.git unit-tests: Update test_serial_gen suite --- diff --git a/src/libstrongswan/tests/suites/test_serial_gen.c b/src/libstrongswan/tests/suites/test_serial_gen.c index 65846fd857..696396175c 100644 --- a/src/libstrongswan/tests/suites/test_serial_gen.c +++ b/src/libstrongswan/tests/suites/test_serial_gen.c @@ -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 #include +#include #include +#include #include #include @@ -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);