diff --git a/.gitignore b/.gitignore index f5b1b0ae..83c432a4 100644 --- a/.gitignore +++ b/.gitignore @@ -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 diff --git a/certgen/Makefile b/certgen/Makefile index 1b460402..bb379c86 100644 --- a/certgen/Makefile +++ b/certgen/Makefile @@ -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.* diff --git a/certgen/README.md b/certgen/README.md index 68ad2328..e7ef9cf4 100644 --- a/certgen/README.md +++ b/certgen/README.md @@ -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 ``` diff --git a/certgen/certgen_example.c b/certgen/certgen_example.c index 18431ec9..d67d1837 100644 --- a/certgen/certgen_example.c +++ b/certgen/certgen_example.c @@ -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 #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 } diff --git a/certgen/csr_example.c b/certgen/csr_example.c index f242821f..30638562 100644 --- a/certgen/csr_example.c +++ b/certgen/csr_example.c @@ -25,88 +25,154 @@ #include #include #include +#include #include +#include #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 } diff --git a/certgen/csr_sign.c b/certgen/csr_sign.c new file mode 100644 index 00000000..8d89e797 --- /dev/null +++ b/certgen/csr_sign.c @@ -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 +#include +#include +#include +#include +#include +#include + +#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 +}