/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/*
 * Certificate handling code
 */

#include "seccomon.h"
#include "secder.h"
#include "nssilock.h"
#include "lowkeyi.h"
#include "secasn1.h"
#include "secoid.h"
#include "secerr.h"
#include "pcert.h"

SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)

static const SEC_ASN1Template nsslowcert_SubjectPublicKeyInfoTemplate[] = {
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWCERTSubjectPublicKeyInfo) },
    { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
      offsetof(NSSLOWCERTSubjectPublicKeyInfo, algorithm),
      SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
    { SEC_ASN1_BIT_STRING,
      offsetof(NSSLOWCERTSubjectPublicKeyInfo, subjectPublicKey) },
    { 0 }
};

static const SEC_ASN1Template nsslowcert_RSAPublicKeyTemplate[] = {
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWKEYPublicKey) },
    { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPublicKey, u.rsa.modulus) },
    { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPublicKey, u.rsa.publicExponent) },
    { 0 }
};
static const SEC_ASN1Template nsslowcert_DSAPublicKeyTemplate[] = {
    { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPublicKey, u.dsa.publicValue) },
    { 0 }
};
static const SEC_ASN1Template nsslowcert_DHPublicKeyTemplate[] = {
    { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPublicKey, u.dh.publicValue) },
    { 0 }
};

/*
 * See bugzilla bug 125359
 * Since NSS (via PKCS#11) wants to handle big integers as unsigned ints,
 * all of the templates above that en/decode into integers must be converted
 * from ASN.1's signed integer type.  This is done by marking either the
 * source or destination (encoding or decoding, respectively) type as
 * siUnsignedInteger.
 */

static void
prepare_low_rsa_pub_key_for_asn1(NSSLOWKEYPublicKey *pubk)
{
    pubk->u.rsa.modulus.type = siUnsignedInteger;
    pubk->u.rsa.publicExponent.type = siUnsignedInteger;
}

static void
prepare_low_dsa_pub_key_for_asn1(NSSLOWKEYPublicKey *pubk)
{
    pubk->u.dsa.publicValue.type = siUnsignedInteger;
    pubk->u.dsa.params.prime.type = siUnsignedInteger;
    pubk->u.dsa.params.subPrime.type = siUnsignedInteger;
    pubk->u.dsa.params.base.type = siUnsignedInteger;
}

static void
prepare_low_dh_pub_key_for_asn1(NSSLOWKEYPublicKey *pubk)
{
    pubk->u.dh.prime.type = siUnsignedInteger;
    pubk->u.dh.base.type = siUnsignedInteger;
    pubk->u.dh.publicValue.type = siUnsignedInteger;
}

/*
 * simple cert decoder to avoid the cost of asn1 engine
 */
static unsigned char *
nsslowcert_dataStart(unsigned char *buf, unsigned int length,
                     unsigned int *data_length, PRBool includeTag,
                     unsigned char *rettag)
{
    unsigned char tag;
    unsigned int used_length = 0;

    /* need at least a tag and a 1 byte length */
    if (length < 2) {
        return NULL;
    }

    tag = buf[used_length++];

    if (rettag) {
        *rettag = tag;
    }

    /* blow out when we come to the end */
    if (tag == 0) {
        return NULL;
    }

    *data_length = buf[used_length++];

    if (*data_length & 0x80) {
        int len_count = *data_length & 0x7f;

        if (len_count + used_length > length) {
            return NULL;
        }

        *data_length = 0;

        while (len_count-- > 0) {
            *data_length = (*data_length << 8) | buf[used_length++];
        }
    }

    if (*data_length > (length - used_length)) {
        *data_length = length - used_length;
        return NULL;
    }
    if (includeTag)
        *data_length += used_length;

    return (buf + (includeTag ? 0 : used_length));
}

static void
SetTimeType(SECItem *item, unsigned char tagtype)
{
    switch (tagtype) {
        case SEC_ASN1_UTC_TIME:
            item->type = siUTCTime;
            break;

        case SEC_ASN1_GENERALIZED_TIME:
            item->type = siGeneralizedTime;
            break;

        default:
            PORT_Assert(0);
            break;
    }
}

