Skip to content

Asn1parse#253

Open
aidankeefe2022 wants to merge 1 commit into
wolfSSL:mainfrom
aidankeefe2022:ans1-parser
Open

Asn1parse#253
aidankeefe2022 wants to merge 1 commit into
wolfSSL:mainfrom
aidankeefe2022:ans1-parser

Conversation

@aidankeefe2022

@aidankeefe2022 aidankeefe2022 commented Jun 17, 2026

Copy link
Copy Markdown
Member

This is based on the asn1.c in the wolfSSL examples. But with the added new strparse feature which allows for the re-parsing of BIT STRINGS and OCTET STRINGS. And the ability for the user to load a custom OID database. Both of these are feature ideas from OpenSSL

The flags and behavior are meant to mimic OpenSSL to allow for users to be comfortable with the tool. Not all of the asn1parse capability is included however.

A man page has been created along with tests for this tool.

A new flag was introduced that enables the build in OID table this is because the table make the binary pretty large. We could remove the table or make it always on if the configure flag is overkill.

The diff says +7000 something but minus the OID table it is about 2000 new lines. The table was taken from asn1.c example code.

If wolfSSL is 5.9.2 or less the -oid feature will not work due to API break

@aidankeefe2022

Copy link
Copy Markdown
Member Author

Tests will fail until wolfssl get this PR merged

@wolfSSL-Fenrir-bot wolfSSL-Fenrir-bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Fenrir Automated Review — PR #253

Scan targets checked: wolfclu-bugs, wolfclu-src

Findings: 2
2 finding(s) posted as inline comments (see file-level comments below)

This review was generated automatically by Fenrir. Findings are non-blocking.

Comment thread wolfclu/asn1/clu_asn1.h Outdated
Comment thread src/asn1/clu_asn1_fmt.c Outdated
Comment thread src/asn1/clu_asn1_fmt.c Outdated
Comment thread wolfclu/asn1/clu_asn1.h Outdated

@wolfSSL-Fenrir-bot wolfSSL-Fenrir-bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Fenrir Automated Review — PR #253

Scan targets checked: wolfclu-bugs, wolfclu-src

No new issues found in the changed files. ✅

Comment thread wolfclu/asn1/clu_oid_name_table.h
Comment thread src/asn1/clu_asn1_parse.c
if (ret == WOLFCLU_SUCCESS) {
/* oid is overwritten by and replaces with DER encoding */
XMEMSET(oid, '\0', *oidSz);
if ((err = wc_EncodeObjectId(arc, idx, (byte*)oid, oidSz)) != 0) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Claude has some thoughts on an extra check in this function:

The -oid file format is per line; if the OID field contains only a single number with no dots (e.g. the line 5 myName My Long Name), OidToDer allocates the arc array with one element per character of the OID string — here just 1 — and calls wc_EncodeObjectId(arc, 1, ...). wolfSSL's EncodeObjectId only rejects inSz <= 0 and always computes the first byte as in[0]*40 + in[1], so with inSz == 1 it reads arc[1], one element past the end of the heap allocation. Please reject OIDs with fewer than 2 components before calling wc_EncodeObjectId.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I made a PR to wolfSSL that adds this check to wc_EncodeObjectId. Should we have checks in both spots for backwards compatibility?

@aidankeefe2022 aidankeefe2022 Jul 2, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Just checked again and the wc_EncodeObjectId function is not compiled in unless it has the updated arg checking this is guarded by the NO_WC_ENCODE_OBJECT_ID macro that checks wolfSSL version

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is this still an issue? It looks like this could still happen from glancing at wc_EncodeObjectId().

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is this resolved?

Comment thread src/asn1/clu_asn1_parse.c Outdated
Comment thread src/asn1/clu_asn1_setup.c Outdated
Comment thread wolfCLU.vcxproj Outdated
Comment thread src/asn1/clu_asn1_setup.c
Comment thread src/asn1/clu_asn1_setup.c Outdated
Comment thread src/asn1/clu_asn1_setup.c Outdated
Comment thread src/asn1/clu_asn1_setup.c Outdated
Comment thread src/x509/clu_config.c Outdated
@cconlon cconlon assigned aidankeefe2022 and unassigned cconlon Jul 1, 2026
@aidankeefe2022
aidankeefe2022 force-pushed the ans1-parser branch 3 times, most recently from eb7fef0 to 9a1ccd0 Compare July 2, 2026 18:28

@wolfSSL-Fenrir-bot wolfSSL-Fenrir-bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Fenrir Automated Review — PR #253

Scan targets checked: wolfclu-bugs, wolfclu-src

Findings: 1
1 finding(s) posted as inline comments (see file-level comments below)

This review was generated automatically by Fenrir. Findings are non-blocking.

Comment thread src/asn1/clu_asn1_parse.c
Comment thread src/asn1/clu_asn1_parse.c
@aidankeefe2022

Copy link
Copy Markdown
Member Author

Jenkins retest this please

@aidankeefe2022
aidankeefe2022 force-pushed the ans1-parser branch 2 times, most recently from 4b15fc7 to 60b6f5a Compare July 2, 2026 21:59
Comment thread src/asn1/clu_asn1_parse.c
Comment thread src/asn1/clu_asn1_parse.c
Comment thread wolfclu/clu_header_main.h Outdated
Comment thread src/asn1/clu_asn1_parse.c
Comment thread src/asn1/clu_asn1_parse.c Outdated
}

