Topic: How to parse Alt Names with wolfSSL

Hi,

I'm trying validate whether a certificate is valid for a requested domain.  I've introduced a MatchRfc2818() function and currently call it against the hostname only.

However, I also need to check the domain against the Certificate's Alt Names, but I cannot seem to find support in wolfssl for doing this.

Specifically, I need something along the lines of

names = (GENERAL_NAMES *)X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
int num = sk_GENERAL_NAME_num(names);

for (i = 0; i < num; i++) {
    const GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
    if (name->type == GEN_DNS) {
        ASN1_STRING_to_UTF8((unsigned char**)&buf, name->d.ia5);
        if (match(buf, pc->hostName)
            // VALID
        else
            // INVALID

I've found a way to get obtain the Alt Names, but I'm not sure if it's the recommended way

int derSz = 0;
const byte* derCert = CyaSSL_X509_get_der(peer, &derSz);

if (derCert == NULL || derSz <= 0) {
    XERR("Unable to get peer's DER cert");
    return;
}

Cert cert = { };
if (SetAltNamesBuffer(&cert, derCert, derSz) < 0) {
    XERR("Unable to get Alt Names");
    return;
}

The Alt Names are now stored in cert.altNames, but how can I iterate over them and decode them using wolfSSL?

In other words, what's the YaSSL equivalent of OpenSSL's sk_GENERAL_NAME_num, sk_GENERAL_NAME_value and ASN1_STRING_to_UTF8?

I've looked through the source code for examples, but have not found anything.

Cheers.
*Joe

Joseph Spadavecchia
joseph@redtrie.com

Share

Re: How to parse Alt Names with wolfSSL

You are correct, wolfSSL doesn't currently have the equivalent Alt Names processing except to get the raw names.  It is on our feature list.

Share

Re: How to parse Alt Names with wolfSSL

Hi Todd,

I needed this functionality urgently for an embedded ssl project, so I've implemented my own Alt Name parsing.  It decodes the X509 certificate Alt Names from the ASN.1 DER buffer provided by wolfSSL's SetAltNamesBuffer() function.

I've created a

struct asn1Object

and a couple of simple functions

asn1BufDecode()

and

asn1SeqPop()

After that, the tricky part was following RFC 3280 and ITU-T Rec. X.680-0207 I ISO/IEC 8824-1 to figure how the Alt Names are encoded.

In the end, the code is pretty simple.

    /* X509 Alt Name parsing by Joseph Spadavecchia <joseph@redtrie.com> */

    asn1Object seq;
    asn1Object obj;

    if (!asn1BufDecode(test, sizeof(test), &seq)) {
        fprintf(stderr, "Alt Names error (failed to decode altNames buffer)\n");
        return 1;
    }

    if (seq.tag != ASN1_TAG_SEQUENCE) {
        fprintf(stderr, "Alt Names error (missing sequence)\n");
        return 1;
    }

    if (!asn1SeqPop(&seq, &obj)) {
        fprintf(stderr, "Alt Names error (failed to pop object identifier)\n");
        return 1;
    }

    if (!asn1ObjEquals(&obj, &X509_ALTNAMES_OBJID)) {
        fprintf(stderr, "Alt Names error (missing object identifier)\n");
        return 1;
    }

    if (!asn1SeqPop(&seq, &obj)) {
        fprintf(stderr, "Alt Names error (failed to pop octet string)\n");
        return 1;
    }

    if (obj.tag != ASN1_TAG_OCTETSTR) {
        fprintf(stderr, "Alt Names error (missing octet string)\n");
        return 1;
    }

    if (!asn1BufDecode(obj.value, obj.len, &seq)) {
        fprintf(stderr, "Alt Names error (unable to decode Alt Names sequence)\n");
        return 1;
    }

    while (asn1SeqPop(&seq, &obj)) {
        if (obj.tag == X509_ALTNAMES_TAG_DNS) {
            char *altName = strndup((char *)obj.value, obj.len);
            fprintf(stderr, "Got DNS Alt Name '%s'\n", altName);
            free(altName);
        }
    }

Please find the attached copy of the source code (asn1-altnames.tar.gz) for inclusion into wolfSSL, if it could be of use to you.

Kind regards,
*Joe

Post's attachments

asn1-altnames.tar.gz 80.52 kb, 3 downloads since 2012-07-31 

You don't have the permssions to download the attachments of this post.
Joseph Spadavecchia
joseph@redtrie.com

Share

Re: How to parse Alt Names with wolfSSL

Thanks Joe!

We've added the feature but in the current wolfSSL ASN framework.  It's now available on github.

Share