static int
nsslowcert_GetValidityFields(unsigned char *buf, int buf_length,
                             SECItem *notBefore, SECItem *notAfter)
{
    unsigned char tagtype;
    notBefore->data = nsslowcert_dataStart(buf, buf_length,
                                           &notBefore->len, PR_FALSE, &tagtype);
    if (notBefore->data == NULL)
        return SECFailure;
    SetTimeType(notBefore, tagtype);
    buf_length -= (notBefore->data - buf) + notBefore->len;
    buf = notBefore->data + notBefore->len;
    notAfter->data = nsslowcert_dataStart(buf, buf_length,
                                          &notAfter->len, PR_FALSE, &tagtype);
    if (notAfter->data == NULL)
        return SECFailure;
    SetTimeType(notAfter, tagtype);
    return SECSuccess;
}

static int
nsslowcert_GetCertFields(unsigned char *cert, int cert_length,
                         SECItem *issuer, SECItem *serial, SECItem *derSN, SECItem *subject,
                         SECItem *valid, SECItem *subjkey, SECItem *extensions)
{
    unsigned char *buf;
    unsigned int buf_length;
    unsigned char *dummy;
    unsigned int dummylen;

    /* get past the signature wrap */
    buf = nsslowcert_dataStart(cert, cert_length, &buf_length, PR_FALSE, NULL);
    if (buf == NULL)
        return SECFailure;
    /* get into the raw cert data */
    buf = nsslowcert_dataStart(buf, buf_length, &buf_length, PR_FALSE, NULL);
    if (buf == NULL)
        return SECFailure;
    /* skip past any optional version number */
    if ((buf[0] & 0xa0) == 0xa0) {
        dummy = nsslowcert_dataStart(buf, buf_length, &dummylen, PR_FALSE, NULL);
        if (dummy == NULL)
            return SECFailure;
        buf_length -= (dummy - buf) + dummylen;
        buf = dummy + dummylen;
    }
    /* serial number */
    if (derSN) {
        derSN->data = nsslowcert_dataStart(buf, buf_length, &derSN->len, PR_TRUE, NULL);
        /* derSN->data  doesn't need to be checked because if it fails so will
         * serial->data below. The only difference between the two calls is
         * whether or not the tags are included in the returned buffer */
    }
    serial->data = nsslowcert_dataStart(buf, buf_length, &serial->len, PR_FALSE, NULL);
    if (serial->data == NULL)
        return SECFailure;
    buf_length -= (serial->data - buf) + serial->len;
    buf = serial->data + serial->len;
    /* skip the OID */
    dummy = nsslowcert_dataStart(buf, buf_length, &dummylen, PR_FALSE, NULL);
    if (dummy == NULL)
        return SECFailure;
    buf_length -= (dummy - buf) + dummylen;
    buf = dummy + dummylen;
    /* issuer */
    issuer->data = nsslowcert_dataStart(buf, buf_length, &issuer->len, PR_TRUE, NULL);
    if (issuer->data == NULL)
        return SECFailure;
    buf_length -= (issuer->data - buf) + issuer->len;
    buf = issuer->data + issuer->len;

    /* only wanted issuer/SN */
    if (valid == NULL) {
        return SECSuccess;
    }
    /* validity */
    valid->data = nsslowcert_dataStart(buf, buf_length, &valid->len, PR_FALSE, NULL);
    if (valid->data == NULL)
        return SECFailure;
    buf_length -= (valid->data - buf) + valid->len;
    buf = valid->data + valid->len;
    /*subject */
    subject->data = nsslowcert_dataStart(buf, buf_length, &subject->len, PR_TRUE, NULL);
    if (subject->data == NULL)
        return SECFailure;
    buf_length -= (subject->data - buf) + subject->len;
    buf = subject->data + subject->len;
    /* subject  key info */
    subjkey->data = nsslowcert_dataStart(buf, buf_length, &subjkey->len, PR_TRUE, NULL);
    if (subjkey->data == NULL)
        return SECFailure;
    buf_length -= (subjkey->data - buf) + subjkey->len;
    buf = subjkey->data + subjkey->len;

    extensions->data = NULL;
    extensions->len = 0;
    while (buf_length > 0) {
        /* EXTENSIONS */
        if (buf[0] == 0xa3) {
            extensions->data = nsslowcert_dataStart(buf, buf_length,
                                                    &extensions->len, PR_FALSE, NULL);
            /* if the DER is bad, we should fail. Previously we accepted
             * bad DER here and treated the extension as missin */
            if (extensions->data == NULL ||
                (extensions->data - buf) + extensions->len != buf_length)
                return SECFailure;
            buf = extensions->data;
            buf_length = extensions->len;
            /* now parse the SEQUENCE holding the extensions. */
            dummy = nsslowcert_dataStart(buf, buf_length, &dummylen, PR_FALSE, NULL);
            if (dummy == NULL ||
                (dummy - buf) + dummylen != buf_length)
                return SECFailure;
            buf_length -= (dummy - buf);
            buf = dummy;
            /* Now parse the extensions inside this sequence */
        }
        dummy = nsslowcert_dataStart(buf, buf_length, &dummylen, PR_FALSE, NULL);
        if (dummy == NULL)
            return SECFailure;
        buf_length -= (dummy - buf) + dummylen;
        buf = dummy + dummylen;
    }
    return SECSuccess;
}

