diff --git a/certs/crl.pem b/certs/crl.pem new file mode 100644 index 00000000..b1b5f1ba --- /dev/null +++ b/certs/crl.pem @@ -0,0 +1,42 @@ +Certificate Revocation List (CRL): + Version 2 (0x1) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, ST=Montana, L=Bozeman, O=Sawtooth, OU=Consulting, CN=www.wolfssl.com, emailAddress=facts@wolfssl.com + Last Update: Jun 11 21:44:40 2026 GMT + Next Update: Mar 7 21:44:40 2029 GMT + CRL extensions: + X509v3 CRL Number: + 2 +Revoked Certificates: + Serial Number: 02 + Revocation Date: Jun 11 21:44:40 2026 GMT + Signature Algorithm: sha256WithRSAEncryption + Signature Value: + 53:dc:68:3d:93:47:65:03:ca:a5:07:e8:13:26:72:94:02:3e: + 6f:c2:8d:27:fc:f6:64:c6:06:77:bc:1f:26:e4:6e:87:95:f8: + fe:18:ee:d7:24:f9:b8:ad:74:85:76:ec:55:92:6c:58:4f:59: + 66:68:f1:17:78:dc:39:6c:4c:2b:38:1e:d4:07:ac:b8:2c:f5: + d4:2b:c1:96:09:79:8a:a2:e2:d1:e5:1e:32:92:1f:12:81:a6: + ad:4d:ce:9d:9a:08:6f:56:e4:fe:58:8d:da:b2:88:54:6a:5a: + 19:07:9c:1b:de:4f:7a:62:dd:35:75:25:29:a2:9a:ba:19:a9: + 32:fe:61:ad:bb:70:06:0f:37:62:7c:02:61:3e:43:22:e9:62: + 12:f2:f7:0b:18:3a:a2:fb:0a:e9:2d:0b:68:fc:e1:41:51:64: + 7c:c8:8c:4c:d6:fc:90:0b:24:e7:e3:52:a5:e9:09:f8:85:e9: + 73:ca:b2:00:19:05:d6:5f:99:af:bb:9a:41:0f:48:a7:b4:25: + 78:d0:b6:ce:3b:3c:c2:2d:fa:65:2e:65:5e:67:01:01:aa:f7: + 4d:ad:5a:8f:b4:30:d4:9c:0c:e9:b6:c5:b6:4a:b6:eb:3a:01: + d1:92:b4:94:e8:62:e3:d3:37:ff:aa:38:8d:9f:e3:de:9c:b1: + 70:c5:11:64 +-----BEGIN X509 CRL----- +MIICBTCB7gIBATANBgkqhkiG9w0BAQsFADCBlTELMAkGA1UEBhMCVVMxEDAOBgNV +BAgMB01vbnRhbmExEDAOBgNVBAcMB0JvemVtYW4xETAPBgNVBAoMCFNhd3Rvb3Ro +MRMwEQYDVQQLDApDb25zdWx0aW5nMRgwFgYDVQQDDA93d3cud29sZnNzbC5jb20x +IDAeBgkqhkiG9w0BCQEWEWZhY3RzQHdvbGZzc2wuY29tFw0yNjA2MTEyMTQ0NDBa +Fw0yOTAzMDcyMTQ0NDBaMBQwEgIBAhcNMjYwNjExMjE0NDQwWqAOMAwwCgYDVR0U +BAMCAQIwDQYJKoZIhvcNAQELBQADggEBAFPcaD2TR2UDyqUH6BMmcpQCPm/CjSf8 +9mTGBne8HybkboeV+P4Y7tck+bitdIV27FWSbFhPWWZo8Rd43DlsTCs4HtQHrLgs +9dQrwZYJeYqi4tHlHjKSHxKBpq1Nzp2aCG9W5P5YjdqyiFRqWhkHnBveT3pi3TV1 +JSmimroZqTL+Ya27cAYPN2J8AmE+QyLpYhLy9wsYOqL7CuktC2j84UFRZHzIjEzW +/JALJOfjUqXpCfiF6XPKsgAZBdZfma+7mkEPSKe0JXjQts47PMIt+mUuZV5nAQGq +902tWo+0MNScDOm2xbZKtus6AdGStJToYuPTN/+qOI2f496csXDFEWQ= +-----END X509 CRL----- diff --git a/certs/include.am b/certs/include.am index 3c30b33c..04e6ba17 100644 --- a/certs/include.am +++ b/certs/include.am @@ -2,6 +2,8 @@ # for test_rsa.c dist_noinst_SCRIPTS += certs/server-key.pem dist_noinst_SCRIPTS += certs/server-cert.pem +dist_noinst_SCRIPTS += certs/ca-cert.pem +dist_noinst_SCRIPTS += certs/crl.pem # for test_ecc.c dist_noinst_SCRIPTS += certs/server-ecc.pem diff --git a/include/wolfprovider/alg_funcs.h b/include/wolfprovider/alg_funcs.h index 1711a2a7..3bf18d19 100644 --- a/include/wolfprovider/alg_funcs.h +++ b/include/wolfprovider/alg_funcs.h @@ -221,6 +221,9 @@ typedef void (*DFUNC)(void); /* Decoder names. */ #define WP_NAMES_DER "DER" +/* Private name: only the file store fetches these, so no other decoder chain + * picks them up. */ +#define WP_NAMES_DER2OBJ "wolfprov-der2obj" /* Store names. */ #define WP_NAMES_FILE "file" @@ -547,6 +550,8 @@ extern const OSSL_DISPATCH wp_mldsa87_spki_decoder_functions[]; extern const OSSL_DISPATCH wp_mldsa87_pki_decoder_functions[]; extern const OSSL_DISPATCH wp_pem_to_der_decoder_functions[]; extern const OSSL_DISPATCH wp_epki_to_pki_decoder_functions[]; +extern const OSSL_DISPATCH wp_der_to_cert_decoder_functions[]; +extern const OSSL_DISPATCH wp_der_to_crl_decoder_functions[]; /* Encode implementations. */ extern const OSSL_DISPATCH wp_rsa_spki_der_encoder_functions[]; extern const OSSL_DISPATCH wp_rsa_spki_pem_encoder_functions[]; diff --git a/src/wp_file_store.c b/src/wp_file_store.c index 32b825ad..e1303580 100644 --- a/src/wp_file_store.c +++ b/src/wp_file_store.c @@ -307,6 +307,210 @@ static int wp_file_decoder_set_input_structure(OSSL_DECODER_CTX* decCtx, return ok; } +/** + * DER certificate/CRL to object decoder context. + */ +typedef struct wp_Der2Obj { + /** Provider context - used to read the core BIO. */ + WOLFPROV_CTX* provCtx; +} wp_Der2Obj; + +/** + * Create a new DER to object decoder context. + * + * @param [in] provCtx Provider context. + * @return Pointer to context. + */ +static wp_Der2Obj* wp_der2obj_newctx(WOLFPROV_CTX* provCtx) +{ + wp_Der2Obj* ctx = NULL; + + if (wolfssl_prov_is_running()) { + ctx = (wp_Der2Obj*)OPENSSL_zalloc(sizeof(*ctx)); + } + if (ctx != NULL) { + ctx->provCtx = provCtx; + } + + return ctx; +} + +/** + * Dispose of DER to object decoder context. + * + * @param [in] ctx DER to object decoder context. + */ +static void wp_der2obj_freectx(wp_Der2Obj* ctx) +{ + OPENSSL_free(ctx); +} + +/** + * Read exactly len bytes from the BIO. + * + * @param [in] bio BIO to read from. + * @param [out] buf Buffer to read into. + * @param [in] len Number of bytes to read. At most INT_MAX. + * @return 1 when all bytes were read. + * @return 0 otherwise. + */ +static int wp_der2obj_read(BIO* bio, unsigned char* buf, word32 len) +{ + int readLen = 1; + + while ((len > 0) && (readLen > 0)) { + readLen = BIO_read(bio, buf, (int)len); + if (readLen > 0) { + buf += readLen; + len -= (word32)readLen; + } + } + + return len == 0; +} + +/** + * Read the header of the DER SEQUENCE at the BIO's position. + * + * @param [in] bio BIO to read from. + * @param [out] hdr Buffer of at least 6 bytes to hold the header. + * @param [out] hdrLen Length of the header in bytes. + * @param [out] objLen Length of the SEQUENCE including its header. + * @return 1 when a DER SEQUENCE header was read. + * @return 0 otherwise. + */ +static int wp_der2obj_read_hdr(BIO* bio, unsigned char* hdr, word32* hdrLen, + word32* objLen) +{ + int ok; + word32 n = 0; + word32 contentLen = 0; + word32 i; + + ok = wp_der2obj_read(bio, hdr, 2) && (hdr[0] == 0x30); + if (ok && (hdr[1] < 0x80)) { + contentLen = hdr[1]; + } + else if (ok) { + n = hdr[1] & 0x7f; + ok = (n >= 1) && (n <= 4) && wp_der2obj_read(bio, hdr + 2, n); + for (i = 0; ok && (i < n); i++) { + contentLen = (contentLen << 8) | hdr[2 + i]; + } + } + /* Keep the whole object within BIO_read's int length. */ + if (ok && (contentLen > (word32)INT_MAX - 2 - n)) { + ok = 0; + } + if (ok) { + *hdrLen = 2 + n; + *objLen = 2 + n + contentLen; + } + + return ok; +} + +/** + * Pass DER data up as a certificate or CRL object, unparsed. + * + * The file store needs this for DER input, as OpenSSL's file store does + * (file_store_any2obj.c): the PEM to DER decoder does the same for PEM input. + * No cryptographic operation is performed. + * + * @param [in] ctx DER to object decoder context. + * @param [in, out] coreBio BIO wrapped for the core. + * @param [in] obj Object type: OSSL_OBJECT_CERT or OSSL_OBJECT_CRL. + * @param [in] dataCb Callback to pass the object to. + * @param [in] dataCbArg Argument to pass to callback. + * @return 1 on success or when the data is not a DER SEQUENCE. + * @return 0 on failure. + */ +static int wp_der2obj_decode(wp_Der2Obj* ctx, OSSL_CORE_BIO* coreBio, int obj, + OSSL_CALLBACK* dataCb, void* dataCbArg) +{ + int ok = 1; + BIO* bio; + unsigned char hdr[6]; + word32 hdrLen = 0; + word32 objLen = 0; + unsigned char* data = NULL; + OSSL_PARAM params[3]; + + WOLFPROV_ENTER(WP_LOG_COMP_PROVIDER, "wp_der2obj_decode"); + + bio = wp_corebio_get_bio(ctx->provCtx, coreBio); + if (bio == NULL) { + ok = 0; + } + /* Read one object only so the next load starts at the next object. + * Not a complete DER SEQUENCE: not for this decoder, let others try. */ + else if (wp_der2obj_read_hdr(bio, hdr, &hdrLen, &objLen)) { + data = (unsigned char*)OPENSSL_malloc(objLen); + if (data == NULL) { + ok = 0; + } + else { + XMEMCPY(data, hdr, hdrLen); + } + if (ok && wp_der2obj_read(bio, data + hdrLen, objLen - hdrLen)) { + params[0] = OSSL_PARAM_construct_octet_string( + OSSL_OBJECT_PARAM_DATA, data, objLen); + params[1] = OSSL_PARAM_construct_int(OSSL_OBJECT_PARAM_TYPE, &obj); + params[2] = OSSL_PARAM_construct_end(); + ok = dataCb(params, dataCbArg); + } + } + OPENSSL_free(data); + BIO_free(bio); + + WOLFPROV_LEAVE(WP_LOG_COMP_PROVIDER, __FILE__ ":" WOLFPROV_STRINGIZE(__LINE__), ok); + return ok; +} + +/** + * Decode DER certificate: pass it up as a certificate object. + */ +static int wp_der2cert_decode(wp_Der2Obj* ctx, OSSL_CORE_BIO* coreBio, + int selection, OSSL_CALLBACK* dataCb, void* dataCbArg, + OSSL_PASSPHRASE_CALLBACK* pwCb, void* pwCbArg) +{ + (void)selection; + (void)pwCb; + (void)pwCbArg; + return wp_der2obj_decode(ctx, coreBio, OSSL_OBJECT_CERT, dataCb, + dataCbArg); +} + +/** + * Decode DER CRL: pass it up as a CRL object. + */ +static int wp_der2crl_decode(wp_Der2Obj* ctx, OSSL_CORE_BIO* coreBio, + int selection, OSSL_CALLBACK* dataCb, void* dataCbArg, + OSSL_PASSPHRASE_CALLBACK* pwCb, void* pwCbArg) +{ + (void)selection; + (void)pwCb; + (void)pwCbArg; + return wp_der2obj_decode(ctx, coreBio, OSSL_OBJECT_CRL, dataCb, + dataCbArg); +} + +/** Dispatch table for DER certificate to object decoder. */ +const OSSL_DISPATCH wp_der_to_cert_decoder_functions[] = { + { OSSL_FUNC_DECODER_NEWCTX, (DFUNC)wp_der2obj_newctx }, + { OSSL_FUNC_DECODER_FREECTX, (DFUNC)wp_der2obj_freectx }, + { OSSL_FUNC_DECODER_DECODE, (DFUNC)wp_der2cert_decode }, + { 0, NULL } +}; + +/** Dispatch table for DER CRL to object decoder. */ +const OSSL_DISPATCH wp_der_to_crl_decoder_functions[] = { + { OSSL_FUNC_DECODER_NEWCTX, (DFUNC)wp_der2obj_newctx }, + { OSSL_FUNC_DECODER_FREECTX, (DFUNC)wp_der2obj_freectx }, + { OSSL_FUNC_DECODER_DECODE, (DFUNC)wp_der2crl_decode }, + { 0, NULL } +}; + /** * Information about supported decoders from file data. */ @@ -404,6 +608,41 @@ static int wp_file_decoder_prop_query(const char* base, const char* caller, return ok; } +/** + * Fetch a decoder and add it to the decoder context. + * + * @param [in] ctx File system context object. + * @param [in, out] decCtx OpenSSL decoder context. + * @param [in] name Decoder name. + * @param [in] propQuery Structure property query. May be NULL. + * @return 1 on success. + * @return 0 on failure. + */ +static int wp_file_add_decoder(wp_FileCtx* ctx, OSSL_DECODER_CTX* decCtx, + const char* name, const char* propQuery) +{ + int ok = 1; + OSSL_DECODER* decoder = NULL; + char* query = NULL; + + if (!wp_file_decoder_prop_query(propQuery, ctx->propQuery, &query)) { + ok = 0; + } + if (ok) { + decoder = OSSL_DECODER_fetch(ctx->provCtx->libCtx, name, query); + if (decoder == NULL) { + ok = 0; + } + } + if (ok && !OSSL_DECODER_CTX_add_decoder(decCtx, decoder)) { + ok = 0; + } + OSSL_DECODER_free(decoder); + OPENSSL_free(query); + + return ok; +} + /** * Set the decoders into the decoder context. * @@ -416,29 +655,22 @@ static int wp_file_set_decoder(wp_FileCtx* ctx, OSSL_DECODER_CTX* decCtx) { int ok = 1; size_t i; - OSSL_DECODER* decoder; - char* query = NULL; WOLFPROV_ENTER(WP_LOG_COMP_PROVIDER, "wp_file_set_decoder"); for (i = 0; ok && (i < WP_DECODERS_SIZE); i++) { - if (!wp_file_decoder_prop_query(wp_decoders[i].propQuery, - ctx->propQuery, &query)) { - ok = 0; - } - if (ok) { - decoder = OSSL_DECODER_fetch(ctx->provCtx->libCtx, - wp_decoders[i].name, query); - if (decoder == NULL) { - ok = 0; - } - if (ok && !OSSL_DECODER_CTX_add_decoder(decCtx, decoder)) { - ok = 0; - } - OSSL_DECODER_free(decoder); - } - OPENSSL_free(query); - query = NULL; + ok = wp_file_add_decoder(ctx, decCtx, wp_decoders[i].name, + wp_decoders[i].propQuery); + } + /* DER certificates and CRLs are passed up unparsed, as OpenSSL's file + * store does. Only added when one is expected: key loading is unchanged. */ + if (ok && (ctx->type == OSSL_STORE_INFO_CERT)) { + ok = wp_file_add_decoder(ctx, decCtx, WP_NAMES_DER2OBJ, + "structure=Certificate"); + } + else if (ok && (ctx->type == OSSL_STORE_INFO_CRL)) { + ok = wp_file_add_decoder(ctx, decCtx, WP_NAMES_DER2OBJ, + "structure=CertificateList"); } WOLFPROV_LEAVE(WP_LOG_COMP_PROVIDER, __FILE__ ":" WOLFPROV_STRINGIZE(__LINE__), ok); diff --git a/src/wp_wolfprov.c b/src/wp_wolfprov.c index 69446838..b648a13e 100644 --- a/src/wp_wolfprov.c +++ b/src/wp_wolfprov.c @@ -1660,6 +1660,14 @@ static const OSSL_ALGORITHM wolfprov_decoder[] = { wp_epki_to_pki_decoder_functions, "" }, + /* DER certificate and CRL pass-through for the file store. */ + { WP_NAMES_DER2OBJ, WP_DECODER_PROPERTIES(Certificate), + wp_der_to_cert_decoder_functions, + "" }, + { WP_NAMES_DER2OBJ, WP_DECODER_PROPERTIES(CertificateList), + wp_der_to_crl_decoder_functions, + "" }, + { NULL, NULL, NULL, NULL } }; diff --git a/test/test_rsa.c b/test/test_rsa.c index 8886afe6..16708021 100644 --- a/test/test_rsa.c +++ b/test/test_rsa.c @@ -2110,6 +2110,256 @@ int test_rsa_load_cert(void* data) return err; } +/** + * Load a DER certificate through the file store. The expected DER comes from + * OpenSSL's own PEM and ASN.1 code; the store must return the same bytes. + */ +int test_rsa_load_cert_der(void* data) +{ + int err; + BIO* pemBio = NULL; + BIO* derBio = NULL; + X509* oracle = NULL; + X509* cert = NULL; + unsigned char* oracleDer = NULL; + unsigned char* certDer = NULL; + int oracleLen = 0; + int certLen = 0; + OSSL_STORE_CTX* ctx = NULL; + OSSL_STORE_INFO* info = NULL; + + (void)data; + + PRINT_MSG("Convert certificate to DER with OpenSSL"); + pemBio = BIO_new_file(CERTS_DIR "/server-cert.pem", "r"); + err = pemBio == NULL; + if (err == 0) { + oracle = PEM_read_bio_X509(pemBio, NULL, NULL, NULL); + err = oracle == NULL; + } + if (err == 0) { + oracleLen = i2d_X509(oracle, &oracleDer); + err = oracleLen <= 0; + } + if (err == 0) { + derBio = BIO_new_mem_buf(oracleDer, oracleLen); + err = derBio == NULL; + } + if (err == 0) { + PRINT_MSG("Load DER certificate from the file store"); + ctx = OSSL_STORE_attach(derBio, "file", wpLibCtx, NULL, NULL, NULL, + NULL, NULL, NULL); + err = ctx == NULL; + } + if (err == 0) { + err = OSSL_STORE_expect(ctx, OSSL_STORE_INFO_CERT) != 1; + } + if (err == 0) { + info = OSSL_STORE_load(ctx); + err = info == NULL; + } + if (err == 0) { + cert = OSSL_STORE_INFO_get1_CERT(info); + err = cert == NULL; + } + if (err == 0) { + PRINT_MSG("Compare with OpenSSL's DER"); + certLen = i2d_X509(cert, &certDer); + err = (certLen != oracleLen) || + (memcmp(certDer, oracleDer, oracleLen) != 0); + } + + OPENSSL_free(certDer); + OPENSSL_free(oracleDer); + X509_free(cert); + X509_free(oracle); + OSSL_STORE_INFO_free(info); + OSSL_STORE_close(ctx); + BIO_free(derBio); + BIO_free(pemBio); + return err; +} + +/** + * Convert a PEM certificate file to DER with OpenSSL's PEM and ASN.1 code. + */ +static int test_rsa_cert_file_der(const char* file, unsigned char** der, + int* derLen) +{ + int err; + BIO* bio = NULL; + X509* x509 = NULL; + + bio = BIO_new_file(file, "r"); + err = bio == NULL; + if (err == 0) { + x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL); + err = x509 == NULL; + } + if (err == 0) { + *derLen = i2d_X509(x509, der); + err = *derLen <= 0; + } + + X509_free(x509); + BIO_free(bio); + return err; +} + +/** + * Load two concatenated DER certificates through the file store. Each load + * must return the next certificate in order, as OpenSSL's file store does. + */ +int test_rsa_load_cert_der_multi(void* data) +{ + int err = 0; + static const char* files[2] = { + CERTS_DIR "/server-cert.pem", + CERTS_DIR "/ca-cert.pem" + }; + unsigned char* oracleDer[2] = { NULL, NULL }; + int oracleLen[2] = { 0, 0 }; + unsigned char* allDer = NULL; + BIO* derBio = NULL; + X509* cert = NULL; + unsigned char* certDer = NULL; + int certLen = 0; + OSSL_STORE_CTX* ctx = NULL; + OSSL_STORE_INFO* info = NULL; + int i; + + (void)data; + + PRINT_MSG("Convert certificates to DER with OpenSSL"); + for (i = 0; (err == 0) && (i < 2); i++) { + err = test_rsa_cert_file_der(files[i], &oracleDer[i], &oracleLen[i]); + } + if (err == 0) { + allDer = (unsigned char*)OPENSSL_malloc(oracleLen[0] + oracleLen[1]); + err = allDer == NULL; + } + if (err == 0) { + memcpy(allDer, oracleDer[0], oracleLen[0]); + memcpy(allDer + oracleLen[0], oracleDer[1], oracleLen[1]); + derBio = BIO_new_mem_buf(allDer, oracleLen[0] + oracleLen[1]); + err = derBio == NULL; + } + if (err == 0) { + PRINT_MSG("Load concatenated DER certificates from the file store"); + ctx = OSSL_STORE_attach(derBio, "file", wpLibCtx, NULL, NULL, NULL, + NULL, NULL, NULL); + err = ctx == NULL; + } + if (err == 0) { + err = OSSL_STORE_expect(ctx, OSSL_STORE_INFO_CERT) != 1; + } + if (err == 0) { + PRINT_MSG("Compare each certificate with OpenSSL's DER, in order"); + } + for (i = 0; (err == 0) && (i < 2); i++) { + info = OSSL_STORE_load(ctx); + err = (info == NULL) || + (OSSL_STORE_INFO_get_type(info) != OSSL_STORE_INFO_CERT); + if (err == 0) { + cert = OSSL_STORE_INFO_get1_CERT(info); + err = cert == NULL; + } + if (err == 0) { + certLen = i2d_X509(cert, &certDer); + err = (certLen != oracleLen[i]) || + (memcmp(certDer, oracleDer[i], oracleLen[i]) != 0); + } + OPENSSL_free(certDer); + certDer = NULL; + X509_free(cert); + cert = NULL; + OSSL_STORE_INFO_free(info); + info = NULL; + } + if (err == 0) { + PRINT_MSG("Check that nothing follows the two certificates"); + err = OSSL_STORE_eof(ctx) != 1; + } + + OSSL_STORE_close(ctx); + BIO_free(derBio); + OPENSSL_free(allDer); + OPENSSL_free(oracleDer[1]); + OPENSSL_free(oracleDer[0]); + return err; +} + +/** + * Load a DER CRL through the file store. The expected DER comes from + * OpenSSL's own PEM and ASN.1 code; the store must return the same bytes. + */ +int test_rsa_load_crl_der(void* data) +{ + int err; + BIO* pemBio = NULL; + BIO* derBio = NULL; + X509_CRL* oracle = NULL; + X509_CRL* crl = NULL; + unsigned char* oracleDer = NULL; + unsigned char* crlDer = NULL; + int oracleLen = 0; + int crlLen = 0; + OSSL_STORE_CTX* ctx = NULL; + OSSL_STORE_INFO* info = NULL; + + (void)data; + + PRINT_MSG("Convert CRL to DER with OpenSSL"); + pemBio = BIO_new_file(CERTS_DIR "/crl.pem", "r"); + err = pemBio == NULL; + if (err == 0) { + oracle = PEM_read_bio_X509_CRL(pemBio, NULL, NULL, NULL); + err = oracle == NULL; + } + if (err == 0) { + oracleLen = i2d_X509_CRL(oracle, &oracleDer); + err = oracleLen <= 0; + } + if (err == 0) { + derBio = BIO_new_mem_buf(oracleDer, oracleLen); + err = derBio == NULL; + } + if (err == 0) { + PRINT_MSG("Load DER CRL from the file store"); + ctx = OSSL_STORE_attach(derBio, "file", wpLibCtx, NULL, NULL, NULL, + NULL, NULL, NULL); + err = ctx == NULL; + } + if (err == 0) { + err = OSSL_STORE_expect(ctx, OSSL_STORE_INFO_CRL) != 1; + } + if (err == 0) { + info = OSSL_STORE_load(ctx); + err = (info == NULL) || + (OSSL_STORE_INFO_get_type(info) != OSSL_STORE_INFO_CRL); + } + if (err == 0) { + crl = OSSL_STORE_INFO_get1_CRL(info); + err = crl == NULL; + } + if (err == 0) { + PRINT_MSG("Compare with OpenSSL's DER"); + crlLen = i2d_X509_CRL(crl, &crlDer); + err = (crlLen != oracleLen) || + (memcmp(crlDer, oracleDer, oracleLen) != 0); + } + + OPENSSL_free(crlDer); + OPENSSL_free(oracleDer); + X509_CRL_free(crl); + X509_CRL_free(oracle); + OSSL_STORE_INFO_free(info); + OSSL_STORE_close(ctx); + BIO_free(derBio); + BIO_free(pemBio); + return err; +} + /** * Load the RSA private key from the file store with a caller property query. * diff --git a/test/unit.c b/test/unit.c index be7f72a2..e4a184f7 100644 --- a/test/unit.c +++ b/test/unit.c @@ -417,6 +417,9 @@ TEST_CASE test_case[] = { TEST_DECL(test_rsa_pss_no_params, NULL), TEST_DECL(test_rsa_load_key, NULL), TEST_DECL(test_rsa_load_cert, NULL), + TEST_DECL(test_rsa_load_cert_der, NULL), + TEST_DECL(test_rsa_load_cert_der_multi, NULL), + TEST_DECL(test_rsa_load_crl_der, NULL), TEST_DECL(test_rsa_load_key_prop_query, NULL), TEST_DECL(test_rsa_fromdata, NULL), TEST_DECL(test_rsa_fromdata_oversize, NULL), diff --git a/test/unit.h b/test/unit.h index 35bc245b..84381bfa 100644 --- a/test/unit.h +++ b/test/unit.h @@ -404,6 +404,9 @@ int test_rsa_pss_no_params(void *data); int test_rsa_load_key(void* data); int test_rsa_load_cert(void* data); +int test_rsa_load_cert_der(void* data); +int test_rsa_load_cert_der_multi(void* data); +int test_rsa_load_crl_der(void* data); int test_rsa_load_key_prop_query(void* data); int test_rsa_fromdata(void* data); int test_rsa_fromdata_oversize(void* data);