Improvements to CSR examples.

* Add ed25519 support to csr_example.
* Added example for signing a CSR using a CA.
* Cleanup the csrgen_example.
pull/275/head
David Garske 2021-11-17 15:58:12 -08:00
parent 6bb6275e95
commit bde4231cb3
6 changed files with 614 additions and 257 deletions

1
.gitignore vendored
View File

@ -108,6 +108,7 @@ signature/signature
certgen/newCert*
certgen/certgen_example
certgen/csr_example
certgen/csr_sign
certgen/csr_w_ed25519_example
certgen/certgen_with_altnames

View File

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

View File

@ -31,28 +31,27 @@ To run the test do:
```
./certgen_example
Open and read in der formatted certificate
Successfully read 1198 bytes
Loading CA certificate
Successfully read 666 bytes from ./ca-ecc-cert.der
Getting the caKey from ./ca-key.der
Successfully read 121 bytes
Init ecc Key
Decode the private key
Successfully retrieved caKey
Loading the CA key
Successfully read 121 bytes from ./ca-ecc-key.der
Decoding the CA private key
Successfully loaded CA Key
initializing the rng
Generating a new ecc key
Successfully created new ecc key
Generating a new ECC key
Successfully created new ECC key
Setting new cert issuer to subject of signer
MakeCert returned 479
SignCert returned 570
Make Cert returned 490
Signed Cert returned 581
Successfully created new certificate
Writing newly generated certificate to file "./newCert.der"
Successfully output 570 bytes
Convert the der cert to pem formatted cert
Resulting pem buffer is 826 bytes
Successfully converted the der to pem. Result is in: ./newCert.pem
Writing newly generated DER certificate to file "./newCert.der"
Successfully output 581 bytes
Convert the DER cert to PEM formatted cert
Resulting PEM buffer is 843 bytes
Successfully converted the DER to PEM to "./newCert.pem"
Tests passed
```
@ -110,21 +109,53 @@ GV+4MAoGCCqGSM49BAMCA0gAMEUCIHURDOezcyCI0mdp8hpG+9JnMcfHWLSd4kiV
## Certificate Signing Request (CSR) Example
```
./csr_example
./csr_example ecc
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIMyXi4zh0EKTfZv2Mdyz9TR97aY8zmuP/Mt41Y8UczfsoAoGCCqGSM49
AwEHoUQDQgAENfB16kF8KZuVQC0744AgiSY5bpuLRegTXJ4JTgCzSWaSHLXZC+CJ
a/0yDzI6bQtDdzNZ0M+0/O+VolN10GaAZw==
MHcCAQEEICJ7jM8zdrZCoTdaeXfiNkRA0Wbf+JlATRLzMEghvGiToAoGCCqGSM49
AwEHoUQDQgAEdfzfuFaVgG1icB3Bwqkv27zZQdhUyOTHeN/4VbEoiB69EW5luFHy
6MWJEn+5a75Pp/dQKjlTb8Ukp/f7dRr8gg==
-----END EC PRIVATE KEY-----
(227)
Saved Key PEM to "ecc-key.pem"
-----BEGIN CERTIFICATE REQUEST-----
MIIBSTCB8QIBAjCBjjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk9SMREwDwYDVQQH
DAhQb3J0bGFuZDEOMAwGA1UECgwFeWFTU0wxFDASBgNVBAsMC0RldmVsb3BtZW50
MRgwFgYDVQQDDA93d3cud29sZnNzbC5jb20xHzAdBgkqhkiG9w0BCQEWEGluZm9A
d29sZnNzbC5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQ18HXqQXwpm5VA
LTvjgCCJJjlum4tF6BNcnglOALNJZpIctdkL4Ilr/TIPMjptC0N3M1nQz7T875Wi
U3XQZoBnoAAwCgYIKoZIzj0EAwIDRwAwRAIgVh5iGYVmbwR4fhdjzCMI06wn2lGS
SmRM6YTRfMWRoSICIAlMGjRJlBKB9dlmukCdlHH3GXNOiKw1+iP/kApE8tRm
MIIBTTCB8wIBAjCBkDELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk9SMREwDwYDVQQH
DAhQb3J0bGFuZDEQMA4GA1UECgwHd29sZlNTTDEUMBIGA1UECwwLRGV2ZWxvcG1l
bnQxGDAWBgNVBAMMD3d3dy53b2xmc3NsLmNvbTEfMB0GCSqGSIb3DQEJARYQaW5m
b0B3b2xmc3NsLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABHX837hWlYBt
YnAdwcKpL9u82UHYVMjkx3jf+FWxKIgevRFuZbhR8ujFiRJ/uWu+T6f3UCo5U2/F
JKf3+3Ua/IKgADAKBggqhkjOPQQDAgNJADBGAiEAtaKt31WXJkFgI4dFw6dG45F3
Ia4BEV4KoPCBbMs81vICIQCj4IiuQpYH5dIsFuN8h0QGIfXTxdd9eqNsJJ1ElOXt
hA==
-----END CERTIFICATE REQUEST-----
(530)
Saved CSR PEM to "ecc-csr.pem"
```
```
./csr_example ed25519
-----BEGIN EDDSA PRIVATE KEY-----
MFICAQAwBQYDK2VwBCIEIJAf0KRMwpoM8PcjTgNzMlJLtdGGml5kbZRJUlSChaxY
oSIEIBsUx1M7yeJiLIY6I/XrWX0VBcyp3UYa5r2IqLiA8Nrg
-----END EDDSA PRIVATE KEY-----
(180)
Saved Key PEM to "ed25519-key.pem"
-----BEGIN CERTIFICATE REQUEST-----
MIIBETCBxAIBAjCBkDELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk9SMREwDwYDVQQH
DAhQb3J0bGFuZDEQMA4GA1UECgwHd29sZlNTTDEUMBIGA1UECwwLRGV2ZWxvcG1l
bnQxGDAWBgNVBAMMD3d3dy53b2xmc3NsLmNvbTEfMB0GCSqGSIb3DQEJARYQaW5m
b0B3b2xmc3NsLmNvbTAqMAUGAytlcAMhABsUx1M7yeJiLIY6I/XrWX0VBcyp3UYa
5r2IqLiA8NrgoAAwBQYDK2VwA0EAy3o01+L7OaB3qo825GQSKspWijGrFulU1BBQ
3z2Pr2lx6L87awbrWUtwvlXOGHQVl5ZjV+UkZURHMeNnS4Q2CQ==
-----END CERTIFICATE REQUEST-----
(448)
Saved CSR PEM to "ed25519-csr.pem"
```
## CSR Signing with CA
```
./csr_sign ed25519-csr.pem ca-ecc-cert.der ca-ecc-key.der
```

