Merge pull request #277 from dgarske/csr_sign

pull/281/head
Anthony Hu 2021-11-30 10:15:51 -05:00 committed by GitHub
commit b96386c95e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 141 additions and 432 deletions

7
.gitignore vendored
View File

@ -112,6 +112,13 @@ certgen/csr_sign
certgen/csr_w_ed25519_example certgen/csr_w_ed25519_example
certgen/certgen_with_altnames certgen/certgen_with_altnames
certgen/ecc-csr.pem
certgen/ecc-key.pem
certgen/ed25519-csr.pem
certgen/ed25519-key.pem
certgen/newCert.der
certgen/newCert.pem
btle/ecc-client btle/ecc-client
btle/ecc-server btle/ecc-server

View File

@ -38,8 +38,8 @@ ORG UNIT = Consulting (10)
``` ```
EXAMPLE B: (Assuming you've built and run the certgen_with_altnames example from EXAMPLE B: (Assuming you've built and run the certgen_example example from
wolfssl-examples/certgen/ directory) wolfssl-examples/certgen/ directory with WOLFSSL_ALT_NAMES)
NOTE: Must configure with `--enable-opensslall` to see the IP address output! NOTE: Must configure with `--enable-opensslall` to see the IP address output!

View File

@ -13,7 +13,7 @@ CFLAGS=-I$(WOLF_INSTALL_DIR)/include -Wall
LIBS=-L$(WOLF_INSTALL_DIR)/lib -lwolfssl LIBS=-L$(WOLF_INSTALL_DIR)/lib -lwolfssl
all:certgen_example csr_example csr_w_ed25519_example csr_sign certgen_with_altnames all:certgen_example csr_example csr_w_ed25519_example csr_sign
certgen_example:certgen_example.o certgen_example:certgen_example.o
$(CC) -o $@ $^ $(CFLAGS) $(CPPFLAGS) $(LIBS) $(CC) -o $@ $^ $(CFLAGS) $(CPPFLAGS) $(LIBS)
@ -27,11 +27,8 @@ csr_w_ed25519_example:csr_w_ed25519_example.o
csr_sign:csr_sign.o csr_sign:csr_sign.o
$(CC) -o $@ $^ $(CFLAGS) $(CPPFLAGS) $(LIBS) $(CC) -o $@ $^ $(CFLAGS) $(CPPFLAGS) $(LIBS)
certgen_with_altnames:certgen_with_altnames.o
$(CC) -o $@ $^ $(CFLAGS) $(CPPFLAGS) $(LIBS)
.PHONY: clean all .PHONY: clean all
clean: clean:
rm -f *.o certgen_example csr_example csr_w_ed25519_example csr_sign certgen_with_altnames rm -f *.o certgen_example csr_example csr_w_ed25519_example csr_sign
rm -f newCert.* rm -f newCert.*

View File

@ -157,7 +157,7 @@ Saved CSR PEM to "ed25519-csr.pem"
This example shows how to use a CSR to sign it using a CA cert and key to produce an X.509 certificate. This example shows how to use a CSR to sign it using a CA cert and key to produce an X.509 certificate.
``` ```
% ./csr_sign ecc ecc-csr.pem ca-ecc-cert.der ca-ecc-key.der % ./csr_sign ecc-csr.pem ca-ecc-cert.der ca-ecc-key.der
Loading CA certificate Loading CA certificate
Read 666 bytes from ca-ecc-cert.der Read 666 bytes from ca-ecc-cert.der
@ -192,10 +192,12 @@ Successfully converted the DER to PEM to "./newCert.pem"
Tests passed Tests passed
``` ```
## Certificate Generation Example with alt names ## Certificate Generation Example with alt names
Pretty much the same as the certgen_example but adds some alt names to the cert The alternate names feature is enabled with the wolfSSL build option
`WOLFSSL_ALT_NAMES`. In the certgen_example.c see the `WOLFSSL_ALT_NAMES`
sections for how to add this to a CSR.
Unfortunately wolfSSL does not yet have an API for this but this example shows Unfortunately wolfSSL does not yet have an API for this but this example shows
how to setup your own ASN.1 format string for using with the wolfSSL certificate how to setup your own ASN.1 format string for using with the wolfSSL certificate
structure. TODO: Add an API for this! structure. TODO: Add an API for this!

View File

