Skip to content

Commit 0d4c9a6

Browse files
Add support for id-on-bundleEID from RFC 9174.
Fixes #10694.
1 parent 18c9684 commit 0d4c9a6

9 files changed

Lines changed: 132 additions & 0 deletions

File tree

.wolfssl_known_macro_extras

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -757,6 +757,7 @@ WOLFSSL_DTLS_DISALLOW_FUTURE
757757
WOLFSSL_DTLS_NO_HVR_ON_RESUME
758758
WOLFSSL_DTLS_RECORDS_CAN_SPAN_DATAGRAMS
759759
WOLFSSL_DTLS_RESEND_ONLY_TIMEOUT
760+
WOLFSSL_DTN
760761
WOLFSSL_DUMP_MEMIO_STREAM
761762
WOLFSSL_DUP_CERTPOL
762763
WOLFSSL_EARLY_DATA_NO_ANTI_REPLAY

certs/bundle-eid-cert.der

690 Bytes
Binary file not shown.

certs/renewcerts.sh

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
# fpki-cert.der
3636
# fpki-certpol-cert.der
3737
# rid-cert.der
38+
# bundle-eid-cert.der
3839
# aia/ca-issuers-cert.pem
3940
# aia/multi-aia-cert.pem
4041
# aia/overflow-aia-cert.pem
@@ -490,6 +491,24 @@ run_renewcerts(){
490491
echo "End of section"
491492
echo "---------------------------------------------------------------------"
492493
###########################################################
494+
########## update and sign bundle-eid-cert.der ############
495+
###########################################################
496+
# RFC 9174 (Bundle Protocol / DTN) leaf cert whose SAN carries an
497+
# id-on-bundleEID OtherName (OID 1.3.6.1.5.5.7.8.11) with an IA5String
498+
# value, plus a dNSName. ECC leaf signed by the ECC CA. Exercised by the
499+
# WOLFSSL_DTN regression test (test_DecodeOtherName_bundleEID).
500+
echo "Updating bundle-eid-cert.der"
501+
echo ""
502+
#pipe the following arguments to openssl req...
503+
echo -e "US\\nMontana\\nBozeman\\nwolfSSL\\nDTN\\nwww.wolfssl.com\\ninfo@wolfssl.com\\n.\\n.\\n" | openssl req -new -key ecc-key.pem -config ./wolfssl.cnf -nodes > bundle-eid-req.pem
504+
check_result $? "Step 1"
505+
506+
openssl x509 -req -in bundle-eid-req.pem -extfile wolfssl.cnf -extensions bundle_eid_ext -days 1000 -CA ca-ecc-cert.pem -CAkey ca-ecc-key.pem -set_serial 16 -out bundle-eid-cert.der -outform DER
507+
check_result $? "Step 2"
508+
rm bundle-eid-req.pem
509+
echo "End of section"
510+
echo "---------------------------------------------------------------------"
511+
###########################################################
493512
########## update and sign server-cert.pem ################
494513
###########################################################
495514
echo "Updating server-cert.pem"

certs/renewcerts/wolfssl.cnf

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -452,3 +452,16 @@ DNS.1 = www.example.org
452452
URI.1 = https://www.wolfssl.com/
453453
otherName.2 = 2.16.840.1.101.3.6.6;FORMAT:HEX,OCT:D1:38:10:D8:28:AF:2C:10:84:35:15:A1:68:58:28:AF:02:10:86:A2:84:E7:39:C3:EB
454454

455+
# RFC 9174 (Bundle Protocol / DTN) id-on-bundleEID OtherName with an
456+
# IA5String value, followed by a dNSName. Used by the WOLFSSL_DTN test.
457+
[bundle_eid_ext]
458+
basicConstraints = critical, CA:FALSE
459+
subjectKeyIdentifier = hash
460+
authorityKeyIdentifier = keyid
461+
keyUsage = critical, digitalSignature
462+
subjectAltName = @bundle_eid_altname
463+
464+
[bundle_eid_altname]
465+
otherName.1 = 1.3.6.1.5.5.7.8.11;IA5STRING:dtn://node000/
466+
DNS.1 = node000.local
467+

scripts/asn1_oid_sum.pl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -912,6 +912,12 @@ sub print_footer {
912912
{ name => "HW_NAME", oid => \@sep_hw_name },
913913
);
914914

915+
# NOTE: SepHardwareName_Sum also carries BUNDLE_EID_OID (1.3.6.1.5.5.7.8.11,
916+
# id-on-bundleEID, RFC 9174). It is maintained directly in oid_sum.h behind
917+
# "#ifdef WOLFSSL_DTN" rather than emitted here, since this generator has no
918+
# per-entry feature-guard support (same approach as ACME_IDENTIFIER_OID).
919+
# old sum = 86, new sum = 0x0e09012e.
920+
915921
print_sum_enum("SepHardwareName", "_OID", \@seps);
916922

917923

tests/api/test_asn.c

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1495,6 +1495,66 @@ int test_DecodeAltNames_length_underflow(void)
14951495
return EXPECT_RESULT();
14961496
}
14971497

