Esempio n. 1
2
int rsa_test()
{
    byte   tmp[1024], tmp2[2048];
    size_t bytes, bytes2;
    RsaKey key;
    RNG    rng;
    word32 idx = 0;
    int    ret;
    byte   in[] = "Everyone gets Friday off.";
    word32 inLen = (word32)strlen((char*)in);
    byte   out[64];
    byte   plain[64];
    DecodedCert cert;

    FILE*  file = fopen(clientKey, "rb"), * file2;

    if (!file)
        return -40;

    bytes = fread(tmp, 1, 1024, file);
  
    InitRsaKey(&key, 0);  
    ret = RsaPrivateKeyDecode(tmp, &idx, &key, (word32)bytes);
    if (ret != 0) return -41;

    ret = InitRng(&rng);
    if (ret != 0) return -42;

    ret = RsaPublicEncrypt(in, inLen, out, sizeof(out), &key, &rng);  

    ret = RsaPrivateDecrypt(out, 64, plain, sizeof(plain), &key);

    if (memcmp(plain, in, inLen)) return -45;

    ret = RsaSSL_Sign(in, inLen, out, sizeof(out), &key, &rng);
    memset(plain, 0, sizeof(plain));
    ret = RsaSSL_Verify(out, 64, plain, sizeof(plain), &key);

    if (memcmp(plain, in, ret)) return -46;

    file2 = fopen(clientCert, "rb");
    if (!file2)
        return -47;

    bytes2 = fread(tmp2, 1, 2048, file2);

    InitDecodedCert(&cert, (byte*)&tmp2, 0);

    ret = ParseCert(&cert, (word32)bytes2, CERT_TYPE, NO_VERIFY, 0);
    if (ret != 0) return -48;

    FreeDecodedCert(&cert);
    FreeRsaKey(&key);

    fclose(file2);
    fclose(file);

    return 0;
}
Esempio n. 2
0
/* init PKCS7 struct with recipient cert, decode into DecodedCert */
int PKCS7_InitWithCert(PKCS7* pkcs7, byte* cert, word32 certSz)
{
    int ret = 0;

    XMEMSET(pkcs7, 0, sizeof(PKCS7));
    if (cert != NULL && certSz > 0) {
        DecodedCert dCert;

        pkcs7->singleCert = cert;
        pkcs7->singleCertSz = certSz;
        InitDecodedCert(&dCert, cert, certSz, 0);

        ret = ParseCert(&dCert, CA_TYPE, NO_VERIFY, 0);
        if (ret < 0) {
            FreeDecodedCert(&dCert);
            return ret;
        }
        XMEMCPY(pkcs7->publicKey, dCert.publicKey, dCert.pubKeySize);
        pkcs7->publicKeySz = dCert.pubKeySize;
        XMEMCPY(pkcs7->issuerHash, dCert.issuerHash, SHA_SIZE);
        pkcs7->issuer = dCert.issuerRaw;
        pkcs7->issuerSz = dCert.issuerRawLen;
        XMEMCPY(pkcs7->issuerSn, dCert.serial, dCert.serialSz);
        pkcs7->issuerSnSz = dCert.serialSz;
        FreeDecodedCert(&dCert);
    }

    return ret;
}
Esempio n. 3
0
int rsa_test()
{
    byte   tmp[1024], tmp2[2048];
    size_t bytes, bytes2;
    RsaKey key;
    RNG    rng;
    word32 idx = 0;
    int    ret;
    byte   in[] = "Everyone gets Friday off.";
    word32 inLen = (word32)strlen((char*)in);
    byte   out[64];
    byte   plain[64];
    DecodedCert cert;

    FILE*  file = fopen(clientKey, "rb"), * file2;

    if (!file)
        return -40;

    bytes = fread(tmp, 1, 1024, file);
  
    InitRsaKey(&key, 0);  
    ret = RsaPrivateKeyDecode(tmp, &idx, &key, (word32)bytes);
    if (ret != 0) return -41;

    ret = InitRng(&rng);
    if (ret != 0) return -42;

    ret = RsaPublicEncrypt(in, inLen, out, sizeof(out), &key, &rng);  

    ret = RsaPrivateDecrypt(out, 64, plain, sizeof(plain), &key);

    if (memcmp(plain, in, inLen)) return -45;

    ret = RsaSSL_Sign(in, inLen, out, sizeof(out), &key, &rng);
    memset(plain, 0, sizeof(plain));
    ret = RsaSSL_Verify(out, 64, plain, sizeof(plain), &key);

    if (memcmp(plain, in, ret)) return -46;

    file2 = fopen(clientCert, "rb");
    if (!file2)
        return -47;

    bytes2 = fread(tmp2, 1, 2048, file2);

    InitDecodedCert(&cert, (byte*)&tmp2, 0);

    ret = ParseCert(&cert, (word32)bytes2, CERT_TYPE, NO_VERIFY, 0);
    if (ret != 0) return -48;

    FreeDecodedCert(&cert);

    fclose(file2);
    fclose(file);

#ifdef CYASSL_KEY_GEN
    {
        byte   der[4096];
        byte   pem[4096];
        word32 derSz = 0;
        word32 pemSz = 0;
        RsaKey derIn;
        RsaKey genKey;
        FILE* keyFile;
        FILE* pemFile;

        InitRsaKey(&genKey, 0);
        ret = MakeRsaKey(&genKey, 1024, 65537, &rng);
        if (ret != 0)
            return -301;

        derSz = RsaKeyToDer(&genKey, der, sizeof(der));
        if (derSz < 0)
            return -302;

        keyFile = fopen("./ker.der", "wb");
        if (!keyFile)
            return -303;
        ret = fwrite(der, derSz, 1, keyFile);
        fclose(keyFile);

        pemSz = DerToPem(der, derSz, pem, sizeof(pem), PRIVATEKEY_TYPE);
        if (pemSz < 0)
            return -304;

        pemFile = fopen("./key.pem", "wb");
        if (!pemFile) 
            return -305;
        ret = fwrite(pem, pemSz, 1, pemFile);
        fclose(pemFile);

        InitRsaKey(&derIn, 0);
        idx = 0;
        ret = RsaPrivateKeyDecode(der, &idx, &derIn, derSz);
        if (ret != 0)
            return -306;
    }
#endif /* CYASSL_KEY_GEN */


#ifdef CYASSL_CERT_GEN
    {
        Cert        myCert;
        byte        derCert[4096];
        byte        pem[4096];
        DecodedCert decode;
        FILE*       derFile;
        FILE*       pemFile;
        int         certSz;
        int         pemSz;

        InitCert(&myCert);

        strncpy(myCert.subject.country, "US", NAME_SIZE);
        strncpy(myCert.subject.state, "OR", NAME_SIZE);
        strncpy(myCert.subject.locality, "Portland", NAME_SIZE);
        strncpy(myCert.subject.org, "yaSSL", NAME_SIZE);
        strncpy(myCert.subject.unit, "Development", NAME_SIZE);
        strncpy(myCert.subject.commonName, "www.yassl.com", NAME_SIZE);
        strncpy(myCert.subject.email, "*****@*****.**", NAME_SIZE);

        certSz = MakeCert(&myCert, derCert, sizeof(derCert), &key, &rng); 
        if (certSz < 0)
            return -401;

        InitDecodedCert(&decode, derCert, 0);
        ret = ParseCert(&decode, certSz, CERT_TYPE, NO_VERIFY, 0);
        if (ret != 0)
            return -402;

        derFile = fopen("./cert.der", "wb");
        if (!derFile)
            return -403;
        ret = fwrite(derCert, certSz, 1, derFile);
        fclose(derFile);

        pemSz = DerToPem(derCert, certSz, pem, sizeof(pem), CERT_TYPE);
        if (pemSz < 0)
            return -404;

        pemFile = fopen("./cert.pem", "wb");
        if (!pemFile)
            return -405;
        ret = fwrite(pem, pemSz, 1, pemFile);
        fclose(pemFile);

        FreeDecodedCert(&decode);

    }
#endif /* CYASSL_CERT_GEN */

    FreeRsaKey(&key);

    return 0;
}
Esempio n. 4
0
/* create ASN.1 fomatted RecipientInfo structure, returns sequence size */
CYASSL_LOCAL int CreateRecipientInfo(const byte* cert, word32 certSz,
                                     int keyEncAlgo, int blockKeySz,
                                     RNG* rng, byte* contentKeyPlain,
                                     byte* contentKeyEnc,
                                     int* keyEncSz, byte* out, word32 outSz)
{
    word32 idx = 0;
    int ret = 0, totalSz = 0;
    int verSz, issuerSz, snSz, keyEncAlgSz;
    int issuerSeqSz, recipSeqSz, issuerSerialSeqSz;
    int encKeyOctetStrSz;

    byte ver[MAX_VERSION_SZ];
    byte serial[MAX_SN_SZ];
    byte issuerSerialSeq[MAX_SEQ_SZ];
    byte recipSeq[MAX_SEQ_SZ];
    byte issuerSeq[MAX_SEQ_SZ];
    byte keyAlgArray[MAX_ALGO_SZ];
    byte encKeyOctetStr[MAX_OCTET_STR_SZ];

    RsaKey pubKey;
    DecodedCert decoded;

    InitDecodedCert(&decoded, (byte*)cert, certSz, 0);
    ret = ParseCert(&decoded, CA_TYPE, NO_VERIFY, 0);
    if (ret < 0) {
        FreeDecodedCert(&decoded);
        return ret;
    }

    /* version */
    verSz = SetMyVersion(0, ver, 0);

    /* IssuerAndSerialNumber */
    if (decoded.issuerRaw == NULL || decoded.issuerRawLen == 0) {
        CYASSL_MSG("DecodedCert lacks raw issuer pointer and length");
        FreeDecodedCert(&decoded);
        return -1;
    }
    issuerSz    = decoded.issuerRawLen;
    issuerSeqSz = SetSequence(issuerSz, issuerSeq);

    if (decoded.serial == NULL || decoded.serialSz == 0) {
        CYASSL_MSG("DecodedCert missing serial number");
        FreeDecodedCert(&decoded);
        return -1;
    }
    snSz = SetSerialNumber(decoded.serial, decoded.serialSz, serial);

    issuerSerialSeqSz = SetSequence(issuerSeqSz + issuerSz + snSz,
                                    issuerSerialSeq);

    /* KeyEncryptionAlgorithmIdentifier, only support RSA now */
    if (keyEncAlgo != RSAk)
        return ALGO_ID_E;

    keyEncAlgSz = SetAlgoID(keyEncAlgo, keyAlgArray, keyType, 0);
    if (keyEncAlgSz == 0)
        return BAD_FUNC_ARG;

    /* EncryptedKey */
    ret = InitRsaKey(&pubKey, 0);
    if (ret != 0) return ret;
    if (RsaPublicKeyDecode(decoded.publicKey, &idx, &pubKey,
                           decoded.pubKeySize) < 0) {
        CYASSL_MSG("ASN RSA key decode error");
        return PUBLIC_KEY_E;
    }

    *keyEncSz = RsaPublicEncrypt(contentKeyPlain, blockKeySz, contentKeyEnc,
                                 MAX_ENCRYPTED_KEY_SZ, &pubKey, rng);
    FreeRsaKey(&pubKey);
    if (*keyEncSz < 0) {
        CYASSL_MSG("RSA Public Encrypt failed");
        return *keyEncSz;
    }

    encKeyOctetStrSz = SetOctetString(*keyEncSz, encKeyOctetStr);

    /* RecipientInfo */
    recipSeqSz = SetSequence(verSz + issuerSerialSeqSz + issuerSeqSz +
                             issuerSz + snSz + keyEncAlgSz + encKeyOctetStrSz +
                             *keyEncSz, recipSeq);

    if (recipSeqSz + verSz + issuerSerialSeqSz + issuerSeqSz + snSz +
        keyEncAlgSz + encKeyOctetStrSz + *keyEncSz > (int)outSz) {
        CYASSL_MSG("RecipientInfo output buffer too small");
        return BUFFER_E;
    }

    XMEMCPY(out + totalSz, recipSeq, recipSeqSz);
    totalSz += recipSeqSz;
    XMEMCPY(out + totalSz, ver, verSz);
    totalSz += verSz;
    XMEMCPY(out + totalSz, issuerSerialSeq, issuerSerialSeqSz);
    totalSz += issuerSerialSeqSz;
    XMEMCPY(out + totalSz, issuerSeq, issuerSeqSz);
    totalSz += issuerSeqSz;
    XMEMCPY(out + totalSz, decoded.issuerRaw, issuerSz);
    totalSz += issuerSz;
    XMEMCPY(out + totalSz, serial, snSz);
    totalSz += snSz;
    XMEMCPY(out + totalSz, keyAlgArray, keyEncAlgSz);
    totalSz += keyEncAlgSz;
    XMEMCPY(out + totalSz, encKeyOctetStr, encKeyOctetStrSz);
    totalSz += encKeyOctetStrSz;
    XMEMCPY(out + totalSz, contentKeyEnc, *keyEncSz);
    totalSz += *keyEncSz;

    FreeDecodedCert(&decoded);

    return totalSz;
}
Esempio n. 5
0
/* return 1 on success and 0 on failure.
 * By side effect returns private key, cert, and optionally ca.
 * Parses and decodes the parts of PKCS12
 *
 * NOTE: can parse with USER RSA enabled but may return cert that is not the
 *       pair for the key when using RSA key pairs.
 *
 * pkcs12 : non-null WC_PKCS12 struct
 * psw    : password to use for PKCS12 decode
 * pkey   : Private key returned
 * cert   : x509 cert returned
 * ca     : optional ca returned
 */
