]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
unit-tests: Check encoding/retrieval of serial numbers
authorAndreas Steffen <andreas.steffen@strongswan.org>
Sat, 19 Nov 2022 11:27:49 +0000 (12:27 +0100)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Mon, 5 Dec 2022 19:18:24 +0000 (20:18 +0100)
src/libstrongswan/tests/Makefile.am
src/libstrongswan/tests/suites/test_serial_gen.c [new file with mode: 0644]
src/libstrongswan/tests/suites/test_serial_parse.c [new file with mode: 0644]
src/libstrongswan/tests/tests.h

index eb96396762d7ec48a934d7f8fce7d3267d3a7d94..2d0ba7f7c6864f58be621f9c3ebbf567db17b408 100644 (file)
@@ -48,6 +48,8 @@ libstrongswan_tests_SOURCES = tests.h tests.c \
   suites/test_rsa_oaep_sha512.c \
   suites/test_certpolicy.c \
   suites/test_certnames.c \
+  suites/test_serial_gen.c \
+  suites/test_serial_parse.c \
   suites/test_host.c \
   suites/test_auth_cfg.c \
   suites/test_hasher.c \
diff --git a/src/libstrongswan/tests/suites/test_serial_gen.c b/src/libstrongswan/tests/suites/test_serial_gen.c
new file mode 100644 (file)
index 0000000..65846fd
--- /dev/null
@@ -0,0 +1,708 @@
+/*
+ * Copyright (C) 2022 Andreas Steffen, strongSec GmbH
+ *
+ * Copyright (C) secunet Security Networks AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#include "test_suite.h"
+
+#include <credentials/certificates/x509.h>
+#include <credentials/certificates/crl.h>
+#include <credentials/certificates/ocsp_response.h>
+#include <credentials/certificates/ac.h>
+
+#include <time.h>
+
+/**
+ * RSA private key, so we don't have to generate one
+ */
+static char keydata[] = {
+  0x30,0x82,0x02,0x5e,0x02,0x01,0x00,0x02,0x81,0x81,0x00,0xb1,0x9b,0xd4,0x51,0x24,
+  0xfc,0x56,0x1d,0x3d,0xfb,0xa2,0xea,0x37,0x02,0x70,0x72,0x87,0x84,0x2f,0x3b,0x2d,
+  0x6e,0x22,0xef,0x3f,0x37,0x04,0xb2,0x6f,0xb7,0xe7,0xd8,0x58,0x05,0xde,0x34,0xbf,
+  0x99,0xe6,0x40,0x7a,0x56,0xa7,0x73,0xf5,0x98,0xcb,0xb0,0x37,0x90,0x5e,0xd1,0x3f,
+  0xf4,0x73,0x50,0x7f,0x53,0x8e,0xf1,0x04,0x25,0xb4,0x77,0x22,0x4e,0x8a,0x9d,0x27,
+  0x8f,0x6f,0xaf,0x59,0xbd,0xb0,0x0f,0xf0,0xaa,0x11,0x94,0x66,0x16,0x10,0x58,0xad,
+  0x77,0xa1,0xac,0x58,0xb4,0xd0,0x0d,0xbc,0x11,0xe0,0xc0,0xe9,0x29,0xdc,0x42,0x63,
+  0x01,0x23,0x4f,0x28,0x41,0x6d,0x34,0x9e,0x0c,0x4a,0xc8,0x62,0x83,0xb5,0x71,0x71,
+  0x0b,0x51,0xc0,0x4c,0x37,0xd4,0x68,0x19,0x52,0x9a,0x8b,0x02,0x03,0x01,0x00,0x01,
+  0x02,0x81,0x81,0x00,0x82,0xca,0x33,0x16,0xb2,0x3a,0xd4,0x1b,0x62,0x9a,0x9c,0xc5,
+  0x07,0x4f,0x57,0x89,0x2f,0x7c,0x4a,0xdf,0xb4,0x3b,0xc7,0xa4,0x11,0x14,0x2d,0xf4,
+  0x4c,0xca,0xcc,0x03,0x88,0x06,0x82,0x34,0xab,0xe7,0xe4,0x24,0x15,0x33,0x1c,0xcb,
+  0x0a,0xcf,0xc3,0x27,0x78,0x33,0x6b,0x6f,0x82,0x3e,0x3c,0x70,0xc9,0xe2,0xb9,0x7f,
+  0x88,0xc3,0x4f,0x59,0xb5,0x8e,0xa3,0x81,0xd9,0x88,0x1f,0xc0,0x38,0xbc,0xc8,0x93,
+  0x40,0x0f,0x43,0xd8,0x72,0x12,0xb4,0xcc,0x6d,0x76,0x0a,0x6f,0x01,0x05,0xa8,0x88,
+  0xf4,0x57,0x44,0xd2,0x05,0xc4,0x77,0xf5,0xfb,0x1b,0xf3,0xb2,0x0d,0x90,0xb8,0xb4,
+  0x63,0x62,0x70,0x2c,0xe4,0x28,0xd8,0x20,0x10,0x85,0x4a,0x5e,0x63,0xa9,0xb0,0xdd,
+  0xba,0xd0,0x32,0x49,0x02,0x41,0x00,0xdb,0x77,0xf1,0xdd,0x1a,0x12,0xc5,0xfb,0x2b,
+  0x5b,0xb2,0xcd,0xb6,0xd0,0x4c,0xc4,0xe5,0x93,0xd6,0xf8,0x88,0xfc,0x18,0x40,0x21,
+  0x9c,0xf7,0x2d,0x60,0x6f,0x91,0xf5,0x73,0x3c,0xf7,0x7f,0x67,0x1d,0x5b,0xb5,0xee,
+  0x29,0xc1,0xd4,0xc6,0xdb,0x44,0x4c,0x40,0x05,0x63,0xaa,0x71,0x95,0x18,0x14,0xa7,
+  0x23,0x9f,0x7a,0xee,0x7f,0xb5,0xc7,0x02,0x41,0x00,0xcf,0x2c,0x24,0x50,0x65,0xf4,
+  0x94,0x7b,0xe9,0xf3,0x13,0x77,0xea,0x27,0x3c,0x6f,0x03,0x84,0xa7,0x7d,0xa2,0x54,
+  0x40,0x97,0x82,0x0e,0xd9,0x09,0x9f,0x4a,0xa6,0x75,0xe5,0x66,0xe4,0x9c,0x59,0xd9,
+  0x3a,0xe6,0xf7,0xd8,0x8b,0x68,0xb0,0x21,0x52,0x31,0xb3,0x4a,0xa0,0x2c,0x41,0xd7,
+  0x1f,0x7b,0xe2,0x0f,0x15,0xc9,0x6e,0xc0,0xe5,0x1d,0x02,0x41,0x00,0x9c,0x1a,0x61,
+  0x9f,0x89,0xc7,0x26,0xa9,0x33,0xba,0xe2,0xa0,0x6d,0xd3,0x15,0x77,0xcb,0x6f,0xef,
+  0xad,0x12,0x0a,0x75,0xd9,0x4f,0xcf,0x4d,0x05,0x2a,0x9d,0xd1,0x2c,0xcb,0xcd,0xe6,
+  0xa0,0xe9,0x20,0x39,0xb6,0x5a,0xf3,0xba,0x99,0xf4,0xe3,0xcb,0x5d,0x8d,0x00,0x08,
+  0x57,0x18,0xb9,0x1a,0xca,0xbd,0xe3,0x99,0xb1,0x1f,0xe9,0x18,0xcb,0x02,0x40,0x65,
+  0x35,0x1b,0x48,0x6b,0x86,0x60,0x43,0x68,0xb6,0xe6,0xfb,0xdd,0xd7,0xed,0x1e,0x0e,
+  0x89,0xef,0x88,0xe0,0x94,0x68,0x39,0x9b,0xbf,0xc5,0x27,0x7e,0x39,0xe9,0xb8,0x0e,
+  0xa9,0x85,0x65,0x1c,0x3f,0x93,0x16,0xe2,0x5d,0x57,0x3d,0x7d,0x4d,0xc9,0xe9,0x9d,
+  0xbd,0x07,0x22,0x97,0xc7,0x90,0x09,0xe5,0x15,0x99,0x7f,0x1e,0x2b,0xfd,0xc1,0x02,
+  0x41,0x00,0x92,0x78,0xfe,0x04,0xa0,0x53,0xed,0x36,0x97,0xbd,0x16,0xce,0x91,0x9b,
+  0xbe,0x1f,0x8e,0x40,0x00,0x99,0x0c,0x49,0x15,0xca,0x59,0xd3,0xe3,0xd4,0xeb,0x71,
+  0xcf,0xda,0xd7,0xc8,0x99,0x74,0xfc,0x6b,0xe8,0xfd,0xe5,0xe0,0x49,0x61,0xcb,0xda,
+  0xe3,0xe7,0x8b,0x72,0xb5,0x69,0x73,0x2b,0x8b,0x54,0xcb,0xd9,0x48,0x6d,0x61,0x02,
+  0x49,0xe8,
+};
+
+/**
+ * Issue a certificate with a given serial number
+ */
+static certificate_t* create_cert(chunk_t serial)
+{
+       private_key_t *privkey;
+       public_key_t *pubkey;
+       certificate_t *cert;
+       identification_t *id;
+
+       privkey = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
+                                                                BUILD_BLOB_ASN1_DER, chunk_from_thing(keydata),
+                                                                BUILD_END);
+       ck_assert(privkey);
+       pubkey = privkey->get_public_key(privkey);
+       ck_assert(pubkey);
+       id = identification_create_from_string("C=CH, O=strongSwan, CN=test");
+       cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
+                                               BUILD_SIGNING_KEY, privkey,
+                                               BUILD_PUBLIC_KEY, pubkey,
+                                               BUILD_SUBJECT, id,
+                                               BUILD_SERIAL, serial,
+                                               BUILD_END);
+       ck_assert(cert);
+       id->destroy(id);
+       privkey->destroy(privkey);
+       pubkey->destroy(pubkey);
+
+       return cert;
+}
+
+CALLBACK(filter, bool,
+       void *data, enumerator_t *orig, va_list args)
+{
+       crl_revoked_t *revoked;
+       crl_reason_t *reason;
+       chunk_t *serial;
+       time_t *date;
+
+       VA_ARGS_VGET(args, serial, date, reason);
+
+       if (orig->enumerate(orig, &revoked))
+       {
+               *serial = revoked->serial;
+               *date   = revoked->date;
+               *reason = revoked->reason;
+               return TRUE;
+       }
+       return FALSE;
+}
+
+/**
+ * Revoke a certificate with a given serial number
+ */
+static certificate_t* create_crl(chunk_t serial, certificate_t *cert)
+{
+       private_key_t *privkey;
+       certificate_t *crl;
+       linked_list_t *list;
+       enumerator_t *enumerator;
+       crl_revoked_t *revoked;
+       time_t date = time(NULL);
+
+       privkey = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
+                                                                BUILD_BLOB_ASN1_DER, chunk_from_thing(keydata),
+                                                                BUILD_END);
+       ck_assert(privkey);
+
+       INIT(revoked,
+               .serial = serial,
+               .reason = CRL_REASON_KEY_COMPROMISE,
+               .date = date
+       );
+       list = linked_list_create();
+       list->insert_last(list, revoked);
+
+       enumerator = enumerator_create_filter(list->create_enumerator(list),
+                                                                                 filter, NULL, NULL);
+       crl = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509_CRL,
+                                               BUILD_SIGNING_KEY, privkey,
+                                               BUILD_NOT_BEFORE_TIME, date,
+                                               BUILD_NOT_AFTER_TIME, date + 30 * 24 * 3600,
+                                               BUILD_SIGNING_CERT, cert,
+                                               BUILD_REVOKED_ENUMERATOR, enumerator,
+                                               BUILD_SERIAL, serial,
+                                               BUILD_BASE_CRL, serial,
+                                               BUILD_END);
+       ck_assert(crl);
+       enumerator->destroy(enumerator);
+       list->destroy(list);
+       free(revoked);
+       privkey->destroy(privkey);
+
+       return crl;
+}
+
+/**
+ * Create an OCSP request for a given serial number
+ */
+static certificate_t* create_ocsp_request(certificate_t *cert)
+{
+       certificate_t *ocsp_req;
+
+       ocsp_req = lib->creds->create(lib->creds,
+                                               CRED_CERTIFICATE, CERT_X509_OCSP_REQUEST,
+                                               BUILD_CA_CERT, cert,
+                                               BUILD_CERT, cert,
+                                               BUILD_END);
+
+       ck_assert(ocsp_req);
+
+       return ocsp_req;
+}
+
+/**
+ * Parse an ASN.1 encoded OCSP response
+ */
+static certificate_t* parse_ocsp_response(chunk_t encoding)
+{
+       certificate_t *ocsp_rsp;
+
+       ocsp_rsp = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509_OCSP_RESPONSE,
+                                               BUILD_BLOB_ASN1_DER, encoding,
+                                               BUILD_END);
+       ck_assert(ocsp_rsp);
+
+       return ocsp_rsp;
+}
+
+/**
+ * Issue an attribute certificate with a given serial number
+ */
+static certificate_t* create_acert(chunk_t serial, certificate_t *cert)
+{
+       private_key_t *privkey;
+       public_key_t *pubkey;
+       certificate_t *acert;
+       linked_list_t *groups = linked_list_create();
+       time_t date = time(NULL);
+
+       privkey = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
+                                                                BUILD_BLOB_ASN1_DER, chunk_from_thing(keydata),
+                                                                BUILD_END);
+       ck_assert(privkey);
+       pubkey = privkey->get_public_key(privkey);
+       ck_assert(pubkey);
+       groups->insert_last(groups, "research");
+       acert = lib->creds->create(lib->creds,
+                                               CRED_CERTIFICATE, CERT_X509_AC,
+                                               BUILD_NOT_BEFORE_TIME, date,
+                                               BUILD_NOT_AFTER_TIME, date + 30 * 24 * 3600,
+                                               BUILD_CERT, cert,
+                                               BUILD_SERIAL, serial,
+                                               BUILD_AC_GROUP_STRINGS, groups,
+                                               BUILD_SIGNING_CERT, cert,
+                                               BUILD_SIGNING_KEY, privkey,
+                                               BUILD_END);
+       ck_assert(acert);
+       groups->destroy(groups);
+       privkey->destroy(privkey);
+       pubkey->destroy(pubkey);
+
+       return acert;
+}
+
+/**
+ * Parse an ASN.1 encoded attribute certificate
+ */
+static certificate_t* parse_acert(chunk_t encoding)
+{
+       certificate_t *acert;
+
+       acert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509_AC,
+                                               BUILD_BLOB_ASN1_DER, encoding,
+                                               BUILD_END);
+       ck_assert(acert);
+
+       return acert;
+}
+
+typedef struct {
+       chunk_t serial;
+       chunk_t serial_asn1;
+} serial_number_t;
+
+static serial_number_t serial_numbers[] = {
+       { chunk_from_chars(0x00),
+         chunk_from_chars(0x01,0x00) },
+       { chunk_from_chars(0x01),
+         chunk_from_chars(0x01,0x01) },
+       { chunk_from_chars(0x7f),
+         chunk_from_chars(0x01,0x7f) },
+       { chunk_from_chars(0x80),
+         chunk_from_chars(0x02,0x00,0x80) },
+       { chunk_from_chars(0xff),
+         chunk_from_chars(0x02,0x00,0xff) },
+       { chunk_from_chars(0x01,0x00),
+         chunk_from_chars(0x02,0x01,0x00) },
+       { chunk_from_chars(0x7f,0xff),
+         chunk_from_chars(0x02,0x7f,0xff) },
+       { chunk_from_chars(0x80,0x00),
+         chunk_from_chars(0x03,0x00,0x80,0x00) },
+       { chunk_from_chars(0xff,0xff),
+         chunk_from_chars(0x03,0x00,0xff,0xff) },
+       { chunk_from_chars(0x01,0x00,0x00),
+         chunk_from_chars(0x03,0x01,0x00,0x00) },
+       { chunk_from_chars(0x7f,0xff,0xff),
+         chunk_from_chars(0x03,0x7f,0xff,0xff) },
+       { chunk_from_chars(0x80,0x00,0x00),
+         chunk_from_chars(0x04,0x00,0x80,0x00,0x00) },
+       { chunk_from_chars(0xff,0xff,0xff),
+         chunk_from_chars(0x04,0x00,0xff,0xff,0xff) },
+       { chunk_from_chars(0x01,0x00,0x00,0x00),
+         chunk_from_chars(0x04,0x01,0x00,0x00,0x00) },
+       { chunk_from_chars(0x7f,0xff,0xff,0xff),
+         chunk_from_chars(0x04,0x7f,0xff,0xff,0xff) },
+       { chunk_from_chars(0x80,0x00,0x00,0x00),
+         chunk_from_chars(0x05,0x00,0x80,0x00,0x00,0x00) },
+       { chunk_from_chars(0xff,0xff,0xff,0xff),
+         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;
+       crl_t *x509_crl;
+       x509_t *x509;
+       ac_t *ac;
+       size_t offset;
+       u_char *pos;
+
+       /**
+        * Use serial number with canonical encoding (no leading zeroes)
+        */
+
+       /* create X.509 certificate */
+       cert = create_cert(serial_numbers[_i].serial);
+
+       /* retrieve configured serial number */
+       x509 = (x509_t*)cert;
+       ck_assert_chunk_eq(x509->get_serial(x509), serial_numbers[_i].serial);
+
+       /* the ASN.1 TLV (Type-Length-Value) encoding of an X.509 certificate is
+        *
+        * 0 "x509",             ASN1_SEQUENCE
+        * 1   "tbsCertificate", ASN1_SEQUENCE
+        * 2     "DEFAULT v1",   ASN1_CONTEXT_C_0
+        * 3       "version",    ASN1_INTEGER
+        * 4     "serialNumber", ASN1_INTEGER
+        * ...
+        *
+        * The one octet length field of the serialNumber (4) is at
+        *   pos = 4 (TL0) + 4 (TL1) + 2 (TL2) + 3 (TLV3) + 1 (T4) = 14
+        */
+       ck_assert(cert->get_encoding(cert, CERT_ASN1_DER, &encoding));
+       DBG2(DBG_LIB, "cert: %B", &encoding);
+
+       /* check ASN.1 integer encoding of serial number */
+       pos = encoding.ptr + 14;
+       serial_asn1 = chunk_create(pos, 1 + *pos);
+       ck_assert_chunk_eq(serial_asn1, serial_numbers[_i].serial_asn1);
+       chunk_free(&encoding);
+
+       /* create X.509 crl */
+       crl = create_crl(serial_numbers[_i].serial, cert);
+
+       /* retrieve configured serial number */
+       x509_crl = (crl_t*)crl;
+       ck_assert_chunk_eq(x509_crl->get_serial(x509_crl), serial_numbers[_i].serial);
+
+       enumerator = x509_crl->create_enumerator(x509_crl);
+       ck_assert(enumerator->enumerate(enumerator, &serial, NULL, NULL));
+       ck_assert_chunk_eq(serial, serial_numbers[_i].serial);
+       enumerator->destroy(enumerator);
+
+       /* retrieve configured base crl number */
+       ck_assert(x509_crl->is_delta_crl(x509_crl, &serial));
+       ck_assert_chunk_eq(x509_crl->get_serial(x509_crl), serial_numbers[_i].serial);
+
+       /* the ASN.1 TLV (Type-Length-Value) encoding of an X.509 crl is
+        *
+        *  0 "certificateList",                    ASN1_SEQUENCE
+        *  1   "tbsCertList",                      ASN1_SEQUENCE
+        *  2     "version",                        ASN1_INTEGER
+        *  3     "signature",                      ASN1_SEQUENCE
+        *  4     "issuer",                         ASN1_SEQUENCE
+        *  5     "thisUpdate"                      ASN1_UTCTIME
+        *  6     "nextUpdate"                      ASN1_UTCTIME
+        *  7     "revokedCertificates",            ASN1_SEQUENCE
+        *  8       "certList",                     ASN1_SEQUENCE
+        *  9         "userCertificate",            ASN1_INTEGER
+        * 10         "revocationDate",             ASN1_UTCTIME
+        * 11         "crlEntryExtensions",         ASN1_SEQUENCE
+        * 12     "optional extensions",            ASN1_CONTEXT_C_0
+        * 13       "crlExtensions",                ASN1_SEQUENCE
+        * 14         "extension",                  ASN1_SEQUENCE
+        * 15           "extnID",                   ASN1_OID
+        * 16           "critical",                 ASN1_BOOLEAN
+        * 17           "extnValue",                ASN1_OCTET_STRING
+        * 18             "authorityKeyIdentifier", ASN1_SEQUENCE
+        * 19         "extension",                  ASN1_SEQUENCE
+        * 20           "extnID",                   ASN1_OID
+        * 21           "critical",                 ASN1_BOOLEAN
+        * 22           "extnValue",                ASN1_OCTET_STRING
+        * 23             "crlNumber"               ASN1_INTEGER
+        * 24         "extension",                  ASN1_SEQUENCE
+        * 25           "extnID",                   ASN1_OID
+        * 26           "critical",                 ASN1_BOOLEAN
+        * 27           "extnValue",                ASN1_OCTET_STRING
+        * 28             "baseCrlNumber"           ASN1_INTEGER
+        * ...
+        *
+        * The one octet length field of the revoked userCertificate (9) is at
+        *   pos = 4 (TL0) + 3 (TL1) + 3 (TLV2) + 15 (TLV3) + 51 (TLV4) + 15 (TLV5) +
+        *         15 (TLV6) + 2 (TL7) + 2 (TL8) + 1 (T9) = 111
+        *
+        * The one octet length field of the crlNumber extension (19) is at
+        *   offset = pos - 1 (T9) + *L8 + 2 (TL12) + 2 (TL13) + 33 (TLV14) + 1 (T19)
+        *          = 110 + *L8 + 38
+        *
+        * The one octet length field of the crlNumber (23) is at
+        *   pos = offset + 1 (L19) + 5 (TLV20) + 0 (TLV21) + 2 (TL22) + 1 (T23)
+        *       = offset + 9
+        *
+        * The one octet length field of the baseCrlNumber (28) is at
+        *   pos = offset + 1 (L19) + *L19 + 2 (TL24) + 5 (TLV25) + 3 (TLV26)
+        *                + 2 (TL27) + 1 (T28)
+        *       = offset + *L19 + 14
+        */
+       ck_assert(crl->get_encoding(crl, CERT_ASN1_DER, &encoding));
+       DBG2(DBG_LIB, "crl: %B", &encoding);
+
+       /* check ASN.1 integer encoding of revoked number */
+       pos = encoding.ptr + 111;
+       serial_asn1 = chunk_create(pos, 1 + *pos);
+       ck_assert_chunk_eq(serial_asn1, serial_numbers[_i].serial_asn1);
+
+       /* check ASN.1 integer encoding of crlNumber */
+       offset = 110 + encoding.ptr[109] + 38;
+       pos = encoding.ptr + offset + 9;
+       serial_asn1 = chunk_create(pos, 1 + *pos);
+       ck_assert_chunk_eq(serial_asn1, serial_numbers[_i].serial_asn1);
+
+       /* check ASN.1 integer encoding of baseCrlNumber */
+       pos = encoding.ptr + offset + encoding.ptr[offset] + 14;
+       serial_asn1 = chunk_create(pos, 1 + *pos);
+       ck_assert_chunk_eq(serial_asn1, serial_numbers[_i].serial_asn1);
+       chunk_free(&encoding);
+
+       /* create ocsp request */
+       ocsp_req = create_ocsp_request(cert);
+
+       /* the ASN.1 TLV (Type-Length-Value) encoding of an OCSP request is
+        *
+        * 0 "OCSPRequest",              ASN1_SEQUENCE
+        * 1   "tbsRequest",             ASN1_SEQUENCE
+        * 2     "requestList",          ASN1_SEQUENCE
+        * 3       "request",            ASN1_SEQUENCE
+        * 4         "reqCert",          ASN1_SEQUENCE,
+        * 5           "hashAlgorithm",  ASN1_SEQUENCE
+        * 6           "issuerNameHash", ASN1_OCTET STRING
+        * 7           "issuerKeyHash",  ASN1_OCTET STRING
+        * 8           "serialNumber",   ASN1_INTEGER
+        * ...
+        *
+        * The one octet length field of the serialNumber (8) is at
+        * pos = 3 (TL0) + 3 (TL1) + 2 (TL2) + 2 (TL3) + 2 (TL4) + 11 (TLV5) +
+                22 (TLV6) + 22 (TLV7) + 1 (T8) = 68
+        */
+       ck_assert(ocsp_req->get_encoding(ocsp_req, CERT_ASN1_DER, &encoding));
+       DBG2(DBG_LIB, "ocsp request: %B", &encoding);
+
+       /* check ASN.1 integer encoding of requested serial number */
+       pos = encoding.ptr + 68;
+       serial_asn1 = chunk_create(pos, 1 + *pos);
+       ck_assert_chunk_eq(serial_asn1, serial_numbers[_i].serial_asn1);
+       chunk_free(&encoding);
+
+       /* test ocsp response */
+       if (_i == 2 || _i == 3)
+       {
+               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);
+       }
+
+       /* create attribute certificate */
+       acert = create_acert(serial_numbers[_i].serial, cert);
+
+       /* retrieve configured serial number */
+       ac = (ac_t*)acert;
+       ck_assert_chunk_eq(ac->get_serial(ac), serial_numbers[_i].serial);
+
+       /* retrieve configured holderSerial number */
+       ck_assert_chunk_eq(ac->get_holderSerial(ac), serial_numbers[_i].serial);
+
+       /* the ASN.1 TLV (Type-Length-Value) encoding of an attribute certificate is
+        *
+        *  0 "AttributeCertificate",                  ASN1_SEQUENCE
+        *  1   "AttributeCertificateInfo",            ASN1_SEQUENCE
+        *  2     "version",                           ASN1_INTEGER
+        *  3     "holder",                            ASN1_SEQUENCE
+        *  4      "baseCertificateID",                ASN1_CONTEXT_C_0
+        *  5         "issuer",                        ASN1_SEQUENCE
+        *  6         "serial",                        ASN1_INTEGER
+        *  7         "issuerUID",                     ASN1_BIT_STRING
+        *  8       "entityName",                      ASN1_CONTEXT_C_1
+        *  9       "objectDigestInfo",                ASN1_CONTEXT_C_2
+        * 10     "v2Form",                            ASN1_CONTEXT_C_0
+        * 11     "signature",                         ASN1_SEQUENCE
+        * 12     "serialNumber"                       ASN1_INTEGER
+        * 13     "attrCertValidityPeriod",            ASN1_SEQUENCE
+        * 14     "attributes",                        ASN1_SEQUENCE
+        * 15     "extensions",                        ASN1_SEQUENCE
+        * 16       "extension",                       ASN1_SEQUENCE
+        * 17         "extnID",                        ASN1_OID
+        * 18         "critical",                      ASN1_BOOLEAN
+        * 19         "extnValue",                     ASN1_OCTET_STRING
+        * 20           "authorityKeyIdentifier",      ASN1_SEQUENCE
+        * 21             "keyIdentifier",             ASN1_CONTEXT_S_0
+        * 22             "authorityCertIssuer",       ASN1_CONTEXT_C_1
+        * 23             "authorityCertSerialNumber", ASN1_CONTEXT_S_2
+        * ...
+        *
+        * The one octet length field of the holder serial number (6) is at
+        *   pos = 4 (TL0) + 4 (TL1) + 3 (TLV2) + 2 (TL3) + 2 (TL4) + 55 (TLV5) +
+        *         1 (T6) = 71
+        *
+        * The one octet length field of the serialNumber (12) is at
+        *   offset = 4 (TL0) + 4 (TL1) + 3 (TLV2) + 2 (TL3) + *L3 + 57 (TLV10) +
+        *            15 (TLV11) + 1 (T12)
+        *          = 13 + *L3 + 73
+        *
+        * The one octet length field of the authorityCertSerialNumber (23) is at
+        *   pos = offset + *L12 + 1 (L12) + 36 (TLV13) + 30 (TLV14) + 2 (TL15)
+        *                + 2 (TL16) + 5 (TLV17) + 0 (TLV18) + 2 (TL19) + 2 (TL20)
+        *                + 22 (TLV21) + 55 (TLV22) + 1 (T23)
+        *   pos = offset + *L12 + 158
+        */
+       ck_assert(acert->get_encoding(acert, CERT_ASN1_DER, &encoding));
+       DBG2(DBG_LIB, "acert: %B", &encoding);
+
+       /* check ASN.1 integer encoding of holder serial number */
+       pos = encoding.ptr + 71;
+       serial_asn1 = chunk_create(pos, 1 + *pos);
+       ck_assert_chunk_eq(serial_asn1, serial_numbers[_i].serial_asn1);
+
+       /* check ASN.1 integer encoding of the AC serialNumber */
+       offset = 13 + encoding.ptr[12] + 73;
+       pos = encoding.ptr + offset;
+       serial_asn1 = chunk_create(pos, 1 + *pos);
+       ck_assert_chunk_eq(serial_asn1, serial_numbers[_i].serial_asn1);
+
+       /* check ASN.1 integer encoding of serial number */
+       pos = encoding.ptr + offset + encoding.ptr[offset] + 158;
+       serial_asn1 = chunk_create(pos, 1 + *pos);
+       ck_assert_chunk_eq(serial_asn1, serial_numbers[_i].serial_asn1);
+
+       /* parse ASN.1 encoded attribute certificate */
+       acert1 = parse_acert(encoding);
+       ac = (ac_t*)acert1;
+
+       /* check serial number */
+       ck_assert_chunk_eq(ac->get_serial(ac), serial_numbers[_i].serial);
+
+       /* check holderSerial number */
+       ck_assert_chunk_eq(ac->get_holderSerial(ac), serial_numbers[_i].serial);
+       chunk_free(&encoding);
+
+       cert->destroy(cert);
+       crl->destroy(crl);
+       ocsp_req->destroy(ocsp_req);
+       acert->destroy(acert);
+       acert1->destroy(acert1);
+
+       /**
+        * Use serial number with two's complement encoding
+        */
+
+       serial = chunk_skip(serial_numbers[_i].serial_asn1, 1);
+
+       /* create certificate */
+       cert = create_cert(serial);
+
+       /* retrieve configured serial number */
+       x509 = (x509_t*)cert;
+       ck_assert_chunk_eq(x509->get_serial(x509), serial_numbers[_i].serial);
+
+       /* check ASN.1 integer encoding */
+       ck_assert(cert->get_encoding(cert, CERT_ASN1_DER, &encoding));
+       pos = encoding.ptr + 14;
+       serial_asn1 = chunk_create(pos, 1 + *pos);
+       ck_assert_chunk_eq(serial_asn1, serial_numbers[_i].serial_asn1);
+       chunk_free(&encoding);
+
+       /* create crl */
+       crl = create_crl(serial, cert);
+
+       /* retrieve configured serial number */
+       x509_crl = (crl_t*)crl;
+       ck_assert_chunk_eq(x509_crl->get_serial(x509_crl), serial_numbers[_i].serial);
+
+       enumerator = x509_crl->create_enumerator(x509_crl);
+       if (enumerator->enumerate(enumerator, &serial, NULL, NULL))
+       {
+               ck_assert_chunk_eq(serial, serial_numbers[_i].serial);
+       }
+       enumerator->destroy(enumerator);
+
+       /* check ASN.1 integer encoding of revoked number */
+       ck_assert(crl->get_encoding(crl, CERT_ASN1_DER, &encoding));
+       pos = encoding.ptr + 111;
+       serial_asn1 = chunk_create(pos, 1 + *pos);
+       ck_assert_chunk_eq(serial_asn1, serial_numbers[_i].serial_asn1);
+
+       /* check ASN.1 integer encoding of crlNumber */
+       offset = 110 + encoding.ptr[109] + 38;
+       pos = encoding.ptr + offset + 9;
+       serial_asn1 = chunk_create(pos, 1 + *pos);
+       ck_assert_chunk_eq(serial_asn1, serial_numbers[_i].serial_asn1);
+
+       /* check ASN.1 integer encoding of baseCrlNumber */
+       pos = encoding.ptr + offset + encoding.ptr[offset] + 14;
+       serial_asn1 = chunk_create(pos, 1 + *pos);
+       ck_assert_chunk_eq(serial_asn1, serial_numbers[_i].serial_asn1);
+       chunk_free(&encoding);
+
+       cert->destroy(cert);
+       crl->destroy(crl);
+}
+END_TEST
+
+Suite *serial_gen_suite_create()
+{
+       Suite *s;
+       TCase *tc;
+
+       s = suite_create("serial_gen");
+
+       tc = tcase_create("generate serial numbers");
+       tcase_add_loop_test(tc, test_gen_serial_numbers, 0, countof(serial_numbers));
+       suite_add_tcase(s, tc);
+
+       return s;
+}
diff --git a/src/libstrongswan/tests/suites/test_serial_parse.c b/src/libstrongswan/tests/suites/test_serial_parse.c
new file mode 100644 (file)
index 0000000..8150c96
--- /dev/null
@@ -0,0 +1,272 @@
+/*
+ * Copyright (C) 2022 Andreas Steffen, strongSec GmbH
+ *
+ * Copyright (C) secunet Security Networks AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#include "test_suite.h"
+
+#include <credentials/certificates/x509.h>
+#include <credentials/certificates/crl.h>
+
+static certificate_t* parse_cert(chunk_t encoding)
+{
+       certificate_t *cert;
+
+       cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
+                                               BUILD_BLOB_ASN1_DER, encoding,
+                                               BUILD_END);
+       ck_assert(cert);
+
+       return cert;
+}
+
+static certificate_t* parse_crl(chunk_t encoding)
+{
+       certificate_t *crl;
+
+       crl = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509_CRL,
+                                               BUILD_BLOB_ASN1_DER, encoding,
+                                               BUILD_END);
+       ck_assert(crl);
+
+       return crl;
+}
+
+typedef struct {
+       chunk_t serial;
+       chunk_t cert_encoding;
+       chunk_t crl_encoding;
+} serial_number_t;
+
+static serial_number_t serial_numbers[] = {
+       { chunk_from_chars(0x00),
+         chunk_from_chars(
+               0x30,0x82,0x01,0xD6,0x30,0x82,0x01,0x3F,0xA0,0x03,0x02,0x01,0x02,0x02,0x01,0x00,
+               0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,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,0x30,0x1E,0x17,0x0D,0x32,0x32,0x31,0x31,0x32,0x30,0x31,0x30,0x31,0x37,
+               0x34,0x34,0x5A,0x17,0x0D,0x32,0x33,0x31,0x31,0x32,0x30,0x31,0x30,0x31,0x37,0x34,
+               0x34,0x5A,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,0x30,0x81,0x9F,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,
+               0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8D,0x00,0x30,0x81,0x89,0x02,0x81,
+               0x81,0x00,0xB1,0x9B,0xD4,0x51,0x24,0xFC,0x56,0x1D,0x3D,0xFB,0xA2,0xEA,0x37,0x02,
+               0x70,0x72,0x87,0x84,0x2F,0x3B,0x2D,0x6E,0x22,0xEF,0x3F,0x37,0x04,0xB2,0x6F,0xB7,
+               0xE7,0xD8,0x58,0x05,0xDE,0x34,0xBF,0x99,0xE6,0x40,0x7A,0x56,0xA7,0x73,0xF5,0x98,
+               0xCB,0xB0,0x37,0x90,0x5E,0xD1,0x3F,0xF4,0x73,0x50,0x7F,0x53,0x8E,0xF1,0x04,0x25,
+               0xB4,0x77,0x22,0x4E,0x8A,0x9D,0x27,0x8F,0x6F,0xAF,0x59,0xBD,0xB0,0x0F,0xF0,0xAA,
+               0x11,0x94,0x66,0x16,0x10,0x58,0xAD,0x77,0xA1,0xAC,0x58,0xB4,0xD0,0x0D,0xBC,0x11,
+               0xE0,0xC0,0xE9,0x29,0xDC,0x42,0x63,0x01,0x23,0x4F,0x28,0x41,0x6D,0x34,0x9E,0x0C,
+               0x4A,0xC8,0x62,0x83,0xB5,0x71,0x71,0x0B,0x51,0xC0,0x4C,0x37,0xD4,0x68,0x19,0x52,
+               0x9A,0x8B,0x02,0x03,0x01,0x00,0x01,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,
+               0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x81,0x81,0x00,0x0D,0x3E,0x13,0x3D,0x58,0x72,
+               0x90,0x21,0x06,0x29,0xBD,0xA5,0x06,0x87,0x67,0x80,0x2C,0xE0,0x61,0xF5,0x66,0x76,
+               0x63,0xAB,0x97,0xD5,0x45,0x9B,0x2B,0x3C,0x6B,0xA7,0xB0,0xB4,0x31,0x52,0xC6,0xD9,
+               0x72,0xFC,0xC5,0x37,0xE5,0xFF,0xD0,0x80,0x63,0x09,0xD2,0x1E,0xC1,0x77,0x92,0xCC,
+               0x07,0x08,0x5D,0xD0,0x30,0x67,0x9A,0x6B,0x82,0x19,0x89,0x0E,0x10,0xC7,0xA4,0xA7,
+               0x7C,0x96,0x76,0x8C,0x72,0xDB,0x73,0x13,0x49,0xE5,0x8B,0xAC,0x0B,0x1E,0xEB,0x31,
+               0x74,0xEB,0xE4,0xA0,0x5D,0x49,0x9A,0x76,0x3C,0xA5,0xEF,0x55,0xE2,0x32,0x25,0x1A,
+               0xE3,0x05,0x37,0xAC,0xFF,0x9F,0x94,0x92,0xE6,0x0E,0x53,0xC0,0xFC,0x52,0xB8,0xD0,
+               0xFA,0x66,0x0B,0xCE,0xCA,0x88,0x66,0x3B,0x83,0x48),
+         chunk_from_chars(
+               0x30,0x82,0x01,0x5D,0x30,0x81,0xC7,0x02,0x01,0x01,0x30,0x0D,0x06,0x09,0x2A,0x86,
+               0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,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,0x17,0x0D,0x32,0x32,
+               0x31,0x31,0x32,0x30,0x31,0x30,0x31,0x37,0x34,0x34,0x5A,0x17,0x0D,0x32,0x32,0x31,
+               0x32,0x32,0x30,0x31,0x30,0x31,0x37,0x34,0x34,0x5A,0x30,0x22,0x30,0x20,0x02,0x01,
+               0x00,0x17,0x0D,0x32,0x32,0x31,0x31,0x32,0x30,0x31,0x30,0x31,0x37,0x34,0x34,0x5A,
+               0x30,0x0C,0x30,0x0A,0x06,0x03,0x55,0x1D,0x15,0x04,0x03,0x0A,0x01,0x01,0xA0,0x3E,
+               0x30,0x3C,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0xE2,
+               0x6D,0x1E,0xDF,0x83,0x8E,0xA2,0x1F,0xC3,0x00,0xDD,0x44,0x6F,0x8A,0x4D,0x70,0x0C,
+               0x02,0xE3,0x1F,0x30,0x0A,0x06,0x03,0x55,0x1D,0x14,0x04,0x03,0x02,0x01,0x00,0x30,
+               0x0D,0x06,0x03,0x55,0x1D,0x1B,0x01,0x01,0xFF,0x04,0x03,0x02,0x01,0x00,0x30,0x0D,
+               0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x81,0x81,
+               0x00,0x35,0x72,0x26,0x38,0x87,0x21,0xA2,0x5C,0xED,0x5C,0x04,0xD9,0x49,0xC0,0xB6,
+               0x75,0x7C,0x5A,0xEA,0x46,0x6E,0x1E,0xED,0x3C,0x9B,0x41,0x31,0x37,0x3F,0xAA,0xE7,
+               0x16,0x39,0x17,0x48,0x5F,0x84,0x48,0x6F,0xA4,0xF6,0x9D,0x79,0xDE,0xC3,0xE9,0x82,
+               0x87,0xEE,0xD4,0xD0,0x2F,0xBF,0x8B,0x74,0x1E,0xA7,0x21,0x63,0xB6,0x5A,0x39,0xFF,
+               0xDE,0xD0,0x6E,0xE3,0xB5,0x3B,0x0C,0x42,0x46,0x97,0x43,0x2E,0x6B,0x4D,0xF8,0x54,
+               0x59,0x8F,0xD8,0x72,0xB3,0xB0,0x29,0xCB,0x56,0xA7,0x8A,0x01,0xD6,0xEA,0xE0,0x69,
+               0xF7,0x36,0xC4,0x06,0xE6,0x05,0xC0,0x10,0xD2,0xB7,0x43,0x46,0xCC,0x8A,0x53,0xA1,
+               0xA6,0xD3,0x88,0x73,0x53,0x29,0x10,0xC2,0xC6,0xCE,0x24,0xC3,0xCE,0x14,0xED,0xB0,
+               0x64)
+       },
+       { chunk_from_chars(0x7f),
+         chunk_from_chars(
+               0x30,0x82,0x01,0xD6,0x30,0x82,0x01,0x3F,0xA0,0x03,0x02,0x01,0x02,0x02,0x01,0x7F,
+               0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,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,0x30,0x1E,0x17,0x0D,0x32,0x32,0x31,0x31,0x31,0x38,0x31,0x33,0x30,0x37,
+               0x32,0x31,0x5A,0x17,0x0D,0x32,0x33,0x31,0x31,0x31,0x38,0x31,0x33,0x30,0x37,0x32,
+               0x31,0x5A,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,0x30,0x81,0x9F,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,
+               0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8D,0x00,0x30,0x81,0x89,0x02,0x81,
+               0x81,0x00,0xB1,0x9B,0xD4,0x51,0x24,0xFC,0x56,0x1D,0x3D,0xFB,0xA2,0xEA,0x37,0x02,
+               0x70,0x72,0x87,0x84,0x2F,0x3B,0x2D,0x6E,0x22,0xEF,0x3F,0x37,0x04,0xB2,0x6F,0xB7,
+               0xE7,0xD8,0x58,0x05,0xDE,0x34,0xBF,0x99,0xE6,0x40,0x7A,0x56,0xA7,0x73,0xF5,0x98,
+               0xCB,0xB0,0x37,0x90,0x5E,0xD1,0x3F,0xF4,0x73,0x50,0x7F,0x53,0x8E,0xF1,0x04,0x25,
+               0xB4,0x77,0x22,0x4E,0x8A,0x9D,0x27,0x8F,0x6F,0xAF,0x59,0xBD,0xB0,0x0F,0xF0,0xAA,
+               0x11,0x94,0x66,0x16,0x10,0x58,0xAD,0x77,0xA1,0xAC,0x58,0xB4,0xD0,0x0D,0xBC,0x11,
+               0xE0,0xC0,0xE9,0x29,0xDC,0x42,0x63,0x01,0x23,0x4F,0x28,0x41,0x6D,0x34,0x9E,0x0C,
+               0x4A,0xC8,0x62,0x83,0xB5,0x71,0x71,0x0B,0x51,0xC0,0x4C,0x37,0xD4,0x68,0x19,0x52,
+               0x9A,0x8B,0x02,0x03,0x01,0x00,0x01,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,
+               0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x81,0x81,0x00,0xA4,0x92,0x32,0x35,0xD2,0xC7,
+               0x67,0x12,0x1E,0x5E,0x7C,0x0C,0x08,0x92,0x95,0xEE,0xD4,0x43,0x59,0xEF,0x0C,0x0A,
+               0x73,0x2C,0xB4,0x6C,0xB6,0x4A,0x98,0x85,0xD5,0xA2,0x96,0x6B,0x90,0xBA,0xB7,0xC2,
+               0x67,0x5F,0x0D,0xCD,0x9E,0xB3,0x5B,0xDE,0xA0,0xF4,0x5C,0x49,0x80,0x66,0x7B,0x33,
+               0x08,0x7F,0xCB,0x65,0xE6,0xCB,0x4F,0x50,0x59,0x16,0x23,0xEA,0xB6,0x70,0xFD,0x98,
+               0xD3,0x65,0x2A,0x94,0x65,0x2E,0x77,0x93,0x48,0x99,0x12,0xC3,0x95,0xDE,0x56,0xA8,
+               0xFE,0x33,0x1E,0x36,0x62,0x29,0x0A,0x5A,0x07,0xF9,0x19,0xF6,0x04,0x86,0xB5,0x43,
+               0x2C,0x49,0x4B,0xC2,0x98,0x3F,0x96,0x95,0x61,0x96,0xF8,0x22,0x4C,0xFB,0x45,0x41,
+               0x27,0x06,0x0E,0x44,0x36,0x19,0x7F,0x51,0x96,0x20),
+         chunk_from_chars(
+               0x30,0x82,0x01,0x5D,0x30,0x81,0xC7,0x02,0x01,0x01,0x30,0x0D,0x06,0x09,0x2A,0x86,
+               0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,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,0x17,0x0D,0x32,0x32,
+               0x31,0x31,0x32,0x30,0x31,0x30,0x31,0x37,0x34,0x34,0x5A,0x17,0x0D,0x32,0x32,0x31,
+               0x32,0x32,0x30,0x31,0x30,0x31,0x37,0x34,0x34,0x5A,0x30,0x22,0x30,0x20,0x02,0x01,
+               0x7F,0x17,0x0D,0x32,0x32,0x31,0x31,0x32,0x30,0x31,0x30,0x31,0x37,0x34,0x34,0x5A,
+               0x30,0x0C,0x30,0x0A,0x06,0x03,0x55,0x1D,0x15,0x04,0x03,0x0A,0x01,0x01,0xA0,0x3E,
+               0x30,0x3C,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0xE2,
+               0x6D,0x1E,0xDF,0x83,0x8E,0xA2,0x1F,0xC3,0x00,0xDD,0x44,0x6F,0x8A,0x4D,0x70,0x0C,
+               0x02,0xE3,0x1F,0x30,0x0A,0x06,0x03,0x55,0x1D,0x14,0x04,0x03,0x02,0x01,0x7F,0x30,
+               0x0D,0x06,0x03,0x55,0x1D,0x1B,0x01,0x01,0xFF,0x04,0x03,0x02,0x01,0x7F,0x30,0x0D,
+               0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x81,0x81,
+               0x00,0x00,0x93,0xAD,0x02,0x09,0x74,0x97,0x3C,0xBE,0x82,0x3D,0x39,0xCC,0xD0,0x55,
+               0x8F,0xBA,0xE4,0xB5,0x53,0x83,0xF0,0x11,0x29,0xE8,0x2B,0x77,0x8D,0xC5,0xA2,0x0F,
+               0x86,0x31,0x87,0x4D,0xAA,0x4B,0x78,0x44,0xFB,0x42,0xDB,0x81,0xC7,0xF0,0xA6,0x65,
+               0x68,0x36,0xC9,0x2D,0x37,0xA7,0x1C,0x23,0xD3,0xA4,0x75,0x85,0x0B,0x09,0xF1,0x1E,
+               0x24,0x19,0xB7,0xEE,0x5A,0x89,0x1C,0xF9,0x98,0xE7,0x6F,0xB8,0xF2,0x9A,0xB2,0x5E,
+               0xC5,0x47,0xE3,0x6D,0x50,0x9D,0x13,0x61,0x85,0x71,0x0A,0xF2,0xF3,0xBC,0x03,0xE6,
+               0xB8,0x1F,0x32,0x92,0x4C,0x95,0x31,0xF0,0xF4,0x85,0x41,0x97,0x1F,0x43,0xC7,0x51,
+               0xD9,0x90,0xBE,0xA6,0xE5,0x06,0x92,0xEF,0xF6,0x81,0xC7,0xD4,0xB3,0xF7,0x1B,0xA3,
+               0x1C),
+       },
+       { chunk_from_chars(0x80),
+         chunk_from_chars(
+               0x30,0x82,0x01,0xD7,0x30,0x82,0x01,0x40,0xA0,0x03,0x02,0x01,0x02,0x02,0x02,0x00,
+               0x80,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,
+               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,0x30,0x1E,0x17,0x0D,0x32,0x32,0x31,0x31,0x31,0x38,0x31,0x33,0x30,
+               0x37,0x32,0x31,0x5A,0x17,0x0D,0x32,0x33,0x31,0x31,0x31,0x38,0x31,0x33,0x30,0x37,
+               0x32,0x31,0x5A,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,0x30,0x81,0x9F,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,
+               0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8D,0x00,0x30,0x81,0x89,0x02,
+               0x81,0x81,0x00,0xB1,0x9B,0xD4,0x51,0x24,0xFC,0x56,0x1D,0x3D,0xFB,0xA2,0xEA,0x37,
+               0x02,0x70,0x72,0x87,0x84,0x2F,0x3B,0x2D,0x6E,0x22,0xEF,0x3F,0x37,0x04,0xB2,0x6F,
+               0xB7,0xE7,0xD8,0x58,0x05,0xDE,0x34,0xBF,0x99,0xE6,0x40,0x7A,0x56,0xA7,0x73,0xF5,
+               0x98,0xCB,0xB0,0x37,0x90,0x5E,0xD1,0x3F,0xF4,0x73,0x50,0x7F,0x53,0x8E,0xF1,0x04,
+               0x25,0xB4,0x77,0x22,0x4E,0x8A,0x9D,0x27,0x8F,0x6F,0xAF,0x59,0xBD,0xB0,0x0F,0xF0,
+               0xAA,0x11,0x94,0x66,0x16,0x10,0x58,0xAD,0x77,0xA1,0xAC,0x58,0xB4,0xD0,0x0D,0xBC,
+               0x11,0xE0,0xC0,0xE9,0x29,0xDC,0x42,0x63,0x01,0x23,0x4F,0x28,0x41,0x6D,0x34,0x9E,
+               0x0C,0x4A,0xC8,0x62,0x83,0xB5,0x71,0x71,0x0B,0x51,0xC0,0x4C,0x37,0xD4,0x68,0x19,
+               0x52,0x9A,0x8B,0x02,0x03,0x01,0x00,0x01,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,
+               0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x81,0x81,0x00,0x54,0xC6,0x85,0x31,0x85,
+               0x17,0x86,0xCB,0xFF,0x63,0x09,0x2A,0x90,0xDD,0x2C,0xC8,0x7E,0xD7,0x8B,0xE0,0x37,
+               0xF7,0x2D,0xE2,0xCF,0x7E,0x57,0x26,0x4C,0x1D,0x3D,0x57,0xF0,0x6D,0x0D,0x18,0xA3,
+               0xAB,0x49,0xD3,0x4E,0x08,0x70,0x4D,0xAE,0x05,0xF7,0xC5,0x47,0x99,0x89,0xFA,0xCA,
+               0x15,0x36,0x3F,0xDA,0xA7,0x64,0xEE,0xE6,0x1C,0x6E,0x6E,0x9D,0x39,0x61,0xCB,0x5E,
+               0x8F,0xAD,0x5C,0x90,0xD6,0xAE,0xCD,0xE9,0xBB,0x62,0xB9,0xCB,0x0E,0x51,0xDD,0x27,
+               0xAF,0xF3,0xE2,0xD0,0xAC,0x9E,0x99,0x55,0xB5,0x2F,0x46,0x99,0xDB,0x2F,0xEC,0x23,
+               0x76,0x0E,0x82,0xE3,0xA7,0xC3,0xF6,0xA2,0x61,0x32,0xC7,0x1F,0xD6,0x22,0x9B,0xFA,
+               0xD8,0xFD,0x8F,0xB2,0xB7,0x6B,0x71,0xF0,0x92,0x1F,0x44),
+         chunk_from_chars(
+               0x30,0x82,0x01,0x60,0x30,0x81,0xCA,0x02,0x01,0x01,0x30,0x0D,0x06,0x09,0x2A,0x86,
+               0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,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,0x17,0x0D,0x32,0x32,
+               0x31,0x31,0x32,0x30,0x31,0x30,0x31,0x37,0x34,0x34,0x5A,0x17,0x0D,0x32,0x32,0x31,
+               0x32,0x32,0x30,0x31,0x30,0x31,0x37,0x34,0x34,0x5A,0x30,0x23,0x30,0x21,0x02,0x02,
+               0x00,0x80,0x17,0x0D,0x32,0x32,0x31,0x31,0x32,0x30,0x31,0x30,0x31,0x37,0x34,0x34,
+               0x5A,0x30,0x0C,0x30,0x0A,0x06,0x03,0x55,0x1D,0x15,0x04,0x03,0x0A,0x01,0x01,0xA0,
+               0x40,0x30,0x3E,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,
+               0xE2,0x6D,0x1E,0xDF,0x83,0x8E,0xA2,0x1F,0xC3,0x00,0xDD,0x44,0x6F,0x8A,0x4D,0x70,
+               0x0C,0x02,0xE3,0x1F,0x30,0x0B,0x06,0x03,0x55,0x1D,0x14,0x04,0x04,0x02,0x02,0x00,
+               0x80,0x30,0x0E,0x06,0x03,0x55,0x1D,0x1B,0x01,0x01,0xFF,0x04,0x04,0x02,0x02,0x00,
+               0x80,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,
+               0x03,0x81,0x81,0x00,0x7D,0x98,0x63,0x80,0x7B,0x43,0xE6,0x56,0xCD,0x59,0x0E,0xEC,
+               0xD7,0x45,0x93,0xE5,0xD1,0x97,0x3E,0x47,0x87,0xFD,0x6F,0x8D,0x10,0xB0,0xDA,0x7C,
+               0x5D,0xDC,0x0B,0x1B,0xC8,0x63,0x5D,0x8D,0x02,0xDE,0xD0,0xC7,0xBB,0xE4,0x50,0xEA,
+               0xA7,0x2E,0x06,0xBC,0xF2,0x36,0x8D,0x7A,0xA2,0xE5,0x67,0x0F,0x03,0x9A,0x75,0x1D,
+               0x18,0x0E,0x57,0x39,0x86,0xF3,0xEF,0x29,0xED,0xDE,0x24,0x50,0x9E,0x1F,0xC7,0x90,
+               0x51,0x95,0xA0,0xD5,0x11,0x5E,0x96,0x0A,0xA5,0x4A,0x4D,0xFE,0x97,0xE4,0x1A,0xEA,
+               0xC3,0x56,0x2A,0x21,0xA6,0x6E,0xE5,0xBA,0xAC,0x70,0xA5,0xE5,0x90,0x9A,0x3C,0x36,
+               0xFF,0xD6,0x8B,0xC2,0x09,0x19,0xF4,0x21,0x68,0x50,0xEC,0x83,0xF8,0xF6,0xB5,0x24,
+               0x8F,0x2B,0x77,0xB2)
+       }
+};
+
+START_TEST(test_parse_serial_numbers)
+{
+       enumerator_t *enumerator;
+       certificate_t *cert, *crl;
+       crl_t *x509_crl;
+       x509_t *x509;
+       chunk_t serial;
+
+       /* parse ASN.1 DER encoded certificate */
+       cert = parse_cert(serial_numbers[_i].cert_encoding);
+
+       /* check parsed serial number */
+       x509 = (x509_t*)cert;
+       ck_assert_chunk_eq(x509->get_serial(x509), serial_numbers[_i].serial);
+       cert->destroy(cert);
+
+       /* parse ASN.1 DER encoded crl */
+       crl = parse_crl(serial_numbers[_i].crl_encoding);
+
+       /* check parsed serial number */
+       x509_crl = (crl_t*)crl;
+       ck_assert_chunk_eq(x509_crl->get_serial(x509_crl), serial_numbers[_i].serial);
+
+       enumerator = x509_crl->create_enumerator(x509_crl);
+       if (enumerator->enumerate(enumerator, &serial, NULL, NULL))
+       {
+               ck_assert_chunk_eq(serial, serial_numbers[_i].serial);
+       }
+       enumerator->destroy(enumerator);
+
+       crl->destroy(crl);
+}
+END_TEST
+
+Suite *serial_parse_suite_create()
+{
+       Suite *s;
+       TCase *tc;
+
+       s = suite_create("serial_parse");
+
+       tc = tcase_create("parse serial numbers");
+       tcase_add_loop_test(tc, test_parse_serial_numbers, 0, countof(serial_numbers));
+       suite_add_tcase(s, tc);
+
+       return s;
+}
index 894830fe42705e2032301d1559780e65ad0c0829..1ad5d05e4bcb7f20d78305b16322e9ac4c5bd46b 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2013 Tobias Brunner
+ * Copyright (C) 2022 Andreas Steffen
  *
  * Copyright (C) secunet Security Networks AG
  *
@@ -42,6 +43,8 @@ TEST_SUITE_DEPEND(rsa_oaep_sha384_suite_create, PRIVKEY_DECRYPT, ENCRYPT_RSA_OAE
 TEST_SUITE_DEPEND(rsa_oaep_sha512_suite_create, PRIVKEY_DECRYPT, ENCRYPT_RSA_OAEP_SHA512)
 TEST_SUITE_DEPEND(certpolicy_suite_create, CERT_ENCODE, CERT_X509)
 TEST_SUITE_DEPEND(certnames_suite_create, CERT_ENCODE, CERT_X509)
+TEST_SUITE_DEPEND(serial_gen_suite_create, CERT_ENCODE, CERT_X509)
+TEST_SUITE(serial_parse_suite_create)
 TEST_SUITE(host_suite_create)
 TEST_SUITE(printf_suite_create)
 TEST_SUITE(auth_cfg_suite_create)