Allow serial number 0 for root CA certificates

This commit is contained in:
jackctj117
2025-12-19 15:28:39 -07:00
parent c73f431687
commit ee744b1f0b
13 changed files with 335 additions and 31 deletions
+1 -1
View File
@@ -27,4 +27,4 @@ jobs:
# The exclude_file contains lines of code that should be ignored. This is useful for individual lines which have non-words that can safely be ignored.
exclude_file: '.codespellexcludelines'
# To skip files entirely from being processed, add it to the following list:
skip: '*.cproject,*.der,*.mtpj,*.pem,*.vcxproj,.git,*.launch,*.scfg,*.revoked,./examples/asn1/dumpasn1.cfg,./examples/asn1/oid_names.h'
skip: '*.cproject,*.csr,*.der,*.mtpj,*.pem,*.vcxproj,.git,*.launch,*.scfg,*.revoked,./examples/asn1/dumpasn1.cfg,./examples/asn1/oid_names.h'
+1
View File
@@ -155,6 +155,7 @@ include certs/ocsp/include.am
include certs/statickeys/include.am
include certs/test/include.am
include certs/test-pathlen/include.am
include certs/test-serial0/include.am
include certs/intermediate/include.am
include certs/falcon/include.am
include certs/rsapss/include.am
+21
View File
@@ -0,0 +1,21 @@
-----BEGIN CERTIFICATE-----
MIIDeDCCAmCgAwIBAgIBZDANBgkqhkiG9w0BAQsFADBEMR4wHAYDVQQDDBVUZXN0
IFJvb3QgQ0EgU2VyaWFsIDAxFTATBgNVBAoMDHdvbGZTU0wgVGVzdDELMAkGA1UE
BhMCVVMwHhcNMjYwMzE5MjA0NjM2WhcNMzYwMzE2MjA0NjM2WjBAMRowGAYDVQQD
DBFFbmQgRW50aXR5IE5vcm1hbDEVMBMGA1UECgwMd29sZlNTTCBUZXN0MQswCQYD
VQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKdhKjg6wGtt
Ivkud3c5BHbytPU1OyvguGwbvoqJszxz7U8ibiEE9k7MHtvrc7vh+mYHhl6py/Z7
9U9BGvS5dQi6MFUSbc1PR5y/mnYbN3/TdwSIv+/faJzvbru6C6fIe8dXo1wSIUyQ
dxP2JbUAERwVsPylIQZypYjJi8E3ku/chJmNLUUfAgal23LQdT6KbYP5kErAMqLt
5z7flt/fNouiWisk8Cf7DuPVA2fOHkwmq7prqkut0MF5N6DtEw0OWXpHsZw0JDlj
a8lKVFZ7hkIfl0m7Ij3pXUjRQ0SMd2CfWao5yOW5X0hHCcepnRQJJw+Hi6ZZjra9
b370bbfT82ECAwEAAaN5MHcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBaAwHQYDVR0l
BBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMB0GA1UdDgQWBBTSS9S9Yn+wHfdPhvEd
NVQzSE/1sDAfBgNVHSMEGDAWgBRh4Nck2fNzW7ljbZ7aY0JNA1WHwDANBgkqhkiG
9w0BAQsFAAOCAQEAG72+EoRdjiudzxfP2SvJ7p1o493NOGhQXjDCZyxyjBkP5s+A
rEbyjA2QEJU3vl/wx5fuxhbcyhSiBUhq8gPjLFkahKHGdDouMhB+b4VXi0sU+HmC
p0DFDckn0YAuejDuzkiBP9DFLmXBhL6xniLtDujEY6k6gXf+nEO3cTj5gf0Zofrr
I4s3sn+kYzp0ltrA3bLAsJD+SSVM6sRPZJSa9IKqyInlJDqyh1CG6U6Dk8TTj4Tr
V3l1KwxiECev0CFul+J7OZE0fdkcEkscZ7ySrsA5cHiqtB9xzcCWMRMR/LYjcUDo
R6o7yosbg6SzoDO78VUImqtwQhKXrvDy7kMwPw==
-----END CERTIFICATE-----
+21
View File
@@ -0,0 +1,21 @@
-----BEGIN CERTIFICATE-----
MIIDejCCAmKgAwIBAgIBADANBgkqhkiG9w0BAQsFADBEMR4wHAYDVQQDDBVUZXN0
IFJvb3QgQ0EgU2VyaWFsIDAxFTATBgNVBAoMDHdvbGZTU0wgVGVzdDELMAkGA1UE
BhMCVVMwHhcNMjYwMzE5MjA0NjM2WhcNMzYwMzE2MjA0NjM2WjBCMRwwGgYDVQQD
DBNFbmQgRW50aXR5IFNlcmlhbCAwMRUwEwYDVQQKDAx3b2xmU1NMIFRlc3QxCzAJ
BgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzQSr4Wfu
rt6+d27Y3Nr9+W8Yxy60KrIhT512OX275xfdCDMzzEC/w6ECIeKHR5PopjmzCvUx
+j0GaQ5vrPmhoVHvBfgWnYNrZvlxRq8ZCHqyQ15Emd44n/14W91dA4n2rqLUXvuF
D2vHX1tQ7D1ZyjkUkJOeRypni2JdFhsUBE1e7WGFFYBUJY6TMPugKAM/jIPk5C0E
h7TJmQDCQNfmbxF8BVboDKu1riVqiwQ3T+3RLQoaNL4/C3MRhfKKLXafuX4dt4n+
8mZ9ATqNPycbRGwa01JNpB3wzHecSeRjlBiY16Aahr+R4vCnXnbslfjI8MM7Q/oU
bLV+mjnt9mP/OQIDAQABo3kwdzAJBgNVHRMEAjAAMAsGA1UdDwQEAwIFoDAdBgNV
HSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwHQYDVR0OBBYEFDfbdXod3raDcV6l
4WVRx3AYleBpMB8GA1UdIwQYMBaAFGHg1yTZ83NbuWNtntpjQk0DVYfAMA0GCSqG
SIb3DQEBCwUAA4IBAQCBooXTFwajQmHYPLnyeBgfUpdSchiPCUuXj/31QyhVZ4NE
6tdlPyFTA8f+SE1sXxIYElF+CAh6mMqKz5pFxpkjjWBMEG7IIliFpQfmgftJDthW
f+R3MD1WlNdrMLmQm/MIv95CGCMqaClX4SkN0N75FSdVT0lDv2Ly1OOYcVmTawN0
MeRgTdJy1qhAhbhncBTKRXBpk+dydOp1RClmoKI0nUGL6x4NUcjNPoIb29lu2MLh
KqjfC8Gy4Z7z00lGPbGvzMlBjRP0qJ8h1ENPjUbPUY56/i0azh+h0QQedLudeN5+
uYn0tWZDeLq932X8gNWKuJQlM1mky1y+1RB/e0F2
-----END CERTIFICATE-----
+88
View File
@@ -0,0 +1,88 @@
#!/bin/bash
#
# Generate test certificates for serial number 0 testing (issue #8615)
#
# Tests verify that root CAs (self-signed + CA:TRUE) with serial 0 are
# accepted as trust anchors, while all other cert types with serial 0
# are rejected per RFC 5280 section 4.1.2.2.
#
# Output files (certs only -- EE keys use temp files):
# root_serial0.pem / root_serial0_key.pem - Root CA with serial 0
# ee_serial0.pem - EE cert with serial 0 (rejected)
# ee_normal.pem - Normal EE cert (serial 100)
# selfsigned_nonca_serial0.pem - Self-signed non-CA, serial 0
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR"
echo "==================================================="
echo "Generating serial 0 test certificates in: $SCRIPT_DIR"
echo "==================================================="
# 1. Create Root CA with serial number 0
echo ""
echo "[1/4] Creating Root CA with serial number 0..."
openssl req -x509 -newkey rsa:2048 -keyout root_serial0_key.pem -out root_serial0.pem \
-days 7300 -nodes -subj "/CN=Test Root CA Serial 0/O=wolfSSL Test/C=US" \
-set_serial 0 \
-addext "basicConstraints=critical,CA:TRUE" \
-addext "keyUsage=critical,keyCertSign,cRLSign"
echo " Root CA serial number:"
openssl x509 -in root_serial0.pem -noout -serial
# 2. Create end-entity cert with serial 0 signed by root_serial0
echo ""
echo "[2/4] Creating end-entity certificate with serial number 0..."
openssl req -newkey rsa:2048 -keyout ee_serial0_key.tmp -out ee_serial0.csr.tmp -nodes \
-subj "/CN=End Entity Serial 0/O=wolfSSL Test/C=US"
openssl x509 -req -in ee_serial0.csr.tmp -CA root_serial0.pem -CAkey root_serial0_key.pem \
-out ee_serial0.pem -days 3650 -set_serial 0 \
-extfile <(echo "basicConstraints=CA:FALSE
keyUsage=digitalSignature,keyEncipherment
extendedKeyUsage=serverAuth,clientAuth")
rm -f ee_serial0_key.tmp ee_serial0.csr.tmp
echo " End-entity cert serial number:"
openssl x509 -in ee_serial0.pem -noout -serial
# 3. Create normal end-entity cert signed by root CA with serial 0
echo ""
echo "[3/4] Creating normal end-entity certificate (signed by serial 0 root)..."
openssl req -newkey rsa:2048 -keyout ee_normal_key.tmp -out ee_normal.csr.tmp -nodes \
-subj "/CN=End Entity Normal/O=wolfSSL Test/C=US"
openssl x509 -req -in ee_normal.csr.tmp -CA root_serial0.pem -CAkey root_serial0_key.pem \
-out ee_normal.pem -days 3650 -set_serial 100 \
-extfile <(echo "basicConstraints=CA:FALSE
keyUsage=digitalSignature,keyEncipherment
extendedKeyUsage=serverAuth,clientAuth")
rm -f ee_normal_key.tmp ee_normal.csr.tmp
echo " Normal end-entity cert serial number:"
openssl x509 -in ee_normal.pem -noout -serial
# 4. Create self-signed non-CA certificate with serial 0
echo ""
echo "[4/4] Creating self-signed non-CA certificate with serial number 0..."
openssl req -x509 -newkey rsa:2048 -keyout selfsigned_nonca_serial0_key.tmp \
-out selfsigned_nonca_serial0.pem -days 3650 -nodes \
-subj "/CN=Self-Signed Non-CA Serial 0/O=wolfSSL Test/C=US" \
-set_serial 0 \
-addext "basicConstraints=CA:FALSE" \
-addext "keyUsage=digitalSignature,keyEncipherment"
rm -f selfsigned_nonca_serial0_key.tmp
echo " Self-signed non-CA cert serial number:"
openssl x509 -in selfsigned_nonca_serial0.pem -noout -serial
echo ""
echo "==================================================="
echo "Certificate generation complete!"
echo "==================================================="
+11
View File
@@ -0,0 +1,11 @@
# vim:ft=automake
# included from Top Level Makefile.am
# All paths should be given relative to the root
EXTRA_DIST += certs/test-serial0/generate_certs.sh \
certs/test-serial0/root_serial0.pem \
certs/test-serial0/root_serial0_key.pem \
certs/test-serial0/ee_serial0.pem \
certs/test-serial0/ee_normal.pem \
certs/test-serial0/selfsigned_nonca_serial0.pem
+21
View File
@@ -0,0 +1,21 @@
-----BEGIN CERTIFICATE-----
MIIDZjCCAk6gAwIBAgIBADANBgkqhkiG9w0BAQsFADBEMR4wHAYDVQQDDBVUZXN0
IFJvb3QgQ0EgU2VyaWFsIDAxFTATBgNVBAoMDHdvbGZTU0wgVGVzdDELMAkGA1UE
BhMCVVMwHhcNMjYwMzE5MjA0NjM2WhcNNDYwMzE0MjA0NjM2WjBEMR4wHAYDVQQD
DBVUZXN0IFJvb3QgQ0EgU2VyaWFsIDAxFTATBgNVBAoMDHdvbGZTU0wgVGVzdDEL
MAkGA1UEBhMCVVMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQChQKbH
G0su7BpynIN8GtTCQk8jNXKR0TnOnCHLyekO8p22QxW+A6r6sfRo/TGxPOqG8VGh
Fec8bs6wv7KX+SbYCxvhZUab4ygnlYCjW/ab6eiRTr4BloBSYWBUqz01k53CDjRD
1CK6orZ4JTAqi+4qtJkqTupMY1sKyxxw9F69PPqzNDHTsUwfZUYcvHa5VQIdX0k3
cFs4MyereNkUvLW5BZrGcDecsZRuvZ9CB5+z6ser2/ROxR3ty6ZgwHA9fLmQoxXo
r89Gb0mrXQLjNTTSDvP3eC4GPqFSLZYFf6aaLx/qFNKICUPEA6Fmk+blliE/c/Z7
DquD86OB+VqON0e1AgMBAAGjYzBhMB0GA1UdDgQWBBRh4Nck2fNzW7ljbZ7aY0JN
A1WHwDAfBgNVHSMEGDAWgBRh4Nck2fNzW7ljbZ7aY0JNA1WHwDAPBgNVHRMBAf8E
BTADAQH/MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAE25IZNDe
ChqyTQ5X00g0ktzN3Lxh8C7EOnWPfhJOcCovgVKY7dj8bLQQ6kZiS1lS+MoLDzgC
XfhrCPMXIk/BGaUUEcfWZbGP579dL3uh2G4aB52lQrbTD81fgfVeqPaTIs3VsVg2
wcgh+UvEun+G/XYSp+ZnexLjhhmBlNtTagppAhvFjDEnuLlgTkXV/4CJSy290R/7
JeATYvKGR0DVhrEa3xNEI4uoYBieFJX7pmwVcuwDyLskOurNvUTVQ1W/IesuP7JT
dFKtsxUkKU3yyBatQ1vwl117d+2dXFA9GzjtQM3kvPZoJ6Q9tOL9Y5+G+K/PoHVm
ujFE1ZTiQhm+4A==
-----END CERTIFICATE-----
+28
View File
@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEugIBADANBgkqhkiG9w0BAQEFAASCBKQwggSgAgEAAoIBAQChQKbHG0su7Bpy
nIN8GtTCQk8jNXKR0TnOnCHLyekO8p22QxW+A6r6sfRo/TGxPOqG8VGhFec8bs6w
v7KX+SbYCxvhZUab4ygnlYCjW/ab6eiRTr4BloBSYWBUqz01k53CDjRD1CK6orZ4
JTAqi+4qtJkqTupMY1sKyxxw9F69PPqzNDHTsUwfZUYcvHa5VQIdX0k3cFs4Myer
eNkUvLW5BZrGcDecsZRuvZ9CB5+z6ser2/ROxR3ty6ZgwHA9fLmQoxXor89Gb0mr
XQLjNTTSDvP3eC4GPqFSLZYFf6aaLx/qFNKICUPEA6Fmk+blliE/c/Z7DquD86OB
+VqON0e1AgMBAAECgf4QdS4GA0WpWXNZ4lHVqJjGqCLu6ap3HqZDz590p2jsrp21
opfXXlR77+54p3L5OqavTarh0Ugr1NKOeF5CLkXVD9zgoZPXyzZhakRTOkxlCfo4
wL6qGE5HPRvwNK/9xV1PJSeOd7+DYEu5rt+wuXYlPxscDPTV+yMrvy8lyOmIjZey
uS64bMaiWVvuF5KEc3p0+VqX5Q1FzSOBxBMdSuN+5xbckeVMBWWQpBUAitxdpGUs
koieaE8vjrwAXlgha2iUF9/3WJO+IYRz4e2x/2cU3wAXB/5Ga4VSltHFgHcpahc5
CN7QxBaMAisKvoGmHL9cmi47KP9+ScUWwNGHgQKBgQDS4oW6oO12W/5+5uGNP6zR
KtJ4utKwrhSeWpV6qu5cXjYC1pJEM0XN2K+K4KGPUxoNtLpspCJ2SR911y+jhz4a
oQ2U5l+gHEYjQP7bOHPwN8aCIZj6HHyD8aTcsWl3vb9dizhRvTw8D+vCiNCWM2sQ
fSdtMLk1Ju7ud5i0onJ+lQKBgQDDv+3RW+7apjuIc5CDlOIG+0Ir2/iyvtkhDRMn
thEUZYL+a8sTKhOk4SfgDZbxdz9oVJVwXFSV01F5ac/gu0/C0VLYb6vbGr2TPf3K
RPRQjoJh3XvM6ydx47hO/iUm8E5bEWjYqBXuhinh0lj11zjCtsf+zkhxCy+0i5ot
WW/8oQKBgD8iGa75pp2chOAw9q12tqIYE9KY+6JxOzL9I2sJ6To16i2HV1qbjvZF
PKhy/2sNEeuwg28q5DZNReHdfiGSx4DpXkuJfG9Oh6DeQG4YxHzR9dfXfxjBlnVZ
zmVTp6N1Zuj2WPH/mRzSF16x3uBYnGDfVwJVZ90Fvtoda9YIHAbRAoGBAKvhuacd
/GvNj3TPVNPVRWsv8PimHIiHgAy/eFRkUDcCs7VHXXekeL9MXUElbab1OJ4Zt2aE
DFnKxj3AJaKFlxHPz9jwpYysvE2wH0sepRCfMelRG8Xhri8Y79uc2W6Jj6Pzc4ba
gPeCowABPdAQfWysJoydAYsRcYAtHOI5KFZBAoGAeiLvbtj/odW1tuOcijKVX4kC
er/cqIYgvgQg1TTMsb02Fv1GBQn8A1C1Jb6TV/cJvxW3TIrqk07cSrM8qIHy1qAk
omQbnSV6p6c4FaJXBFPk9ileSPwBegxuBSiby2X29cJ88D1Wdq8Osjmc5wK/umuy
Vowu3kDcLFcpu3v6368=
-----END PRIVATE KEY-----
@@ -0,0 +1,21 @@
-----BEGIN CERTIFICATE-----
MIIDaTCCAlGgAwIBAgIBADANBgkqhkiG9w0BAQsFADBKMSQwIgYDVQQDDBtTZWxm
LVNpZ25lZCBOb24tQ0EgU2VyaWFsIDAxFTATBgNVBAoMDHdvbGZTU0wgVGVzdDEL
MAkGA1UEBhMCVVMwHhcNMjYwMzE5MjA0NjM2WhcNMzYwMzE2MjA0NjM2WjBKMSQw
IgYDVQQDDBtTZWxmLVNpZ25lZCBOb24tQ0EgU2VyaWFsIDAxFTATBgNVBAoMDHdv
bGZTU0wgVGVzdDELMAkGA1UEBhMCVVMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
ggEKAoIBAQDvEEbR+b6q0W5Kz3i37Iyfphd4qdEV2/dAzVSQC7Wgyd0soR2Fh6qB
t2C2yD/Ixj+JtdsR48mUUs0MPsbtreJOTKe9It2PJrp7mR1oOGHwfhebAegpyIh3
ytO6c7YNAE5Yd4bSAGjw0UwjpN3Yl4DVx9QLkf9+YnXaz71fNQmmC07WN7vJcn2Y
mvD8AHf3ujsRkIDZEsUsamIFnPvICqxK9d1nMVSZSN4Uf7wdsJxct0L13rlJ/TKC
UETpgyydIk3VVwPWeOYU4C/sDhI2Wl8rytqhOVnBssw+pyLGkgsQ1VDo/j+FOEup
M+sMb4s6oSLePw17L0YXkF/kdbi0J7P5AgMBAAGjWjBYMB0GA1UdDgQWBBQQg6+e
TkcmWxgBTgHYn8NawThfozAfBgNVHSMEGDAWgBQQg6+eTkcmWxgBTgHYn8NawThf
ozAJBgNVHRMEAjAAMAsGA1UdDwQEAwIFoDANBgkqhkiG9w0BAQsFAAOCAQEARLo5
6LXXU5Pp/+uF2AA+C+Eg4lECJD+j8Ice4f/WnHpdrEgyfluOw0d/XI8OnBDckvDx
cjuWOEhjwQCXSkB/604TVw6DncWVotfkA/RKJGuvmUkkSXGjRka7rDAnHqzs5xvn
4iU/n3NdWc9R0NjE9yFiURGMWbh/xRiEThm9ge0L5wzetdtIdne7tReznVy+uOgQ
FB6n5AyKK/y6ONfhNUoDnukGBuH1RB7lTs/ZuvpCEM7vrP6Llt0A9wqffOOeZ8B2
9z6YPT95t39Z6899mhnBc2rq+b7EP526Ou+KYU7e2u5gj4rZHuvlkuKA3JVn7V35
dgos00E67av5sbeXDw==
-----END CERTIFICATE-----
+11 -15
View File
@@ -23777,24 +23777,24 @@ static int test_MakeCertWith0Ser(void)
{
EXPECT_DECLS;
#if defined(WOLFSSL_CERT_REQ) && !defined(NO_ASN_TIME) && \
defined(WOLFSSL_CERT_GEN) && defined(HAVE_ECC) && \
defined(WOLFSSL_ASN_TEMPLATE)
defined(WOLFSSL_CERT_GEN) && !defined(NO_RSA) && \
defined(WOLFSSL_KEY_GEN) && defined(WOLFSSL_ASN_TEMPLATE)
Cert cert;
DecodedCert decodedCert;
byte der[FOURK_BUF];
int derSize = 0;
WC_RNG rng;
ecc_key key;
RsaKey key;
int ret;
XMEMSET(&rng, 0, sizeof(WC_RNG));
XMEMSET(&key, 0, sizeof(ecc_key));
XMEMSET(&key, 0, sizeof(RsaKey));
XMEMSET(&cert, 0, sizeof(Cert));
XMEMSET(&decodedCert, 0, sizeof(DecodedCert));
ExpectIntEQ(wc_InitRng(&rng), 0);
ExpectIntEQ(wc_ecc_init(&key), 0);
ExpectIntEQ(wc_ecc_make_key(&rng, 32, &key), 0);
ExpectIntEQ(wc_InitRsaKey(&key, NULL), 0);
ExpectIntEQ(wc_MakeRsaKey(&key, 2048, WC_RSA_EXPONENT, &rng), 0);
ExpectIntEQ(wc_InitCert(&cert), 0);
(void)XSTRNCPY(cert.subject.country, "US", CTC_NAME_SIZE);
@@ -23808,20 +23808,16 @@ static int test_MakeCertWith0Ser(void)
CTC_NAME_SIZE);
cert.selfSigned = 1;
cert.isCA = 1;
cert.sigType = CTC_SHA256wECDSA;
#ifdef WOLFSSL_CERT_EXT
cert.keyUsage |= KEYUSE_KEY_CERT_SIGN;
#endif
cert.isCA = 0;
cert.sigType = CTC_SHA256wRSA;
/* set serial number to 0 */
cert.serialSz = 1;
cert.serial[0] = 0;
ExpectIntGE(wc_MakeCert(&cert, der, FOURK_BUF, NULL, &key, &rng), 0);
ExpectIntGE(wc_MakeCert(&cert, der, FOURK_BUF, &key, NULL, &rng), 0);
ExpectIntGE(derSize = wc_SignCert(cert.bodySz, cert.sigType, der,
FOURK_BUF, NULL, &key, &rng), 0);
FOURK_BUF, &key, NULL, &rng), 0);
wc_InitDecodedCert(&decodedCert, der, (word32)derSize, NULL);
@@ -23834,7 +23830,7 @@ static int test_MakeCertWith0Ser(void)
#endif
wc_FreeDecodedCert(&decodedCert);
ret = wc_ecc_free(&key);
ret = wc_FreeRsaKey(&key);
ExpectIntEQ(ret, 0);
ret = wc_FreeRng(&rng);
ExpectIntEQ(ret, 0);
+66
View File
@@ -1029,6 +1029,72 @@ int test_DecodeAltNames_length_underflow(void)
return EXPECT_RESULT();
}
int test_SerialNumber0_RootCA(void)
{
EXPECT_DECLS;
#if !defined(NO_CERTS) && !defined(NO_FILESYSTEM) && !defined(NO_RSA) && \
!defined(WOLFSSL_NO_PEM) && defined(WOLFSSL_PEM_TO_DER)
/* Test that root CA certificates with serial number 0 are accepted,
* while non-root certificates with serial 0 are rejected (issue #8615) */
#if !defined(WOLFSSL_NO_ASN_STRICT) && !defined(WOLFSSL_PYTHON) && \
!defined(WOLFSSL_ASN_ALLOW_0_SERIAL) && \
!defined(WOLFSSL_TEST_APPLE_NATIVE_CERT_VALIDATION)
WOLFSSL_CERT_MANAGER* cm = NULL;
const char* rootSerial0File = "./certs/test-serial0/root_serial0.pem";
const char* selfSignedNonCASerial0File =
"./certs/test-serial0/selfsigned_nonca_serial0.pem";
/* Test 1: Root CA with serial 0 should load successfully */
ExpectNotNull(cm = wolfSSL_CertManagerNew());
ExpectIntEQ(wolfSSL_CertManagerLoadCA(cm, rootSerial0File, NULL),
WOLFSSL_SUCCESS);
#if (!defined(NO_WOLFSSL_CLIENT) || !defined(WOLFSSL_NO_CLIENT_AUTH)) || \
defined(OPENSSL_EXTRA)
{
const char* eeSerial0File = "./certs/test-serial0/ee_serial0.pem";
const char* eeNormalFile = "./certs/test-serial0/ee_normal.pem";
/* Test 2: End-entity cert with serial 0 should be rejected during
* verify */
ExpectIntEQ(wolfSSL_CertManagerVerify(cm, eeSerial0File,
WOLFSSL_FILETYPE_PEM), WC_NO_ERR_TRACE(ASN_PARSE_E));
/* Test 3: Normal end-entity cert signed by root CA with serial 0
* should verify successfully */
ExpectIntEQ(wolfSSL_CertManagerVerify(cm, eeNormalFile,
WOLFSSL_FILETYPE_PEM), WOLFSSL_SUCCESS);
}
#endif
if (cm != NULL) {
wolfSSL_CertManagerFree(cm);
cm = NULL;
}
/* Balance the wolfSSL_Init refcount incremented by internal
* wolfSSL_CTX_new_ex calls in CertManagerLoadCA/Verify. */
wolfSSL_Cleanup();
/* Test 4: Self-signed non-CA certificate with serial 0 should be rejected */
ExpectNotNull(cm = wolfSSL_CertManagerNew());
ExpectIntNE(wolfSSL_CertManagerLoadCA(cm, selfSignedNonCASerial0File, NULL),
WOLFSSL_SUCCESS);
if (cm != NULL) {
wolfSSL_CertManagerFree(cm);
cm = NULL;
}
wolfSSL_Cleanup();
#endif /* !WOLFSSL_NO_ASN_STRICT && !WOLFSSL_PYTHON &&
!WOLFSSL_ASN_ALLOW_0_SERIAL &&
!WOLFSSL_TEST_APPLE_NATIVE_CERT_VALIDATION */
#endif /* !NO_CERTS && !NO_FILESYSTEM && !NO_RSA && !WOLFSSL_NO_PEM */
return EXPECT_RESULT();
}
int test_wc_DecodeObjectId(void)
{
EXPECT_DECLS;
+3 -1
View File
@@ -29,6 +29,7 @@ int test_GetSetShortInt(void);
int test_wc_IndexSequenceOf(void);
int test_wolfssl_local_MatchBaseName(void);
int test_wc_DecodeRsaPssParams(void);
int test_SerialNumber0_RootCA(void);
int test_DecodeAltNames_length_underflow(void);
int test_wc_DecodeObjectId(void);
@@ -38,7 +39,8 @@ int test_wc_DecodeObjectId(void);
TEST_DECL_GROUP("asn", test_wc_IndexSequenceOf), \
TEST_DECL_GROUP("asn", test_wolfssl_local_MatchBaseName), \
TEST_DECL_GROUP("asn", test_wc_DecodeRsaPssParams), \
TEST_DECL_GROUP("asn", test_DecodeAltNames_length_underflow), \
TEST_DECL_GROUP("asn", test_SerialNumber0_RootCA), \
TEST_DECL_GROUP("asn", test_DecodeAltNames_length_underflow), \
TEST_DECL_GROUP("asn", test_wc_DecodeObjectId)
#endif /* WOLFCRYPT_TEST_ASN_H */
+42 -14
View File
@@ -21169,21 +21169,10 @@ static int DecodeCertInternal(DecodedCert* cert, int verify, int* criticalExt,
cert->version = version;
cert->serialSz = (int)serialSz;
#if !defined(WOLFSSL_NO_ASN_STRICT) && !defined(WOLFSSL_PYTHON) && \
!defined(WOLFSSL_ASN_ALLOW_0_SERIAL)
/* RFC 5280 section 4.1.2.2 states that non-conforming CAs may issue
* a negative or zero serial number and should be handled gracefully.
* Since it is a non-conforming CA that issues a serial of 0 then we
* treat it as an error here. */
if (cert->serialSz == 1 && cert->serial[0] == 0) {
WOLFSSL_MSG("Error serial number of 0, use WOLFSSL_NO_ASN_STRICT "
"if wanted");
ret = ASN_PARSE_E;
}
#endif
/* RFC 5280 requires serial number to be present and at least 1 byte */
if (cert->serialSz == 0) {
WOLFSSL_MSG("Error serial size is zero. Should be at least one "
"even with no serial number.");
WOLFSSL_MSG("Error: certificate serial number is empty "
"(zero-length serial is invalid per RFC 5280)");
ret = ASN_PARSE_E;
}
@@ -21401,6 +21390,25 @@ static int DecodeCertInternal(DecodedCert* cert, int verify, int* criticalExt,
}
}
#if !defined(WOLFSSL_NO_ASN_STRICT) && !defined(WOLFSSL_PYTHON) && \
!defined(WOLFSSL_ASN_ALLOW_0_SERIAL)
/* Check for serial number of 0. RFC 5280 section 4.1.2.2 requires
* positive serial numbers. However, allow zero for self-signed CA
* certificates (root CAs) being loaded as trust anchors since they
* are explicitly trusted and some legacy root CAs in real-world
* trust stores have serial number 0. */
if ((ret == 0) && (cert->serialSz == 1) && (cert->serial[0] == 0)) {
if (!(cert->isCA && cert->selfSigned)
#ifdef WOLFSSL_CERT_REQ
&& !cert->isCSR
#endif
) {
WOLFSSL_MSG("Error serial number of 0 for non-root certificate");
ret = ASN_PARSE_E;
}
}
#endif
if ((ret == 0) && (!done) && (badDate != 0)) {
/* Parsed whole certificate fine but return any date errors. */
ret = badDate;
@@ -22806,6 +22814,26 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm,
}
#endif
#if !defined(WOLFSSL_NO_ASN_STRICT) && !defined(WOLFSSL_PYTHON) && \
!defined(WOLFSSL_ASN_ALLOW_0_SERIAL)
/* Check for serial number of 0. RFC 5280 section 4.1.2.2 requires
* positive serial numbers. However, allow zero for self-signed CA
* certificates (root CAs) being loaded as trust anchors since they
* are explicitly trusted and some legacy root CAs in real-world
* trust stores have serial number 0. */
if ((ret == 0) && (cert->serialSz == 1) && (cert->serial[0] == 0)) {
if (!((type == CA_TYPE || type == TRUSTED_PEER_TYPE) &&
cert->isCA && cert->selfSigned)
#ifdef WOLFSSL_CERT_REQ
&& !cert->isCSR
#endif
) {
WOLFSSL_MSG("Error serial number of 0 for non-root certificate");
return ASN_PARSE_E;
}
}
#endif
#ifndef ALLOW_INVALID_CERTSIGN
/* https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.1.9
* If the cA boolean is not asserted, then the keyCertSign bit in the