/* Handle offsets, strparse, etc... */
if (ret == WOLFCLU_SUCCESS) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

this ret check not needed.

Comment thread src/asn1/clu_asn1_parse.c
WOLFCLU_OID_TO_NAME_free(&AdditionalOidNames);
return ret;
#else
#if !defined(WOLFSSL_ASN_PRINT)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why are these additional ifdefs inside an already failing else?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I still don't understand why these additional ifdef's are inside of this #else , which will only return FATAL_ERROR.

Comment thread src/asn1/clu_asn1_parse.c
return ret;
}

#endif

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Please comment this #endif's closing scope `#endif /* BLAH_BLAH */

Same with other #endif that are separated by many lines.

Also double blank line.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Please comment #endif if it's many lines from the opening #if blah blah.

Comment thread src/asn1/clu_asn1_setup.c
Comment thread src/asn1/clu_asn1_setup.c
Comment thread src/asn1/clu_asn1_setup.c Outdated
return WOLFCLU_SUCCESS;
}

static WOLFCLU_ASN1_PARSE_OPTIONS asn1Config = { 0 };

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Does this need to be a global?

with openssl.

added help to explain oid command

added comments to header file

resolved configure.ac merge conflict

added oid support to header includes

added man page for asn1parse and fixed more skoll

oid are properly handled

Made -out output DER of input after processing

Removed extra fmt file and put all in parse

custom oid now compiled out for 5.9.2

added header to include.am

fenrir fixes

moved oid table

added WOLFSSL_ASN_PRINT to windows build

skoll fixes
Comment thread src/asn1/clu_asn1_parse.c
WOLFCLU_OID_TO_NAME_free(&AdditionalOidNames);
return ret;
#else
#if !defined(WOLFSSL_ASN_PRINT)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I still don't understand why these additional ifdef's are inside of this #else , which will only return FATAL_ERROR.

Comment thread src/asn1/clu_asn1_parse.c
return ret;
}

#endif

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Please comment #endif if it's many lines from the opening #if blah blah.

Comment thread src/asn1/clu_asn1_parse.c

return ret;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

triple blank line.

Comment thread src/asn1/clu_asn1_parse.c
if (ret == WOLFCLU_SUCCESS) {
/* oid is overwritten by and replaces with DER encoding */
XMEMSET(oid, '\0', *oidSz);
if ((err = wc_EncodeObjectId(arc, idx, (byte*)oid, oidSz)) != 0) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is this resolved?

Comment thread src/asn1/clu_asn1_parse.c
}

/* Callback that wolfSSL uses to assign byte oids to names */
static WOLFCLU_OID_TO_NAME AdditionalOidNames = {0};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Does this need to be a global?

Comment thread src/asn1/clu_asn1_setup.c
else {
out[(*outSz)++] = val;
}
token = XSTRTOK(NULL, ",", &end);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Should this token = XSTRTOK(NULL, ",", &end); be only in the non-error else?

Or alternatively, shouldn't the error if's break?

Comment thread src/asn1/clu_asn1_parse.c

/* The decoded length must fit within the bytes remaining after the
* tag and length octets. */
if (len < 0 || (word32)len > asn1->max - asn1->curr) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

is len == 0 ok for some fields here?

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds an asn1parse subcommand to wolfCLU modeled after OpenSSL’s tool, including re-parsing of nested BIT STRING / OCTET STRING payloads (-strparse) and support for user-supplied OID name mappings (-oid), plus build-time optional inclusion of a large built-in OID table.