static SECStatus
nsslowcert_GetCertTimes(NSSLOWCERTCertificate *c, PRTime *notBefore, PRTime *notAfter)
{
    int rv;
    NSSLOWCERTValidity validity;

    rv = nsslowcert_GetValidityFields(c->validity.data, c->validity.len,
                                      &validity.notBefore, &validity.notAfter);
    if (rv != SECSuccess) {
        return rv;
    }

    /* convert DER not-before time */
    rv = DER_DecodeTimeChoice(notBefore, &validity.notBefore);
    if (rv) {
        return (SECFailure);
    }

    /* convert DER not-after time */
    rv = DER_DecodeTimeChoice(notAfter, &validity.notAfter);
    if (rv) {
        return (SECFailure);
    }

    return (SECSuccess);
}

/*
 * is certa newer than certb?  If one is expired, pick the other one.
 */
PRBool
nsslowcert_IsNewer(NSSLOWCERTCertificate *certa, NSSLOWCERTCertificate *certb)
{
    PRTime notBeforeA, notAfterA, notBeforeB, notAfterB, now;
    SECStatus rv;
    PRBool newerbefore, newerafter;

    rv = nsslowcert_GetCertTimes(certa, &notBeforeA, &notAfterA);
    if (rv != SECSuccess) {
        return (PR_FALSE);
    }

    rv = nsslowcert_GetCertTimes(certb, &notBeforeB, &notAfterB);
    if (rv != SECSuccess) {
        return (PR_TRUE);
    }

    newerbefore = PR_FALSE;
    if (LL_CMP(notBeforeA, >, notBeforeB)) {
        newerbefore = PR_TRUE;
    }

    newerafter = PR_FALSE;
    if (LL_CMP(notAfterA, >, notAfterB)) {
        newerafter = PR_TRUE;
    }

    if (newerbefore && newerafter) {
        return (PR_TRUE);
    }

    if ((!newerbefore) && (!newerafter)) {
        return (PR_FALSE);
    }

    /* get current time */
    now = PR_Now();

    if (newerbefore) {
        /* cert A was issued after cert B, but expires sooner */
        /* if A is expired, then pick B */
        if (LL_CMP(notAfterA, <, now)) {
            return (PR_FALSE);
        }
        return (PR_TRUE);
    } else {
        /* cert B was issued after cert A, but expires sooner */
        /* if B is expired, then pick A */
        if (LL_CMP(notAfterB, <, now)) {
            return (PR_TRUE);
        }
        return (PR_FALSE);
    }
}

