From d4b1995a2c58bc9cb7ab1e57f34a96de01b24e85 Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Fri, 22 Mar 2024 08:51:17 +1000 Subject: [PATCH] ASN.1 testing: add tests of bad DER encodings Certificates with bad DER encoded ASN.1 added to testing. Fix comment in asn.c. --- certs/test/cert-bad-neg-int.der | Bin 0 -> 956 bytes certs/test/cert-bad-oid.der | Bin 0 -> 956 bytes certs/test/cert-bad-utf8.der | Bin 0 -> 987 bytes certs/test/include.am | 5 +- wolfcrypt/src/asn.c | 4 +- wolfcrypt/test/test.c | 84 ++++++++++++++++++++++++++++++-- 6 files changed, 86 insertions(+), 7 deletions(-) create mode 100644 certs/test/cert-bad-neg-int.der create mode 100644 certs/test/cert-bad-oid.der create mode 100644 certs/test/cert-bad-utf8.der diff --git a/certs/test/cert-bad-neg-int.der b/certs/test/cert-bad-neg-int.der new file mode 100644 index 0000000000000000000000000000000000000000..8e5fc4647bd1475af71d560ab1292113f88e8bed GIT binary patch literal 956 zcmXqLV%}lU#H_f0nTe5!iSz%8_zNo(0#=zB@Un4gwRyCC=VfGMVP!CAoMp&uz{$oO z%EBhhv!hFH`If==s z3c;1dC8@c^h9U++APH_^ZpVUxoXq6JlFa-(LmmSzkSMb-bE1)jp|*i0+yR`7Vlp|I ziFxUI$r-764#i;8iYvi}=_Tjq8pw(B8X6gx85tOw8d?~bM~U+qfw+cH?%;NO<9y_> zW@KexZtP_+XzXNaY-IS}DwmtvbW>yr>t^$BS6Mf1HkxTSDiyD+EZLUB05)ZA9K{vTX^^78i%dERUIe)Mr} z{okeETATU4pE;*@a&5NxI(DC#pN_Y4RQ+7evB1(jZF9v3?#fS(wpvb#SPr4H=36*n-%~7tW`A( literal 0 HcmV?d00001 diff --git a/certs/test/cert-bad-oid.der b/certs/test/cert-bad-oid.der new file mode 100644 index 0000000000000000000000000000000000000000..cda316511f97897742ec91de4c69c0b62258c6c2 GIT binary patch literal 956 zcmXqLV%}lU#H_f0nTe5!iIZVP{Dlb7P&)UOIKu=BnuJfGOV;H(8`@`Z#lHtmO|? z?TztgELg;@*)2a4WK-9({j_fEw#IL7rD8T;=`l@wHnnZ$&&0x4-Q{sReET#`7Bew3 zGB7S~Vq`LC{BI!3#vCfk$0Eie!gThFReRH!NH)$IKK8Pj&wM_WHw+rjgXEQ28jl+^ z9%;a;W?|!kC5>}w5gk-ZOHD{wfCuCuVHQ>cW=6*U$dSYXiljz{qjDzQhc-XVe#zl# z`DaR%Rd3sE+l4tL7mC9frXJ6d7h^W^+t{>wyUFrQ`+KeTd%uY?^8euSlb64D$n##q z_oI(<>;EqO*4oVX{mePNlWVih*RlJ|{B*pXqw42!js=$PX`3rPa94hMwAIq`BI7Nw XC2h^d9!=geFK*yYz0tgk*|Y!vO&2uw literal 0 HcmV?d00001 diff --git a/certs/test/cert-bad-utf8.der b/certs/test/cert-bad-utf8.der new file mode 100644 index 0000000000000000000000000000000000000000..54e0889109e9c2f81cc1d081f484d5f10028b695 GIT binary patch literal 987 zcmXqLV!m$B#I%0_GZP~d6DPwdhsl+)MMb9!c-c6$+C196^D;7WvoaVoHW+dnaI!In zvaks=IXfB(81R8O96ap)c_oQOnfZqN2D~5`dbHu-ua)dbxb>K z>Ta>zZvI0xv4S&Kze$Ny=TAPRe!6MBTZW=*f& z$3NAVmohOkGB7RwWn&JNI zB4HrbfL#G7@yH6Zuo^HkGX6&nb8c{$GcxqXap&u6l9SYhDJmjdxz?%V!ey|*PUCTrmwwS*RrH-F=&T~TFw@@j2M-IL5M%JN$Q?yX|b literal 0 HcmV?d00001 diff --git a/certs/test/include.am b/certs/test/include.am index 8f123f35f..ed03557ab 100644 --- a/certs/test/include.am +++ b/certs/test/include.am @@ -29,7 +29,10 @@ EXTRA_DIST += \ certs/test/cert-ext-joi.cfg \ certs/test/cert-ext-multiple.cfg \ certs/test/cert-ext-multiple.der \ - certs/test/cert-ext-multiple.pem + certs/test/cert-ext-multiple.pem \ + certs/test/cert-bad-neg-int.der \ + certs/test/cert-bad-oid.der \ + certs/test/cert-bad-utf8.der # The certs/server-cert with the last byte (signature byte) changed EXTRA_DIST += \ diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index ac5099587..9377297e9 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -1209,8 +1209,8 @@ static int GetASN_ObjectId(const byte* input, word32 idx, int length) #endif ret = ASN_PARSE_E; } - /* Last octet of a subidentifier has bit 8 clear. Last octet must be last - * of a subidentifier. Ensure last octet hasn't got top bit set indicating. + /* Last octet of a sub-identifier has bit 8 clear. Last octet must be last + * of a subidentifier. Ensure last octet hasn't got top bit set. */ else if ((input[(int)idx + length - 1] & 0x80) != 0x00) { WOLFSSL_MSG("OID last octet has top bit set"); diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index feab257fb..316039bee 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -1871,9 +1871,9 @@ options: [-s max_relative_stack_bytes] [-m max_relative_heap_memory_bytes]\n\ #if !defined(NO_ASN) && !defined(NO_ASN_TIME) if ( (ret = time_test()) != 0) - TEST_FAIL("time test failed!\n", ret); + TEST_FAIL("time test failed!\n", ret); else - TEST_PASS("time test passed!\n"); + TEST_PASS("time test passed!\n"); #endif #if defined(__INCLUDE_NUTTX_CONFIG_H) @@ -2438,8 +2438,10 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t asn_test(void) { wc_test_ret_t ret; /* ASN1 encoded date buffer */ - WOLFSSL_SMALL_STACK_STATIC const byte dateBuf[] = {0x17, 0x0d, 0x31, 0x36, 0x30, 0x38, 0x31, 0x31, - 0x32, 0x30, 0x30, 0x37, 0x33, 0x37, 0x5a}; + WOLFSSL_SMALL_STACK_STATIC const byte dateBuf[] = { + 0x17, 0x0d, 0x31, 0x36, 0x30, 0x38, 0x31, 0x31, + 0x32, 0x30, 0x30, 0x37, 0x33, 0x37, 0x5a + }; byte format; int length; const byte* datePart; @@ -16220,6 +16222,16 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t memory_test(void) CERT_ROOT "test" CERT_PATH_SEP "cert-ext-ia.der"; static const char* certExtNct = CERT_ROOT "test" CERT_PATH_SEP "cert-ext-nct.der"; +#ifndef WOLFSSL_ASN_INT_LEAD_0_ANY + static const char* certBadNegInt = + CERT_ROOT "test" CERT_PATH_SEP "cert-bad-neg-int.der"; +#endif + static const char* certBadOid = + CERT_ROOT "test" CERT_PATH_SEP "cert-bad-oid.der"; +#ifndef WOLFSSL_NO_ASN_STRICT + static const char* certBadUtf8 = + CERT_ROOT "test" CERT_PATH_SEP "cert-bad-utf8.der"; +#endif #endif #ifndef NO_WRITE_TEMP_FILES @@ -16469,6 +16481,68 @@ done: return ret; } +static wc_test_ret_t cert_load_bad(const char* fname, byte* tmp, int err) +{ + wc_test_ret_t ret; + DecodedCert cert; + XFILE file; + size_t bytes; + + file = XFOPEN(fname, "rb"); + if (!file) { + ERROR_OUT(WC_TEST_RET_ENC_ERRNO, done); + } + bytes = XFREAD(tmp, 1, FOURK_BUF, file); + XFCLOSE(file); + if (bytes == 0) { + ERROR_OUT(WC_TEST_RET_ENC_ERRNO, done); + } + InitDecodedCert(&cert, tmp, (word32)bytes, 0); + ret = ParseCert(&cert, CERT_TYPE, NO_VERIFY, NULL); + FreeDecodedCert(&cert); + if (ret != err) { + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done); + } + ret = 0; + +done: + return ret; +} + +static wc_test_ret_t cert_bad_asn1_test(void) +{ + wc_test_ret_t ret = 0; + byte* tmp; + + tmp = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + if (tmp == NULL) { + ret = WC_TEST_RET_ENC_ERRNO; + } + +#ifndef WOLFSSL_ASN_INT_LEAD_0_ANY + if (ret == 0) { + /* Serial number: 0xff 0xa8. 0xff and top bit set on next byte invalid. + */ + ret = cert_load_bad(certBadNegInt, tmp, ASN_EXPECT_0_E); + } +#endif + if (ret == 0) { + /* Subject name OID: 55 04 f4. Last byte with top bit set invalid. */ + ret = cert_load_bad(certBadOid, tmp, ASN_PARSE_E); + } +#ifndef WOLFSSL_NO_ASN_STRICT + if (ret == 0) { + /* Issuer name UTF8STRING: df 52 4e 44. Top bit of second byte not set. + */ + ret = cert_load_bad(certBadUtf8, tmp, ASN_PARSE_E); + } +#endif + + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + + return ret; +} + WOLFSSL_TEST_SUBROUTINE wc_test_ret_t cert_test(void) { #if !defined(NO_FILESYSTEM) @@ -16542,6 +16616,8 @@ done: if (ret == 0) ret = cert_asn1_test(); + if (ret == 0) + ret = cert_bad_asn1_test(); return ret; }