Changes:

  • Introduces asn1parse command wiring, option parsing, and ASN.1 decode/print pipeline (DER/PEM/B64, offset/length/strparse, dump/indent/noout).
  • Adds optional built-in OID name table via --enable-oid-table configure flag, along with manpage documentation.
  • Adds Python tests for the new tool (including config probing) and a parallel Python test runner.

Reviewed changes

Copilot reviewed 19 out of 22 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
wolfclu/include.am Installs new ASN.1 public header; adds OID table header to build.
wolfclu/clu_optargs.h Adds new mode/flags enums for asn1parse.
wolfclu/clu_header_main.h Version-gates NO_WC_ENCODE_OBJECT_ID; declares wolfCLU_StrToWord32.
wolfclu/asn1/clu_asn1.h Defines ASN.1 parse options struct and public entry points.
wolfCLU.vcxproj.filters Adds ASN.1 header to Visual Studio filters.
wolfCLU.vcxproj Adds ASN.1 sources/headers to Windows project build.
tests/wolfclu_test.py Adds helper to read generated wolfclu/config.h defines for feature-gated tests.
tests/run_tests_parallel.py New parallel test runner for Python test files.
tests/asn1/include.am Hooks ASN.1 test script into automake test distribution.
tests/asn1/asn1-test.py Adds functional tests for DER/PEM/B64, offset/length, strparse, OID mapping, and OID table.
src/x509/clu_config.c Refactors RID parsing to use wolfCLU_StrToWord32 and supports 32-bit arcs.
src/tools/clu_funcs.c Adds asn1parse to help output; implements wolfCLU_StrToWord32.
src/include.am Adds ASN.1 sources to automake build.
src/clu_main.c Adds asn1parse mode and dispatch to wolfCLU_Asn1Setup.
src/asn1/clu_asn1_setup.c New CLI option parsing / validation for asn1parse.
src/asn1/clu_asn1_parse.c New core ASN.1 parsing/printing, PEM finding, base64 handling, OID callback support.
manpages/wolfssl-asn1parse.1 New man page for wolfssl asn1parse.
Makefile.am Installs the new man page; includes ASN.1 tests.
ide/winvs/user_settings.h Enables WOLFSSL_ASN_PRINT for the Windows VS settings.
configure.ac Adds --enable-oid-table and version gating for NO_WC_ENCODE_OBJECT_ID.
.gitignore Updates ignored config template path.
Comments suppressed due to low confidence (2)

src/asn1/clu_asn1_parse.c:288

  • FindPem() confirms the PEM header by running XSTRNCMP(data+i, "-----", 5) without checking that i+5 is within bounds. This can read out of bounds when i is near len; guard the compare with a remaining-length check.
        for (; i < len; i++) {
            if ((data[i] == '-') &&
                    (XSTRNCMP((char*)data + i, "-----", 5) == 0)) {
                break;

src/asn1/clu_asn1_parse.c:303

  • FindPem() searches for the PEM footer using XSTRNCMP(data+j, "-----END", 8) without checking that j+8 is within bounds. Add a bounds check so the scan can't read past the end of the buffer.
        for (j = i + 1; j < len; j++) {
            if ((data[j] == '-') &&
                    (XSTRNCMP((char*)data + j, "-----END", 8) == 0)) {
                break;

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/asn1/clu_asn1_parse.c
Comment on lines +272 to +273
if ((data[i] == '-') &&
(XSTRNCMP((char*)data + i, "-----BEGIN", 10) == 0)) {
Comment thread src/asn1/clu_asn1_setup.c
XFCLOSE(opt->outputFile);
}

*opt = (WOLFCLU_ASN1_PARSE_OPTIONS){ 0 };
Comment thread src/asn1/clu_asn1_parse.c
Comment on lines +392 to +401
int ret = WOLFCLU_SUCCESS;
int err;
int idx = 0;
char* token;
char* end;
word32* arc = (word32*)XMALLOC(sizeof(*arc) * *oidSz,
HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
if (arc == NULL) {
return MEMORY_E;
}
Comment thread tests/asn1/asn1-test.py
"""True when the build can DER-encode the OIDs from an -oid file.

-oid relies on wc_EncodeObjectId, which is compiled out via
NO_WC_ENCODE_OBJECT_ID for libwolfssl <= 5.9.1 (set in configure.ac).
Comment thread tests/asn1/include.am
@@ -0,0 +1,6 @@
# vim:ft=automake
# included from top level Makefile.am
# ALl path should be given relative to root directory
@philljj philljj assigned aidankeefe2022 and unassigned philljj Jul 24, 2026
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.

6 participants