#define SOFT_DEFAULT_CHUNKSIZE 2048

static SECStatus
nsslowcert_KeyFromIssuerAndSN(PLArenaPool *arena,
                              SECItem *issuer, SECItem *sn, SECItem *key)
{
    unsigned int len = sn->len + issuer->len;

    if (!arena) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        goto loser;
    }
    if (len > NSS_MAX_LEGACY_DB_KEY_SIZE) {
        PORT_SetError(SEC_ERROR_INPUT_LEN);
        goto loser;
    }
    key->data = (unsigned char *)PORT_ArenaAlloc(arena, len);
    if (!key->data) {
        goto loser;
    }

    key->len = len;
    /* copy the serialNumber */
    PORT_Memcpy(key->data, sn->data, sn->len);

    /* copy the issuer */
    PORT_Memcpy(&key->data[sn->len], issuer->data, issuer->len);

    return (SECSuccess);

loser:
    return (SECFailure);
}

static SECStatus
nsslowcert_KeyFromIssuerAndSNStatic(unsigned char *space,
                                    int spaceLen, SECItem *issuer, SECItem *sn, SECItem *key)
{
    unsigned int len = sn->len + issuer->len;

    key->data = pkcs11_allocStaticData(len, space, spaceLen);
    if (!key->data) {
        goto loser;
    }

    key->len = len;
    /* copy the serialNumber */
    PORT_Memcpy(key->data, sn->data, sn->len);

    /* copy the issuer */
    PORT_Memcpy(&key->data[sn->len], issuer->data, issuer->len);

    return (SECSuccess);

loser:
    return (SECFailure);
}

static char *
nsslowcert_EmailName(SECItem *derDN, char *space, unsigned int len)
{
    unsigned char *buf;
    unsigned int buf_length;

    /* unwrap outer sequence */
    buf = nsslowcert_dataStart(derDN->data, derDN->len, &buf_length, PR_FALSE, NULL);
    if (buf == NULL)
        return NULL;

    /* Walk each RDN */
    while (buf_length > 0) {
        unsigned char *rdn;
        unsigned int rdn_length;

        /* grab next rdn */
        rdn = nsslowcert_dataStart(buf, buf_length, &rdn_length, PR_FALSE, NULL);
        if (rdn == NULL) {
            return NULL;
        }
        buf_length -= (rdn - buf) + rdn_length;
        buf = rdn + rdn_length;

        while (rdn_length > 0) {
            unsigned char *ava;
            unsigned int ava_length;
            unsigned char *oid;
            unsigned int oid_length;
            unsigned char *name;
            unsigned int name_length;
            SECItem oidItem;
            SECOidTag type;

            /* unwrap the ava */
            ava = nsslowcert_dataStart(rdn, rdn_length, &ava_length, PR_FALSE,
                                       NULL);
            if (ava == NULL)
                return NULL;
            rdn_length -= (ava - rdn) + ava_length;
            rdn = ava + ava_length;

            oid = nsslowcert_dataStart(ava, ava_length, &oid_length, PR_FALSE,
                                       NULL);
            if (oid == NULL) {
                return NULL;
            }
            ava_length -= (oid - ava) + oid_length;
            ava = oid + oid_length;

            name = nsslowcert_dataStart(ava, ava_length, &name_length, PR_FALSE,
                                        NULL);
            if (name == NULL) {
                return NULL;
            }
            ava_length -= (name - ava) + name_length;
            ava = name + name_length;

            oidItem.data = oid;
            oidItem.len = oid_length;
            type = SECOID_FindOIDTag(&oidItem);
            if ((type == SEC_OID_PKCS9_EMAIL_ADDRESS) ||
                (type == SEC_OID_RFC1274_MAIL)) {
                /* Email is supposed to be IA5String, so no
                 * translation necessary */
                char *emailAddr;
                emailAddr = (char *)pkcs11_copyStaticData(name, name_length + 1,
                                                          (unsigned char *)space, len);
                if (emailAddr) {
                    emailAddr[name_length] = 0;
                }
                return emailAddr;
            }
        }
    }
    return NULL;
}

