#include <stdio.h>
#include "wolfssl/options.h"
#include "wolfssl/wolfcrypt/settings.h"
#include "wolfssl/wolfcrypt/asn_public.h" /* Used for cert generation */
#include "wolfssl/wolfcrypt/random.h"
#include "wolfssl/wolfcrypt/rsa.h" /* Used for RNG and RSA Key */
/*
./configure CFLAGS="-DKEEP_PEER_CERT -DWOLFSSL_ALT_NAMES" --enable-keygen --enable-certgen --enable-sni --enable-debug && make
sudo make install
gcc -Wall -g -o certgen_sign -lwolfssl certgen_sign.c
*/
#define MAX_BUF_SZ 4096
int main() {
int res;
word32 idx = 0;
RsaKey genKey;
RsaKey cakey;
WC_RNG rng;
FILE *fp;
int cacertbufsize;
byte cacertbuf[MAX_BUF_SZ*2];
byte cacertder[MAX_BUF_SZ];
int cakeybufsize;
byte cakeybuf[MAX_BUF_SZ];
byte pemcert[MAX_BUF_SZ];
byte dercert[MAX_BUF_SZ];
int certsize;
int certpemsize;
byte caderkey[MAX_BUF_SZ];
int keysize;
byte keyDer[MAX_BUF_SZ];
int keypemsize;
byte keypem[MAX_BUF_SZ];
Cert testcert;
memset(&rng, 0, sizeof(rng));
memset(&cakey, 0, sizeof(cakey));
memset(&genKey, 0, sizeof(genKey));
memset(&testcert, 0, sizeof(testcert));
res = wc_InitRng(&rng);
if (res != 0) goto exit;
res = wc_InitRsaKey(&genKey,0);
if (res != 0) goto exit;
res = wc_MakeRsaKey(&genKey, 2048, 65537, &rng);
if (res != 0) goto exit;
/* Save off the private key we are going to use */
res = wc_RsaKeyToDer(&genKey, keyDer, sizeof(keyDer));
if (res < 0) goto exit;
keysize = res;
res = wc_DerToPem(keyDer, keysize, keypem, sizeof(keypem), PRIVATEKEY_TYPE);
if (res < 0) goto exit;
keypemsize = res;
/* Save the new private key */
fp = fopen("TestprivateKey.pem", "w+");
if (fp == NULL) { res = -1; goto exit; }
fwrite(keypem, 1, keypemsize, fp);
fclose(fp);
/* Create a CERT */
wc_InitCert(&testcert);
testcert.sigType = CTC_SHA256wRSA;
testcert.isCA = 0;
strcpy(testcert.subject.country, "US");
strcpy(testcert.subject.state, "ZZ");
strcpy(testcert.subject.locality, "This City");
strcpy(testcert.subject.org, "Yada");
strcpy(testcert.subject.unit, "Dev");
strcpy(testcert.subject.commonName, "www.whatever.com");
strcpy(testcert.subject.email, "Info@whatever.com");
/* Use for SELF SIGNED */
//certsize = wc_MakeSelfCert(&testcert, dercert, sizeof(dercert), &genKey, &rng);
/* Use to sign it */
/* Load the CA cert to use */
fp = fopen("./certs/ca-cert.pem", "r");
if (fp == NULL) { res = -1; goto exit; }
cacertbufsize = fread(cacertbuf, 1, sizeof(cacertbuf), fp);
fclose(fp);
/* Need to convert it to DER */
res = wc_CertPemToDer(cacertbuf, cacertbufsize, cacertder, sizeof(cacertder), CERT_TYPE);
if (res < 0) goto exit;
cacertbufsize = res;
res = wc_SetIssuerBuffer(&testcert, cacertder, cacertbufsize);
if (res != 0) goto exit;
/* Now we can make the certificate */
res = wc_MakeCert_ex(&testcert, dercert, sizeof(dercert), RSA_TYPE, &genKey, &rng);
if (res < 0) goto exit;
certsize = res;
/* Now load the CA key */
fp = fopen("./certs/ca-key.pem", "r");
if (fp == NULL) { res = -1; goto exit; }
cakeybufsize = fread(cakeybuf, 1, sizeof(cakeybuf), fp);
fclose(fp);
/* Need to conver it to DER */
wc_InitRsaKey(&cakey, 0);
res = wc_KeyPemToDer(cakeybuf, cakeybufsize, caderkey, sizeof(caderkey), NULL /* no password */);
if (res < 0) goto exit;
cakeybufsize = res;
res = wc_RsaPrivateKeyDecode((const byte *)caderkey, &idx, &cakey, cakeybufsize);
if (res < 0) goto exit;
/* Now we sign the certificate */
res = wc_SignCert(testcert.bodySz, testcert.sigType, dercert, sizeof(dercert), &cakey, NULL, &rng);
if (res < 0) goto exit;
certsize = res;
/* Save the signed signed cert (DER) */
fp = fopen("TestprivateCert.der", "w+");
if (fp == NULL) { res = -1; goto exit; }
fwrite(dercert, 1, certsize, fp);
fclose(fp);
/* Convert the DER to PEM */
res = wc_DerToPem(dercert, certsize, pemcert, sizeof(pemcert), CERT_TYPE);
if (res < 0) goto exit;
certpemsize = res;
res = 0; /* success */
/* Save the signed signed cert (PEM) */
fp = fopen("TestprivateCert.pem", "w+");
if (fp == NULL) { res = -1; goto exit; }
fwrite(pemcert, 1, certpemsize, fp);
fclose(fp);
exit:
printf("Result %d\n", res);
wc_FreeRsaKey(&cakey);
wc_FreeRsaKey(&genKey);
wc_FreeRng(&rng);
return res;
}