int wc_PKCS12_parse(WC_PKCS12* pkcs12, const char* psw,
        byte** pkey, word32* pkeySz, byte** cert, word32* certSz,
        WC_DerCertList** ca)
{
    ContentInfo* ci       = NULL;
    WC_DerCertList* certList = NULL;
    byte* buf             = NULL;
    word32 i, oid;
    int ret, pswSz;

    WOLFSSL_ENTER("wc_PKCS12_parse");

    if (pkcs12 == NULL || psw == NULL || cert == NULL || certSz == NULL ||
        pkey == NULL || pkeySz == NULL) {
        return BAD_FUNC_ARG;
    }
    pswSz = (int)XSTRLEN(psw);
    *cert = NULL;
    *pkey = NULL;
    if (ca != NULL) {
        *ca = NULL;
    }

    /* if there is sign data then verify the MAC */
    if (pkcs12->signData != NULL ) {
        if ((ret = wc_PKCS12_verify(pkcs12, pkcs12->safe->data,
                               pkcs12->safe->dataSz, (byte*)psw, pswSz)) != 0) {
            WOLFSSL_MSG("PKCS12 Bad MAC on verify");
            WOLFSSL_LEAVE("wc_PKCS12_parse verify ", ret);
            return MAC_CMP_FAILED_E;
        }
    }


    /* Decode content infos */
    ci = pkcs12->safe->CI;
    for (i = 0; i < pkcs12->safe->numCI; i++) {
        byte*  data;
        word32 idx = 0;
        int    size, totalSz;

        if (ci->type == WC_PKCS12_ENCRYPTED_DATA) {
            int number;

            WOLFSSL_MSG("Decrypting PKCS12 Content Info Container");
            data = ci->data;
            if (data[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) {
                freeBuffers(*pkey, buf, pkcs12->heap);
                freeCertList(certList, pkcs12->heap);
                return ASN_PARSE_E;
            }
            if ((ret = GetLength(data, &idx, &size, ci->dataSz)) < 0) {
                freeBuffers(*pkey, buf, pkcs12->heap);
                freeCertList(certList, pkcs12->heap);
                return ret;
            }

            if ((ret = GetSequence(data, &idx, &size, ci->dataSz)) < 0) {
                freeBuffers(*pkey, buf, pkcs12->heap);
                freeCertList(certList, pkcs12->heap);
                return ret;
            }

            if ((ret = GetShortInt(data, &idx, &number, ci->dataSz)) < 0) {
                freeBuffers(*pkey, buf, pkcs12->heap);
                freeCertList(certList, pkcs12->heap);
                return ret;
            }

            if (number != 0) {
                WOLFSSL_MSG("Expecting 0 for Integer with Encrypted PKCS12");
            }

            if ((ret = GetSequence(data, &idx, &size, ci->dataSz)) < 0) {
                freeBuffers(*pkey, buf, pkcs12->heap);
                freeCertList(certList, pkcs12->heap);
                return ret;
            }

            ret = GetObjectId(data, &idx, &oid, oidIgnoreType, ci->dataSz);
            if (ret < 0 || oid != WC_PKCS12_DATA) {
                WOLFSSL_MSG("Not PKCS12 DATA object or get object parse error");
                freeBuffers(*pkey, buf, pkcs12->heap);
                freeCertList(certList, pkcs12->heap);
                return ASN_PARSE_E;
            }

            /* decrypted content overwrites input buffer */
            size = ci->dataSz - idx;
            buf = (byte*)XMALLOC(size, pkcs12->heap, DYNAMIC_TYPE_PKCS);
            if (buf == NULL) {
                freeBuffers(*pkey, buf, pkcs12->heap);
                freeCertList(certList, pkcs12->heap);
                return MEMORY_E;
            }
            XMEMCPY(buf, data + idx, size);

            if ((ret = DecryptContent(buf, size, psw, pswSz)) < 0) {
                freeBuffers(*pkey, buf, pkcs12->heap);
                freeCertList(certList, pkcs12->heap);
                WOLFSSL_MSG("Decryption failed, algorithm not compiled in?");
                return ret;
            }

            data = buf;
            idx = 0;
            #ifdef WOLFSSL_DEBUG_PKCS12
            {
                byte* p;
                for (printf("\tData = "), p = (byte*)buf;
                    p < (byte*)buf + size;
                    printf("%02X", *p), p++);
                printf("\n");
            }
            #endif
        }
        else { /* type DATA */
            WOLFSSL_MSG("Parsing PKCS12 DATA Content Info Container");
            data = ci->data;
            if (data[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) {
                freeBuffers(*pkey, buf, pkcs12->heap);
                freeCertList(certList, pkcs12->heap);
                return ASN_PARSE_E;
            }
            if ((ret = GetLength(data, &idx, &size, ci->dataSz)) <= 0) {
                freeBuffers(*pkey, buf, pkcs12->heap);
                freeCertList(certList, pkcs12->heap);
                return ret;
            }
            if (data[idx++] != ASN_OCTET_STRING) {
                freeBuffers(*pkey, buf, pkcs12->heap);
                freeCertList(certList, pkcs12->heap);
                return ASN_PARSE_E;
            }
            if ((ret = GetLength(data, &idx, &size, ci->dataSz)) < 0) {
                freeBuffers(*pkey, buf, pkcs12->heap);
                freeCertList(certList, pkcs12->heap);
                return ret;
            }

        }

        /* parse through bags in ContentInfo */
        if ((ret = GetSequence(data, &idx, &totalSz, ci->dataSz)) < 0) {
            freeBuffers(*pkey, buf, pkcs12->heap);
            freeCertList(certList, pkcs12->heap);
            return ret;
        }
        totalSz += idx;

        while ((int)idx < totalSz) {
            int bagSz;
            if ((ret = GetSequence(data, &idx, &bagSz, ci->dataSz)) < 0) {
                freeBuffers(*pkey, buf, pkcs12->heap);
                freeCertList(certList, pkcs12->heap);
                return ret;
            }
            bagSz += idx;

            if ((ret = GetObjectId(data, &idx, &oid, oidIgnoreType,
                                                             ci->dataSz)) < 0) {
                freeBuffers(*pkey, buf, pkcs12->heap);
                freeCertList(certList, pkcs12->heap);
                return ret;
            }

            switch (oid) {
                case WC_PKCS12_KeyBag: /* 667 */
                    WOLFSSL_MSG("PKCS12 Key Bag found");
                    if (data[idx++] !=
                                     (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) {
                        freeBuffers(*pkey, buf, pkcs12->heap);
                        freeCertList(certList, pkcs12->heap);
                        return ASN_PARSE_E;
                    }
                    if ((ret = GetLength(data, &idx, &size, ci->dataSz)) <= 0) {
                        freeBuffers(*pkey, buf, pkcs12->heap);
                        freeCertList(certList, pkcs12->heap);
                        return ASN_PARSE_E;
                    }
                    if (*pkey == NULL) {
                        *pkey = (byte*)XMALLOC(size, pkcs12->heap,
                                                             DYNAMIC_TYPE_PKCS);
                        if (*pkey == NULL) {
                            freeBuffers(*pkey, buf, pkcs12->heap);
                            freeCertList(certList, pkcs12->heap);
                            return MEMORY_E;
                        }
                        XMEMCPY(*pkey, data + idx, size);
                        *pkeySz =  ToTraditional(*pkey, size);
                    }
                    #ifdef WOLFSSL_DEBUG_PKCS12
                        {
                            byte* p;
                            for (printf("\tKey = "), p = (byte*)*pkey;
                                p < (byte*)*pkey + size;
                                printf("%02X", *p), p++);
                            printf("\n");
                        }
                    #endif
                    idx += size;
                    break;

                case WC_PKCS12_ShroudedKeyBag: /* 668 */
                    {
                        byte* k;
                        WOLFSSL_MSG("PKCS12 Shrouded Key Bag found");
                        if (data[idx++] !=
                                     (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) {
                            freeBuffers(*pkey, buf, pkcs12->heap);
                            freeCertList(certList, pkcs12->heap);
                            return ASN_PARSE_E;
                        }
                        if ((ret = GetLength(data, &idx, &size,
                                                             ci->dataSz)) < 0) {
                            freeBuffers(*pkey, buf, pkcs12->heap);
                            freeCertList(certList, pkcs12->heap);
                            return ASN_PARSE_E;
                        }

                        k = (byte*)XMALLOC(size, pkcs12->heap,
                                                             DYNAMIC_TYPE_PKCS);
                        if (k == NULL) {
                            freeBuffers(*pkey, buf, pkcs12->heap);
                            freeCertList(certList, pkcs12->heap);
                            return MEMORY_E;
                        }
                        XMEMCPY(k, data + idx, size);

                        /* overwrites input, be warned */
                        if ((ret = ToTraditionalEnc(k, size, psw, pswSz)) < 0) {
                            freeBuffers(k, NULL, pkcs12->heap);
                            freeBuffers(*pkey, buf, pkcs12->heap);
                            freeCertList(certList, pkcs12->heap);
                            return ret;
                        }

                        if (ret < size) {
                            /* shrink key buffer */
                            k = (byte*)XREALLOC(k, ret, pkcs12->heap,
                                                             DYNAMIC_TYPE_PKCS);
                            if (k == NULL) {
                                freeBuffers(*pkey, buf, pkcs12->heap);
                                freeCertList(certList, pkcs12->heap);
                                return MEMORY_E;
                            }
                        }
                        size = ret;

                        if (*pkey == NULL) {
                            *pkey = k;
                            *pkeySz = size;
                        }
                        else { /* only expecting one key */
                            freeBuffers(k, NULL, pkcs12->heap);
                        }
                        idx += size;

                        #ifdef WOLFSSL_DEBUG_PKCS12
                        {
                            byte* p;
                            for (printf("\tKey = "), p = (byte*)k;
                                p < (byte*)k + ret;
                                printf("%02X", *p), p++);
                            printf("\n");
                        }
                        #endif
                    }
                    break;

                case WC_PKCS12_CertBag: /* 669 */
                {
                    WC_DerCertList* node;
                    WOLFSSL_MSG("PKCS12 Cert Bag found");
                    if (data[idx++] !=
                                     (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) {
                        freeBuffers(*pkey, buf, pkcs12->heap);
                        freeCertList(certList, pkcs12->heap);
                        return ASN_PARSE_E;
                    }
                    if ((ret = GetLength(data, &idx, &size, ci->dataSz)) < 0) {
                        freeBuffers(*pkey, buf, pkcs12->heap);
                        freeCertList(certList, pkcs12->heap);
                        return ret;
                    }

                    /* get cert bag type */
                    if ((ret = GetSequence(data, &idx, &size, ci->dataSz)) <0) {
                        freeBuffers(*pkey, buf, pkcs12->heap);
                        freeCertList(certList, pkcs12->heap);
                        return ret;
                    }

                    if ((ret = GetObjectId(data, &idx, &oid, oidIgnoreType,
                                                             ci->dataSz)) < 0) {
                        freeBuffers(*pkey, buf, pkcs12->heap);
                        freeCertList(certList, pkcs12->heap);
                        return ret;
                    }

                    switch (oid) {
                        case WC_PKCS12_CertBag_Type1:  /* 675 */
                            /* type 1 */
                            WOLFSSL_MSG("PKCS12 cert bag type 1");
                            if (data[idx++] !=
                                     (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) {
                                freeBuffers(*pkey, buf, pkcs12->heap);
                                freeCertList(certList, pkcs12->heap);
                                return ASN_PARSE_E;
                            }
                            if ((ret = GetLength(data, &idx, &size, ci->dataSz))
                                                                         <= 0) {
                                freeBuffers(*pkey, buf, pkcs12->heap);
                                freeCertList(certList, pkcs12->heap);
                                return ret;
                            }
                            if (data[idx++] != ASN_OCTET_STRING) {
                                freeBuffers(*pkey, buf, pkcs12->heap);
                                freeCertList(certList, pkcs12->heap);
                                return ASN_PARSE_E;
                            }
                            if ((ret = GetLength(data, &idx, &size, ci->dataSz))
                                                                          < 0) {
                                freeBuffers(*pkey, buf, pkcs12->heap);
                                freeCertList(certList, pkcs12->heap);
                                return ret;
                            }
                            break;
                       default:
                            WOLFSSL_MSG("Unknown PKCS12 cert bag type");
                    }

                    if (size + idx > (word32)bagSz) {
                        freeBuffers(*pkey, buf, pkcs12->heap);
                        freeCertList(certList, pkcs12->heap);
                        return ASN_PARSE_E;
                    }

                    /* list to hold all certs found */
                    node = (WC_DerCertList*)XMALLOC(sizeof(WC_DerCertList),
                                               pkcs12->heap, DYNAMIC_TYPE_PKCS);
                    if (node == NULL) {
                        freeBuffers(*pkey, buf, pkcs12->heap);
                        freeCertList(certList, pkcs12->heap);
                        return MEMORY_E;
                    }
                    XMEMSET(node, 0, sizeof(WC_DerCertList));

                    node->buffer = (byte*)XMALLOC(size, pkcs12->heap,
                                                             DYNAMIC_TYPE_PKCS);
                    if (node->buffer == NULL) {
                        XFREE(node, pkcs12->heap, DYNAMIC_TYPE_PKCS);
                        freeBuffers(*pkey, buf, pkcs12->heap);
                        freeCertList(certList, pkcs12->heap);
                        return MEMORY_E;
                    }
                    XMEMCPY(node->buffer, data + idx, size);
                    node->bufferSz = size;

                    /* put the new node into the list */
                    if (certList != NULL) {
                        WOLFSSL_MSG("Pushing new cert onto stack");
                        node->next = certList;
                        certList = node;
                    }
                    else {
                        certList = node;
                    }

                    /* on to next */
                    idx += size;
                }
                    break;

                case WC_PKCS12_CrlBag: /* 670 */
                    WOLFSSL_MSG("PKCS12 CRL BAG not yet supported");
                    break;

                case WC_PKCS12_SecretBag: /* 671 */
                    WOLFSSL_MSG("PKCS12 Secret BAG not yet supported");
                    break;

                case WC_PKCS12_SafeContentsBag: /* 672 */
                    WOLFSSL_MSG("PKCS12 Safe Contents BAG not yet supported");
                    break;

                default:
                    WOLFSSL_MSG("Unknown PKCS12 BAG type found");
            }

            /* Attribute, unknown bag or unsupported */
            if ((int)idx < bagSz) {
                idx = bagSz; /* skip for now */
            }
        }

        /* free temporary buffer */
        if (buf != NULL) {
            XFREE(buf, pkcs12->heap, DYNAMIC_TYPE_PKCS);
            buf = NULL;
        }
        ci = ci->next;
        WOLFSSL_MSG("Done Parsing PKCS12 Content Info Container");
    }

    /* check if key pair, remove from list */
    {
        WC_DerCertList* current  = certList;
        WC_DerCertList* previous = NULL;

        if (*pkey != NULL) {

        while (current != NULL) {
            DecodedCert DeCert;
            InitDecodedCert(&DeCert, current->buffer, current->bufferSz,
                                                                  pkcs12->heap);
            if (ParseCertRelative(&DeCert, CERT_TYPE, NO_VERIFY, NULL) == 0) {
                if (wc_CheckPrivateKey(*pkey, *pkeySz, &DeCert) == 1) {
                    WOLFSSL_MSG("Key Pair found");
                    *cert = current->buffer;
                    *certSz = current->bufferSz;

                    if (previous == NULL) {
                        certList = current->next;
                    }
                    else {
                        previous->next = current->next;
                    }
                    FreeDecodedCert(&DeCert);
                    XFREE(current, pkcs12->heap, DYNAMIC_TYPE_PKCS);
                    break;
                }
            }

            FreeDecodedCert(&DeCert);
            previous = current;
            current  = current->next;
        }

        }
    }

    if (ca != NULL) {
        *ca = certList;
    }
    else {
        /* free list, not wanted */
        freeCertList(certList, pkcs12->heap);
    }

    return 1;
}