static char *
nsslowcert_EmailAltName(NSSLOWCERTCertificate *cert, char *space,
                        unsigned int len)
{
    unsigned char *exts;
    unsigned int exts_length;

    /* unwrap the sequence */
    exts = nsslowcert_dataStart(cert->extensions.data, cert->extensions.len,
                                &exts_length, PR_FALSE, NULL);
    /* loop through extension */
    while (exts && exts_length > 0) {
        unsigned char *ext;
        unsigned int ext_length;
        unsigned char *oid;
        unsigned int oid_length;
        unsigned char *nameList;
        unsigned int nameList_length;
        SECItem oidItem;
        SECOidTag type;

        ext = nsslowcert_dataStart(exts, exts_length, &ext_length,
                                   PR_FALSE, NULL);
        if (ext == NULL) {
            break;
        }
        exts_length -= (ext - exts) + ext_length;
        exts = ext + ext_length;

        oid = nsslowcert_dataStart(ext, ext_length, &oid_length, PR_FALSE, NULL);
        if (oid == NULL) {
            break;
        }
        ext_length -= (oid - ext) + oid_length;
        ext = oid + oid_length;
        oidItem.data = oid;
        oidItem.len = oid_length;
        type = SECOID_FindOIDTag(&oidItem);

        /* get Alt Extension */
        if (type != SEC_OID_X509_SUBJECT_ALT_NAME) {
            continue;
        }

        /* skip passed the critical flag */
        if (ext[0] == 0x01) { /* BOOLEAN */
            unsigned char *dummy;
            unsigned int dummy_length;
            dummy = nsslowcert_dataStart(ext, ext_length, &dummy_length,
                                         PR_FALSE, NULL);
            if (dummy == NULL) {
                break;
            }
            ext_length -= (dummy - ext) + dummy_length;
            ext = dummy + dummy_length;
        }

        /* unwrap the name list */
        nameList = nsslowcert_dataStart(ext, ext_length, &nameList_length,
                                        PR_FALSE, NULL);
        if (nameList == NULL) {
            break;
        }
        ext_length -= (nameList - ext) + nameList_length;
        ext = nameList + nameList_length;
        nameList = nsslowcert_dataStart(nameList, nameList_length,
                                        &nameList_length, PR_FALSE, NULL);
        /* loop through the name list */
        while (nameList && nameList_length > 0) {
            unsigned char *thisName;
            unsigned int thisName_length;

            thisName = nsslowcert_dataStart(nameList, nameList_length,
                                            &thisName_length, PR_FALSE, NULL);
            if (thisName == NULL) {
                break;
            }
            if (nameList[0] == 0xa2) { /* DNS Name */
                SECItem dn;
                char *emailAddr;

                dn.data = thisName;
                dn.len = thisName_length;
                emailAddr = nsslowcert_EmailName(&dn, space, len);
                if (emailAddr) {
                    return emailAddr;
                }
            }
            if (nameList[0] == 0x81) { /* RFC 822name */
                char *emailAddr;
                emailAddr = (char *)pkcs11_copyStaticData(thisName,
                                                          thisName_length + 1, (unsigned char *)space, len);
                if (emailAddr) {
                    emailAddr[thisName_length] = 0;
                }
                return emailAddr;
            }
            nameList_length -= (thisName - nameList) + thisName_length;
            nameList = thisName + thisName_length;
        }
        break;
    }
    return NULL;
}

static char *
nsslowcert_GetCertificateEmailAddress(NSSLOWCERTCertificate *cert)
{
    char *emailAddr = NULL;
    char *str;

    emailAddr = nsslowcert_EmailName(&cert->derSubject, cert->emailAddrSpace,
                                     sizeof(cert->emailAddrSpace));
    /* couldn't find the email address in the DN, check the subject Alt name */
    if (!emailAddr && cert->extensions.data) {
        emailAddr = nsslowcert_EmailAltName(cert, cert->emailAddrSpace,
                                            sizeof(cert->emailAddrSpace));
    }

    /* make it lower case */
    str = emailAddr;
    while (str && *str) {
        *str = tolower(*str);
        str++;
    }
    return emailAddr;
}