1498+
/* Regression test for id-on-bundleEID (RFC 9174) OtherName decoding.
1499+
*
1500+
* A SAN OtherName with OID 1.3.6.1.5.5.7.8.11 whose value is an IA5String must
1501+
* be decoded - not rejected with ASN_PARSE_E - when WOLFSSL_DTN is enabled.
1502+
* Reproduces the GitHub report "X509 decoder fails to handle OtherName with
1503+
* value of an IA5String".
1504+
*
1505+
* The certificate is generated by certs/renewcerts.sh (bundle-eid-cert.der):
1506+
* an ECDSA P-256 leaf whose SAN holds an id-on-bundleEID OtherName carrying
1507+
* the IA5String "dtn://node000/", followed by a dNSName "node000.local". */
1508+
int test_DecodeOtherName_bundleEID(void)
1509+
{
1510+
EXPECT_DECLS;
1511+
#if defined(WOLFSSL_DTN) && \
1512+
(defined(WOLFSSL_SEP) || defined(WOLFSSL_FPKI)) && \
1513+
defined(HAVE_ECC) && !defined(NO_CERTS) && !defined(NO_ASN) && \
1514+
!defined(NO_FILESYSTEM)
1515+
const char* bundleEidCert = "./certs/bundle-eid-cert.der";
1516+
XFILE f = XBADFILE;
1517+
byte buf[2048];
1518+
int bytes = 0;
1519+
DecodedCert cert;
1520+
DNS_entry* dns = NULL;
1521+
int foundBundleEid = 0;
1522+
int foundDns = 0;
1523+
1524+
ExpectTrue((f = XFOPEN(bundleEidCert, "rb")) != XBADFILE);
1525+
ExpectIntGT(bytes = (int)XFREAD(buf, 1, sizeof(buf), f), 0);
1526+
if (f != XBADFILE)
1527+
XFCLOSE(f);
1528+
1529+
wc_InitDecodedCert(&cert, buf, (word32)bytes, NULL);
1530+
/* Before the fix this failed with ASN_PARSE_E because the OtherName value
1531+
* (an IA5String) did not match any of the supported value types. */
1532+
ExpectIntEQ(wc_ParseCert(&cert, CERT_TYPE, NO_VERIFY, NULL), 0);
1533+
1534+
for (dns = cert.altNames; dns != NULL; dns = dns->next) {
1535+
if ((dns->type == ASN_OTHER_TYPE) && (dns->len == 14) &&
1536+
(XMEMCMP(dns->name, "dtn://node000/", 14) == 0)) {
1537+
foundBundleEid = 1;
1538+
#ifdef WOLFSSL_FPKI
1539+
ExpectIntEQ(dns->oidSum, BUNDLE_EID_OID);
1540+
#endif
1541+
}
1542+
if ((dns->type == ASN_DNS_TYPE) && (dns->len == 13) &&
1543+
(XMEMCMP(dns->name, "node000.local", 13) == 0)) {
1544+
foundDns = 1;
1545+
}
1546+
}
1547+
/* The bundleEID IA5String value must be decoded into an OtherName entry,
1548+
* and the trailing dNSName must still be parsed. */
1549+
ExpectIntEQ(foundBundleEid, 1);
1550+
ExpectIntEQ(foundDns, 1);
1551+
1552+
wc_FreeDecodedCert(&cert);
1553+
#endif /* WOLFSSL_DTN && (WOLFSSL_SEP || WOLFSSL_FPKI) && HAVE_ECC &&
1554+
* !NO_CERTS && !NO_ASN && !NO_FILESYSTEM */
1555+
return EXPECT_RESULT();
1556+
}
1557+
14981558
/* A certificate must not carry two certificatePolicies extensions
14991559
* (non-repeatable per RFC 5280 4.2). DecodeCertExtensions calls
15001560
* DecodeExtensionType once per extension; with strict ASN.1 (the default) a

tests/api/test_asn.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ int test_wolfssl_local_MatchUriNameConstraint(void);
3535
int test_wc_DecodeRsaPssParams(void);
3636
int test_SerialNumber0_RootCA(void);
3737
int test_DecodeAltNames_length_underflow(void);
38+
int test_DecodeOtherName_bundleEID(void);
3839
int test_DecodeCertExtensions_dup_certpol(void);
3940
int test_ParseCert_SM3wSM2_short_pubkey(void);
4041
int test_wc_DecodeObjectId(void);
@@ -55,6 +56,7 @@ int test_ToTraditional_ex_mldsa_bad_params(void);
5556
TEST_DECL_GROUP("asn", test_wc_DecodeRsaPssParams), \
5657
TEST_DECL_GROUP("asn", test_SerialNumber0_RootCA), \
5758
TEST_DECL_GROUP("asn", test_DecodeAltNames_length_underflow), \
59+
TEST_DECL_GROUP("asn", test_DecodeOtherName_bundleEID), \
5860
TEST_DECL_GROUP("asn", test_DecodeCertExtensions_dup_certpol), \
5961
TEST_DECL_GROUP("asn", test_ParseCert_SM3wSM2_short_pubkey), \
6062
TEST_DECL_GROUP("asn", test_wc_DecodeObjectId), \

wolfcrypt/src/asn.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18724,12 +18724,20 @@ static int ConfirmNameConstraints(Signer* signer, DecodedCert* cert)
1872418724
* (RFC3280 sec 4.2.1.7). Often used with FIPS 201 smartcard login.
1872518725
* FASC-N (Federal Agency Smart Credential Number), defined in the document
1872618726
* fpki-x509-cert-policy-common.pdf. Used for a smart card ID.
18727+
*
18728+
* id-on-bundleEID (RFC 9174, sec 4.4.1), an Other Name whose value is an
18729+
* IA5String holding a Bundle Protocol node/endpoint ID (e.g. "dtn://node/").
18730+
* Only handled when WOLFSSL_DTN is defined as these OIDs are specific to
18731+
* Delay-Tolerant Networking (DTN) / the Bundle Protocol.
1872718732
*/
1872818733
static const ASNItem otherNameASN[] = {
1872918734
/* TYPEID */ { 0, ASN_OBJECT_ID, 0, 0, 0 },
1873018735
/* VALUE */ { 0, ASN_CONTEXT_SPECIFIC | ASN_OTHERNAME_VALUE, 1, 1, 0 },
1873118736
/* UPN */ { 1, ASN_UTF8STRING, 0, 0, 2 },
1873218737
/* FASC-N */ { 1, ASN_OCTET_STRING, 0, 0, 2 },
18738+
#ifdef WOLFSSL_DTN
18739+
/* BEID */ { 1, ASN_IA5_STRING, 0, 0, 2 },
18740+
#endif
1873318741
/* HWN_SEQ */ { 1, ASN_SEQUENCE, 1, 0, 2 },
1873418742
/* HWN_TYPE */ { 2, ASN_OBJECT_ID, 0, 0, 0 },
1873518743
/* HWN_NUM */ { 2, ASN_OCTET_STRING, 0, 0, 0 }
@@ -18739,6 +18747,9 @@ enum {
1873918747
OTHERNAMEASN_IDX_VALUE,
1874018748
OTHERNAMEASN_IDX_UPN,
1874118749
OTHERNAMEASN_IDX_FASCN,
18750+
#ifdef WOLFSSL_DTN
18751+
OTHERNAMEASN_IDX_BEID,
18752+
#endif
1874218753
OTHERNAMEASN_IDX_HWN_SEQ,
1874318754
OTHERNAMEASN_IDX_HWN_TYPE,
1874418755
OTHERNAMEASN_IDX_HWN_NUM
@@ -18806,6 +18817,13 @@ static int DecodeOtherHelper(ASNGetData* dataASN, DecodedCert* cert, int oid)
1880618817
bufLen = dataASN[OTHERNAMEASN_IDX_UPN].data.ref.length;
1880718818
buf = (const char*)dataASN[OTHERNAMEASN_IDX_UPN].data.ref.data;
1880818819
break;
18820+
#ifdef WOLFSSL_DTN
18821+
case BUNDLE_EID_OID:
18822+
/* id-on-bundleEID (RFC 9174) carries an IA5String value. */
18823+
bufLen = dataASN[OTHERNAMEASN_IDX_BEID].data.ref.length;
18824+
buf = (const char*)dataASN[OTHERNAMEASN_IDX_BEID].data.ref.data;
18825+
break;
18826+
#endif /* WOLFSSL_DTN */
1880918827
default:
1881018828
WOLFSSL_ERROR_VERBOSE(ASN_UNKNOWN_OID_E);
1881118829
ret = ASN_UNKNOWN_OID_E;
@@ -18869,6 +18887,9 @@ static int DecodeOtherName(DecodedCert* cert, const byte* input,
1886918887
#ifdef WOLFSSL_FPKI
1887018888
case FASCN_OID:
1887118889
#endif /* WOLFSSL_FPKI */
18890+
#ifdef WOLFSSL_DTN
18891+
case BUNDLE_EID_OID:
18892+
#endif /* WOLFSSL_DTN */
1887218893
case UPN_OID:
1887318894
ret = DecodeOtherHelper(dataASN, cert,
1887418895
(int)dataASN[OTHERNAMEASN_IDX_TYPEID].data.oid.sum);

wolfssl/wolfcrypt/oid_sum.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1250,9 +1250,19 @@ enum SepHardwareName_Sum {
12501250
#ifdef WOLFSSL_OLD_OID_SUM
12511251
/* 0x2b,0x06,0x01,0x05,0x05,0x07,0x08,0x04 */
12521252
HW_NAME_OID = 79 /* 1.3.6.1.5.5.7.8.4 */
1253+
#ifdef WOLFSSL_DTN
1254+
,
1255+
/* 0x2b,0x06,0x01,0x05,0x05,0x07,0x08,0x0b */
1256+
BUNDLE_EID_OID = 86 /* 1.3.6.1.5.5.7.8.11 */
1257+
#endif
12531258
#else
12541259
/* 0x2b,0x06,0x01,0x05,0x05,0x07,0x08,0x04 */
12551260
HW_NAME_OID = 0x0109012e /* 1.3.6.1.5.5.7.8.4 */
1261+
#ifdef WOLFSSL_DTN
1262+
,
1263+
/* 0x2b,0x06,0x01,0x05,0x05,0x07,0x08,0x0b */
1264+
BUNDLE_EID_OID = 0x0e09012e /* 1.3.6.1.5.5.7.8.11 */
1265+
#endif
12561266
#endif
12571267
};
12581268

0 commit comments

Comments
 (0)