int GetName(DecodedCert* cert, int nameType, int maxIdx)
{
    int    length;  /* length of all distinguished names */
    int    dummy;
    int    ret;
    char*  full;
    byte*  hash;
    word32 idx, localIdx = 0;
    byte   tag;
#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
            !defined(WOLFCRYPT_ONLY)
    WOLFSSL_X509_NAME* dName;
#endif /* OPENSSL_EXTRA */

    WOLFSSL_MSG("Getting Cert Name");

    if (nameType == ISSUER) {
        full = cert->issuer;
        hash = cert->issuerHash;
    }
    else {
        full = cert->subject;
        hash = cert->subjectHash;
    }

    if (cert->srcIdx >= (word32)maxIdx) {
        return BUFFER_E;
    }

    localIdx = cert->srcIdx;
    if (GetASNTag(cert->source, &localIdx, &tag, maxIdx) < 0) {
        return ASN_PARSE_E;
    }

    if (tag == ASN_OBJECT_ID) {
        WOLFSSL_MSG("Trying optional prefix...");

        if (SkipObjectId(cert->source, &cert->srcIdx, maxIdx) < 0)
            return ASN_PARSE_E;
        WOLFSSL_MSG("Got optional prefix");
    }

    /* For OCSP, RFC2560 section 4.1.1 states the issuer hash should be
     * calculated over the entire DER encoding of the Name field, including
     * the tag and length. */
    idx = cert->srcIdx;
    if (GetSequence(cert->source, &cert->srcIdx, &length, maxIdx) < 0)
        return ASN_PARSE_E;

    ret = CalcHashId(&cert->source[idx], length + cert->srcIdx - idx, hash);
    if (ret != 0)
        return ret;

    length += cert->srcIdx;
    idx = 0;

#if defined(HAVE_PKCS7) || defined(WOLFSSL_CERT_EXT)
    /* store pointer to raw issuer */
    if (nameType == ISSUER) {
        cert->issuerRaw = &cert->source[cert->srcIdx];
        cert->issuerRawLen = length - cert->srcIdx;
    }
#endif
#ifndef IGNORE_NAME_CONSTRAINTS
    if (nameType == SUBJECT) {
        cert->subjectRaw = &cert->source[cert->srcIdx];
        cert->subjectRawLen = length - cert->srcIdx;
    }
#endif
#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
    !defined(WOLFCRYPT_ONLY)
    dName = wolfSSL_X509_NAME_new();
    if (dName == NULL) {
        return MEMORY_E;
    }
#endif /* OPENSSL_EXTRA */

    while (cert->srcIdx < (word32)length) {
        byte        b       = 0;
        byte        joint[3];
        byte        tooBig  = FALSE;
        int         oidSz;
        const char* copy    = NULL;
        int         copyLen = 0;
        int         strLen  = 0;
        byte        id      = 0;
    #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) \
                && !defined(WOLFCRYPT_ONLY)
         int        nid = NID_undef;
         int        enc;
    #endif /* OPENSSL_EXTRA */

        if (GetSet(cert->source, &cert->srcIdx, &dummy, maxIdx) < 0) {
            WOLFSSL_MSG("Cert name lacks set header, trying sequence");
        }

        if (GetSequence(cert->source, &cert->srcIdx, &dummy, maxIdx) <= 0) {
        #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
            !defined(WOLFCRYPT_ONLY)
            wolfSSL_X509_NAME_free(dName);
        #endif /* OPENSSL_EXTRA */
            return ASN_PARSE_E;
        }

        ret = GetASNObjectId(cert->source, &cert->srcIdx, &oidSz, maxIdx);
        if (ret != 0) {
        #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
            !defined(WOLFCRYPT_ONLY)
            wolfSSL_X509_NAME_free(dName);
        #endif /* OPENSSL_EXTRA */
            return ret;
        }

        /* make sure there is room for joint */
        if ((cert->srcIdx + sizeof(joint)) > (word32)maxIdx) {
        #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
            !defined(WOLFCRYPT_ONLY)
            wolfSSL_X509_NAME_free(dName);
        #endif /* OPENSSL_EXTRA */
            return ASN_PARSE_E;
        }

        XMEMCPY(joint, &cert->source[cert->srcIdx], sizeof(joint));

        /* v1 name types */
        if (joint[0] == 0x55 && joint[1] == 0x04) {
            cert->srcIdx += 3;
            id = joint[2];
            if (GetHeader(cert->source, &b, &cert->srcIdx, &strLen,
                          maxIdx, 1) < 0) {
            #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
            !defined(WOLFCRYPT_ONLY)
                wolfSSL_X509_NAME_free(dName);
            #endif /* OPENSSL_EXTRA */
                return ASN_PARSE_E;
            }

            if (id == ASN_COMMON_NAME) {
                if (nameType == SUBJECT) {
                    cert->subjectCN = (char *)&cert->source[cert->srcIdx];
                    cert->subjectCNLen = strLen;
                    cert->subjectCNEnc = b;
                }

                copy = WOLFSSL_COMMON_NAME;
                copyLen = sizeof(WOLFSSL_COMMON_NAME) - 1;
            #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) \
                && !defined(WOLFCRYPT_ONLY)
                nid = NID_commonName;
            #endif /* OPENSSL_EXTRA */
            }
            else if (id == ASN_SUR_NAME) {
                copy = WOLFSSL_SUR_NAME;
                copyLen = sizeof(WOLFSSL_SUR_NAME) - 1;
                #ifdef WOLFSSL_CERT_GEN
                    if (nameType == SUBJECT) {
                        cert->subjectSN = (char*)&cert->source[cert->srcIdx];
                        cert->subjectSNLen = strLen;
                        cert->subjectSNEnc = b;
                    }
                #endif /* WOLFSSL_CERT_GEN */
                #if (defined(OPENSSL_EXTRA) || \
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
                        && !defined(WOLFCRYPT_ONLY)
                    nid = NID_surname;
                #endif /* OPENSSL_EXTRA */
            }
            else if (id == ASN_COUNTRY_NAME) {
                copy = WOLFSSL_COUNTRY_NAME;
                copyLen = sizeof(WOLFSSL_COUNTRY_NAME) - 1;
                #ifdef WOLFSSL_CERT_GEN
                    if (nameType == SUBJECT) {
                        cert->subjectC = (char*)&cert->source[cert->srcIdx];
                        cert->subjectCLen = strLen;
                        cert->subjectCEnc = b;
                    }
                #endif /* WOLFSSL_CERT_GEN */
                #if (defined(OPENSSL_EXTRA) || \
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
                        && !defined(WOLFCRYPT_ONLY)
                    nid = NID_countryName;
                #endif /* OPENSSL_EXTRA */
            }
            else if (id == ASN_LOCALITY_NAME) {
                copy = WOLFSSL_LOCALITY_NAME;
                copyLen = sizeof(WOLFSSL_LOCALITY_NAME) - 1;
                #ifdef WOLFSSL_CERT_GEN
                    if (nameType == SUBJECT) {
                        cert->subjectL = (char*)&cert->source[cert->srcIdx];
                        cert->subjectLLen = strLen;
                        cert->subjectLEnc = b;
                    }
                #endif /* WOLFSSL_CERT_GEN */
                #if (defined(OPENSSL_EXTRA) || \
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
                        && !defined(WOLFCRYPT_ONLY)
                    nid = NID_localityName;
                #endif /* OPENSSL_EXTRA */
            }
            else if (id == ASN_STATE_NAME) {
                copy = WOLFSSL_STATE_NAME;
                copyLen = sizeof(WOLFSSL_STATE_NAME) - 1;
                #ifdef WOLFSSL_CERT_GEN
                    if (nameType == SUBJECT) {
                        cert->subjectST = (char*)&cert->source[cert->srcIdx];
                        cert->subjectSTLen = strLen;
                        cert->subjectSTEnc = b;
                    }
                #endif /* WOLFSSL_CERT_GEN */
                #if (defined(OPENSSL_EXTRA) || \
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
                        && !defined(WOLFCRYPT_ONLY)
                    nid = NID_stateOrProvinceName;
                #endif /* OPENSSL_EXTRA */
            }
            else if (id == ASN_ORG_NAME) {
                copy = WOLFSSL_ORG_NAME;
                copyLen = sizeof(WOLFSSL_ORG_NAME) - 1;
                #ifdef WOLFSSL_CERT_GEN
                    if (nameType == SUBJECT) {
                        cert->subjectO = (char*)&cert->source[cert->srcIdx];
                        cert->subjectOLen = strLen;
                        cert->subjectOEnc = b;
                    }
                #endif /* WOLFSSL_CERT_GEN */
                #if (defined(OPENSSL_EXTRA) || \
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
                        && !defined(WOLFCRYPT_ONLY)
                    nid = NID_organizationName;
                #endif /* OPENSSL_EXTRA */
            }
            else if (id == ASN_ORGUNIT_NAME) {
                copy = WOLFSSL_ORGUNIT_NAME;
                copyLen = sizeof(WOLFSSL_ORGUNIT_NAME) - 1;
                #ifdef WOLFSSL_CERT_GEN
                    if (nameType == SUBJECT) {
                        cert->subjectOU = (char*)&cert->source[cert->srcIdx];
                        cert->subjectOULen = strLen;
                        cert->subjectOUEnc = b;
                    }
                #endif /* WOLFSSL_CERT_GEN */
                #if (defined(OPENSSL_EXTRA) || \
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
                        && !defined(WOLFCRYPT_ONLY)
                    nid = NID_organizationalUnitName;
                #endif /* OPENSSL_EXTRA */
            }
            else if (id == ASN_SERIAL_NUMBER) {
                copy = WOLFSSL_SERIAL_NUMBER;
                copyLen = sizeof(WOLFSSL_SERIAL_NUMBER) - 1;
                #ifdef WOLFSSL_CERT_GEN
                    if (nameType == SUBJECT) {
                        cert->subjectSND = (char*)&cert->source[cert->srcIdx];
                        cert->subjectSNDLen = strLen;
                        cert->subjectSNDEnc = b;
                    }
                #endif /* WOLFSSL_CERT_GEN */
                #if (defined(OPENSSL_EXTRA) || \
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
                        && !defined(WOLFCRYPT_ONLY)
                    nid = NID_serialNumber;
                #endif /* OPENSSL_EXTRA */
            }
        #ifdef WOLFSSL_CERT_EXT
            else if (id == ASN_BUS_CAT) {
                copy = WOLFSSL_BUS_CAT;
                copyLen = sizeof(WOLFSSL_BUS_CAT) - 1;
            #ifdef WOLFSSL_CERT_GEN
                if (nameType == SUBJECT) {
                    cert->subjectBC = (char*)&cert->source[cert->srcIdx];
                    cert->subjectBCLen = strLen;
                    cert->subjectBCEnc = b;
                }
            #endif /* WOLFSSL_CERT_GEN */
            #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) \
                        && !defined(WOLFCRYPT_ONLY)
                nid = NID_businessCategory;
            #endif /* OPENSSL_EXTRA */
            }
        #endif /* WOLFSSL_CERT_EXT */
        }
    #ifdef WOLFSSL_CERT_EXT
        else if ((cert->srcIdx + ASN_JOI_PREFIX_SZ + 2 <= (word32)maxIdx) &&
                 (0 == XMEMCMP(&cert->source[cert->srcIdx], ASN_JOI_PREFIX,
                               ASN_JOI_PREFIX_SZ)) &&
                 ((cert->source[cert->srcIdx+ASN_JOI_PREFIX_SZ] == ASN_JOI_C) ||
                  (cert->source[cert->srcIdx+ASN_JOI_PREFIX_SZ] == ASN_JOI_ST)))
        {
            cert->srcIdx += ASN_JOI_PREFIX_SZ;
            id = cert->source[cert->srcIdx++];
            b = cert->source[cert->srcIdx++]; /* encoding */

            if (GetLength(cert->source, &cert->srcIdx, &strLen,
                          maxIdx) < 0) {
            #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
            !defined(WOLFCRYPT_ONLY)
                wolfSSL_X509_NAME_free(dName);
            #endif /* OPENSSL_EXTRA */
                return ASN_PARSE_E;
            }

            /* Check for jurisdiction of incorporation country name */
            if (id == ASN_JOI_C) {
                copy = WOLFSSL_JOI_C;
                copyLen = sizeof(WOLFSSL_JOI_C) - 1;
                #ifdef WOLFSSL_CERT_GEN
                    if (nameType == SUBJECT) {
                        cert->subjectJC = (char*)&cert->source[cert->srcIdx];
                        cert->subjectJCLen = strLen;
                        cert->subjectJCEnc = b;
                    }
                #endif /* WOLFSSL_CERT_GEN */
                #if (defined(OPENSSL_EXTRA) || \
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
                        && !defined(WOLFCRYPT_ONLY)
                    nid = NID_jurisdictionCountryName;
                #endif /* OPENSSL_EXTRA */
            }

            /* Check for jurisdiction of incorporation state name */
            else if (id == ASN_JOI_ST) {
                copy = WOLFSSL_JOI_ST;
                copyLen = sizeof(WOLFSSL_JOI_ST) - 1;
                #ifdef WOLFSSL_CERT_GEN
                    if (nameType == SUBJECT) {
                        cert->subjectJS = (char*)&cert->source[cert->srcIdx];
                        cert->subjectJSLen = strLen;
                        cert->subjectJSEnc = b;
                    }
                #endif /* WOLFSSL_CERT_GEN */
                #if (defined(OPENSSL_EXTRA) || \
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
                        && !defined(WOLFCRYPT_ONLY)
                    nid = NID_jurisdictionStateOrProvinceName;
                #endif /* OPENSSL_EXTRA */
            }

            if ((strLen + copyLen) > (int)(ASN_NAME_MAX - idx)) {
                WOLFSSL_MSG("ASN Name too big, skipping");
                tooBig = TRUE;
            }
        }
    #endif /* WOLFSSL_CERT_EXT */
        else {
            /* skip */
            byte email = FALSE;
            byte pilot = FALSE;

            if (joint[0] == 0x2a && joint[1] == 0x86) {  /* email id hdr */
                id = ASN_EMAIL_NAME;
                email = TRUE;
            }

            if (joint[0] == 0x9  && joint[1] == 0x92) { /* uid id hdr */
                /* last value of OID is the type of pilot attribute */
                id    = cert->source[cert->srcIdx + oidSz - 1];
                pilot = TRUE;
            }

            cert->srcIdx += oidSz + 1;

            if (GetLength(cert->source, &cert->srcIdx, &strLen, maxIdx) < 0) {
            #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
            !defined(WOLFCRYPT_ONLY)
                wolfSSL_X509_NAME_free(dName);
            #endif /* OPENSSL_EXTRA */
                return ASN_PARSE_E;
            }

            if (strLen > (int)(ASN_NAME_MAX - idx)) {
                WOLFSSL_MSG("ASN name too big, skipping");
                tooBig = TRUE;
            }

            if (email) {
                copyLen = sizeof(WOLFSSL_EMAIL_ADDR) - 1;
                if ((copyLen + strLen) > (int)(ASN_NAME_MAX - idx)) {
                    WOLFSSL_MSG("ASN name too big, skipping");
                    tooBig = TRUE;
                }
                else {
                    copy = WOLFSSL_EMAIL_ADDR;
                }

                #ifdef WOLFSSL_CERT_GEN
                    if (nameType == SUBJECT) {
                        cert->subjectEmail = (char*)&cert->source[cert->srcIdx];
                        cert->subjectEmailLen = strLen;
                    }
                #endif /* WOLFSSL_CERT_GEN */
                #if (defined(OPENSSL_EXTRA) || \
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
                        && !defined(WOLFCRYPT_ONLY)
                    nid = NID_emailAddress;
                #endif /* OPENSSL_EXTRA */
                #ifndef IGNORE_NAME_CONSTRAINTS
                    {
                        DNS_entry* emailName;

                        emailName = (DNS_entry*)XMALLOC(sizeof(DNS_entry),
                                              cert->heap, DYNAMIC_TYPE_ALTNAME);
                        if (emailName == NULL) {
                            WOLFSSL_MSG("\tOut of Memory");
                        #if (defined(OPENSSL_EXTRA) || \
                                defined(OPENSSL_EXTRA_X509_SMALL)) && \
                                !defined(WOLFCRYPT_ONLY)
                            wolfSSL_X509_NAME_free(dName);
                        #endif /* OPENSSL_EXTRA */
                            return MEMORY_E;
                        }
                        emailName->type = 0;
                        emailName->name = (char*)XMALLOC(strLen + 1,
                                              cert->heap, DYNAMIC_TYPE_ALTNAME);
                        if (emailName->name == NULL) {
                            WOLFSSL_MSG("\tOut of Memory");
                            XFREE(emailName, cert->heap, DYNAMIC_TYPE_ALTNAME);
                        #if (defined(OPENSSL_EXTRA) || \
                                defined(OPENSSL_EXTRA_X509_SMALL)) && \
                                !defined(WOLFCRYPT_ONLY)
                            wolfSSL_X509_NAME_free(dName);
                        #endif /* OPENSSL_EXTRA */
                            return MEMORY_E;
                        }
                        emailName->len = strLen;
                        XMEMCPY(emailName->name, &cert->source[cert->srcIdx],
                                                                        strLen);
                        emailName->name[strLen] = '\0';

                        emailName->next = cert->altEmailNames;
                        cert->altEmailNames = emailName;
                    }
                #endif /* IGNORE_NAME_CONSTRAINTS */
            }

            if (pilot) {
                switch (id) {
                    case ASN_USER_ID:
                        copy = WOLFSSL_USER_ID;
                        copyLen = sizeof(WOLFSSL_USER_ID) - 1;
                    #if (defined(OPENSSL_EXTRA) || \
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
                        && !defined(WOLFCRYPT_ONLY)
                        nid = NID_userId;
                    #endif /* OPENSSL_EXTRA */
                        break;

                    case ASN_DOMAIN_COMPONENT:
                        copy = WOLFSSL_DOMAIN_COMPONENT;
                        copyLen = sizeof(WOLFSSL_DOMAIN_COMPONENT) - 1;
                    #if (defined(OPENSSL_EXTRA) || \
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
                        && !defined(WOLFCRYPT_ONLY)
                        nid = NID_domainComponent;
                    #endif /* OPENSSL_EXTRA */
                        break;
                    case ASN_FAVOURITE_DRINK:
                        copy = WOLFSSL_FAVOURITE_DRINK;
                        copyLen = sizeof(WOLFSSL_FAVOURITE_DRINK) - 1;
                    #if (defined(OPENSSL_EXTRA) || \
                        defined(OPENSSL_EXTRA_X509_SMALL)) \
                        && !defined(WOLFCRYPT_ONLY)
                        nid = NID_favouriteDrink;
                    #endif /* OPENSSL_EXTRA */
                        break;

                    default:
                        WOLFSSL_MSG("Unknown pilot attribute type");
                    #if (defined(OPENSSL_EXTRA) || \
                                defined(OPENSSL_EXTRA_X509_SMALL)) && \
                                !defined(WOLFCRYPT_ONLY)
                        wolfSSL_X509_NAME_free(dName);
                    #endif /* OPENSSL_EXTRA */
                        return ASN_PARSE_E;
                }
            }
        }
        if ((copyLen + strLen) > (int)(ASN_NAME_MAX - idx))
        {
            WOLFSSL_MSG("ASN Name too big, skipping");
            tooBig = TRUE;
        }
        if ((copy != NULL) && !tooBig) {
            XMEMCPY(&full[idx], copy, copyLen);
            idx += copyLen;
            XMEMCPY(&full[idx], &cert->source[cert->srcIdx], strLen);
            idx += strLen;
        }
        #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
            !defined(WOLFCRYPT_ONLY)
        switch (b) {
            case CTC_UTF8:
                enc = MBSTRING_UTF8;
                break;
            case CTC_PRINTABLE:
                enc = V_ASN1_PRINTABLESTRING;
                break;
            default:
                WOLFSSL_MSG("Unknown encoding type, using UTF8 by default");
                enc = MBSTRING_UTF8;
        }

        if (nid != NID_undef) {
            if (wolfSSL_X509_NAME_add_entry_by_NID(dName, nid, enc,
                            &cert->source[cert->srcIdx], strLen, -1, -1) !=
                            WOLFSSL_SUCCESS) {
                wolfSSL_X509_NAME_free(dName);
                return ASN_PARSE_E;
            }
        }
        #endif /* OPENSSL_EXTRA */
        cert->srcIdx += strLen;
    }
    full[idx++] = 0;


#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
            !defined(WOLFCRYPT_ONLY)
    if (nameType == ISSUER) {
        cert->issuerName = dName;
    }
    else {
        cert->subjectName = dName;
    }
#endif
    return 0;
}