/*
 * take a DER certificate and decode it into a certificate structure
 */
NSSLOWCERTCertificate *
nsslowcert_DecodeDERCertificate(SECItem *derSignedCert, char *nickname)
{
    NSSLOWCERTCertificate *cert;
    int rv;

    /* allocate the certificate structure */
    cert = nsslowcert_CreateCert();

    if (!cert) {
        goto loser;
    }

    /* point to passed in DER data */
    cert->derCert = *derSignedCert;
    cert->nickname = NULL;
    cert->certKey.data = NULL;
    cert->referenceCount = 1;

    /* decode the certificate info */
    rv = nsslowcert_GetCertFields(cert->derCert.data, cert->derCert.len,
                                  &cert->derIssuer, &cert->serialNumber, &cert->derSN, &cert->derSubject,
                                  &cert->validity, &cert->derSubjKeyInfo, &cert->extensions);

    if (rv != SECSuccess) {
        goto loser;
    }

    /* cert->subjectKeyID;   x509v3 subject key identifier */
    cert->subjectKeyID.data = NULL;
    cert->subjectKeyID.len = 0;
    cert->dbEntry = NULL;
    cert->trust = NULL;
    cert->dbhandle = NULL;

    /* generate and save the database key for the cert */
    rv = nsslowcert_KeyFromIssuerAndSNStatic(cert->certKeySpace,
                                             sizeof(cert->certKeySpace), &cert->derIssuer,
                                             &cert->serialNumber, &cert->certKey);
    if (rv) {
        goto loser;
    }

    /* set the nickname */
    if (nickname == NULL) {
        cert->nickname = NULL;
    } else {
        /* copy and install the nickname */
        cert->nickname = pkcs11_copyNickname(nickname, cert->nicknameSpace,
                                             sizeof(cert->nicknameSpace));
    }

#ifdef FIXME
    /* initialize the subjectKeyID */
    rv = cert_GetKeyID(cert);
    if (rv != SECSuccess) {
        goto loser;
    }
#endif

    /* set the email address */
    cert->emailAddr = nsslowcert_GetCertificateEmailAddress(cert);

    cert->referenceCount = 1;

    return (cert);

loser:
    if (cert) {
        nsslowcert_DestroyCertificate(cert);
    }

    return (0);
}

char *
nsslowcert_FixupEmailAddr(char *emailAddr)
{
    char *retaddr;
    char *str;

    if (emailAddr == NULL) {
        return (NULL);
    }

    /* copy the string */
    str = retaddr = PORT_Strdup(emailAddr);
    if (str == NULL) {
        return (NULL);
    }

    /* make it lower case */
    while (*str) {
        *str = tolower(*str);
        str++;
    }

    return (retaddr);
}

/*
 * Generate a database key, based on serial number and issuer, from a
 * DER certificate.
 */
SECStatus
nsslowcert_KeyFromDERCert(PLArenaPool *arena, SECItem *derCert, SECItem *key)
{
    int rv;
    NSSLOWCERTCertKey certkey;

    PORT_Memset(&certkey, 0, sizeof(NSSLOWCERTCertKey));

    rv = nsslowcert_GetCertFields(derCert->data, derCert->len,
                                  &certkey.derIssuer, &certkey.serialNumber, NULL, NULL,
                                  NULL, NULL, NULL);

    if (rv) {
        goto loser;
    }

    return (nsslowcert_KeyFromIssuerAndSN(arena, &certkey.derIssuer,
                                          &certkey.serialNumber, key));
loser:
    return (SECFailure);
}

