Skip to content

Store in extensions the full octet string #8967

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

ribes96
Copy link
Contributor

@ribes96 ribes96 commented Jul 4, 2025

Store in WOLFSSL_X509_EXTENSION.value always the full contents of the OCTET STRING of the extension, instead of different type of data depending on the type of extension. Previously this was only done for unknown extensions.

Description

It is clear from Issue #8941 that X509_EXTENSION_get_data has a clear different behavior on OpenSSL than in WolfSSL. RFC8280 defines an extension as:

Extension  ::=  SEQUENCE  {
     extnID      OBJECT IDENTIFIER,
     critical    BOOLEAN DEFAULT FALSE,
     extnValue   OCTET STRING
                 -- contains the DER encoding of an ASN.1 value
                 -- corresponding to the extension type identified
                 -- by extnID
     }

Whereas OpenSSL always returns the full OCTET STRING when calling X509_EXTENSION_get_data, WolfSSL returns a different type of object depending on the type of extension parsed. This can be observed in the following program:

#include <stdio.h>
#include <err.h>

#ifdef USE_WOLFSSL

#define WOLFSSL_USE_OPTIONS_H

#include <wolfssl/ssl.h>
#include <wolfssl/openssl/pem.h>
#include <wolfssl/openssl/ssl.h>
#include <wolfssl/openssl/buffer.h>

#endif /* USE_WOLFSSL */

#ifdef USE_OPENSSL

#include <openssl/x509.h>
#include <openssl/pem.h>
#include <openssl/err.h>

#endif /* USE_OPENSSL */

int main (int argc, char **argv)
{
	const char     *filename;
	FILE           *f;
	X509           *x509;
	int            n_extensions;
	int            i;

	if (argc < 2)
		errx (-1, "Error: Usage: <filename>");

	filename = argv[1];

	if ((f = fopen (filename, "r")) == NULL)
		err (-1, "%s", filename);

	if ((x509 = PEM_read_X509 (f, NULL, NULL, NULL)) == NULL)
		err (-1, NULL);

	fclose (f);

	n_extensions = X509_get_ext_count (x509);
	for (i = 0; i < n_extensions; ++i)
	{
		X509_EXTENSION         *ext;
		ASN1_OBJECT            *object;
		char                   oid[32];
		int                    j;
		#ifdef USE_WOLFSSL
		ASN1_STRING            *data;
		#endif /* USE_WOLFSSL */

		#ifdef USE_OPENSSL
		ASN1_OCTET_STRING      *data;
		#endif /* USE_OPENSSL */

		if ((ext = X509_get_ext (x509, i)) == NULL)
			errx (-1, "Error: No extension at %d\n", i);

		if ((object = X509_EXTENSION_get_object (ext)) == NULL)
			errx (-1, "Error: No object for extension at %d\n", i);

		OBJ_obj2txt (oid, sizeof (oid), object, 1);

		if ((data = X509_EXTENSION_get_data (ext)) == NULL)
			errx (-1, "Error: No data for extension at %d\n", i);

		printf ("i=%d\n", i);
		printf ("oid=%s\n", oid);
		printf ("data->length=%d\n", data->length);
		printf ("data->data={");
		for (j = 0; j < data->length; ++j)
			printf ("%02X:", (unsigned char) data->data[j]);
		printf ("}\n");
		printf ("\n");
	}


	X509_free (x509);
	return 0;
}

For example with this extension