View File

@ -1,6 +1,6 @@
/* certgen_example.c
*
* Copyright (C) 2006-2020 wolfSSL Inc.
* Copyright (C) 2006-2021 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
@ -28,19 +28,10 @@
#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)
printf("Please compile wolfSSL with --enable-certreq --enable-certgen\n");
return 0;
#else
#define LARGE_TEMP_SZ 4096
static int do_csrgen(int argc, char** argv)
{
int ret = 0;
Cert newCert;
@ -61,92 +52,88 @@ int main(void) {
WC_RNG rng;
ecc_key caKey;
ecc_key newKey;
word32 idx3 = 0;
word32 idx = 0;
int initRng = 0, initCaKey = 0, initNewKey = 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");
#ifdef WOLFSSL_DER_TO_PEM
char pemOutput[] = "./newCert.pem";
int pemBufSz;
#endif
derBuf = (byte*) XMALLOC(FOURK_SZ, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
if (derBuf == NULL) goto fail;
/*---------------------------------------------------------------------------*/
/* 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");
XMEMSET(derBuf, 0, FOURK_SZ);
derBuf = (byte*)XMALLOC(LARGE_TEMP_SZ, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
if (derBuf == NULL) goto exit;
XMEMSET(derBuf, 0, LARGE_TEMP_SZ);
file = fopen(certToUse, "rb");
if (!file) {
printf("failed to find file: %s\n", certToUse);
goto fail;
printf("failed to open file: %s\n", certToUse);
goto exit;
}
derBufSz = fread(derBuf, 1, FOURK_SZ, file);
derBufSz = fread(derBuf, 1, LARGE_TEMP_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);
/*---------------------------------------------------------------------------*/
/* END */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/* open caKey file and get the caKey, we need it to sign our new cert */
/*---------------------------------------------------------------------------*/
printf("Getting the caKey from %s\n", caKeyFile);
printf("Successfully read %d bytes from %s\n\n", derBufSz, certToUse);
caKeyBuf = (byte*) XMALLOC(FOURK_SZ, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
if (caKeyBuf == NULL) goto fail;
/*---------------------------------------------------------------------------*/
/* open caKey file and get the caKey, we need it to sign our new cert */
/*---------------------------------------------------------------------------*/
printf("Loading the CA key\n");
caKeyBuf = (byte*)XMALLOC(LARGE_TEMP_SZ, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
if (caKeyBuf == NULL) goto exit;
XMEMSET(caKeyBuf, 0, LARGE_TEMP_SZ);
file = fopen(caKeyFile, "rb");
if (!file) {
printf("failed to open file: %s\n", caKeyFile);
goto fail;
goto exit;
}
caKeySz = fread(caKeyBuf, 1, FOURK_SZ, file);
caKeySz = fread(caKeyBuf, 1, LARGE_TEMP_SZ, file);
fclose(file);
if (caKeySz <= 0) {
printf("Failed to read caKey from file\n");
goto fail;
goto exit;
}
printf("Successfully read %d bytes from %s\n", caKeySz, caKeyFile);
fclose(file);
printf("Successfully read %d bytes\n", caKeySz);
printf("Init ecc Key\n");
wc_ecc_init(&caKey);
initCaKey = 1;
printf("Decode the private key\n");
ret = wc_EccPrivateKeyDecode(caKeyBuf, &idx3, &caKey, (word32)caKeySz);
if (ret != 0) goto fail;
printf("Decoding the CA private key\n");
idx = 0;
ret = wc_EccPrivateKeyDecode(caKeyBuf, &idx, &caKey, (word32)caKeySz);
if (ret != 0) goto exit;
printf("Successfully retrieved caKey\n\n");
/*---------------------------------------------------------------------------*/
/* END */
/*---------------------------------------------------------------------------*/
printf("Successfully loaded CA Key\n\n");
/*---------------------------------------------------------------------------*/
/* Generate new private key to go with our new cert */
/*---------------------------------------------------------------------------*/
printf("initializing the rng\n");
/*---------------------------------------------------------------------------*/
/* Generate new private key to go with our new cert */
/*---------------------------------------------------------------------------*/
ret = wc_InitRng(&rng);
if (ret != 0) goto fail;
if (ret != 0) goto exit;
initRng = 1;
printf("Generating a new ecc key\n");
printf("Generating a new ECC key\n");
ret = wc_ecc_init(&newKey);
if (ret != 0) goto fail;
if (ret != 0) goto exit;
initNewKey = 1;
ret = wc_ecc_make_key(&rng, 32, &newKey);
if (ret != 0) goto fail;
if (ret != 0) goto exit;
printf("Successfully created new ecc key\n\n");
/*---------------------------------------------------------------------------*/
/* END */
/*---------------------------------------------------------------------------*/
printf("Successfully created new ECC key\n\n");
/*---------------------------------------------------------------------------*/
/* Create a new certificate using SUBJECT information from ca cert
* for ISSUER information in generated cert */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/* 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);
@ -162,113 +149,91 @@ int main(void) {
newCert.sigType = CTC_SHA256wECDSA;
ret = wc_SetIssuerBuffer(&newCert, derBuf, derBufSz);
if (ret != 0) goto fail;
if (ret != 0) goto exit;
ret = wc_MakeCert(&newCert, derBuf, FOURK_SZ, NULL, &newKey, &rng); //ecc certificate
if (ret < 0) goto fail;
ret = wc_MakeCert(&newCert, derBuf, LARGE_TEMP_SZ, NULL, &newKey, &rng);
if (ret < 0) goto exit;
printf("Make Cert returned %d\n", ret);
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);
ret = wc_SignCert(newCert.bodySz, newCert.sigType, derBuf, LARGE_TEMP_SZ, NULL,
&caKey, &rng);
if (ret < 0) goto exit;
printf("Signed Cert returned %d\n", ret);
derBufSz = ret;
printf("Successfully created new certificate\n");
/*---------------------------------------------------------------------------*/
/* END */
/*---------------------------------------------------------------------------*/
printf("Successfully created new certificate\n\n");
/*---------------------------------------------------------------------------*/
/* write the new cert to file in der format */
/*---------------------------------------------------------------------------*/
printf("Writing newly generated certificate to file \"%s\"\n",
newCertOutput);
/*---------------------------------------------------------------------------*/
/* write the new cert to file in der format */
/*---------------------------------------------------------------------------*/
printf("Writing newly generated DER certificate to file \"%s\"\n",
newCertOutput);
file = fopen(newCertOutput, "wb");
if (!file) {
printf("failed to open file: %s\n", newCertOutput);
goto fail;
goto exit;
}
ret = (int) fwrite(derBuf, 1, derBufSz, file);
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;
#ifdef WOLFSSL_DER_TO_PEM
/*---------------------------------------------------------------------------*/
/* 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);
if (pemBuf == NULL) goto exit;
XMEMSET(pemBuf, 0, LARGE_TEMP_SZ);
pemBuf = (byte*) XMALLOC(FOURK_SZ, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
if (pemBuf == NULL) goto fail;
pemBufSz = wc_DerToPem(derBuf, derBufSz, pemBuf, LARGE_TEMP_SZ, CERT_TYPE);
if (pemBufSz < 0) goto exit;
XMEMSET(pemBuf, 0, FOURK_SZ);
printf("Resulting PEM buffer is %d bytes\n", pemBufSz);
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);
file = fopen(pemOutput, "wb");
if (!file) {
printf("failed to open file: %s\n", pemOutput);
goto exit;
}
/*---------------------------------------------------------------------------*/
/* END */
/*---------------------------------------------------------------------------*/
fwrite(pemBuf, 1, pemBufSz, file);
fclose(file);
printf("Successfully converted the DER to PEM to \"%s\"\n\n",
pemOutput);
#endif
goto success;
ret = 0; /* success */
fail:
free_things(&derBuf, &pemBuf, &caKeyBuf, &caKey, &newKey, &rng);
printf("Failure code was %d\n", ret);
return -1;
exit:
success:
free_things(&derBuf, &pemBuf, &caKeyBuf, &caKey, &newKey, &rng);
printf("Tests passed\n");
return 0;
XFREE(derBuf, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(pemBuf, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(caKeyBuf, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
if (initCaKey)
wc_ecc_free(&caKey);
if (initNewKey)
wc_ecc_free(&newKey);
if (initRng) {
wc_FreeRng(&rng);
}
if (ret == 0)
printf("Tests passed\n");
else
printf("Failure code was %d\n", ret);
return ret;
}
void free_things(byte** a, byte** b, byte** c, ecc_key* d, ecc_key* e,
WC_RNG* f)
int main(int argc, char** argv)
{
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);
#if !defined(WOLFSSL_CERT_REQ) || !defined(WOLFSSL_CERT_GEN) || !defined(WOLFSSL_KEY_GEN)
printf("Please compile wolfSSL with --enable-certreq --enable-certgen --enable-keygen\n");
return 0;
#else
return do_csrgen(argc, argv);
#endif
}

View File

@ -25,88 +25,154 @@
#include <wolfssl/wolfcrypt/settings.h>
#include <wolfssl/wolfcrypt/ecc.h>
#include <wolfssl/wolfcrypt/rsa.h>
#include <wolfssl/wolfcrypt/ed25519.h>
#include <wolfssl/wolfcrypt/asn_public.h>
#include <wolfssl/wolfcrypt/error-crypt.h>
#define LARGE_TEMP_SZ 4096
enum {
EC_KEY_TYPE = 0,
RSA_KEY_TYPE = 1,
};
void usage(void);
int gen_csr(int type);
int gen_csr(int type)
static void usage(void)
{
printf("Invalid input supplied try one of the below examples\n");
printf("Examples:\n\n");
printf("./csr_example rsa\n");
printf("./csr_example ecc\n");
printf("./csr_example ed25519\n");
}
static int gen_csr(const char* arg1)
{
#if !defined(WOLFSSL_CERT_REQ) || !defined(WOLFSSL_CERT_GEN) && \
!defined(WOLFSSL_KEY_GEN)
printf("ERROR: Please compile wolfSSL with --enable-certreq"
" --enable-certgen --enable-keygen\n");
return 0;
#else
int ret;
int type;
#ifdef HAVE_ECC
ecc_key ecKey;
#endif
#ifndef NO_RSA
RsaKey rsaKey;
#endif
#ifdef HAVE_ED25519
ed25519_key edKey;
#endif
void* keyPtr = NULL;
WC_RNG rng;
Cert req;
byte der[LARGE_TEMP_SZ], pem[LARGE_TEMP_SZ];
int derSz, pemSz;
byte der[LARGE_TEMP_SZ];
int derSz;
#ifdef WOLFSSL_DER_TO_PEM
byte pem[LARGE_TEMP_SZ];
int pemSz;
FILE* file = NULL;
char outFile[255];
#endif
XMEMSET(der, 0, LARGE_TEMP_SZ);
#ifdef WOLFSSL_DER_TO_PEM
XMEMSET(pem, 0, LARGE_TEMP_SZ);
#endif
if (type == EC_KEY_TYPE) {
ret = wc_ecc_init(&ecKey);
(void) rsaKey; /* Not using rsaKey in EC_KEY_TYPE case */
} else {
ret = wc_InitRsaKey(&rsaKey, NULL);
(void) ecKey; /* Not using ecKey in RSA_KEY_TYPE case */
if (XSTRNCMP(arg1, "rsa", 3) == 0)
type = RSA_TYPE;
else if (XSTRNCMP(arg1, "ecc", 3) == 0)
type = ECC_TYPE;
else if (XSTRNCMP(arg1, "ed25519", 7) == 0)
type = ED25519_TYPE;
else
return NOT_COMPILED_IN;
ret = wc_InitRng(&rng);
if (ret != 0) {
printf("RNG initialization failed: %d\n", ret);
return ret;
}
#ifdef HAVE_ECC
if (type == ECC_TYPE) {
keyPtr = &ecKey;
ret = wc_ecc_init(&ecKey);
}
#endif
#ifndef NO_RSA
if (type == RSA_TYPE) {
keyPtr = &rsaKey;
ret = wc_InitRsaKey(&rsaKey, NULL);
}
#endif
#ifdef HAVE_ED25519
if (type == ED25519_TYPE) {
keyPtr = &edKey;
ret = wc_ed25519_init(&edKey);
}
#endif
if (ret != 0) {
printf("Key initialization failed: %d\n", ret);
goto exit;
}
ret = wc_InitRng(&rng);
if (ret != 0) {
printf("RNG initialization failed: %d\n", ret);
goto exit;
}
if (type == EC_KEY_TYPE) {
#ifdef HAVE_ECC
if (type == ECC_TYPE)
ret = wc_ecc_make_key_ex(&rng, 32, &ecKey, ECC_SECP256R1);
} else {
#endif
#ifndef NO_RSA
if (type == RSA_TYPE)
ret = wc_MakeRsaKey(&rsaKey, 2048, WC_RSA_EXPONENT, &rng);
}
#endif
#ifdef HAVE_ED25519
if (type == ED25519_TYPE)
ret = wc_ed25519_make_key(&rng, ED25519_KEY_SIZE, &edKey);
#endif
if (ret != 0) {
printf("Key generation failed: %d\n", ret);
goto exit;
}
if (type == EC_KEY_TYPE) {
#ifdef HAVE_ECC
if (type == ECC_TYPE)
ret = wc_EccKeyToDer(&ecKey, der, sizeof(der));
} else {
#endif
#ifndef NO_RSA
if (type == RSA_TYPE)
ret = wc_RsaKeyToDer(&rsaKey, der, sizeof(der));
}
#endif
#ifdef HAVE_ED25519
if (type == ED25519_TYPE)
ret = wc_Ed25519KeyToDer(&edKey, der, sizeof(der));
#endif
if (ret <= 0) {
printf("Key To DER failed: %d\n", ret);
goto exit;
}
derSz = ret;
#ifdef WOLFSSL_DER_TO_PEM
memset(pem, 0, sizeof(pem));
if (type == EC_KEY_TYPE) {
#ifdef HAVE_ECC
if (type == ECC_TYPE)
ret = wc_DerToPem(der, derSz, pem, sizeof(pem), ECC_PRIVATEKEY_TYPE);
} else {
#endif
#ifndef NO_RSA
if (type == RSA_TYPE)
ret = wc_DerToPem(der, derSz, pem, sizeof(pem), PRIVATEKEY_TYPE);
}
#endif
#ifdef HAVE_ED25519
if (type == ED25519_TYPE)
ret = wc_DerToPem(der, derSz, pem, sizeof(pem), ED25519_TYPE);
#endif
if (ret <= 0) {
printf("DER to PEM failed: %d\n", ret);
printf("Key DER to PEM failed: %d\n", ret);
goto exit;
}
pemSz = ret;
printf("%s (%d)", pem, pemSz);
printf("%s (%d)\n", pem, pemSz);
snprintf(outFile, sizeof(outFile), "%s-key.pem", arg1);
printf("Saved Key PEM to \"%s\"\n", outFile);
file = fopen(outFile, "wb");
if (file) {
ret = (int)fwrite(pem, 1, pemSz, file);
fclose(file);
}
#endif /* WOLFSSL_DER_TO_PEM */
ret = wc_InitCert(&req);
if (ret != 0) {
@ -120,75 +186,83 @@ int gen_csr(int type)
strncpy(req.subject.unit, "Development", CTC_NAME_SIZE);
strncpy(req.subject.commonName, "www.wolfssl.com", CTC_NAME_SIZE);
strncpy(req.subject.email, "info@wolfssl.com", CTC_NAME_SIZE);
if (type == EC_KEY_TYPE) {
ret = wc_MakeCertReq(&req, der, sizeof(der), NULL, &ecKey);
} else {
ret = wc_MakeCertReq(&req, der, sizeof(der), &rsaKey, NULL);
}
ret = wc_MakeCertReq_ex(&req, der, sizeof(der), type, keyPtr);
if (ret <= 0) {
printf("Make Cert Req failed: %d\n", ret);
goto exit;
}
derSz = ret;
if (type == EC_KEY_TYPE) {
#ifdef HAVE_ECC
if (type == ECC_TYPE)
req.sigType = CTC_SHA256wECDSA;
ret = wc_SignCert(req.bodySz, req.sigType, der, sizeof(der), NULL,
&ecKey, &rng);
} else {
#endif
#ifndef NO_RSA
if (type == RSA_TYPE)
req.sigType = CTC_SHA256wRSA;
ret = wc_SignCert(req.bodySz, req.sigType, der, sizeof(der), &rsaKey,
NULL, &rng);
}
#endif
#ifdef HAVE_ED25519
if (type == ED25519_TYPE)
req.sigType = CTC_ED25519;
#endif
ret = wc_SignCert_ex(req.bodySz, req.sigType, der, sizeof(der), type,
keyPtr, &rng);
if (ret <= 0) {
printf("Sign Cert failed: %d\n", ret);
goto exit;
}
derSz = ret;
#ifdef WOLFSSL_DER_TO_PEM
memset(pem, 0, sizeof(pem));
ret = wc_DerToPem(der, derSz, pem, sizeof(pem), CERTREQ_TYPE);
if (ret <= 0) {
printf("DER to PEM failed: %d\n", ret);
printf("CSR DER to PEM failed: %d\n", ret);
goto exit;
}
pemSz = ret;
printf("%s (%d)", pem, pemSz);
printf("%s (%d)\n", pem, pemSz);
ret = 0;
snprintf(outFile, sizeof(outFile), "%s-csr.pem", arg1);
printf("Saved CSR PEM to \"%s\"\n", outFile);
file = fopen(outFile, "wb");
if (file) {
ret = (int)fwrite(pem, 1, pemSz, file);
fclose(file);
}
#endif
ret = 0; /* success */
exit:
if (type == EC_KEY_TYPE) {
#ifdef HAVE_ECC
if (type == ECC_TYPE)
wc_ecc_free(&ecKey);
} else {
#endif
#ifndef NO_RSA
if (type == RSA_TYPE)
wc_FreeRsaKey(&rsaKey);
}
#endif
#ifdef HAVE_ED25519
if (type == ED25519_TYPE)
wc_ed25519_free(&edKey);
#endif
wc_FreeRng(&rng);
return ret;
#endif
}
int main(int argc, char** argv)
{
#if !defined(WOLFSSL_CERT_REQ) || !defined(WOLFSSL_CERT_GEN) || !defined(WOLFSSL_KEY_GEN)
printf("Please compile wolfSSL with --enable-certreq --enable-certgen --enable-keygen\n");
return 0;
#else
if (argc != 2) {
usage();
return 1;
}
if (XSTRNCMP(argv[1], "rsa", 3) == 0)
return gen_csr(RSA_KEY_TYPE);
else if (XSTRNCMP(argv[1], "ecc", 3) == 0)
return gen_csr(EC_KEY_TYPE);
else
usage();
return -1;
}
void usage(void)
{
printf("Invalid input supplied try one of the below examples\n");
printf("Examples:\n\n");
printf("./csr_example rsa\n");
printf("./csr_example ecc\n");
return gen_csr(argv[1]);
#endif
}

283
certgen/csr_sign.c 100644
View File

@ -0,0 +1,283 @@
/* csr_sign.c
*
* Copyright (C) 2006-2021 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 LARGE_TEMP_SZ 4096
/* Check if the internal asn API's are available */
#if defined(WOLFSSL_TEST_CERT) || defined(OPENSSL_EXTRA) || \
defined(OPENSSL_EXTRA_X509_SMALL)
#define HAVE_DECODEDCERT
#endif
static void usage(void)
{
printf("Usage: ./csr_sign [type] [csr.pem] [ca-cert.pem] [ca-key.pem]\n");
printf("Example:\n");
printf("./csr_sign ecc ecc-csr.pem ca-ecc-cert.der ca-ecc-key.der\n");
}
static int do_csrsign(int argc, char** argv)
{
int ret = 0;
int type;
Cert newCert;
FILE* file;
const char* typeStr = argv[1];
const char* csrPemFile = argv[2];
const char* caCertPemFile = argv[3];
const char* caKeyPemFile = argv[4];
const char* newCertOutput = "./newCert.der";
const char* newCertPemFile = "./newCert.pem";
int derSz = 0;
int pemSz = 0;
int caKeySz = 0;
int caCertSz = 0;
byte* derBuf = NULL;
byte* pemBuf = NULL;
byte* caKeyBuf = NULL;
byte* caCertBuf = NULL;
#ifdef HAVE_ECC
ecc_key newKey;
ecc_key caKey;
#endif
void* keyPtr = NULL;
WC_RNG rng;
int initRng = 0, initCaKey = 0, initNewKey = 0;
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);
if (derBuf == NULL) goto exit;
XMEMSET(derBuf, 0, LARGE_TEMP_SZ);
pemBuf = (byte*)XMALLOC(LARGE_TEMP_SZ, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
if (pemBuf == NULL) goto exit;
XMEMSET(pemBuf, 0, LARGE_TEMP_SZ);
caKeyBuf = (byte*)XMALLOC(LARGE_TEMP_SZ, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
if (caKeyBuf == NULL) goto exit;
XMEMSET(caKeyBuf, 0, LARGE_TEMP_SZ);
caCertBuf = (byte*)XMALLOC(LARGE_TEMP_SZ, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
if (caCertBuf == NULL) goto exit;
XMEMSET(caCertBuf, 0, LARGE_TEMP_SZ);
/*---------------------------------------------------------------------------*/
/* Loading the CA Certificate PEM File */
/*---------------------------------------------------------------------------*/
printf("Loading CA certificate\n");
file = fopen(caCertPemFile, "rb");
if (!file) {
printf("failed to open file: %s\n", caCertPemFile);
goto exit;
}
pemSz = fread(pemBuf, 1, LARGE_TEMP_SZ, file);
fclose(file);
printf("Successfully read %d bytes from %s\n\n", pemSz, caCertPemFile);
ret = wc_CertPemToDer(pemBuf, pemSz, caCertBuf, LARGE_TEMP_SZ, CERT_TYPE);
if (ret >= 0) {
caCertSz = ret;
ret = 0;
}
printf("Converted CA Cert PEM to DER %d bytes\n\n", caCertSz);
/*---------------------------------------------------------------------------*/
/* Load the CA Key PEM File */
/*---------------------------------------------------------------------------*/
printf("Loading the CA key\n");
file = fopen(caKeyPemFile, "rb");
if (!file) {
printf("failed to open file: %s\n", caKeyPemFile);
goto exit;
}
pemSz = fread(pemBuf, 1, LARGE_TEMP_SZ, file);
fclose(file);
if (caKeySz <= 0) {
printf("Failed to read caKey from file\n");
goto exit;
}
printf("Successfully read %d bytes from %s\n", pemSz, caKeyPemFile);
ret = wc_KeyPemToDer(pemBuf, pemSz, caKeyBuf, LARGE_TEMP_SZ, NULL);
if (ret >= 0) {
caKeySz = ret;
ret = 0;
}
printf("Converted Key PEM to DER %d bytes\n\n", caKeySz);
/*---------------------------------------------------------------------------*/
/* Load CSR PEM */
/*---------------------------------------------------------------------------*/
printf("Loading CSR certificate\n");
file = fopen(csrPemFile, "rb");
if (!file) {
printf("failed to open file: %s\n", csrPemFile);
goto exit;
}
pemSz = fread(pemBuf, 1, LARGE_TEMP_SZ, file);
fclose(file);
printf("Successfully read %d bytes from %s\n\n", pemSz, csrPemFile);
ret = wc_CertPemToDer(pemBuf, pemSz, derBuf, LARGE_TEMP_SZ, CERTREQ_TYPE);
if (ret >= 0) {
derSz = ret;
ret = 0;
}
printf("Converted CSR Cert PEM to DER %d bytes\n\n", derSz);
/*---------------------------------------------------------------------------*/
/* 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);
newCert.isCA = 0;
newCert.sigType = CTC_SHA256wECDSA;
ret = wc_SetSubjectBuffer(&newCert, derBuf, derSz);
if (ret != 0) goto exit;
ret = wc_SetIssuerBuffer(&newCert, caCertBuf, caCertSz);
if (ret != 0) goto exit;
ret = wc_InitRng(&rng);
if (ret != 0) goto exit;
initRng = 1;
ret = wc_MakeCert(&newCert, derBuf, LARGE_TEMP_SZ, NULL, &newKey, &rng);
if (ret < 0) goto exit;
printf("Make Cert returned %d\n", ret);
ret = wc_SignCert_ex(newCert.bodySz, newCert.sigType, derBuf, LARGE_TEMP_SZ, type, &caKey, &rng);
if (ret < 0) goto exit;
derSz = ret;
printf("Signed Cert returned %d\n", derSz);
printf("Successfully signed certificate\n\n");
/*---------------------------------------------------------------------------*/
/* write the new cert to file in DER format */
/*---------------------------------------------------------------------------*/
printf("Writing newly generated DER certificate to file \"%s\"\n",
newCertOutput);
file = fopen(newCertOutput, "wb");
if (!file) {
printf("failed to open file: %s\n", newCertOutput);
goto exit;
}
ret = (int)fwrite(derBuf, 1, derSz, file);
fclose(file);
printf("Successfully output %d bytes\n", ret);
#ifdef WOLFSSL_DER_TO_PEM
/*---------------------------------------------------------------------------*/
/* convert the DER to a PEM and write it to a file */
/*---------------------------------------------------------------------------*/
printf("Convert the DER cert to PEM formatted cert\n");
pemSz = wc_DerToPem(derBuf, derSz, pemBuf, LARGE_TEMP_SZ, CERT_TYPE);
if (pemSz < 0) goto exit;
printf("Resulting PEM buffer is %d bytes\n", pemSz);
file = fopen(newCertPemFile, "wb");
if (!file) {
printf("failed to open file: %s\n", newCertPemFile);
goto exit;
}
fwrite(pemBuf, 1, pemSz, file);
fclose(file);
printf("Successfully converted the DER to PEM to \"%s\"\n\n",
newCertPemFile);
#endif
ret = 0; /* success */
exit:
XFREE(derBuf, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(pemBuf, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(caKeyBuf, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(caCertBuf, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
if (initCaKey)
wc_ecc_free(&caKey);
if (initNewKey)
wc_ecc_free(&newKey);
if (initRng) {
wc_FreeRng(&rng);
}
if (ret == 0)
printf("Tests passed\n");
else
printf("Failure code was %d\n", ret);
(void)keyPtr;
return ret;
}
int main(int argc, char** argv)
{
#if !defined(WOLFSSL_CERT_REQ) || !defined(WOLFSSL_CERT_GEN) || !defined(HAVE_DECODEDCERT)
printf("Please compile wolfSSL with --enable-certreq --enable-certgen CFLAGS=-DOPENSSL_EXTRA_X509_SMALL\n");
return 0;
#else
if (argc != 5) {
usage();
return 1;
}
return do_csrsign(argc, argv);
#endif
}