NSSLOWKEYPublicKey *
nsslowcert_ExtractPublicKey(NSSLOWCERTCertificate *cert)
{
    NSSLOWCERTSubjectPublicKeyInfo spki;
    NSSLOWKEYPublicKey *pubk;
    SECItem os;
    SECStatus rv;
    PLArenaPool *arena;
    SECOidTag tag;
    SECItem newDerSubjKeyInfo;

    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (arena == NULL)
        return NULL;

    pubk = (NSSLOWKEYPublicKey *)
        PORT_ArenaZAlloc(arena, sizeof(NSSLOWKEYPublicKey));
    if (pubk == NULL) {
        PORT_FreeArena(arena, PR_FALSE);
        return NULL;
    }

    pubk->arena = arena;
    PORT_Memset(&spki, 0, sizeof(spki));

    /* copy the DER into the arena, since Quick DER returns data that points
       into the DER input, which may get freed by the caller */
    rv = SECITEM_CopyItem(arena, &newDerSubjKeyInfo, &cert->derSubjKeyInfo);
    if (rv != SECSuccess) {
        PORT_FreeArena(arena, PR_FALSE);
        return NULL;
    }

    /* we haven't bothered decoding the spki struct yet, do it now */
    rv = SEC_QuickDERDecodeItem(arena, &spki,
                                nsslowcert_SubjectPublicKeyInfoTemplate, &newDerSubjKeyInfo);
    if (rv != SECSuccess) {
        PORT_FreeArena(arena, PR_FALSE);
        return NULL;
    }

    /* Convert bit string length from bits to bytes */
    os = spki.subjectPublicKey;
    DER_ConvertBitString(&os);

    tag = SECOID_GetAlgorithmTag(&spki.algorithm);
    switch (tag) {
        case SEC_OID_X500_RSA_ENCRYPTION:
        case SEC_OID_PKCS1_RSA_ENCRYPTION:
        case SEC_OID_PKCS1_RSA_PSS_SIGNATURE:
            pubk->keyType = NSSLOWKEYRSAKey;
            prepare_low_rsa_pub_key_for_asn1(pubk);
            rv = SEC_QuickDERDecodeItem(arena, pubk,
                                        nsslowcert_RSAPublicKeyTemplate, &os);
            if (rv == SECSuccess)
                return pubk;
            break;
        case SEC_OID_ANSIX9_DSA_SIGNATURE:
            pubk->keyType = NSSLOWKEYDSAKey;
            prepare_low_dsa_pub_key_for_asn1(pubk);
            rv = SEC_QuickDERDecodeItem(arena, pubk,
                                        nsslowcert_DSAPublicKeyTemplate, &os);
            if (rv == SECSuccess)
                return pubk;
            break;
        case SEC_OID_X942_DIFFIE_HELMAN_KEY:
            pubk->keyType = NSSLOWKEYDHKey;
            prepare_low_dh_pub_key_for_asn1(pubk);
            rv = SEC_QuickDERDecodeItem(arena, pubk,
                                        nsslowcert_DHPublicKeyTemplate, &os);
            if (rv == SECSuccess)
                return pubk;
            break;
        case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
            pubk->keyType = NSSLOWKEYECKey;
            /* Since PKCS#11 directly takes the DER encoding of EC params
             * and public value, we don't need any decoding here.
             */
            rv = SECITEM_CopyItem(arena, &pubk->u.ec.ecParams.DEREncoding,
                                  &spki.algorithm.parameters);
            if (rv != SECSuccess)
                break;

            /* Fill out the rest of the ecParams structure
             * based on the encoded params
             */
            if (LGEC_FillParams(arena, &pubk->u.ec.ecParams.DEREncoding,
                                &pubk->u.ec.ecParams) != SECSuccess)
                break;

            rv = SECITEM_CopyItem(arena, &pubk->u.ec.publicValue, &os);
            if (rv == SECSuccess)
                return pubk;
            break;
        default:
            rv = SECFailure;
            break;
    }

    lg_nsslowkey_DestroyPublicKey(pubk);
    return NULL;
}