@ -27,6 +27,9 @@
#include <wolfssl/wolfcrypt/asn.h> #include <wolfssl/wolfcrypt/asn.h>
#include <wolfssl/wolfcrypt/error-crypt.h> #include <wolfssl/wolfcrypt/error-crypt.h>
#if defined(WOLFSSL_CERT_REQ) && defined(WOLFSSL_CERT_GEN) && \
defined(WOLFSSL_KEY_GEN) && defined(HAVE_ECC)
#define HEAP_HINT NULL #define HEAP_HINT NULL
#define LARGE_TEMP_SZ 4096 #define LARGE_TEMP_SZ 4096
@ -60,10 +63,45 @@ static int do_csrgen(int argc, char** argv)
int pemBufSz; int pemBufSz;
#endif #endif
/*---------------------------------------------------------------------------*/ #ifdef WOLFSSL_ALT_NAMES
/* open the CA der formatted certificate, we need to get it's subject line to /* Add some alt names to our cert: */
* use in the new cert we're creating as the "Issuer" line */ const char myAltNames[] = {
/*---------------------------------------------------------------------------*/ /* SEQUENCE (1 element with 3 segments. Entire length is 41
* (0x29 in hex))
*/
0x30, 0x29,
/* This is a String 0x8, it denotes a DNSName 0x2 -> 0x82
* This strings' length is 9 (0x09)
*/
0x82, 0x09,
/* This strings value is "localhost" (in hex) */
0x6C, 0x6F, 0x63, 0x61, 0x6C, 0x68, 0x6F, 0x73, 0x74,
/* This is a String 0x8, it denotes a DNSName 0x2 -> 0x82
* This strings' length is 11 (0x0B)
*/
0x82, 0x0B,
/* This strings value is "example.com" (in hex) */
0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d,
/* This is a String 0x8, it denotes a DNSName 0x2 -> 0x82
* This strings' length is 9 (0x09)
*/
0x82, 0x09,
/* This strings value is "127.0.0.1" (in hex) */
0x31, 0x32, 0x37, 0x2e, 0x30, 0x2e, 0x30, 0x2e, 0x31,
/* This is a string 0x08, it denotes an IP Address 0x07 -> 0x87 */
/* This strings length is 4 (0x04) */
0x87, 0x04,
/* The IP address is 127 (0x7F), 0 (0x00), 0, (0x00), 1 (0x01) ->
* 127.0.0.1
*/
0x7F, 0x00, 0x00, 0x01
};
#endif
/*------------------------------------------------------------------------*/
/* open the CA der formatted certificate, we need to get it's subject line
* to use in the new cert we're creating as the "Issuer" line */
/*------------------------------------------------------------------------*/
printf("Loading CA certificate\n"); printf("Loading CA certificate\n");
derBuf = (byte*)XMALLOC(LARGE_TEMP_SZ, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); derBuf = (byte*)XMALLOC(LARGE_TEMP_SZ, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
@ -80,9 +118,9 @@ static int do_csrgen(int argc, char** argv)
printf("Successfully read %d bytes from %s\n\n", derBufSz, certToUse); printf("Successfully read %d bytes from %s\n\n", derBufSz, certToUse);
/*---------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
/* open caKey file and get the caKey, we need it to sign our new cert */ /* open caKey file and get the caKey, we need it to sign our new cert */
/*---------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
printf("Loading the CA key\n"); printf("Loading the CA key\n");
caKeyBuf = (byte*)XMALLOC(LARGE_TEMP_SZ, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); caKeyBuf = (byte*)XMALLOC(LARGE_TEMP_SZ, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
@ -113,9 +151,9 @@ static int do_csrgen(int argc, char** argv)
printf("Successfully loaded CA Key\n\n"); printf("Successfully loaded CA Key\n\n");
/*---------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
/* Generate new private key to go with our new cert */ /* Generate new private key to go with our new cert */
/*---------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
ret = wc_InitRng(&rng); ret = wc_InitRng(&rng);
if (ret != 0) goto exit; if (ret != 0) goto exit;
initRng = 1; initRng = 1;
@ -130,10 +168,10 @@ static int do_csrgen(int argc, char** argv)
printf("Successfully created new ECC key\n\n"); printf("Successfully created new ECC key\n\n");
/*---------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
/* Create a new certificate using SUBJECT information from ca cert /* Create a new certificate using SUBJECT information from ca cert
* for ISSUER information in generated cert */ * for ISSUER information in generated cert */
/*---------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
printf("Setting new cert issuer to subject of signer\n"); printf("Setting new cert issuer to subject of signer\n");
wc_InitCert(&newCert); wc_InitCert(&newCert);
@ -145,6 +183,12 @@ static int do_csrgen(int argc, char** argv)
strncpy(newCert.subject.unit, "yourUnitNameHere", CTC_NAME_SIZE); strncpy(newCert.subject.unit, "yourUnitNameHere", CTC_NAME_SIZE);
strncpy(newCert.subject.commonName, "www.yourDomain.com", CTC_NAME_SIZE); strncpy(newCert.subject.commonName, "www.yourDomain.com", CTC_NAME_SIZE);
strncpy(newCert.subject.email, "yourEmail@yourDomain.com", CTC_NAME_SIZE); strncpy(newCert.subject.email, "yourEmail@yourDomain.com", CTC_NAME_SIZE);
#ifdef WOLFSSL_ALT_NAMES
XMEMCPY(newCert.altNames, myAltNames, sizeof(myAltNames));
newCert.altNamesSz = (int) sizeof(myAltNames);
#endif
newCert.isCA = 0; newCert.isCA = 0;
newCert.sigType = CTC_SHA256wECDSA; newCert.sigType = CTC_SHA256wECDSA;
@ -155,8 +199,8 @@ static int do_csrgen(int argc, char** argv)
if (ret < 0) goto exit; if (ret < 0) goto exit;
printf("Make Cert returned %d\n", ret); printf("Make Cert returned %d\n", ret);
ret = wc_SignCert(newCert.bodySz, newCert.sigType, derBuf, LARGE_TEMP_SZ, NULL, ret = wc_SignCert(newCert.bodySz, newCert.sigType, derBuf, LARGE_TEMP_SZ,
&caKey, &rng); NULL, &caKey, &rng);
if (ret < 0) goto exit; if (ret < 0) goto exit;
printf("Signed Cert returned %d\n", ret); printf("Signed Cert returned %d\n", ret);
@ -164,9 +208,9 @@ static int do_csrgen(int argc, char** argv)
printf("Successfully created new certificate\n\n"); printf("Successfully created new certificate\n\n");
/*---------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
/* write the new cert to file in der format */ /* write the new cert to file in der format */
/*---------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
printf("Writing newly generated DER certificate to file \"%s\"\n", printf("Writing newly generated DER certificate to file \"%s\"\n",
newCertOutput); newCertOutput);
file = fopen(newCertOutput, "wb"); file = fopen(newCertOutput, "wb");
@ -180,9 +224,9 @@ static int do_csrgen(int argc, char** argv)
printf("Successfully output %d bytes\n", ret); printf("Successfully output %d bytes\n", ret);
#ifdef WOLFSSL_DER_TO_PEM #ifdef WOLFSSL_DER_TO_PEM
/*---------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
/* convert the der to a pem and write it to a file */ /* convert the der to a pem and write it to a file */
/*---------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
printf("Convert the DER cert to PEM formatted cert\n"); printf("Convert the DER cert to PEM formatted cert\n");
pemBuf = (byte*)XMALLOC(LARGE_TEMP_SZ, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); pemBuf = (byte*)XMALLOC(LARGE_TEMP_SZ, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
@ -227,11 +271,14 @@ exit:
printf("Failure code was %d\n", ret); printf("Failure code was %d\n", ret);
return ret; return ret;
} }
#endif
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
#if !defined(WOLFSSL_CERT_REQ) || !defined(WOLFSSL_CERT_GEN) || !defined(WOLFSSL_KEY_GEN) #if !defined(WOLFSSL_CERT_REQ) || !defined(WOLFSSL_CERT_GEN) || \
printf("Please compile wolfSSL with --enable-certreq --enable-certgen --enable-keygen\n"); !defined(WOLFSSL_KEY_GEN) || !defined(HAVE_ECC)
printf("Please compile wolfSSL with --enable-certreq --enable-certgen "
"--enable-keygen --enable-ecc\n");
return 0; return 0;
#else #else
return do_csrgen(argc, argv); return do_csrgen(argc, argv);

View File

@ -1,356 +0,0 @@
/* certgen_with_altnames.c
*
* Copyright (C) 2006-2020 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 <stdio.h>
#include <wolfssl/options.h>
#include <wolfssl/wolfcrypt/settings.h>
#include <wolfssl/wolfcrypt/ecc.h>
#include <wolfssl/wolfcrypt/asn_public.h>
#include <wolfssl/wolfcrypt/asn.h>
#include <wolfssl/wolfcrypt/error-crypt.h>
#define HEAP_HINT NULL
#define FOURK_SZ 4096
#if defined(WOLFSSL_CERT_REQ) && defined(WOLFSSL_CERT_GEN)
void free_things(byte** a, byte** b, byte** c, ecc_key* d, ecc_key* e,
WC_RNG* f);
#endif
int main(void) {
#if !defined(WOLFSSL_CERT_REQ) || !defined(WOLFSSL_CERT_GEN) || \
!defined(WOLFSSL_ALT_NAMES)
printf("Please compile wolfSSL with the following and try again:\n");
printf(" --enable-certreq --enable-certgen CFLAGS=-DWOLFSSL_ALT_NAMES\n");
return 0;
#else
int ret = 0;
Cert newCert;
FILE* file;
char certToUse[] = "./ca-ecc-cert.der";
char caKeyFile[] = "./ca-ecc-key.der";
char newCertOutput[] = "./newCert.der";
char newKeyOutput[] = "./newKey.der";
int derBufSz;
int caKeySz;
byte* derBuf = NULL;
byte* pemBuf = NULL;
byte* caKeyBuf = NULL;
/* for MakeCert and SignCert */
WC_RNG rng;
ecc_key caKey;
ecc_key newKey;
word32 idx3 = 0;
/*---------------------------------------------------------------------------*/
/* open the CA der formatted certificate, we need to get it's subject line to
* use in the new cert we're creating as the "Issuer" line */
/*---------------------------------------------------------------------------*/
printf("Open and read in der formatted certificate\n");
derBuf = (byte*) XMALLOC(FOURK_SZ, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
if (derBuf == NULL) goto fail;
XMEMSET(derBuf, 0, FOURK_SZ);
file = fopen(certToUse, "rb");
if (!file) {
printf("failed to find file: %s\n", certToUse);
goto fail;
}
derBufSz = fread(derBuf, 1, FOURK_SZ, file);
fclose(file);
printf("Successfully read the CA cert we are using to sign our new cert\n");
printf("Cert was %d bytes\n\n", derBufSz);
derBufSz = FOURK_SZ;
/*---------------------------------------------------------------------------*/
/* END */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/* open caKey file and get the caKey, we need it to sign our new cert */
/*---------------------------------------------------------------------------*/
printf("Getting the caKey from %s\n", caKeyFile);
caKeyBuf = (byte*) XMALLOC(FOURK_SZ, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
if (caKeyBuf == NULL) goto fail;
file = fopen(caKeyFile, "rb");
if (!file) {
printf("failed to open file: %s\n", caKeyFile);
goto fail;
}
caKeySz = fread(caKeyBuf, 1, FOURK_SZ, file);
if (caKeySz <= 0) {
printf("Failed to read caKey from file\n");
goto fail;
}
fclose(file);
printf("Successfully read %d bytes\n", caKeySz);
printf("Init ecc Key\n");
wc_ecc_init(&caKey);
printf("Decode the private key\n");
ret = wc_EccPrivateKeyDecode(caKeyBuf, &idx3, &caKey, (word32)caKeySz);
if (ret != 0) goto fail;
printf("Successfully retrieved caKey\n\n");
/*---------------------------------------------------------------------------*/
/* END */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/* Generate new private key to go with our new cert */
/*---------------------------------------------------------------------------*/
printf("initializing the rng\n");
ret = wc_InitRng(&rng);
if (ret != 0) goto fail;
printf("Generating a new ecc key\n");
ret = wc_ecc_init(&newKey);
if (ret != 0) goto fail;
ret = wc_ecc_make_key(&rng, 32, &newKey);
if (ret != 0) goto fail;
printf("Successfully created new ecc key\n\n");
/*---------------------------------------------------------------------------*/
/* END */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/* Create a new certificate using SUBJECT information from ca cert
* for ISSUER information in generated cert */
/*---------------------------------------------------------------------------*/
printf("Setting new cert issuer to subject of signer\n");
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);
/* Add some alt names to our cert: */
char myAltNames[] = {
/* SEQUENCE (1 element with 3 segments. Entire length is 41
* (0x29 in hex))
*/
0x30, 0x29,
/* This is a String 0x8, it denotes a DNSName 0x2 -> 0x82
* This strings' length is 9 (0x09)
*/
0x82, 0x09,
/* This strings value is "localhost" (in hex) */
0x6C, 0x6F, 0x63, 0x61, 0x6C, 0x68, 0x6F, 0x73, 0x74,
/* This is a String 0x8, it denotes a DNSName 0x2 -> 0x82
* This strings' length is 11 (0x0B)
*/
0x82, 0x0B,
/* This strings value is "example.com" (in hex) */
0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d,
/* This is a String 0x8, it denotes a DNSName 0x2 -> 0x82
* This strings' length is 9 (0x09)
*/
0x82, 0x09,
/* This strings value is "127.0.0.1" (in hex) */
0x31, 0x32, 0x37, 0x2e, 0x30, 0x2e, 0x30, 0x2e, 0x31,
/* This is a string 0x08, it denotes an IP Address 0x07 -> 0x87 */
/* This strings length is 4 (0x04) */
0x87, 0x04,
/* The IP address is 127 (0x7F), 0 (0x00), 0, (0x00), 1 (0x01) ->
* 127.0.0.1
*/
0x7F, 0x00, 0x00, 0x01
};
XMEMCPY(newCert.altNames, myAltNames, sizeof(myAltNames));
newCert.altNamesSz = (int) sizeof(myAltNames);
newCert.isCA = 0;
newCert.sigType = CTC_SHA256wECDSA;
ret = wc_SetIssuerBuffer(&newCert, derBuf, derBufSz);
if (ret != 0) goto fail;
ret = wc_MakeCert(&newCert, derBuf, FOURK_SZ, NULL, &newKey, &rng); //ecc certificate
if (ret < 0) goto fail;
printf("MakeCert returned %d\n", ret);
ret = wc_SignCert(newCert.bodySz, newCert.sigType, derBuf, FOURK_SZ, NULL,
&caKey, &rng);
if (ret < 0) goto fail;
printf("SignCert returned %d\n", ret);
derBufSz = ret;
printf("Successfully created new certificate\n");
/*---------------------------------------------------------------------------*/
/* END */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/* write the new cert to file in der format */
/*---------------------------------------------------------------------------*/
printf("Writing newly generated certificate to file \"%s\"\n",
newCertOutput);
file = fopen(newCertOutput, "wb");
if (!file) {
printf("failed to open file: %s\n", newCertOutput);
goto fail;
}
ret = (int) fwrite(derBuf, 1, derBufSz, file);
fclose(file);
printf("Successfully output %d bytes\n", ret);
/*---------------------------------------------------------------------------*/
/* END */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/* convert the der to a pem and write it to a file */
/*---------------------------------------------------------------------------*/
{
char pemOutput[] = "./newCert.pem";
int pemBufSz;
printf("Convert the der cert to pem formatted cert\n");
pemBuf = (byte*) XMALLOC(FOURK_SZ, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
if (pemBuf == NULL) goto fail;
XMEMSET(pemBuf, 0, FOURK_SZ);
pemBufSz = wc_DerToPem(derBuf, derBufSz, pemBuf, FOURK_SZ, CERT_TYPE);
if (pemBufSz < 0) goto fail;
printf("Resulting pem buffer is %d bytes\n", pemBufSz);
file = fopen(pemOutput, "wb");
if (!file) {
printf("failed to open file: %s\n", pemOutput);
goto fail;
}
fwrite(pemBuf, 1, pemBufSz, file);
fclose(file);
printf("Successfully converted the der to pem. Result is in: %s\n\n",
pemOutput);
}
{
char pemOutput[] = "./newKey.pem";
int pemBufSz;
XMEMSET(derBuf, 0, FOURK_SZ);
printf("Convert the key to a DER buffer\n");
derBufSz = wc_EccKeyToDer(&newKey, derBuf, FOURK_SZ);
if (derBufSz < 0) goto fail;
printf("Writing new key to file \"%s\"\n", newKeyOutput);
file = fopen(newKeyOutput, "wb");
if (!file) {
printf("failed to open file: %s\n", newKeyOutput);
goto fail;
}
ret = (int) fwrite(derBuf, 1, derBufSz, file);
fclose(file);
printf("Successfully output %d bytes\n", ret);
printf("Convert the der cert to pem formatted key\n");
XMEMSET(pemBuf, 0, FOURK_SZ);
pemBufSz = wc_DerToPem(derBuf, derBufSz, pemBuf, FOURK_SZ,
ECC_PRIVATEKEY_TYPE);
if (pemBufSz < 0) goto fail;
printf("Resulting pem buffer is %d bytes\n", pemBufSz);
file = fopen(pemOutput, "wb");
if (!file) {
printf("failed to open file: %s\n", pemOutput);
goto fail;
}
fwrite(pemBuf, 1, pemBufSz, file);
fclose(file);
printf("Successfully converted the der to pem. Result is in: %s\n\n",
pemOutput);
}
/*---------------------------------------------------------------------------*/
/* END */
/*---------------------------------------------------------------------------*/
goto success;
fail:
free_things(&derBuf, &pemBuf, &caKeyBuf, &caKey, &newKey, &rng);
printf("Failure code was %d\n", ret);
return -1;
success:
free_things(&derBuf, &pemBuf, &caKeyBuf, &caKey, &newKey, &rng);
printf("Tests passed\n");
return 0;
}
void free_things(byte** a, byte** b, byte** c, ecc_key* d, ecc_key* e,
WC_RNG* f)
{
if (a != NULL) {
if (*a != NULL) {
XFREE(*a, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
*a = NULL;
}
}
if (b != NULL) {
if (*b != NULL) {
XFREE(*b, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
*b = NULL;
}
}
if (c != NULL) {
if (*c != NULL) {
XFREE(*c, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
*c = NULL;
}
}
wc_ecc_free(d);
wc_ecc_free(e);
wc_FreeRng(f);
#endif
}

View File

@ -27,34 +27,37 @@
#include <wolfssl/wolfcrypt/asn.h> #include <wolfssl/wolfcrypt/asn.h>
#include <wolfssl/wolfcrypt/error-crypt.h> #include <wolfssl/wolfcrypt/error-crypt.h>
#define HEAP_HINT NULL
#define LARGE_TEMP_SZ 4096
/* Check if the internal asn API's are available */ /* Check if the internal asn API's are available */
#if defined(WOLFSSL_TEST_CERT) || defined(OPENSSL_EXTRA) || \ #if defined(WOLFSSL_TEST_CERT) || defined(OPENSSL_EXTRA) || \
defined(OPENSSL_EXTRA_X509_SMALL) defined(OPENSSL_EXTRA_X509_SMALL)
#define HAVE_DECODEDCERT #define HAVE_DECODEDCERT
#endif #endif
#if defined(WOLFSSL_CERT_REQ) && defined(WOLFSSL_CERT_GEN) && \
defined(HAVE_ECC)
#define HEAP_HINT NULL
#define LARGE_TEMP_SZ 4096
static void usage(void) static void usage(void)
{ {
printf("Usage: ./csr_sign [type] [csr.pem] [ca-cert.pem] [ca-key.pem]\n"); printf("Usage: ./csr_sign csr.pem ca-cert.pem ca-key.pem\n");
printf("Example:\n"); printf("Example:\n");
printf("./csr_sign ecc ecc-csr.pem ca-ecc-cert.pem ca-ecc-key.pem\n"); printf("./csr_sign ecc-csr.pem ca-ecc-cert.pem ca-ecc-key.pem\n");
} }
static int do_csrsign(int argc, char** argv) static int do_csrsign(int argc, char** argv)
{ {
int ret = 0; int ret = 0;
int type; int type = ECC_TYPE;
const char* typeStr = "ecc";
Cert newCert; Cert newCert;
FILE* file; FILE* file;
const char* typeStr = argv[1]; const char* csrPemFile = argv[1];
const char* csrPemFile = argv[2]; const char* caCertPemFile = argv[2];
const char* caCertPemFile = argv[3]; const char* caKeyPemFile = argv[3];
const char* caKeyPemFile = argv[4];
const char* newCertOutput = "./newCert.der"; const char* newCertOutput = "./newCert.der";
const char* newCertPemFile = "./newCert.pem"; const char* newCertPemFile = "./newCert.pem";
@ -80,15 +83,6 @@ static int do_csrsign(int argc, char** argv)
int initDecode = 0; int initDecode = 0;
#endif #endif
if (XSTRNCMP(typeStr, "rsa", 3) == 0)
type = RSA_TYPE;
else if (XSTRNCMP(typeStr, "ecc", 3) == 0)
type = ECC_TYPE;
else if (XSTRNCMP(typeStr, "ed25519", 7) == 0)
type = ED25519_TYPE;
else
return NOT_COMPILED_IN;
derBuf = (byte*)XMALLOC(LARGE_TEMP_SZ, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); derBuf = (byte*)XMALLOC(LARGE_TEMP_SZ, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
if (derBuf == NULL) goto exit; if (derBuf == NULL) goto exit;
XMEMSET(derBuf, 0, LARGE_TEMP_SZ); XMEMSET(derBuf, 0, LARGE_TEMP_SZ);
@ -102,9 +96,9 @@ static int do_csrsign(int argc, char** argv)
XMEMSET(caCertBuf, 0, LARGE_TEMP_SZ); XMEMSET(caCertBuf, 0, LARGE_TEMP_SZ);
/*---------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
/* Loading the CA Certificate PEM File */ /* Loading the CA Certificate PEM File */
/*---------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
printf("Loading CA certificate\n"); printf("Loading CA certificate\n");
file = fopen(caCertPemFile, "rb"); file = fopen(caCertPemFile, "rb");
@ -132,9 +126,9 @@ static int do_csrsign(int argc, char** argv)
goto exit; goto exit;
} }
/*---------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
/* Load the CA Key PEM File */ /* Load the CA Key PEM File */
/*---------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
printf("Loading the CA key\n"); printf("Loading the CA key\n");
file = fopen(caKeyPemFile, "rb"); file = fopen(caKeyPemFile, "rb");
@ -163,14 +157,17 @@ static int do_csrsign(int argc, char** argv)
} }
printf("Loading CA key to ecc_key struct\n"); printf("Loading CA key to ecc_key struct\n");
idx = 0; ret = wc_ecc_init(&caKey);
ret = wc_EccPrivateKeyDecode(derBuf, &idx, &caKey, derSz);
if (ret != 0) goto exit; if (ret != 0) goto exit;
initCaKey = 1; initCaKey = 1;
/*---------------------------------------------------------------------------*/ idx = 0;
ret = wc_EccPrivateKeyDecode(derBuf, &idx, &caKey, derSz);
if (ret != 0) goto exit;
/*------------------------------------------------------------------------*/
/* Load CSR PEM */ /* Load CSR PEM */
/*---------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
printf("Loading CSR certificate\n"); printf("Loading CSR certificate\n");
file = fopen(csrPemFile, "rb"); file = fopen(csrPemFile, "rb");
@ -191,7 +188,8 @@ static int do_csrsign(int argc, char** argv)
#ifdef HAVE_DECODEDCERT #ifdef HAVE_DECODEDCERT
/* Code for parsing a CSR to a DecodedCert struct */ /* Code for parsing a CSR to a DecodedCert struct */
/* Note: These are not public API's unless WOLFSSL_TEST_CERT or the compat layer is enabled */ /* Note: These are not public API's unless WOLFSSL_TEST_CERT or the compat
* layer is enabled */
InitDecodedCert(&decoded, derBuf, derSz, NULL); InitDecodedCert(&decoded, derBuf, derSz, NULL);
ret = ParseCert(&decoded, CERTREQ_TYPE, NO_VERIFY, NULL); ret = ParseCert(&decoded, CERTREQ_TYPE, NO_VERIFY, NULL);
if (ret != 0) goto exit; if (ret != 0) goto exit;
@ -205,13 +203,15 @@ static int do_csrsign(int argc, char** argv)
initCsrKey = 1; initCsrKey = 1;
idx = 0; idx = 0;
ret = wc_EccPublicKeyDecode(decoded.publicKey, &idx, &csrKey, decoded.pubKeySize); ret = wc_EccPublicKeyDecode(decoded.publicKey, &idx, &csrKey,
decoded.pubKeySize);
if (ret != 0) goto exit; if (ret != 0) goto exit;
#endif #endif
/*---------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
/* Create a new certificate using SUBJECT information from CSR and ISSUER from CA cert */ /* Create a new certificate using SUBJECT information from CSR and ISSUER
/*---------------------------------------------------------------------------*/ * from CA cert */
/*------------------------------------------------------------------------*/
wc_InitCert(&newCert); wc_InitCert(&newCert);
newCert.isCA = 0; newCert.isCA = 0;
@ -219,15 +219,24 @@ static int do_csrsign(int argc, char** argv)
printf("Setting certificate subject\n"); printf("Setting certificate subject\n");
#ifdef HAVE_DECODEDCERT #ifdef HAVE_DECODEDCERT
if (decoded.subjectC) strncpy(newCert.subject.country, decoded.subjectC, decoded.subjectCLen); if (decoded.subjectC)
if (decoded.subjectST) strncpy(newCert.subject.state, decoded.subjectST, decoded.subjectSTLen); strncpy(newCert.subject.country, decoded.subjectC, decoded.subjectCLen);
if (decoded.subjectL) strncpy(newCert.subject.locality, decoded.subjectL, decoded.subjectLLen); if (decoded.subjectST)
if (decoded.subjectO) strncpy(newCert.subject.org, decoded.subjectO, decoded.subjectOLen); strncpy(newCert.subject.state, decoded.subjectST, decoded.subjectSTLen);
if (decoded.subjectOU) strncpy(newCert.subject.unit, decoded.subjectOU, decoded.subjectOULen); if (decoded.subjectL)
if (decoded.subjectSN) strncpy(newCert.subject.sur, decoded.subjectSN, decoded.subjectSNLen); strncpy(newCert.subject.locality, decoded.subjectL, decoded.subjectLLen);
if (decoded.subjectSND) strncpy(newCert.subject.serialDev, decoded.subjectSND, decoded.subjectSNDLen); if (decoded.subjectO)
if (decoded.subjectCN) strncpy(newCert.subject.commonName, decoded.subjectCN, decoded.subjectCNLen); strncpy(newCert.subject.org, decoded.subjectO, decoded.subjectOLen);
if (decoded.subjectEmail) strncpy(newCert.subject.email, decoded.subjectEmail, decoded.subjectEmailLen); if (decoded.subjectOU)
strncpy(newCert.subject.unit, decoded.subjectOU, decoded.subjectOULen);
if (decoded.subjectSN)
strncpy(newCert.subject.sur, decoded.subjectSN, decoded.subjectSNLen);
if (decoded.subjectSND)
strncpy(newCert.subject.serialDev, decoded.subjectSND, decoded.subjectSNDLen);
if (decoded.subjectCN)
strncpy(newCert.subject.commonName, decoded.subjectCN, decoded.subjectCNLen);
if (decoded.subjectEmail)
strncpy(newCert.subject.email, decoded.subjectEmail, decoded.subjectEmailLen);
#else #else
/* This can be used if the DER is an X.509 certificate (not CSR) */ /* This can be used if the DER is an X.509 certificate (not CSR) */
//ret = wc_SetSubjectBuffer(&newCert, derBuf, derSz); //ret = wc_SetSubjectBuffer(&newCert, derBuf, derSz);
@ -278,9 +287,9 @@ static int do_csrsign(int argc, char** argv)
derSz = ret; derSz = ret;
printf("Successfully signed certificate %d\n\n", derSz); printf("Successfully signed certificate %d\n\n", derSz);
/*---------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
/* write the new cert to file in DER format */ /* write the new cert to file in DER format */
/*---------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
printf("Writing newly generated DER certificate to file \"%s\"\n", printf("Writing newly generated DER certificate to file \"%s\"\n",
newCertOutput); newCertOutput);
file = fopen(newCertOutput, "wb"); file = fopen(newCertOutput, "wb");
@ -294,9 +303,9 @@ static int do_csrsign(int argc, char** argv)
printf("Successfully output %d bytes\n", ret); printf("Successfully output %d bytes\n", ret);
#ifdef WOLFSSL_DER_TO_PEM #ifdef WOLFSSL_DER_TO_PEM
/*---------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
/* convert the DER to a PEM and write it to a file */ /* convert the DER to a PEM and write it to a file */
/*---------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
printf("Convert the DER cert to PEM formatted cert\n"); printf("Convert the DER cert to PEM formatted cert\n");
pemSz = wc_DerToPem(derBuf, derSz, pemBuf, LARGE_TEMP_SZ, CERT_TYPE); pemSz = wc_DerToPem(derBuf, derSz, pemBuf, LARGE_TEMP_SZ, CERT_TYPE);
@ -345,14 +354,17 @@ exit:
return ret; return ret;
} }
#endif
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
#if !defined(WOLFSSL_CERT_REQ) || !defined(WOLFSSL_CERT_GEN) || !defined(HAVE_DECODEDCERT) #if !defined(WOLFSSL_CERT_REQ) || !defined(WOLFSSL_CERT_GEN) || \
printf("Please compile wolfSSL with --enable-certreq --enable-certgen CFLAGS=-DOPENSSL_EXTRA_X509_SMALL\n"); !defined(HAVE_ECC)
printf("Please compile wolfSSL with --enable-certreq --enable-certgen "
"--enable-ecc CFLAGS=-DOPENSSL_EXTRA_X509_SMALL\n");
return 0; return 0;
#else #else
if (argc != 5) { if (argc != 4) {
usage(); usage();
return 1; return 1;
} }