mirror of https://github.com/wolfSSL/wolfssl.git
PKCS12 : Add PKCS12 parsing
parent
7ef037af0f
commit
b686deecbe
|
@ -146,6 +146,7 @@ mplabx/wolfcrypt_test.X/nbproject/Makefile-*
|
|||
mplabx/wolfcrypt_test.X/nbproject/Package-default.bash
|
||||
mplabx/wolfssl.X/nbproject/Makefile-*
|
||||
mplabx/wolfssl.X/nbproject/Package-default.bash
|
||||
*.dSYM
|
||||
|
||||
# Vagrant folder
|
||||
.vagrant/
|
||||
|
|
|
@ -28,7 +28,8 @@ EXTRA_DIST += \
|
|||
certs/server-keyPkcs8.pem \
|
||||
certs/server-revoked-cert.pem \
|
||||
certs/server-revoked-key.pem \
|
||||
certs/wolfssl-website-ca.pem
|
||||
certs/wolfssl-website-ca.pem \
|
||||
certs/test-servercert.p12
|
||||
EXTRA_DIST += \
|
||||
certs/ca-key.der \
|
||||
certs/ca-cert.der \
|
||||
|
|
Binary file not shown.
|
@ -210,6 +210,7 @@ mkdir -p $RPM_BUILD_ROOT/
|
|||
%{_includedir}/wolfssl/wolfcrypt/mpi_class.h
|
||||
%{_includedir}/wolfssl/wolfcrypt/mpi_superclass.h
|
||||
%{_includedir}/wolfssl/wolfcrypt/pkcs7.h
|
||||
%{_includedir}/wolfssl/wolfcrypt/pkcs12.h
|
||||
%{_includedir}/wolfssl/wolfcrypt/wc_port.h
|
||||
%{_includedir}/wolfssl/wolfcrypt/poly1305.h
|
||||
%{_includedir}/wolfssl/wolfcrypt/pwdbased.h
|
||||
|
@ -274,6 +275,8 @@ mkdir -p $RPM_BUILD_ROOT/
|
|||
%{_libdir}/pkgconfig/wolfssl.pc
|
||||
|
||||
%changelog
|
||||
* Fri Oct 28 2016 Jacob Barthelmeh <jacob@wolfssl.com>
|
||||
- Added header for pkcs12
|
||||
* Fri Sep 23 2016 John Safranek <john@wolfssl.com>
|
||||
- Add the dtls-sctp example sources
|
||||
* Mon Jun 14 2016 Jacob Barthelmeh <jacob@wolfssl.com>
|
||||
|
|
|
@ -153,6 +153,7 @@ endif
|
|||
|
||||
if BUILD_PWDBASED
|
||||
src_libwolfssl_la_SOURCES += wolfcrypt/src/pwdbased.c
|
||||
src_libwolfssl_la_SOURCES += wolfcrypt/src/pkcs12.c
|
||||
endif
|
||||
|
||||
if BUILD_DSA
|
||||
|
|
407
src/ssl.c
407
src/ssl.c
|
@ -11371,6 +11371,99 @@ byte* wolfSSL_X509_get_hw_serial_number(WOLFSSL_X509* x509,byte* in,
|
|||
|
||||
#endif /* WOLFSSL_SEP */
|
||||
|
||||
/* require OPENSSL_EXTRA since wolfSSL_X509_free is wrapped by OPENSSL_EXTRA */
|
||||
#if !defined(NO_CERTS) && defined(OPENSSL_EXTRA)
|
||||
/* return 1 on success 0 on fail */
|
||||
int wolfSSL_sk_X509_push(STACK_OF(WOLFSSL_X509_NAME)* sk, WOLFSSL_X509* x509)
|
||||
{
|
||||
WOLFSSL_STACK* node;
|
||||
|
||||
if (sk == NULL || x509 == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* no previous values in stack */
|
||||
if (sk->data.x509 == NULL) {
|
||||
sk->data.x509 = x509;
|
||||
sk->num += 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* stack already has value(s) create a new node and add more */
|
||||
node = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL,
|
||||
DYNAMIC_TYPE_X509);
|
||||
if (node == NULL) {
|
||||
WOLFSSL_MSG("Memory error");
|
||||
return 0;
|
||||
}
|
||||
XMEMSET(node, 0, sizeof(WOLFSSL_STACK));
|
||||
|
||||
/* push new x509 onto head of stack */
|
||||
node->data.x509 = sk->data.x509;
|
||||
node->next = sk->next;
|
||||
sk->next = node;
|
||||
sk->data.x509 = x509;
|
||||
sk->num += 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
WOLFSSL_X509* wolfSSL_sk_X509_pop(STACK_OF(WOLFSSL_X509_NAME)* sk) {
|
||||
WOLFSSL_STACK* node;
|
||||
WOLFSSL_X509* x509;
|
||||
|
||||
if (sk == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
node = sk->next;
|
||||
x509 = sk->data.x509;
|
||||
|
||||
if (node != NULL) { /* update sk and remove node from stack */
|
||||
sk->data.x509 = node->data.x509;
|
||||
sk->next = node->next;
|
||||
XFREE(node, NULL, DYNAMIC_TYPE_X509);
|
||||
}
|
||||
else { /* last x509 in stack */
|
||||
sk->data.x509 = NULL;
|
||||
}
|
||||
|
||||
if (sk->num > 0) {
|
||||
sk->num -= 1;
|
||||
}
|
||||
|
||||
return x509;
|
||||
}
|
||||
|
||||
|
||||
/* free structure for x509 stack */
|
||||
void wolfSSL_sk_X509_free(STACK_OF(WOLFSSL_X509_NAME)* sk) {
|
||||
WOLFSSL_STACK* node;
|
||||
|
||||
if (sk == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* parse through stack freeing each node */
|
||||
node = sk->next;
|
||||
while (sk->num > 1) {
|
||||
WOLFSSL_STACK* tmp = node;
|
||||
node = node->next;
|
||||
|
||||
wolfSSL_X509_free(tmp->data.x509);
|
||||
XFREE(tmp, NULL, DYNAMIC_TYPE_X509);
|
||||
sk->num -= 1;
|
||||
}
|
||||
|
||||
/* free head of stack */
|
||||
if (sk->num == 1) {
|
||||
wolfSSL_X509_free(sk->data.x509);
|
||||
}
|
||||
XFREE(sk, NULL, DYNAMIC_TYPE_X509);
|
||||
}
|
||||
#endif /* NO_CERTS && OPENSSL_EXTRA */
|
||||
|
||||
|
||||
WOLFSSL_X509* wolfSSL_X509_d2i(WOLFSSL_X509** x509, const byte* in, int len)
|
||||
{
|
||||
|
@ -12411,6 +12504,320 @@ WOLFSSL_X509_LOOKUP* wolfSSL_X509_STORE_add_lookup(WOLFSSL_X509_STORE* store,
|
|||
|
||||
|
||||
#ifndef NO_CERTS
|
||||
|
||||
#if !defined(NO_ASN) && !defined(NO_PWDBASED)
|
||||
WC_PKCS12* wolfSSL_d2i_PKCS12_bio(WOLFSSL_BIO* bio, WC_PKCS12** pkcs12)
|
||||
{
|
||||
WC_PKCS12* localPkcs12 = NULL;
|
||||
const unsigned char* mem = NULL;
|
||||
int ret;
|
||||
word32 size;
|
||||
|
||||
WOLFSSL_ENTER("wolfSSL_d2i_PKCS12_bio");
|
||||
|
||||
if (bio == NULL) {
|
||||
WOLFSSL_MSG("Bad Function Argument bio is NULL");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
localPkcs12 = wc_PKCS12_new();
|
||||
if (localPkcs12 == NULL) {
|
||||
WOLFSSL_MSG("Memory error");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (pkcs12 != NULL) {
|
||||
*pkcs12 = localPkcs12;
|
||||
}
|
||||
|
||||
ret = wolfSSL_BIO_get_mem_data(bio, &mem);
|
||||
if (mem == NULL || ret <= 0) {
|
||||
WOLFSSL_MSG("Failed to get data from bio struct");
|
||||
wc_PKCS12_free(localPkcs12);
|
||||
if (pkcs12 != NULL) {
|
||||
*pkcs12 = NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
size = ret;
|
||||
|
||||
ret = wc_d2i_PKCS12(mem, size, localPkcs12);
|
||||
if (ret <= 0) {
|
||||
WOLFSSL_MSG("Failed to get PKCS12 sequence");
|
||||
wc_PKCS12_free(localPkcs12);
|
||||
if (pkcs12 != NULL) {
|
||||
*pkcs12 = NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return localPkcs12;
|
||||
}
|
||||
|
||||
|
||||
/* return 1 on success, 0 on failure */
|
||||
int wolfSSL_PKCS12_parse(WC_PKCS12* pkcs12, const char* psw,
|
||||
WOLFSSL_EVP_PKEY** pkey, WOLFSSL_X509** cert, STACK_OF(WOLFSSL_X509)** ca)
|
||||
{
|
||||
DecodedCert DeCert;
|
||||
int ret;
|
||||
byte* certData = NULL;
|
||||
word32 certDataSz;
|
||||
byte* pk = NULL;
|
||||
word32 pkSz;
|
||||
DerCertList* certList = NULL;
|
||||
|
||||
WOLFSSL_ENTER("wolfSSL_PKCS12_parse");
|
||||
|
||||
if (pkcs12 == NULL || psw == NULL || pkey == NULL || cert == NULL) {
|
||||
WOLFSSL_MSG("Bad argument value");
|
||||
return 0;
|
||||
}
|
||||
|
||||
*pkey = NULL;
|
||||
*cert = NULL;
|
||||
|
||||
if (ca == NULL) {
|
||||
ret = wc_PKCS12_parse(pkcs12, psw, &pk, &pkSz, &certData, &certDataSz,
|
||||
NULL);
|
||||
}
|
||||
else {
|
||||
*ca = NULL;
|
||||
ret = wc_PKCS12_parse(pkcs12, psw, &pk, &pkSz, &certData, &certDataSz,
|
||||
&certList);
|
||||
}
|
||||
if (ret < 0) {
|
||||
WOLFSSL_LEAVE("wolfSSL_PKCS12_parse", ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Decode cert and place in X509 stack struct */
|
||||
if (certList != NULL) {
|
||||
DerCertList* current = certList;
|
||||
|
||||
*ca = (STACK_OF(WOLFSSL_X509)*)XMALLOC(sizeof(STACK_OF(WOLFSSL_X509)),
|
||||
pkcs12->heap, DYNAMIC_TYPE_PKCS);
|
||||
if (*ca == NULL) {
|
||||
if (pk != NULL) {
|
||||
XFREE(pk, pkcs12->heap, DYNAMIC_TYPE_PKCS);
|
||||
}
|
||||
if (certData != NULL) {
|
||||
XFREE(*cert, pkcs12->heap, DYNAMIC_TYPE_PKCS); *cert = NULL;
|
||||
}
|
||||
/* Free up DerCertList and move on */
|
||||
while (current != NULL) {
|
||||
DerCertList* next = current->next;
|
||||
|
||||
XFREE(current->buffer, pkcs12->heap, DYNAMIC_TYPE_PKCS);
|
||||
XFREE(current, pkcs12->heap, DYNAMIC_TYPE_PKCS);
|
||||
current = next;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
XMEMSET(*ca, 0, sizeof(STACK_OF(WOLFSSL_X509)));
|
||||
|
||||
/* add list of DER certs as X509's to stack */
|
||||
while (current != NULL) {
|
||||
DerCertList* toFree = current;
|
||||
WOLFSSL_X509* x509;
|
||||
|
||||
x509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), pkcs12->heap,
|
||||
DYNAMIC_TYPE_PKCS);
|
||||
InitX509(x509, 1, pkcs12->heap);
|
||||
InitDecodedCert(&DeCert, current->buffer, current->bufferSz,
|
||||
pkcs12->heap);
|
||||
if (ParseCertRelative(&DeCert, CERT_TYPE, NO_VERIFY, NULL) != 0) {
|
||||
WOLFSSL_MSG("Issue with parsing certificate");
|
||||
FreeDecodedCert(&DeCert);
|
||||
wolfSSL_X509_free(x509);
|
||||
}
|
||||
else {
|
||||
if ((ret = CopyDecodedToX509(x509, &DeCert)) != 0) {
|
||||
WOLFSSL_MSG("Failed to copy decoded cert");
|
||||
FreeDecodedCert(&DeCert);
|
||||
wolfSSL_X509_free(x509);
|
||||
wolfSSL_sk_X509_free(*ca); *ca = NULL;
|
||||
if (pk != NULL) {
|
||||
XFREE(pk, pkcs12->heap, DYNAMIC_TYPE_PKCS);
|
||||
}
|
||||
if (certData != NULL) {
|
||||
XFREE(certData, pkcs12->heap, DYNAMIC_TYPE_PKCS);
|
||||
}
|
||||
/* Free up DerCertList */
|
||||
while (current != NULL) {
|
||||
DerCertList* next = current->next;
|
||||
|
||||
XFREE(current->buffer, pkcs12->heap, DYNAMIC_TYPE_PKCS);
|
||||
XFREE(current, pkcs12->heap, DYNAMIC_TYPE_PKCS);
|
||||
current = next;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
FreeDecodedCert(&DeCert);
|
||||
|
||||
if (wolfSSL_sk_X509_push(*ca, x509) != 1) {
|
||||
WOLFSSL_MSG("Failed to push x509 onto stack");
|
||||
wolfSSL_X509_free(x509);
|
||||
wolfSSL_sk_X509_free(*ca); *ca = NULL;
|
||||
if (pk != NULL) {
|
||||
XFREE(pk, pkcs12->heap, DYNAMIC_TYPE_PKCS);
|
||||
}
|
||||
if (certData != NULL) {
|
||||
XFREE(certData, pkcs12->heap, DYNAMIC_TYPE_PKCS);
|
||||
}
|
||||
|
||||
/* Free up DerCertList */
|
||||
while (current != NULL) {
|
||||
DerCertList* next = current->next;
|
||||
|
||||
XFREE(current->buffer, pkcs12->heap, DYNAMIC_TYPE_PKCS);
|
||||
XFREE(current, pkcs12->heap, DYNAMIC_TYPE_PKCS);
|
||||
current = next;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
current = current->next;
|
||||
XFREE(toFree->buffer, pkcs12->heap, DYNAMIC_TYPE_PKCS);
|
||||
XFREE(toFree, pkcs12->heap, DYNAMIC_TYPE_PKCS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Decode cert and place in X509 struct */
|
||||
if (certData != NULL) {
|
||||
*cert = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), pkcs12->heap,
|
||||
DYNAMIC_TYPE_PKCS);
|
||||
if (*cert == NULL) {
|
||||
if (pk != NULL) {
|
||||
XFREE(pk, pkcs12->heap, DYNAMIC_TYPE_PKCS);
|
||||
}
|
||||
if (ca != NULL) {
|
||||
wolfSSL_sk_X509_free(*ca); *ca = NULL;
|
||||
}
|
||||
XFREE(certData, pkcs12->heap, DYNAMIC_TYPE_PKCS);
|
||||
return 0;
|
||||
}
|
||||
InitX509(*cert, 1, pkcs12->heap);
|
||||
InitDecodedCert(&DeCert, certData, certDataSz, pkcs12->heap);
|
||||
if (ParseCertRelative(&DeCert, CERT_TYPE, NO_VERIFY, NULL) != 0) {
|
||||
WOLFSSL_MSG("Issue with parsing certificate");
|
||||
}
|
||||
if ((ret = CopyDecodedToX509(*cert, &DeCert)) != 0) {
|
||||
WOLFSSL_MSG("Failed to copy decoded cert");
|
||||
FreeDecodedCert(&DeCert);
|
||||
if (pk != NULL) {
|
||||
XFREE(pk, pkcs12->heap, DYNAMIC_TYPE_PKCS);
|
||||
}
|
||||
if (ca != NULL) {
|
||||
wolfSSL_sk_X509_free(*ca); *ca = NULL;
|
||||
}
|
||||
wolfSSL_X509_free(*cert); *cert = NULL;
|
||||
return 0;
|
||||
}
|
||||
FreeDecodedCert(&DeCert);
|
||||
XFREE(certData, pkcs12->heap, DYNAMIC_TYPE_PKCS);
|
||||
}
|
||||
|
||||
|
||||
/* get key type */
|
||||
ret = BAD_STATE_E;
|
||||
if (pk != NULL) { /* decode key if present */
|
||||
*pkey = (WOLFSSL_EVP_PKEY*)XMALLOC(sizeof(WOLFSSL_EVP_PKEY),
|
||||
pkcs12->heap, DYNAMIC_TYPE_PKCS);
|
||||
if (*pkey == NULL) {
|
||||
wolfSSL_X509_free(*cert); *cert = NULL;
|
||||
if (ca != NULL) {
|
||||
wolfSSL_sk_X509_free(*ca); *ca = NULL;
|
||||
}
|
||||
XFREE(pk, pkcs12->heap, DYNAMIC_TYPE_PKCS);
|
||||
return 0;
|
||||
}
|
||||
#ifndef NO_RSA
|
||||
{
|
||||
word32 keyIdx = 0;
|
||||
RsaKey key;
|
||||
|
||||
if (wc_InitRsaKey(&key, pkcs12->heap) != 0) {
|
||||
ret = BAD_STATE_E;
|
||||
}
|
||||
else {
|
||||
if ((ret = wc_RsaPrivateKeyDecode(pk, &keyIdx, &key, pkSz))
|
||||
== 0) {
|
||||
(*pkey)->type = RSAk;
|
||||
WOLFSSL_MSG("Found PKCS12 RSA key");
|
||||
}
|
||||
wc_FreeRsaKey(&key);
|
||||
}
|
||||
}
|
||||
#endif /* NO_RSA */
|
||||
|
||||
#ifdef HAVE_ECC
|
||||
{
|
||||
word32 keyIdx = 0;
|
||||
ecc_key key;
|
||||
|
||||
if (ret != 0) { /* if is in fail state check if ECC key */
|
||||
if (wc_ecc_init(&key) != 0) {
|
||||
wolfSSL_X509_free(*cert); *cert = NULL;
|
||||
if (ca != NULL) {
|
||||
wolfSSL_sk_X509_free(*ca); *ca = NULL;
|
||||
}
|
||||
XFREE(*pkey, pkcs12->heap, DYNAMIC_TYPE_PKCS); *pkey = NULL;
|
||||
XFREE(pk, pkcs12->heap, DYNAMIC_TYPE_PKCS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((ret = wc_EccPrivateKeyDecode(pk, &keyIdx, &key, pkSz))
|
||||
!= 0) {
|
||||
wolfSSL_X509_free(*cert); *cert = NULL;
|
||||
if (ca != NULL) {
|
||||
wolfSSL_sk_X509_free(*ca); *ca = NULL;
|
||||
}
|
||||
XFREE(*pkey, pkcs12->heap, DYNAMIC_TYPE_PKCS); *pkey = NULL;
|
||||
XFREE(pk, pkcs12->heap, DYNAMIC_TYPE_PKCS);
|
||||
WOLFSSL_MSG("Bad PKCS12 key format");
|
||||
return 0;
|
||||
}
|
||||
(*pkey)->type = ECDSAk;
|
||||
(*pkey)->pkey_curve = key.dp->oidSum;
|
||||
wc_ecc_free(&key);
|
||||
WOLFSSL_MSG("Found PKCS12 ECC key");
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (ret != 0) { /* if is in fail state and no ECC then fail */
|
||||
wolfSSL_X509_free(*cert); *cert = NULL;
|
||||
if (ca != NULL) {
|
||||
wolfSSL_sk_X509_free(*ca); *ca = NULL;
|
||||
}
|
||||
XFREE(*pkey, pkcs12->heap, DYNAMIC_TYPE_PKCS); *pkey = NULL;
|
||||
XFREE(pk, pkcs12->heap, DYNAMIC_TYPE_PKCS);
|
||||
WOLFSSL_MSG("Bad PKCS12 key format");
|
||||
return 0;
|
||||
}
|
||||
#endif /* HAVE_ECC */
|
||||
|
||||
(*pkey)->save_type = 0;
|
||||
(*pkey)->pkey_sz = pkSz;
|
||||
(*pkey)->pkey.ptr = (char*)pk;
|
||||
}
|
||||
|
||||
(void)ret;
|
||||
(void)ca;
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif /* !defined(NO_ASN) && !defined(NO_PWDBASED) */
|
||||
|
||||
|
||||
/* no-op function. Was initially used for adding encryption algorithms available
|
||||
* for PKCS12 */
|
||||
void wolfSSL_PKCS12_PBE_add(void)
|
||||
{
|
||||
WOLFSSL_ENTER("wolfSSL_PKCS12_PBE_add");
|
||||
}
|
||||
|
||||
int wolfSSL_X509_STORE_add_cert(WOLFSSL_X509_STORE* store, WOLFSSL_X509* x509)
|
||||
{
|
||||
int result = SSL_FATAL_ERROR;
|
||||
|
|
79
tests/api.c
79
tests/api.c
|
@ -45,6 +45,7 @@
|
|||
|
||||
#ifdef OPENSSL_EXTRA
|
||||
#include <wolfssl/openssl/ssl.h>
|
||||
#include <wolfssl/openssl/pkcs12.h>
|
||||
#endif
|
||||
|
||||
/* enable testing buffer load functions */
|
||||
|
@ -1996,6 +1997,83 @@ static void test_wolfSSL_X509_NAME_get_entry(void)
|
|||
#endif /* !NO_CERTS */
|
||||
}
|
||||
|
||||
|
||||
/* Testing functions dealing with PKCS12 parsing out X509 certs */
|
||||
static void test_wolfSSL_PKCS12(void)
|
||||
{
|
||||
/* .p12 file is encrypted with DES3 */
|
||||
#if defined(OPENSSL_EXTRA) && !defined(NO_DES3) && !defined(NO_FILESYSTEM) && \
|
||||
!defined(NO_ASN) && !defined(NO_PWDBASED)
|
||||
byte buffer[5300];
|
||||
char file[] = "./certs/test-servercert.p12";
|
||||
FILE *f;
|
||||
int bytes, ret;
|
||||
WOLFSSL_BIO *bio;
|
||||
WOLFSSL_EVP_PKEY *pkey;
|
||||
WC_PKCS12 *pkcs12;
|
||||
WOLFSSL_X509 *cert;
|
||||
WOLFSSL_X509 *tmp;
|
||||
STACK_OF(WOLFSSL_X509) *ca;
|
||||
|
||||
printf(testingFmt, "wolfSSL_PKCS12()");
|
||||
|
||||
f = fopen(file, "rb");
|
||||
AssertNotNull(f);
|
||||
bytes = (int)fread(buffer, 1, sizeof(buffer), f);
|
||||
fclose(f);
|
||||
|
||||
bio = BIO_new_mem_buf((void*)buffer, bytes);
|
||||
AssertNotNull(bio);
|
||||
|
||||
pkcs12 = d2i_PKCS12_bio(bio, NULL);
|
||||
AssertNotNull(pkcs12);
|
||||
PKCS12_free(pkcs12);
|
||||
|
||||
d2i_PKCS12_bio(bio, &pkcs12);
|
||||
AssertNotNull(pkcs12);
|
||||
|
||||
/* check verify MAC fail case */
|
||||
ret = PKCS12_parse(pkcs12, "bad", &pkey, &cert, NULL);
|
||||
AssertIntEQ(ret, 0);
|
||||
AssertNull(pkey);
|
||||
AssertNull(cert);
|
||||
|
||||
/* check parse with no extra certs kept */
|
||||
ret = PKCS12_parse(pkcs12, "wolfSSL test", &pkey, &cert, NULL);
|
||||
AssertIntEQ(ret, 1);
|
||||
AssertNotNull(pkey);
|
||||
AssertNotNull(cert);
|
||||
|
||||
wolfSSL_EVP_PKEY_free(pkey);
|
||||
wolfSSL_X509_free(cert);
|
||||
|
||||
/* check parse with extra certs kept */
|
||||
ret = PKCS12_parse(pkcs12, "wolfSSL test", &pkey, &cert, &ca);
|
||||
AssertIntEQ(ret, 1);
|
||||
AssertNotNull(pkey);
|
||||
AssertNotNull(cert);
|
||||
AssertNotNull(ca);
|
||||
|
||||
/* should be 2 other certs on stack */
|
||||
tmp = sk_X509_pop(ca);
|
||||
AssertNotNull(tmp);
|
||||
X509_free(tmp);
|
||||
tmp = sk_X509_pop(ca);
|
||||
AssertNotNull(tmp);
|
||||
X509_free(tmp);
|
||||
AssertNull(sk_X509_pop(ca));
|
||||
|
||||
EVP_PKEY_free(pkey);
|
||||
X509_free(cert);
|
||||
BIO_free(bio);
|
||||
PKCS12_free(pkcs12);
|
||||
sk_X509_free(ca);
|
||||
|
||||
printf(resultFmt, passed);
|
||||
#endif /* OPENSSL_EXTRA */
|
||||
}
|
||||
|
||||
|
||||
/* Testing function wolfSSL_CTX_SetMinVersion; sets the minimum downgrade
|
||||
* version allowed.
|
||||
* POST: 1 on success.
|
||||
|
@ -2155,6 +2233,7 @@ void ApiTest(void)
|
|||
|
||||
/* X509 tests */
|
||||
test_wolfSSL_X509_NAME_get_entry();
|
||||
test_wolfSSL_PKCS12();
|
||||
|
||||
/*OCSP Stapling. */
|
||||
AssertIntEQ(test_wolfSSL_UseOCSPStapling(), SSL_SUCCESS);
|
||||
|
|
|
@ -582,12 +582,15 @@ WOLFSSL_LOCAL int GetSet(const byte* input, word32* inOutIdx, int* len,
|
|||
|
||||
/* Windows header clash for WinCE using GetVersion */
|
||||
WOLFSSL_LOCAL int GetMyVersion(const byte* input, word32* inOutIdx,
|
||||
int* version)
|
||||
int* version, word32 maxIdx)
|
||||
{
|
||||
word32 idx = *inOutIdx;
|
||||
|
||||
WOLFSSL_ENTER("GetMyVersion");
|
||||
|
||||
if (idx + MIN_VERSION_SZ > maxIdx)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
if (input[idx++] != ASN_INTEGER)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
|
@ -603,13 +606,16 @@ WOLFSSL_LOCAL int GetMyVersion(const byte* input, word32* inOutIdx,
|
|||
|
||||
#ifndef NO_PWDBASED
|
||||
/* Get small count integer, 32 bits or less */
|
||||
static int GetShortInt(const byte* input, word32* inOutIdx, int* number)
|
||||
int GetShortInt(const byte* input, word32* inOutIdx, int* number, word32 maxIdx)
|
||||
{
|
||||
word32 idx = *inOutIdx;
|
||||
word32 len;
|
||||
|
||||
*number = 0;
|
||||
|
||||
if (idx + 2 > maxIdx) /*one for type and one for length */
|
||||
return ASN_PARSE_E;
|
||||
|
||||
if (input[idx++] != ASN_INTEGER)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
|
@ -617,6 +623,9 @@ static int GetShortInt(const byte* input, word32* inOutIdx, int* number)
|
|||
if (len > 4)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
if (len + idx > maxIdx)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
while (len--) {
|
||||
*number = *number << 8 | input[idx++];
|
||||
}
|
||||
|
@ -629,14 +638,15 @@ static int GetShortInt(const byte* input, word32* inOutIdx, int* number)
|
|||
|
||||
#ifndef NO_ASN_TIME
|
||||
/* May not have one, not an error */
|
||||
static int GetExplicitVersion(const byte* input, word32* inOutIdx, int* version)
|
||||
static int GetExplicitVersion(const byte* input, word32* inOutIdx, int* version,
|
||||
word32 maxIdx)
|
||||
{
|
||||
word32 idx = *inOutIdx;
|
||||
|
||||
WOLFSSL_ENTER("GetExplicitVersion");
|
||||
if (input[idx++] == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) {
|
||||
*inOutIdx = ++idx; /* eat header */
|
||||
return GetMyVersion(input, inOutIdx, version);
|
||||
return GetMyVersion(input, inOutIdx, version, maxIdx);
|
||||
}
|
||||
|
||||
/* go back as is */
|
||||
|
@ -1365,7 +1375,7 @@ int wc_RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
|
|||
if (GetSequence(input, inOutIdx, &length, inSz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
if (GetMyVersion(input, inOutIdx, &version) < 0)
|
||||
if (GetMyVersion(input, inOutIdx, &version, inSz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
key->type = RSA_PRIVATE;
|
||||
|
@ -1393,7 +1403,7 @@ int ToTraditional(byte* input, word32 sz)
|
|||
if (GetSequence(input, &inOutIdx, &length, sz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
if (GetMyVersion(input, &inOutIdx, &version) < 0)
|
||||
if (GetMyVersion(input, &inOutIdx, &version, sz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
if (GetAlgoId(input, &inOutIdx, &oid, oidKeyType, sz) < 0)
|
||||
|
@ -1419,6 +1429,108 @@ int ToTraditional(byte* input, word32 sz)
|
|||
}
|
||||
|
||||
|
||||
/* check that the private key is a pair for the public key in certificate
|
||||
* return 1 (true) on match
|
||||
* return 0 or negative value on failure/error
|
||||
*
|
||||
* key : buffer holding DER fromat key
|
||||
* keySz : size of key buffer
|
||||
* der : a initialized and parsed DecodedCert holding a certificate */
|
||||
int wc_CheckPrivateKey(byte* key, word32 keySz, DecodedCert* der)
|
||||
{
|
||||
if (key == NULL || der == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
#if !defined(NO_RSA)
|
||||
{
|
||||
RsaKey a, b;
|
||||
word32 keyIdx = 0;
|
||||
int ret = 0;
|
||||
|
||||
/* test if RSA key */
|
||||
if (wc_InitRsaKey(&a, NULL) == 0) {
|
||||
if (wc_RsaPrivateKeyDecode(key, &keyIdx, &a, keySz) == 0 &&
|
||||
der->keyOID == RSAk) {
|
||||
WOLFSSL_MSG("Checking RSA key pair");
|
||||
keyIdx = 0; /* reset to 0 for parsing public key */
|
||||
|
||||
if (wc_InitRsaKey(&b, NULL) == 0) {
|
||||
if ((ret = wc_RsaPublicKeyDecode(der->publicKey, &keyIdx,
|
||||
&b, der->pubKeySize)) == 0) {
|
||||
/* limit for user RSA crypto because of RsaKey
|
||||
* dereference. */
|
||||
#if defined(HAVE_USER_RSA)
|
||||
WOLFSSL_MSG("Cannot verify RSA pair with user RSA");
|
||||
wc_FreeRsaKey(&b);
|
||||
wc_FreeRsaKey(&a);
|
||||
return 1; /* return first RSA cert as match */
|
||||
#else
|
||||
/* both keys extracted successfully now check n and e
|
||||
* values are the same. This is dereferencing RsaKey */
|
||||
if (mp_cmp(&(a.n), &(b.n)) != MP_EQ ||
|
||||
mp_cmp(&(a.e), &(b.e)) != MP_EQ) {
|
||||
ret = MP_CMP_E;
|
||||
}
|
||||
else {
|
||||
/* match found, free keys and return success */
|
||||
wc_FreeRsaKey(&b);
|
||||
wc_FreeRsaKey(&a);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
wc_FreeRsaKey(&b);
|
||||
}
|
||||
}
|
||||
wc_FreeRsaKey(&a);
|
||||
}
|
||||
|
||||
/* if ret is not 0 then there was a failed comparision attempt */
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
#endif /* NO_RSA */
|
||||
|
||||
#ifdef HAVE_ECC
|
||||
{
|
||||
int ret = 0;
|
||||
word32 keyIdx = 0;
|
||||
ecc_key key_pair;
|
||||
|
||||
if ((ret = wc_ecc_init(&key_pair)) == 0) {
|
||||
if (wc_EccPrivateKeyDecode(key, &keyIdx, &key_pair, keySz) == 0 &&
|
||||
der->keyOID == ECDSAk) {
|
||||
WOLFSSL_MSG("Checking ECC key pair");
|
||||
keyIdx = 0;
|
||||
if ((ret = wc_ecc_import_x963(der->publicKey, der->pubKeySize,
|
||||
&key_pair)) == 0) {
|
||||
/* public and private extracted successfuly no check if is
|
||||
* a pair and also do sanity checks on key. wc_ecc_check_key
|
||||
* checks that private * base generator equals pubkey */
|
||||
if ((ret = wc_ecc_check_key(&key_pair)) == 0) {
|
||||
/* found a match */
|
||||
wc_ecc_free(&key_pair);
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
wc_ecc_free(&key_pair);
|
||||
}
|
||||
|
||||
/* error on attempt to match */
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_ECC */
|
||||
|
||||
/* no match found */
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef NO_PWDBASED
|
||||
|
||||
/* Check To see if PKCS version algo is supported, set id if it is return 0
|
||||
|
@ -1715,7 +1827,7 @@ int ToTraditionalEnc(byte* input, word32 sz,const char* password,int passwordSz)
|
|||
XMEMCPY(salt, &input[inOutIdx], saltSz);
|
||||
inOutIdx += saltSz;
|
||||
|
||||
if (GetShortInt(input, &inOutIdx, &iterations) < 0) {
|
||||
if (GetShortInt(input, &inOutIdx, &iterations, sz) < 0) {
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(salt, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
|
@ -1803,6 +1915,150 @@ int ToTraditionalEnc(byte* input, word32 sz,const char* password,int passwordSz)
|
|||
return ToTraditional(input, length);
|
||||
}
|
||||
|
||||
/* decrypt PKCS */
|
||||
int DecryptContent(byte* input, word32 sz,const char* password,int passwordSz)
|
||||
{
|
||||
word32 inOutIdx = 0, oid;
|
||||
int ret;
|
||||
int first, second, length, version, saltSz, id;
|
||||
int iterations = 0;
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
byte* salt = NULL;
|
||||
byte* cbcIv = NULL;
|
||||
#else
|
||||
byte salt[MAX_SALT_SIZE];
|
||||
byte cbcIv[MAX_IV_SIZE];
|
||||
#endif
|
||||
|
||||
if (GetAlgoId(input, &inOutIdx, &oid, oidSigType, sz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
first = input[inOutIdx - 2]; /* PKCS version always 2nd to last byte */
|
||||
second = input[inOutIdx - 1]; /* version.algo, algo id last byte */
|
||||
|
||||
if (CheckAlgo(first, second, &id, &version) < 0)
|
||||
return ASN_INPUT_E; /* Algo ID error */
|
||||
|
||||
if (version == PKCS5v2) {
|
||||
|
||||
if (GetSequence(input, &inOutIdx, &length, sz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
if (GetAlgoId(input, &inOutIdx, &oid, oidKdfType, sz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
if (oid != PBKDF2_OID)
|
||||
return ASN_PARSE_E;
|
||||
}
|
||||
|
||||
if (GetSequence(input, &inOutIdx, &length, sz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
if (input[inOutIdx++] != ASN_OCTET_STRING)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
if (GetLength(input, &inOutIdx, &saltSz, sz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
if (saltSz > MAX_SALT_SIZE)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
salt = (byte*)XMALLOC(MAX_SALT_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (salt == NULL)
|
||||
return MEMORY_E;
|
||||
#endif
|
||||
|
||||
XMEMCPY(salt, &input[inOutIdx], saltSz);
|
||||
inOutIdx += saltSz;
|
||||
|
||||
if (GetShortInt(input, &inOutIdx, &iterations, sz) < 0) {
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(salt, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
return ASN_PARSE_E;
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
cbcIv = (byte*)XMALLOC(MAX_IV_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (cbcIv == NULL) {
|
||||
XFREE(salt, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
return MEMORY_E;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (version == PKCS5v2) {
|
||||
/* get encryption algo */
|
||||
/* JOHN: New type. Need a little more research. */
|
||||
if (GetAlgoId(input, &inOutIdx, &oid, oidBlkType, sz) < 0) {
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(salt, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
return ASN_PARSE_E;
|
||||
}
|
||||
|
||||
if (CheckAlgoV2(oid, &id) < 0) {
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(salt, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
return ASN_PARSE_E; /* PKCS v2 algo id error */
|
||||
}
|
||||
|
||||
if (input[inOutIdx++] != ASN_OCTET_STRING) {
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(salt, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
return ASN_PARSE_E;
|
||||
}
|
||||
|
||||
if (GetLength(input, &inOutIdx, &length, sz) < 0) {
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(salt, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
return ASN_PARSE_E;
|
||||
}
|
||||
|
||||
XMEMCPY(cbcIv, &input[inOutIdx], length);
|
||||
inOutIdx += length;
|
||||
}
|
||||
|
||||
if (input[inOutIdx++] != ASN_LONG_LENGTH) {
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(salt, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
return ASN_PARSE_E;
|
||||
}
|
||||
|
||||
if (GetLength(input, &inOutIdx, &length, sz) < 0) {
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(salt, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
return ASN_PARSE_E;
|
||||
}
|
||||
|
||||
if ((ret = DecryptKey(password, passwordSz, salt, saltSz, iterations, id,
|
||||
input + inOutIdx, length, version, cbcIv)) < 0) {
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(salt, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
return ret; /* decrypt failure */
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(salt, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
|
||||
XMEMMOVE(input, input + inOutIdx, length);
|
||||
return length;
|
||||
}
|
||||
#endif /* NO_PWDBASED */
|
||||
|
||||
#ifndef NO_RSA
|
||||
|
@ -1813,6 +2069,10 @@ int wc_RsaPublicKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
|
|||
{
|
||||
int length;
|
||||
|
||||
if (input == NULL || inOutIdx == NULL || key == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (GetSequence(input, inOutIdx, &length, inSz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
|
@ -1995,7 +2255,7 @@ int DsaPrivateKeyDecode(const byte* input, word32* inOutIdx, DsaKey* key,
|
|||
if (GetSequence(input, inOutIdx, &length, inSz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
if (GetMyVersion(input, inOutIdx, &version) < 0)
|
||||
if (GetMyVersion(input, inOutIdx, &version, inSz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
if (GetInt(&key->p, input, inOutIdx, inSz) < 0 ||
|
||||
|
@ -2320,7 +2580,8 @@ static int GetCertHeader(DecodedCert* cert)
|
|||
return ASN_PARSE_E;
|
||||
cert->sigIndex = len + cert->srcIdx;
|
||||
|
||||
if (GetExplicitVersion(cert->source, &cert->srcIdx, &cert->version) < 0)
|
||||
if (GetExplicitVersion(cert->source, &cert->srcIdx, &cert->version,
|
||||
cert->maxIdx) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
if (GetSerialNumber(cert->source, &cert->srcIdx, cert->serial,
|
||||
|
@ -3188,6 +3449,7 @@ static int GetDate(DecodedCert* cert, int dateType)
|
|||
byte b;
|
||||
word32 startIdx = 0;
|
||||
|
||||
XMEMSET(date, 0, MAX_DATE_SIZE);
|
||||
if (dateType == BEFORE)
|
||||
cert->beforeDate = &cert->source[cert->srcIdx];
|
||||
else
|
||||
|
@ -8605,7 +8867,7 @@ int wc_EccPrivateKeyDecode(const byte* input, word32* inOutIdx, ecc_key* key,
|
|||
if (GetSequence(input, inOutIdx, &length, inSz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
if (GetMyVersion(input, inOutIdx, &version) < 0)
|
||||
if (GetMyVersion(input, inOutIdx, &version, inSz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
b = input[*inOutIdx];
|
||||
|
@ -9161,7 +9423,7 @@ static int DecodeResponseData(byte* source,
|
|||
if (source[idx] == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED))
|
||||
{
|
||||
idx += 2; /* Eat the value and length */
|
||||
if (GetMyVersion(source, &idx, &version) < 0)
|
||||
if (GetMyVersion(source, &idx, &version, size) < 0)
|
||||
return ASN_PARSE_E;
|
||||
} else
|
||||
version = 0;
|
||||
|
@ -9821,7 +10083,7 @@ int ParseCRL(DecodedCRL* dcrl, const byte* buff, word32 sz, void* cm)
|
|||
|
||||
/* may have version */
|
||||
if (buff[idx] == ASN_INTEGER) {
|
||||
if (GetMyVersion(buff, &idx, &version) < 0)
|
||||
if (GetMyVersion(buff, &idx, &version, sz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -735,7 +735,7 @@ int wc_PKCS7_VerifySignedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz)
|
|||
return ASN_PARSE_E;
|
||||
|
||||
/* Get the version */
|
||||
if (GetMyVersion(pkiMsg, &idx, &version) < 0)
|
||||
if (GetMyVersion(pkiMsg, &idx, &version, pkiMsgSz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
if (version != 1) {
|
||||
|
@ -830,7 +830,7 @@ int wc_PKCS7_VerifySignedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz)
|
|||
return ASN_PARSE_E;
|
||||
|
||||
/* Get the version */
|
||||
if (GetMyVersion(pkiMsg, &idx, &version) < 0)
|
||||
if (GetMyVersion(pkiMsg, &idx, &version, pkiMsgSz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
if (version != 1) {
|
||||
|
@ -1530,7 +1530,7 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg,
|
|||
if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
if (GetMyVersion(pkiMsg, &idx, &version) < 0)
|
||||
if (GetMyVersion(pkiMsg, &idx, &version, pkiMsgSz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
if (version != 0) {
|
||||
|
@ -1563,7 +1563,7 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg,
|
|||
break;
|
||||
}
|
||||
|
||||
if (GetMyVersion(pkiMsg, &idx, &version) < 0) {
|
||||
if (GetMyVersion(pkiMsg, &idx, &version, pkiMsgSz) < 0) {
|
||||
idx = savedIdx;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -259,6 +259,10 @@
|
|||
RelativePath=".\wolfcrypt\src\pkcs7.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\wolfcrypt\src\pkcs12.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\wolfcrypt\src\poly1305.c"
|
||||
>
|
||||
|
|
|
@ -305,6 +305,7 @@
|
|||
<ClCompile Include="wolfcrypt\src\md5.c" />
|
||||
<ClCompile Include="wolfcrypt\src\memory.c" />
|
||||
<ClCompile Include="wolfcrypt\src\pkcs7.c" />
|
||||
<ClCompile Include="wolfcrypt\src\pkcs12.c" />
|
||||
<ClCompile Include="wolfcrypt\src\poly1305.c" />
|
||||
<ClCompile Include="wolfcrypt\src\pwdbased.c" />
|
||||
<ClCompile Include="wolfcrypt\src\rabbit.c" />
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
#endif
|
||||
#ifndef NO_ASN
|
||||
#include <wolfssl/wolfcrypt/asn.h>
|
||||
#include <wolfssl/wolfcrypt/pkcs12.h>
|
||||
#endif
|
||||
#ifndef NO_MD5
|
||||
#include <wolfssl/wolfcrypt/md5.h>
|
||||
|
@ -2485,6 +2486,17 @@ typedef struct Arrays {
|
|||
#define MAX_DATE_SZ 32
|
||||
#endif
|
||||
|
||||
typedef struct WOLFSSL_STACK {
|
||||
unsigned long num; /* number of nodes in stack
|
||||
* (saftey measure for freeing and shortcut for count) */
|
||||
union {
|
||||
WOLFSSL_X509* x509;
|
||||
WOLFSSL_BIO* bio;
|
||||
} data;
|
||||
WOLFSSL_STACK* next;
|
||||
} WOLFSSL_STACK;
|
||||
|
||||
|
||||
struct WOLFSSL_X509_NAME {
|
||||
char *name;
|
||||
char staticName[ASN_NAME_MAX];
|
||||
|
|
|
@ -1,2 +1,14 @@
|
|||
/* pkcs12.h for openssl */
|
||||
|
||||
#include <wolfssl/wolfcrypt/pkcs12.h>
|
||||
|
||||
/* wolfCrypt level does not make use of ssl.h */
|
||||
#define PKCS12 WC_PKCS12
|
||||
#define PKCS12_new wc_PKCS12_new
|
||||
#define PKCS12_free wc_PKCS12_free
|
||||
|
||||
/* wolfSSL level using structs from ssl.h and calls down to wolfCrypt */
|
||||
#define d2i_PKCS12_bio wolfSSL_d2i_PKCS12_bio
|
||||
#define PKCS12_parse wolfSSL_PKCS12_parse
|
||||
#define PKCS12_PBE_add wolfSSL_PKCS12_PBE_add
|
||||
|
||||
|
|
|
@ -398,6 +398,8 @@ typedef WOLFSSL_X509_STORE_CTX X509_STORE_CTX;
|
|||
|
||||
#define sk_num wolfSSL_sk_num
|
||||
#define sk_value wolfSSL_sk_value
|
||||
#define sk_X509_pop wolfSSL_sk_X509_pop
|
||||
#define sk_X509_free wolfSSL_sk_X509_free
|
||||
|
||||
#define SSL_CTX_get_ex_data wolfSSL_CTX_get_ex_data
|
||||
#define SSL_CTX_set_ex_data wolfSSL_CTX_set_ex_data
|
||||
|
|
|
@ -70,6 +70,7 @@ typedef struct WOLFSSL_SESSION WOLFSSL_SESSION;
|
|||
typedef struct WOLFSSL_METHOD WOLFSSL_METHOD;
|
||||
typedef struct WOLFSSL_CTX WOLFSSL_CTX;
|
||||
|
||||
typedef struct WOLFSSL_STACK WOLFSSL_STACK;
|
||||
typedef struct WOLFSSL_X509 WOLFSSL_X509;
|
||||
typedef struct WOLFSSL_X509_NAME WOLFSSL_X509_NAME;
|
||||
typedef struct WOLFSSL_X509_NAME_ENTRY WOLFSSL_X509_NAME_ENTRY;
|
||||
|
@ -422,7 +423,11 @@ WOLFSSL_API const char* wolfSSL_ERR_reason_error_string(unsigned long);
|
|||
|
||||
/* extras */
|
||||
|
||||
#define STACK_OF(x) x
|
||||
#define STACK_OF(x) WOLFSSL_STACK
|
||||
WOLFSSL_API int wolfSSL_sk_X509_push(STACK_OF(WOLFSSL_X509_NAME)* sk,
|
||||
WOLFSSL_X509* x509);
|
||||
WOLFSSL_API WOLFSSL_X509* wolfSSL_sk_X509_pop(STACK_OF(WOLFSSL_X509_NAME)* sk);
|
||||
WOLFSSL_API void wolfSSL_sk_X509_free(STACK_OF(WOLFSSL_X509_NAME)* sk);
|
||||
|
||||
WOLFSSL_API int wolfSSL_set_ex_data(WOLFSSL*, int, void*);
|
||||
WOLFSSL_API int wolfSSL_get_shutdown(const WOLFSSL*);
|
||||
|
@ -982,6 +987,18 @@ WOLFSSL_API WOLFSSL_X509* wolfSSL_X509_load_certificate_buffer(
|
|||
/* connect enough to get peer cert */
|
||||
WOLFSSL_API int wolfSSL_connect_cert(WOLFSSL* ssl);
|
||||
|
||||
|
||||
|
||||
/* PKCS12 compatibility */
|
||||
typedef struct WC_PKCS12 WC_PKCS12;
|
||||
WOLFSSL_API WC_PKCS12* wolfSSL_d2i_PKCS12_bio(WOLFSSL_BIO* bio,
|
||||
WC_PKCS12** pkcs12);
|
||||
WOLFSSL_API int wolfSSL_PKCS12_parse(WC_PKCS12* pkcs12, const char* psw,
|
||||
WOLFSSL_EVP_PKEY** pkey, WOLFSSL_X509** cert, STACK_OF(WOLFSSL_X509)** ca);
|
||||
WOLFSSL_API void wolfSSL_PKCS12_PBE_add(void);
|
||||
|
||||
|
||||
|
||||
#ifndef NO_DH
|
||||
/* server Diffie-Hellman parameters */
|
||||
WOLFSSL_API int wolfSSL_SetTmpDH(WOLFSSL*, const unsigned char* p, int pSz,
|
||||
|
@ -1778,8 +1795,9 @@ WOLFSSL_API char* wolfSSL_ASN1_TIME_to_string(WOLFSSL_ASN1_TIME* time,
|
|||
char* buf, int len);
|
||||
#endif /* WOLFSSL_MYSQL_COMPATIBLE */
|
||||
|
||||
#ifdef OPENSSL_EXTRA /*lighttp compatibility */
|
||||
#ifdef OPENSSL_EXTRA
|
||||
|
||||
/*lighttp compatibility */
|
||||
#include <wolfssl/openssl/asn1.h>
|
||||
struct WOLFSSL_X509_NAME_ENTRY {
|
||||
WOLFSSL_ASN1_OBJECT* object; /* not defined yet */
|
||||
|
|
|
@ -195,7 +195,8 @@ enum Misc_ASN {
|
|||
MAX_PUBLIC_KEY_SZ = MAX_NTRU_ENC_SZ + MAX_ALGO_SZ + MAX_SEQ_SZ * 2,
|
||||
/* use bigger NTRU size */
|
||||
HEADER_ENCRYPTED_KEY_SIZE = 88,/* Extra header size for encrypted key */
|
||||
TRAILING_ZERO = 1 /* Used for size of zero pad */
|
||||
TRAILING_ZERO = 1, /* Used for size of zero pad */
|
||||
MIN_VERSION_SZ = 3 /* Min bytes needed for GetMyVersion */
|
||||
};
|
||||
|
||||
|
||||
|
@ -633,6 +634,7 @@ WOLFSSL_LOCAL void FreeTrustedPeerTable(TrustedPeerCert**, int, void*);
|
|||
|
||||
WOLFSSL_LOCAL int ToTraditional(byte* buffer, word32 length);
|
||||
WOLFSSL_LOCAL int ToTraditionalEnc(byte* buffer, word32 length,const char*,int);
|
||||
WOLFSSL_LOCAL int DecryptContent(byte* input, word32 sz,const char* psw,int pswSz);
|
||||
|
||||
typedef struct tm wolfssl_tm;
|
||||
#if defined(WOLFSSL_MYSQL_COMPATIBLE)
|
||||
|
@ -646,6 +648,8 @@ WOLFSSL_LOCAL int ValidateDate(const byte* date, byte format, int dateType);
|
|||
#ifdef WOLFSSL_CERT_GEN
|
||||
WOLFSSL_TEST_API int SetName(byte* output, word32 outputSz, CertName* name);
|
||||
#endif
|
||||
WOLFSSL_LOCAL int GetShortInt(const byte* input, word32* inOutIdx, int* number,
|
||||
word32 maxIdx);
|
||||
WOLFSSL_LOCAL int GetLength(const byte* input, word32* inOutIdx, int* len,
|
||||
word32 maxIdx);
|
||||
WOLFSSL_LOCAL int GetSequence(const byte* input, word32* inOutIdx, int* len,
|
||||
|
@ -653,7 +657,7 @@ WOLFSSL_LOCAL int GetSequence(const byte* input, word32* inOutIdx, int* len,
|
|||
WOLFSSL_LOCAL int GetSet(const byte* input, word32* inOutIdx, int* len,
|
||||
word32 maxIdx);
|
||||
WOLFSSL_LOCAL int GetMyVersion(const byte* input, word32* inOutIdx,
|
||||
int* version);
|
||||
int* version, word32 maxIdx);
|
||||
WOLFSSL_LOCAL int GetInt(mp_int* mpi, const byte* input, word32* inOutIdx,
|
||||
word32 maxIdx);
|
||||
#ifdef HAVE_OID_ENCODING
|
||||
|
@ -681,6 +685,7 @@ WOLFSSL_LOCAL int GetSerialNumber(const byte* input, word32* inOutIdx,
|
|||
byte* serial, int* serialSz, word32 maxIdx);
|
||||
WOLFSSL_LOCAL int GetNameHash(const byte* source, word32* idx, byte* hash,
|
||||
int maxIdx);
|
||||
WOLFSSL_LOCAL int wc_CheckPrivateKey(byte* key, word32 keySz, DecodedCert* der);
|
||||
|
||||
#ifdef HAVE_ECC
|
||||
/* ASN sig helpers */
|
||||
|
|
|
@ -57,7 +57,8 @@ nobase_include_HEADERS+= \
|
|||
wolfssl/wolfcrypt/mpi_class.h \
|
||||
wolfssl/wolfcrypt/mpi_superclass.h \
|
||||
wolfssl/wolfcrypt/mem_track.h \
|
||||
wolfssl/wolfcrypt/wolfevent.h
|
||||
wolfssl/wolfcrypt/wolfevent.h \
|
||||
wolfssl/wolfcrypt/pkcs12.h
|
||||
|
||||
noinst_HEADERS+= \
|
||||
wolfssl/wolfcrypt/port/pic32/pic32mz-crypt.h \
|
||||
|
|
|
@ -0,0 +1,114 @@
|
|||
/* pkcs12.h
|
||||
*
|
||||
* Copyright (C) 2006-2016 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL.
|
||||
*
|
||||
* wolfSSL is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* wolfSSL is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
||||
*/
|
||||
|
||||
|
||||
#ifndef WOLF_CRYPT_PKCS12_H
|
||||
#define WOLF_CRYPT_PKCS12_H
|
||||
|
||||
#include <wolfssl/wolfcrypt/types.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
enum {
|
||||
WC_PKCS12_KeyBag = 667,
|
||||
WC_PKCS12_ShroudedKeyBag = 668,
|
||||
WC_PKCS12_CertBag = 669,
|
||||
WC_PKCS12_CertBag_Type1 = 675,
|
||||
WC_PKCS12_CrlBag = 670,
|
||||
WC_PKCS12_SecretBag = 671,
|
||||
WC_PKCS12_SafeContentsBag = 672,
|
||||
WC_PKCS12_DATA = 651,
|
||||
WC_PKCS12_ENCRYPTED_DATA = 656,
|
||||
};
|
||||
|
||||
|
||||
typedef struct DerCertList DerCertList;
|
||||
typedef struct DerCertList {
|
||||
byte* buffer;
|
||||
word32 bufferSz;
|
||||
DerCertList* next;
|
||||
} DerCertList;
|
||||
|
||||
|
||||
typedef struct ContentInfo ContentInfo;
|
||||
typedef struct ContentInfo {
|
||||
byte* data;
|
||||
ContentInfo* next;
|
||||
word32 encC; /* encryptedContent */
|
||||
word32 dataSz;
|
||||
int type; /* DATA / encrypted / envelpoed */
|
||||
} ContentInfo;
|
||||
|
||||
|
||||
typedef struct AuthenticatedSafe {
|
||||
ContentInfo* CI;
|
||||
byte* data; /* T contents.... */
|
||||
word32 oid; /* encrypted or not */
|
||||
word32 numCI; /* number of Content Info structs */
|
||||
word32 dataSz;
|
||||
} AuthenticatedSafe;
|
||||
|
||||
|
||||
typedef struct MacData {
|
||||
byte* digest;
|
||||
byte* salt;
|
||||
word32 oid;
|
||||
word32 digestSz;
|
||||
word32 saltSz;
|
||||
int itt; /* number of itterations when creating HMAC key */
|
||||
} MacData;
|
||||
|
||||
|
||||
/* for friendlyName, localKeyId .... */
|
||||
typedef struct WC_PKCS12_ATTRIBUTE {
|
||||
byte* data;
|
||||
word32 oid;
|
||||
word32 dataSz;
|
||||
} WC_PKCS12_ATTRIBUTE;
|
||||
|
||||
|
||||
typedef struct WC_PKCS12 {
|
||||
void* heap;
|
||||
AuthenticatedSafe* safe;
|
||||
MacData* signData;
|
||||
word32 oid; /* DATA / Enveloped DATA ... */
|
||||
} WC_PKCS12;
|
||||
|
||||
|
||||
WOLFSSL_API WC_PKCS12* wc_PKCS12_new(void);
|
||||
WOLFSSL_API void wc_PKCS12_free(WC_PKCS12* pkcs12);
|
||||
WOLFSSL_API int wc_d2i_PKCS12(const byte* der, word32 derSz, WC_PKCS12* pkcs12);
|
||||
WOLFSSL_API int wc_PKCS12_parse(WC_PKCS12* pkcs12, const char* psw,
|
||||
byte** pkey, word32* pkeySz, byte** cert, word32* certSz,
|
||||
DerCertList** ca);
|
||||
|
||||
WOLFSSL_LOCAL int wc_PKCS12_SetHeap(WC_PKCS12* pkcs12, void* heap);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* WOLF_CRYPT_PKCS12_H */
|
||||
|
Loading…
Reference in New Issue