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; }
/* 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; }
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; }
/* 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; }
/* 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; }