add PKCS12 create example

pull/192/head
Jacob Barthelmeh 2020-03-18 18:19:00 -06:00
parent aeedfa36c0
commit 81827fac5d
3 changed files with 289 additions and 1 deletions

View File

@ -2,10 +2,15 @@ CC=gcc
CFLAGS=-Wall CFLAGS=-Wall
LIBS= -lwolfssl LIBS= -lwolfssl
all:pkcs12-example pkcs12-create-example
pkcs12-example: pkcs12-example.o pkcs12-example: pkcs12-example.o
$(CC) -o $@ $^ $(CFLAGS) $(LIBS) $(CC) -o $@ $^ $(CFLAGS) $(LIBS)
pkcs12-create-example: pkcs12-create-example.o
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
.PHONY: clean .PHONY: clean
clean: clean:
rm -f *.o pkcs12-example rm -f *.o pkcs12-example pkcs12-create-example output.p12

View File

@ -10,3 +10,13 @@ How to use pkcs12-example.c
3) Running 'make clean' will delete the excecutable as well as any created 3) Running 'make clean' will delete the excecutable as well as any created
files. Making sure that the only files left are 'pkcs12-example.c', files. Making sure that the only files left are 'pkcs12-example.c',
'Makefile', 'test-servercert.p12'and 'README'. 'Makefile', 'test-servercert.p12'and 'README'.
How to use pkcs12-create-example
1) Compile wolfSSL with PKCS12 enabled then run 'make' from this directory.
2) A new key and certificate is generated then output into the output.p12 pkcs12
bundled created. The default password is "test password"
./pkcs12-create-example

View File