-----BEGIN CERTIFICATE-----
MIIFYjCCBEqgAwIBAgIQd70NbNs2+RrqIQ/E8FjTDTANBgkqhkiG9w0BAQsFADBX
MQswCQYDVQQGEwJCRTEZMBcGA1UEChMQR2xvYmFsU2lnbiBudi1zYTEQMA4GA1UE
CxMHUm9vdCBDQTEbMBkGA1UEAxMSR2xvYmFsU2lnbiBSb290IENBMB4XDTIwMDYx
OTAwMDA0MloXDTI4MDEyODAwMDA0MlowRzELMAkGA1UEBhMCVVMxIjAgBgNVBAoT
GUdvb2dsZSBUcnVzdCBTZXJ2aWNlcyBMTEMxFDASBgNVBAMTC0dUUyBSb290IFIx
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAthECix7joXebO9y/lD63
ladAPKH9gvl9MgaCcfb2jH/76Nu8ai6Xl6OMS/kr9rH5zoQdsfnFl97vufKj6bwS
iV6nqlKr+CMny6SxnGPb15l+8Ape62im9MZaRw1NEDPjTrETo8gYbEvs/AmQ351k
KSUjB6G00j0uYODP0gmHu81I8E3CwnqIiru6z1kZ1q+PsAewnjHxgsHA3y6mbWwZ
DrXYfiYaRQM9sHmklCitD38m5agI/pboPGiUU+6DOogrFZYJsuB6jC511pzrp1Zk
j5ZPaK49l8KEj8C8QMALXL32h7M1bKwYUH+E4EzNktMg6TO8UpmvMrUpsyUqtEj5
cuHKZPfmghCN6J3Cioj6OGaK/GP5Afl4/Xtcd/p2h/rs37EOeZVXtL0m79YB0esW
CruOC7XFxYpVq9Os6pFLKcwZpDIlTirxZUTQAs6qzkm06p98g7BAe+dDq6dso499
iYH6TKX/1Y7DzkvgtdizjkXPdsDtQCv9Uw+wp9U7DbGKogPeMa3Md+pvez7W35Ei
Eua++tgy/BBjFFFy3l3WFpO9KWgz7zpm7AeKJt8T11dleCfeXkkUAKIAf5qoIbap
sZWwpbkNFhHax2xIPEDgfg1azVY80ZcFuctL7TlLnMQ/0lUTbiSw1nH69MG6zO0b
9f6BQdgAmD06yK56mDcYBZUCAwEAAaOCATgwggE0MA4GA1UdDwEB/wQEAwIBhjAP
BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTkrysmcRorSCeFL1JmLO/wiRNxPjAf
BgNVHSMEGDAWgBRge2YaRQ2XyolQL30EzTSo//z9SzBgBggrBgEFBQcBAQRUMFIw
JQYIKwYBBQUHMAGGGWh0dHA6Ly9vY3NwLnBraS5nb29nL2dzcjEwKQYIKwYBBQUH
MAKGHWh0dHA6Ly9wa2kuZ29vZy9nc3IxL2dzcjEuY3J0MDIGA1UdHwQrMCkwJ6Al
oCOGIWh0dHA6Ly9jcmwucGtpLmdvb2cvZ3NyMS9nc3IxLmNybDA7BgNVHSAENDAy
MAgGBmeBDAECATAIBgZngQwBAgIwDQYLKwYBBAHWeQIFAwIwDQYLKwYBBAHWeQIF
AwMwDQYJKoZIhvcNAQELBQADggEBADSkHrEoo9C0dhemMXoh6dFSPsjbdBZBiLg9
NR3t5P+T4Vxfq7vqfM/b5A3Ri1fyJm9bvhdGaJQ3b2t6yMAYN/olUazsaL+yyEn9
WprKASOshIArAoyZl+tJaox118fessmXn1hIVw41oeQa1v1vg4Fv74zPl6/AhSrw
9U5pCZEt4Wi4wStz6dTZ/CLANx8LZh1J7QJVj2fhMtfTJr9w4z30Z209fOU0iOMy
+qduBmpvvYuR7hZL6Dupszfnw0Skfths18dG9ZKb59UhvmaSGZRVbNQpsg3BZlvi
d0lIKO2d1xozclOzgjXPYovJJIultzkMu34qQb9Sz/yilrbCgj8=
-----END CERTIFICATE-----

Given that wolfSSL_X509_EXTENSION_get_data is currently aliased to X509_EXTENSION_get_data, I would say the intention is for them to have the same behaviour, so this PR changes how an extension is stored in WolfSSL.

Now, this is a clear change of behavior, and will probably break a lot of tests. To start, the API of the public function would need to be changed to return an ASN1_OCTET_STRING instead of an ASN1_STRING. But I don't really see a utility for a function that returns different type of data depending on the type of extension, other than to print it in a console.

So, this PR is not really intended to be merged yet, but to trigger a discussion about how should WolfSSL behave. If it is acknowledged that they should not have the same behavior, I think the alias to OpenSSL alternatives should be removed.

Please describe the scope of the fix or feature addition.

The storage format of an X.509 extension is changed

Fixes #8941

Testing

How did you test?

No testing other than running the attached program

Checklist

  • added tests
  • updated/added doxygen
  • updated appropriate READMEs
  • Updated manual and documentation

@wolfSSL-Bot
Copy link

Can one of the admins verify this patch?

@dgarske
Copy link
Contributor

dgarske commented Jul 4, 2025

Okay to test. No approved contributor agreement yet but process started.

@ribes96
Copy link
Contributor Author

ribes96 commented Jul 8, 2025

Last pushed commit (979d732 (Add missing ext_sk to ALT_NAMES extension, 2025-07-08)) makes the LDAP tests pass.

libspdm is failing because the 'wolfSSL/osp' project has a patch with the following contents:

--- a/library/spdm_crypt_lib/libspdm_crypt_cert.c
+++ b/library/spdm_crypt_lib/libspdm_crypt_cert.c
@@ -911,11 +911,13 @@ static bool libspdm_verify_leaf_cert_spdm_eku(const uint8_t *cert, size_t cert_s
     req_auth_oid_find_success = false;
     rsp_auth_oid_find_success = false;
 
+#ifndef SPDM_USING_WOLFSSL /* wolfssl returns data without sequence tag */
     status = libspdm_asn1_get_tag(&ptr, eku + eku_size, &obj_len,
                                   LIBSPDM_CRYPTO_ASN1_SEQUENCE | LIBSPDM_CRYPTO_ASN1_CONSTRUCTED);
     if (!status) {
         return false;
     }
+#endif
 
     while(ptr < eku + eku_size) {
         status = libspdm_asn1_get_tag(&ptr, eku + eku_size, &obj_len, LIBSPDM_CRYPTO_ASN1_OID);

So it is working around precisely the behavior that this PR is fixing. With the patch fixed, the libspdm tests pass in my workstation.

@dgarske
Copy link
Contributor

dgarske commented Jul 8, 2025

Okay to test. Contributor agreement approved and on file.

@dgarske dgarske requested review from Copilot and SparkiDev July 8, 2025 22:50
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR refactors how X.509 extensions are stored in WolfSSL to always retain the full DER-encoded OCTET STRING, matching OpenSSL’s behavior, and removes per-extension type special-case storage.

  • Eliminates per-OID ASN1_STRING_set calls and moves to a unified post-switch copy of the raw OCTET STRING into ext->value
  • Introduces a generic “read critical flag then copy octet string” parsing block after all known OID cases
  • Updates related print and d2i routines to work with the new raw OCTET STRING storage

objSz++;
objSz += SetLength(length, oidBuf + 1);
objSz += length;
/* The ASN1_OBJECT in the extension is set in the same way
Copy link
Preview

Copilot AI Jul 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All of the per-extension ext->crit = x509->*Crit assignments were removed, so known extensions no longer honor their critical flag. You’ll need to preserve the original critical values for each OID (e.g. basicConstCrit, authKeyIdCrit, etc.) before the unified parsing so that ext->crit is correctly set.

Copilot uses AI. Check for mistakes.

@dgarske
Copy link
Contributor

dgarske commented Jul 8, 2025

Last pushed commit (979d732 (Add missing ext_sk to ALT_NAMES extension, 2025-07-08)) makes the LDAP tests pass.

libspdm is failing because the 'wolfSSL/osp' project has a patch with the following contents:

--- a/library/spdm_crypt_lib/libspdm_crypt_cert.c
+++ b/library/spdm_crypt_lib/libspdm_crypt_cert.c
@@ -911,11 +911,13 @@ static bool libspdm_verify_leaf_cert_spdm_eku(const uint8_t *cert, size_t cert_s
     req_auth_oid_find_success = false;
     rsp_auth_oid_find_success = false;
 
+#ifndef SPDM_USING_WOLFSSL /* wolfssl returns data without sequence tag */
     status = libspdm_asn1_get_tag(&ptr, eku + eku_size, &obj_len,
                                   LIBSPDM_CRYPTO_ASN1_SEQUENCE | LIBSPDM_CRYPTO_ASN1_CONSTRUCTED);
     if (!status) {
         return false;
     }
+#endif
 
     while(ptr < eku + eku_size) {
         status = libspdm_asn1_get_tag(&ptr, eku + eku_size, &obj_len, LIBSPDM_CRYPTO_ASN1_OID);

So it is working around precisely the behavior that this PR is fixing. With the patch fixed, the libspdm tests pass in my workstation.

@julek-wolfssl will you please work on updating the libspdm patch and reviewing this PR?

Copy link
Contributor

@SparkiDev SparkiDev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Otherwise good to have this change.

julek-wolfssl added a commit to julek-wolfssl/osp that referenced this pull request Jul 11, 2025
wolfSSL/wolfssl#8967 updates wolfSSL to return DER data in the same way as OpenSSL. When this PR goes in then wolfSSL/wolfssl#8967 needs to be re-run and merged so that other wolfSSL PR's are not blocked on libspdm test failures.
Copy link
Member

@julek-wolfssl julek-wolfssl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like the growing complexity of wolfSSL_X509V3_EXT_d2i. At this point I would prefer to use DecodeCertExtensions to parse the extension and then set the appropriate fields from DecodedCert. @ribes96 are you up for such a refactor or should one of us tackle this section?

@ribes96
Copy link
Contributor Author

ribes96 commented Jul 11, 2025

I don't like the growing complexity of wolfSSL_X509V3_EXT_d2i. At this point I would prefer to use DecodeCertExtensions to parse the extension and then set the appropriate fields from DecodedCert. @ribes96 are you up for such a refactor or should one of us tackle this section?

In fact this this function is just replicating what the following functions do:

DecodeBasicCaConstraint
DecodeSubjKeyId
DecodeAuthKeyId
DecodeKeyUsage

But they couldn't be used on the one hand because they are private of wolfcrypt, and on the other because they all receive as parameter a DecodedCert, which is not available in wolfSSL_X509V3_EXT_d2i because there is simply no certificate, just an extension.

So the path forward would be to add a version of these functions to the public API of wolfcrypt, that doesn't receive a DecodedCert but some specific data, and use them both inside current functions DecodeBasicCaConstraint, etc, and from wolfSSL_X509V3_EXT_d2i.

I can do that

@dgarske dgarske self-assigned this Jul 11, 2025
@dgarske
Copy link
Contributor

dgarske commented Jul 11, 2025

./configure CC="clang -fsanitize=address,undefined -g" --enable-all --enable-sp-math-all
FAIL: scripts/unit.test

See: https://github.com/wolfSSL/wolfssl/actions/runs/16224294061/job/45819565451?pr=8967

    710: test_wolfSSL_X509V3_EXT                            :tests/api.c:43770:5: runtime error: call to function (unknown) through pointer to incorrect function type 'char *(*)(struct WOLFSSL_v3_ext_method *, void *)'
(/home/davidgarske/GitHub/wolfssl/src/.libs/libwolfssl.so.43+0x6cd898): note: (unknown) defined here
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior tests/api.c:43770:5 
 passed (  0.00069)
    711: test_wolfSSL_X509V3_EXT_bc                         : passed (  0.00000)
    712: test_wolfSSL_X509V3_EXT_san                        : passed (  0.00000)
    713: test_wolfSSL_X509V3_EXT_aia                        : passed (  0.00001)
    714: test_wolfSSL_X509V3_EXT_print                      :=================================================================
==2033422==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7bafba8f4aa1 at pc 0x0000004af87f bp 0x7ffec4fbc410 sp 0x7ffec4fbbbd0
READ of size 611 at 0x7bafba8f4aa1 thread T0
    #0 0x0000004af87e  (/home/davidgarske/GitHub/wolfssl/tests/.libs/unit.test+0x4af87e) (BuildId: 0fc9b9dcb8ce3765825afd11856edfdf479144ea)
    #1 0x7fafbd0c2a15  (/home/davidgarske/GitHub/wolfssl/src/.libs/libwolfssl.so.43+0x6c2a15) (BuildId: b849fc0057905a409e0b93d1836dbe2acfb1bc78)
    #2 0x7fafbd1c4010  (/home/davidgarske/GitHub/wolfssl/src/.libs/libwolfssl.so.43+0x7c4010) (BuildId: b849fc0057905a409e0b93d1836dbe2acfb1bc78)
    #3 0x0000006f849e  (/home/davidgarske/GitHub/wolfssl/tests/.libs/unit.test+0x6f849e) (BuildId: 0fc9b9dcb8ce3765825afd11856edfdf479144ea)
    #4 0x000000974389  (/home/davidgarske/GitHub/wolfssl/tests/.libs/unit.test+0x974389) (BuildId: 0fc9b9dcb8ce3765825afd11856edfdf479144ea)
    #5 0x0000004f7476  (/home/davidgarske/GitHub/wolfssl/tests/.libs/unit.test+0x4f7476) (BuildId: 0fc9b9dcb8ce3765825afd11856edfdf479144ea)
    #6 0x7fafbc6c65f4  (/lib64/libc.so.6+0x35f4) (BuildId: c4b06a608071b2c9852fae62ca3b69cdc22cd022)
    #7 0x7fafbc6c66a7  (/lib64/libc.so.6+0x36a7) (BuildId: c4b06a608071b2c9852fae62ca3b69cdc22cd022)
    #8 0x00000040e074  (/home/davidgarske/GitHub/wolfssl/tests/.libs/unit.test+0x40e074) (BuildId: 0fc9b9dcb8ce3765825afd11856edfdf479144ea)

Address 0x7bafba8f4aa1 is located in stack of thread T0 at offset 161 in frame
    #0 0x7fafbd1c37c7  (/home/davidgarske/GitHub/wolfssl/src/.libs/libwolfssl.so.43+0x7c37c7) (BuildId: b849fc0057905a409e0b93d1836dbe2acfb1bc78)

  This frame has 3 object(s):
    [32, 161) 'tmp' (line 1474)
    [240, 245) 'isCa' (line 1501) <== Memory access at offset 161 partially underflows this variable
    [272, 278) 'notCa' (line 1502) <== Memory access at offset 161 partially underflows this variable
HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
      (longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow (/home/davidgarske/GitHub/wolfssl/tests/.libs/unit.test+0x4af87e) (BuildId: 0fc9b9dcb8ce3765825afd11856edfdf479144ea) 
Shadow bytes around the buggy address:
  0x7bafba8f4800: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
  0x7bafba8f4880: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
  0x7bafba8f4900: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
  0x7bafba8f4980: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
  0x7bafba8f4a00: f1 f1 f1 f1 00 00 00 00 00 00 00 00 00 00 00 00
=>0x7bafba8f4a80: 00 00 00 00[01]f2 f2 f2 f2 f2 f2 f2 f2 f2 f8 f2
  0x7bafba8f4b00: f2 f2 f8 f3 f3 f3 f3 f3 00 00 00 00 00 00 00 00
  0x7bafba8f4b80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7bafba8f4c00: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
  0x7bafba8f4c80: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
  0x7bafba8f4d00: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==2033422==ABORTING

@SparkiDev
Copy link
Contributor

Consider putting in #ifdefs to have the library do the old behaviour for those that are expecting it.

@dgarske
Copy link
Contributor

dgarske commented Jul 14, 2025

Retest this please: "AgentOfflineException"

@julek-wolfssl
Copy link
Member

@ribes96 My plan was to expose DecodeCertExtensions and to allocate a DecodedCert on the stack to decode the extensions. This wasy asn.c changes stay minimal.

@ribes96
Copy link
Contributor Author

ribes96 commented Jul 15, 2025

@ribes96 My plan was to expose DecodeCertExtensions and to allocate a DecodedCert on the stack to decode the extensions. This wasy asn.c changes stay minimal.

I'm not seeing how that can be done. DecodeCertExtensions expects a full extensions sequence inside DecodedCert->{extensions, extensionsSz} and then fills DecodedCert with the extensions found there. Are you proposing to construct a dummy extensions sequence, containing the only one extension available in wolfSSL_X509V3_EXT_d2i, initialize a new DecodedCert by just filling extensions and extensionsSz with the dummy extensions sequence, then call DecodeCertExtensions and extract from DecodedCert the appropriate fields depending on the extension?

@ribes96
Copy link
Contributor Author

ribes96 commented Jul 17, 2025

Consider putting in #ifdefs to have the library do the old behaviour for those that are expecting it.

I am now working on this
I am considering adding a new private function that transforms a given WOLFSSL_ASN1_STRING from containing the full extension OCTET STRING into the old contents. Then function wolfSSL_X509_EXTENSION_get_data would call it in the end depending on the #ifdefs. wolfSSL_X509_EXTENSION_get_data should be split into an internal version and an external version, to ensure that internal callers get the expected behavior independently of the #ifdef.

Any proposal for the name of the feature flag?

Strictly speaking, wolfSSL_X509_EXTENSION_get_data should be updated to return an ASN1_OCTET_STRING instead of an ASN1_STRING. They are currently aliased:

#define ASN1_OCTET_STRING         WOLFSSL_ASN1_STRING

Should we change the function signature? I'm not sure how will this affect existing callers

SparkiDev
SparkiDev previously approved these changes Jul 20, 2025
@ribes96
Copy link
Contributor Author

ribes96 commented Jul 22, 2025

Should I merge master to resolve the conflicts?

@dgarske
Copy link
Contributor

dgarske commented Jul 22, 2025

Hi @ribes96 , please resolve merge conflicts. Thank you

Copy link
Contributor

@dgarske dgarske left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#ifdef WOLFSSL_ASN_TEMPLATE
^
/tmp/workspace/PRB-multi-test-script/wolfssl/wolfcrypt/src/asn.c:23789:2: warning: nested redundant #ifndef; consider removing it [readability-redundant-preprocessor]
#ifndef WOLFSSL_ASN_TEMPLATE
^
/tmp/workspace/PRB-multi-test-script/wolfssl/wolfcrypt/src/asn.c:22894:2: note: previous #ifdef was here
#ifdef WOLFSSL_ASN_TEMPLATE
^
/tmp/workspace/PRB-multi-test-script/wolfssl/wolfcrypt/src/asn.c:23853:2: warning: nested redundant #ifndef; consider removing it [readability-redundant-preprocessor]
#ifndef WOLFSSL_ASN_TEMPLATE
^
/tmp/workspace/PRB-multi-test-script/wolfssl/wolfcrypt/src/asn.c:22894:2: note: previous #ifdef was here
#ifdef WOLFSSL_ASN_TEMPLATE
^
./configure --enable-jobserver=4 CC="clang -fsanitize=address,undefined -g" --enable-all --enable-sp-math-all
make check
FAIL: scripts/unit.test

Copy link
Contributor

@dgarske dgarske left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

c:\jenkins\workspace\prb-windows-test-v2\src\x509.c(1971): warning C4244: 'function' : conversion from 'int' to 'byte', possible loss of data [C:\jenkins\workspace\PRB-windows-test-v2\wolfssl.vcxproj]

c:\jenkins\workspace\prb-windows-test-v2\src\x509.c(2005): warning C4244: 'function' : conversion from 'int' to 'byte', possible loss of data [C:\jenkins\workspace\PRB-windows-test-v2\wolfssl.vcxproj]

c:\jenkins\workspace\prb-windows-test-v2\src\x509.c(2056): warning C4244: 'function' : conversion from 'int' to 'byte', possible loss of data [C:\jenkins\workspace\PRB-windows-test-v2\wolfssl.vcxproj]

Copy link
Contributor

@dgarske dgarske left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @ribes96 ,

This breaks some of the return code logic. For example the test_wolfSSL_CRL_duplicate_extensions we have a faketime test that pushes the clock a year out. We expect a CRL_CERT_DATE_ERR, but now we get a ASN_PARSE_E. Can you please make sure we aren't loosing some of the return code logic.

[all-check-certs-one-year] [7 of 50] [e6b39baf40] [previously fail_check]
    autogen.sh e6b39baf40...   real 0m4.007s  user 0m2.797s  sys 0m0.248s
    configure...   real 0m6.777s  user 0m4.823s  sys 0m2.537s
    build...   real 0m17.111s  user 1m26.745s  sys 0m3.905s
    check[faketime]...   real 0m0.055s  user 0m0.046s  sys 0m0.014s
    configure...   real 0m6.531s  user 0m4.536s  sys 0m2.573s
    build...   real 0m16.726s  user 1m26.467s  sys 0m4.037s
    check[faketime]...FAILURES:
   real 0m11.347s  user 0m3.251s  sys 0m0.056s
ERROR - tests/api.c line 4291 failed with:
    expected: ret == ASN_PARSE_E
    result:   -179 != -140
ERROR - tests/api.c line 68860 failed with:
    expected: Test failed
    result:   ret 0
ERROR - tests/api.c line 9892 failed with:
    expected: wolfSSL_read_ex(ssl_s, buf, sizeof(buf), &count) == WOLFSSL_SUCCESS
    result:   5 != 1
ERROR - tests/api.c line 64228 failed with:
    expected: wolfSSL_shutdown(ssl_c) == 1
    result:   0 != 1

FAILURES:
   917: test_wolfSSL_CRL_duplicate_extensions

Here is that specific test with the logging and WOLFSSL_DEBUG_ASN_TEMPLATE set.

davidgarske@i9w680:/tmp/wolfssl_test_workdir.811078/wolfssl$ faketime -f +1y scripts/unit.test -917
starting unit tests...
 Begin API Tests
wolfSSL Entering wolfSSL_Init

wolfSSL Entering wolfCrypt_Init
RNG_HEALTH_TEST_CHECK_SIZE = 128
sizeof(seedB_data)         = 128
    917: test_wolfSSL_CRL_duplicate_extensions              :wolfSSL Entering wolfSSL_CertManagerNew
heap param is null
DYNAMIC_TYPE_CERT_MANAGER Allocating = 392 bytes
Testing CRL with duplicate Authority Key Identifier extensions
wolfSSL Entering wolfSSL_CertManagerLoadCRLBuffer
wolfSSL Entering wolfSSL_CertManagerEnableCRL
wolfSSL Entering InitCRL
wolfSSL Entering BufferLoadCRL
wolfSSL Entering PemToDer
InitDecodedCRL
ParseCRL
TEMPLATE: crlASN
wolfSSL Entering GetASN_Items
 0:    0  520 +  SEQUENCE        
 1:    4  241 +   SEQUENCE        
 2:    7    1      INTEGER         
 3:   10   13 +    SEQUENCE        
 4:   12    9       OBJECT ID       
 5:   23    0       NULL            
 7:   25  121 +    SEQUENCE        
 8:  148   13      UTCTime         
10:  163   13      UTCTime         
13:  178   68 +    [0]             
14:  180   66 +     SEQUENCE        
15:  248   13 +   SEQUENCE        
16:  250    9      OBJECT ID       
17:  261    0      NULL            
19:  263  257     BIT STRING      
Date AFTER check failed
CRL after date is no longer valid
wolfSSL error occurred, error = 179 line:41004 file:wolfcrypt/src/asn.c
ParseCRL error
wolfSSL Entering FreeCRL_Entry
FreeDecodedCRL

ERROR - tests/api.c line 4291 failed with:
    expected: ret == ASN_PARSE_E
    result:   -179 != -140

wolfSSL Entering wolfSSL_CertManagerFree
wolfSSL Entering FreeCRL
 failed (  0.00010)

ERROR - tests/api.c line 68860 failed with:
    expected: Test failed

    result:   ret 0

wolfSSL Entering wolfSSL_ERR_clear_error
wolfSSL Entering wolfSSL_Cleanup
wolfSSL Entering wolfSSL_crypto_policy_disable
wolfSSL Entering wolfCrypt_Cleanup

FAILURES:
   917: test_wolfSSL_CRL_duplicate_extensions

 End API Tests
 Failed/Skipped/Passed/All: 1/0/0/1
davidgarske@i9w680:/tmp/wolfssl_test_workdir.811078/wolfssl$ 

@ribes96
Copy link
Contributor Author

ribes96 commented Jul 28, 2025

Hi @ribes96 ,

This breaks some of the return code logic. For example the test_wolfSSL_CRL_duplicate_extensions we have a faketime test that pushes the clock a year out. We expect a CRL_CERT_DATE_ERR, but now we get a ASN_PARSE_E. Can you please make sure we aren't loosing some of the return code logic.

[all-check-certs-one-year] [7 of 50] [e6b39baf40] [previously fail_check]
    autogen.sh e6b39baf40...   real 0m4.007s  user 0m2.797s  sys 0m0.248s
    configure...   real 0m6.777s  user 0m4.823s  sys 0m2.537s
    build...   real 0m17.111s  user 1m26.745s  sys 0m3.905s
    check[faketime]...   real 0m0.055s  user 0m0.046s  sys 0m0.014s
    configure...   real 0m6.531s  user 0m4.536s  sys 0m2.573s
    build...   real 0m16.726s  user 1m26.467s  sys 0m4.037s
    check[faketime]...FAILURES:
   real 0m11.347s  user 0m3.251s  sys 0m0.056s
ERROR - tests/api.c line 4291 failed with:
    expected: ret == ASN_PARSE_E
    result:   -179 != -140
ERROR - tests/api.c line 68860 failed with:
    expected: Test failed
    result:   ret 0
ERROR - tests/api.c line 9892 failed with:
    expected: wolfSSL_read_ex(ssl_s, buf, sizeof(buf), &count) == WOLFSSL_SUCCESS
    result:   5 != 1
ERROR - tests/api.c line 64228 failed with:
    expected: wolfSSL_shutdown(ssl_c) == 1
    result:   0 != 1

FAILURES:
   917: test_wolfSSL_CRL_duplicate_extensions

Here is that specific test with the logging and WOLFSSL_DEBUG_ASN_TEMPLATE set.

davidgarske@i9w680:/tmp/wolfssl_test_workdir.811078/wolfssl$ faketime -f +1y scripts/unit.test -917
starting unit tests...
 Begin API Tests
wolfSSL Entering wolfSSL_Init

wolfSSL Entering wolfCrypt_Init
RNG_HEALTH_TEST_CHECK_SIZE = 128
sizeof(seedB_data)         = 128
    917: test_wolfSSL_CRL_duplicate_extensions              :wolfSSL Entering wolfSSL_CertManagerNew
heap param is null
DYNAMIC_TYPE_CERT_MANAGER Allocating = 392 bytes
Testing CRL with duplicate Authority Key Identifier extensions
wolfSSL Entering wolfSSL_CertManagerLoadCRLBuffer
wolfSSL Entering wolfSSL_CertManagerEnableCRL
wolfSSL Entering InitCRL
wolfSSL Entering BufferLoadCRL
wolfSSL Entering PemToDer
InitDecodedCRL
ParseCRL
TEMPLATE: crlASN
wolfSSL Entering GetASN_Items
 0:    0  520 +  SEQUENCE        
 1:    4  241 +   SEQUENCE        
 2:    7    1      INTEGER         
 3:   10   13 +    SEQUENCE        
 4:   12    9       OBJECT ID       
 5:   23    0       NULL            
 7:   25  121 +    SEQUENCE        
 8:  148   13      UTCTime         
10:  163   13      UTCTime         
13:  178   68 +    [0]             
14:  180   66 +     SEQUENCE        
15:  248   13 +   SEQUENCE        
16:  250    9      OBJECT ID       
17:  261    0      NULL            
19:  263  257     BIT STRING      
Date AFTER check failed
CRL after date is no longer valid
wolfSSL error occurred, error = 179 line:41004 file:wolfcrypt/src/asn.c
ParseCRL error
wolfSSL Entering FreeCRL_Entry
FreeDecodedCRL

ERROR - tests/api.c line 4291 failed with:
    expected: ret == ASN_PARSE_E
    result:   -179 != -140

wolfSSL Entering wolfSSL_CertManagerFree
wolfSSL Entering FreeCRL
 failed (  0.00010)

ERROR - tests/api.c line 68860 failed with:
    expected: Test failed

    result:   ret 0

wolfSSL Entering wolfSSL_ERR_clear_error
wolfSSL Entering wolfSSL_Cleanup
wolfSSL Entering wolfSSL_crypto_policy_disable
wolfSSL Entering wolfCrypt_Cleanup

FAILURES:
   917: test_wolfSSL_CRL_duplicate_extensions

 End API Tests
 Failed/Skipped/Passed/All: 1/0/0/1
davidgarske@i9w680:/tmp/wolfssl_test_workdir.811078/wolfssl$ 

I'm sorry, I don't understand.

test_wolfSSL_CRL_duplicate_extensions gives me the same results in master (cc2f792 (Merge pull request #9035 from douzzer/20250725-wc_linuxkm_relax_long_loop, 2025-07-26)) and in the last commit of this branch (b07a0e0 (Fix return correct error code in DecodeSubjKeyIdInternal, 2025-07-25)).

The test checks that wolfSSL_CertManagerLoadCRLBuffer returns ASN_PARSE_E. I see this behaviour both with and without faketime.

You are talking about this test, right?

static int test_wolfSSL_CRL_duplicate_extensions(void)
{
    EXPECT_DECLS;
#if defined(WOLFSSL_ASN_TEMPLATE) && !defined(NO_CERTS) && \
    defined(HAVE_CRL) && !defined(NO_RSA) && !defined(WOLFSSL_NO_ASN_STRICT) && \
    (defined(WC_ASN_RUNTIME_DATE_CHECK_CONTROL) || defined(NO_ASN_TIME_CHECK))
    const unsigned char crl_duplicate_akd[] =
        "-----BEGIN X509 CRL-----\n"
        "MIICCDCB8QIBATANBgkqhkiG9w0BAQsFADB5MQswCQYDVQQGEwJVUzETMBEGA1UE\n"
        "CAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzETMBEGA1UECgwK\n"
        "TXkgQ29tcGFueTETMBEGA1UEAwwKTXkgUm9vdCBDQTETMBEGA1UECwwKTXkgUm9v\n"
        "dCBDQRcNMjQwOTAxMDAwMDAwWhcNMjUxMjAxMDAwMDAwWqBEMEIwHwYDVR0jBBgw\n"
        "FoAU72ng99Ud5pns3G3Q9+K5XGRxgzUwHwYDVR0jBBgwFoAU72ng99Ud5pns3G3Q\n"
        "9+K5XGRxgzUwDQYJKoZIhvcNAQELBQADggEBAIFVw4jrS4taSXR/9gPzqGrqFeHr\n"
        "IXCnFtHJTLxqa8vUOAqSwqysvNpepVKioMVoGrLjFMjANjWQqTEiMROAnLfJ/+L8\n"
        "FHZkV/mZwOKAXMhIC9MrJzifxBICwmvD028qnwQm09EP8z4ICZptD6wPdRTDzduc\n"
        "KBuAX+zn8pNrJgyrheRKpPgno9KsbCzK4D/RIt1sTK2M3vVOtY+vpsN70QYUXvQ4\n"
        "r2RZac3omlT43x5lddPxIlcouQpwWcVvr/K+Va770MRrjn88PBrJmvsEw/QYVBXp\n"
        "Gxv2b78HFDacba80sMIm8ltRdqUCa5qIc6OATsz7izCQXEbkTEeESrcK1MA=\n"
        "-----END X509 CRL-----\n";

    WOLFSSL_CERT_MANAGER* cm = NULL;
    int ret;

    (void)wc_AsnSetSkipDateCheck(1);

    cm = wolfSSL_CertManagerNew();
    ExpectNotNull(cm);

    /* Test loading CRL with duplicate extensions */
    WOLFSSL_MSG("Testing CRL with duplicate Authority Key Identifier extensions");
    ret = wolfSSL_CertManagerLoadCRLBuffer(cm, crl_duplicate_akd,
                                           sizeof(crl_duplicate_akd),
                                           WOLFSSL_FILETYPE_PEM);
    ExpectIntEQ(ret, ASN_PARSE_E);

    wolfSSL_CertManagerFree(cm);

    (void)wc_AsnSetSkipDateCheck(0);
#endif
    return EXPECT_RESULT();
}

I am building with

./configure --enable-all CFLAGS="-DWC_ASN_RUNTIME_DATE_CHECK_CONTROL"

I am using faketime: Version 0.9.7

@dgarske dgarske self-assigned this Jul 29, 2025
@dgarske dgarske self-requested a review July 29, 2025 16:30
@dgarske
Copy link
Contributor

dgarske commented Jul 29, 2025

Hi @ribes96 ,

I was wrong, your PR is passing that all-check-certs-one-year test. It was after I did a rebase to master. Also I seem to have an issue with rebasing this on master. Can you please squash these commits and force push?

Thanks,
David Garske, wolfSSL

@dgarske dgarske removed their assignment Jul 29, 2025
Store in WOLFSSL_X509_EXTENSION.value always the full contents of the
OCTET STRING of the extension, instead of different type of data
depending on the type of extension. Previously this was only done for
unknown extensions.
@ribes96 ribes96 force-pushed the extension-full-value branch from b07a0e0 to 3e36057 Compare July 29, 2025 21:18
@dgarske
Copy link
Contributor

dgarske commented Jul 29, 2025

Jenkins retest this please. Agent Offline

@dgarske
Copy link
Contributor

dgarske commented Jul 29, 2025

Hi @ribes96 ,

It seems like the changes in this PR are breaking some of the tests for libspdm, socat and zephyr?

[  FAILED  ] spdm_crypt_lib_tests: 5 test(s), listed below:
[  FAILED  ] libspdm_test_crypt_spdm_x509_certificate_check
[  FAILED  ] libspdm_test_crypt_spdm_x509_certificate_check_ex
[  FAILED  ] libspdm_test_crypt_spdm_x509_set_cert_certificate_check_ex
[  FAILED  ] libspdm_test_crypt_spdm_verify_cert_chain_data_ex
[  FAILED  ] libspdm_test_crypt_spdm_verify_certificate_chain_buffer_ex

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Get full OCTET STRING of an extension
5 participants