@ -0,0 +1,273 @@
/* pkcs12-create-example.c
*
* 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
*/
#include <wolfssl/options.h>
#include <wolfssl/wolfcrypt/logging.h>
#include <wolfssl/wolfcrypt/pkcs12.h>
#include <wolfssl/wolfcrypt/asn.h>
#include <wolfssl/wolfcrypt/rsa.h>
#include <wolfssl/wolfcrypt/error-crypt.h>
#define WC_RSA_KEYSIZE 2048
#define HEAP_HINT NULL
static int createKey(byte** keyDer, word32* keySz, RsaKey* key, WC_RNG* rng)
{
int ret;
*keyDer = NULL;
*keySz = 0;
ret = wc_InitRsaKey(key, HEAP_HINT);
if (ret == 0) {
ret = wc_InitRng(rng);
}
if (ret == 0) {
ret = wc_MakeRsaKey(key, WC_RSA_KEYSIZE, WC_RSA_EXPONENT, rng);
}
if (ret == 0) {
*keySz = wc_RsaKeyToDer(key, NULL, 0);
if (*keySz < 0) {
printf("unable to convert RSA key to DER\n");
ret = *keySz;
}
}
if (ret == 0) {
*keyDer = (byte*)XMALLOC(*keySz, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
if (*keyDer == NULL) {
ret = MEMORY_E;
}
}
if (ret == 0) {
*keySz = wc_RsaKeyToDer(key, *keyDer, *keySz);
if (*keySz < 0) {
printf("unable to convert RSA key to DER\n");
ret = *keySz;
}
}
return ret;
}
static void outputFile(byte* out, word32 outSz, char* fileName)
{
FILE* file;
file = fopen(fileName, "wb");
if (!file) {
printf("failed to open file: %s\n", fileName);
}
else {
printf("printing out %d bytes\n", outSz);
fwrite(out, 1, outSz, file);
fclose(file);
}
}
static int readFile(byte** out, word32* outSz, char* fileName)
{
FILE* file;
int ret = 0;
file = fopen(fileName, "rb");
if (!file) {
printf("failed to open file: %s\n", fileName);
return -1;
}
fseek(file, 0, SEEK_END);
*outSz = ftell(file);
rewind(file);
*out = (byte*) XMALLOC(*outSz, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
if (*out == NULL) {
ret = MEMORY_E;
}
else {
*outSz = fread(*out, 1, *outSz, file);
if (*outSz <= 0) {
printf("Failed to read from file\n");
ret = *outSz;
}
else {
printf("Successfully read %d bytes\n", *outSz);
}
}
fclose(file);
return ret;
}
static int getCa(byte** caCert, word32* caCertSz, RsaKey* caKey)
{
int ret;
char caCertFile[] = "../../certs/ca-cert.der";
char caKeyFile[] = "../../certs/ca-key.der";
byte* caKeyDer = NULL;
word32 caKeyDerSz;
word32 idx = 0;
*caCert = NULL;
*caCertSz = 0;
printf("Getting the caKey from %s\n", caKeyFile);
ret = readFile(&caKeyDer, &caKeyDerSz, caKeyFile);
if (ret == 0) {
ret = wc_InitRsaKey(caKey, HEAP_HINT);
}
if (ret == 0) {
ret = wc_RsaPrivateKeyDecode(caKeyDer, &idx, caKey, caKeyDerSz);
if (ret != 0) {
printf("unable to decode RSA key\n");
}
}
/* now get certificate */
if (ret == 0) {
printf("Getting the caCert from %s\n", caCertFile);
ret = readFile(caCert, caCertSz, caCertFile);
}
XFREE(caKeyDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
return ret;
}
static int createCert(byte** certDer, word32* certSz, RsaKey* key, WC_RNG* rng)
{
int ret;
Cert newCert;
RsaKey caKey;
byte* caCert = NULL;
word32 caCertSz;
*certDer = NULL;
*certSz = 4096;
wc_InitCert(&newCert);
strncpy(newCert.subject.country, "US", CTC_NAME_SIZE);
strncpy(newCert.subject.state, "MT", CTC_NAME_SIZE);
strncpy(newCert.subject.locality, "Bozeman", CTC_NAME_SIZE);
strncpy(newCert.subject.org, "yourOrgNameHere", CTC_NAME_SIZE);
strncpy(newCert.subject.unit, "yourUnitNameHere", CTC_NAME_SIZE);
strncpy(newCert.subject.commonName, "www.yourDomain.com", CTC_NAME_SIZE);
strncpy(newCert.subject.email, "yourEmail@yourDomain.com", CTC_NAME_SIZE);
newCert.isCA = 0;
newCert.sigType = CTC_SHA256wRSA;
ret = getCa(&caCert, &caCertSz, &caKey);
if (ret == 0) {
ret = wc_SetIssuerBuffer(&newCert, caCert, caCertSz);
}
if (ret == 0) {
*certDer = (byte*)XMALLOC(*certSz, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
if (*certDer == NULL) {
ret = MEMORY_E;
}
else {
ret = wc_MakeCert(&newCert, *certDer, *certSz, key, NULL, rng);
}
}
printf("MakeCert returned %d\n", ret);
if (ret >= 0) {
ret = wc_SignCert(newCert.bodySz, newCert.sigType, *certDer, *certSz,
&caKey, NULL, rng);
if (ret < 0) {
printf("SignCert returned %d\n", ret);
}
else {
*certSz = ret;
ret = 0; /* return 0 on success */
printf("Successfully created new certificate\n");
}
}
XFREE(caCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
return ret;
}
int main(int argc, char* argv[])
{
WC_PKCS12* pkcs12 = NULL;
WC_RNG rng;
RsaKey rsa;
byte* keyDer = NULL;
word32 keySz;
byte* certDer = NULL;
word32 certSz;
if (createKey(&keyDer, &keySz, &rsa, &rng) != 0) {
printf("Unable to create RSA key\n");
return -1;
}
if (createCert(&certDer, &certSz, &rsa, &rng) != 0) {
printf("Unable to create certificate\n");
wc_FreeRsaKey(&rsa);
wc_FreeRng(&rng);
XFREE(keyDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
return -1;
}
pkcs12 = wc_PKCS12_create("test password", strlen("test password"),
NULL, keyDer, keySz, certDer, certSz,
NULL, PBE_SHA1_DES3, PBE_SHA1_DES3, 100, 100, 0, HEAP_HINT);
if (pkcs12 != NULL) {
int ret;
int pkcs12DerSz = 0;
byte* pkcs12Der = NULL;
printf("Created new PKCS12 structure now converting to DER\n");
if ((ret = wc_i2d_PKCS12(pkcs12, &pkcs12Der, &pkcs12DerSz)) < 0) {
printf("unable to convert structure to DER\n");
}
else {
char output[] = "output.p12";
printf("Printing PKCS12 DER file to %s\n", output);
outputFile(pkcs12Der, ret, output);
XFREE(pkcs12Der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
}
wc_PKCS12_free(pkcs12);
}
wc_FreeRsaKey(&rsa);
wc_FreeRng(&rng);
XFREE(keyDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(certDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
return 0;
}