Improvements based on peer review. Added section in README.md.

pull/297/head
David Garske 2022-02-23 15:59:17 -08:00
parent 042956c74b
commit 45a13e1491
3 changed files with 245 additions and 148 deletions

View File

@ -252,3 +252,84 @@ bmQHbpv7R5cK0GP2bFkqggIgN1wA6w19lVFdjukGx6VvfYsdaY2O+Fu6Ew4qX7SG
GxI= GxI=
-----END CERTIFICATE----- -----END CERTIFICATE-----
``` ```
## Certificate Signing Request (CSR) Example with Crypto Callbacks
Example of generating a PEM-encoded certificate signing request (CSR) using the
Crypto Callbacks to show signing against HSM/TPM
Tested with these wolfSSL build options:
```
./configure --enable-certreq --enable-certgen --enable-certext --enable-cryptocb
make
sudo make install
```
### `csr_cryptocb` Example output
```
% ./csr_cryptocb
Invalid input supplied try one of the below examples
Examples:
./csr_cryptocb rsa
./csr_cryptocb ecc
./csr_cryptocb ed25519
```
```
% ./csr_cryptocb ecc
CryptoCb: PK ECDSA-Sign (4)
-----BEGIN CERTIFICATE REQUEST-----
MIIBTDCB8wIBAjCBkDELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk9SMREwDwYDVQQH
DAhQb3J0bGFuZDEQMA4GA1UECgwHd29sZlNTTDEUMBIGA1UECwwLRGV2ZWxvcG1l
bnQxGDAWBgNVBAMMD3d3dy53b2xmc3NsLmNvbTEfMB0GCSqGSIb3DQEJARYQaW5m
b0B3b2xmc3NsLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABLszrEwnUErG
SqUEwzzenzbbci3OlOor+ssgCTksFuhhAumvTdMCk5oxW5eSIX/wzxjakRECNIbo
IFgzC4A0idigADAKBggqhkjOPQQDAgNIADBFAiEAmJK6ZapcFw4NTjImNoBrpudZ
6sFvRccABG35QyASvIsCIFXcN4Wo5qiH37OjT7dehbdZvQbJFw4hKOtim1gw5Z4p
-----END CERTIFICATE REQUEST-----
(525)
Saved CSR PEM to "ecc-csr.pem"
```
% ./csr_cryptocb rsa
CryptoCb: PK RSA (1)
-----BEGIN CERTIFICATE REQUEST-----
MIIC1jCCAb4CAQIwgZAxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJPUjERMA8GA1UE
BwwIUG9ydGxhbmQxEDAOBgNVBAoMB3dvbGZTU0wxFDASBgNVBAsMC0RldmVsb3Bt
ZW50MRgwFgYDVQQDDA93d3cud29sZnNzbC5jb20xHzAdBgkqhkiG9w0BCQEWEGlu
Zm9Ad29sZnNzbC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDD
A9Er/jmkMkU7U8iEKyp8dJq9qipSB0fWpjayBzKO0Lppe8bDRJ7UgUj9LWiii2e7
oXXINixK0hv3i7rPDfnv7PGBHnubA0eav2XMf2UkaaboFIlb5DT3xbAUk/Vnezp6
eOEBVlaRphNCjdI8QJxM79GG3zdRGwyhO/Xxo0o15OHOlt8bfr9Ol9AQ6KgIMIGv
IAtDFMV0Z7Qygm+NhsKIQJk2g7oeQHIiF9dSZSRzsM7vGc2u/3hse8ASA9ROcg1Q
bTujO6OZXp3I2QyFs9mK2VQm2236rLv/JUzE0Xn0cdOGQBgTsGO1ck4wxJeEhi1W
L9cV93/ArvX8W+X7obrTAgMBAAGgADANBgkqhkiG9w0BAQsFAAOCAQEAK+RxSIQ4
CqxYbicHcbFZgHrTy7MOoA8uM5XWIP/AKZ4u64zbF2K6XIMItrfIGEouc6MDfKVh
W8ml6O75SR/7h/8S/9GClqcuzFqtNflzmb20Oadkl09sRIXPhFXMpt4V+Zc4cOka
kcqL0q+oEU+8naRJJ6pa6LL1NWRq79es4DykvtHcGkx0J1VPlu3ux7iYlQ0fVfRs
QUI1z3K52qfuchKW5zwkDjkVDbiWPd0/pbtUW2f8TAC21h0NabwMGISrrxmu6SX2
wI8YHCyLX5sMUosQ78vuGBD0bD5rxil0lzO9pjvWiSLZe0ubJ2Qq+FiuqIqITRiy
5AMQEs5siVCCEA==
-----END CERTIFICATE REQUEST-----
(1062)
Saved CSR PEM to "rsa-csr.pem"
```
```
% ./csr_cryptocb ed25519
CryptoCb: PK ED25519-Sign (6)
-----BEGIN CERTIFICATE REQUEST-----
MIIBETCBxAIBAjCBkDELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk9SMREwDwYDVQQH
DAhQb3J0bGFuZDEQMA4GA1UECgwHd29sZlNTTDEUMBIGA1UECwwLRGV2ZWxvcG1l
bnQxGDAWBgNVBAMMD3d3dy53b2xmc3NsLmNvbTEfMB0GCSqGSIb3DQEJARYQaW5m
b0B3b2xmc3NsLmNvbTAqMAUGAytlcAMhAOZXWxMbx1EUa+079dH6q55stusCCaOZ
9W6/nTz+VDnmoAAwBQYDK2VwA0EAZX+pExcyCYxJHJmmISW8AxfhgJ/PmTPK4+uH
7iTt+VTNvi/Z6IPjlg+UWIbyyCno0RoNnB7GiqnvPn8fVAcsAw==
-----END CERTIFICATE REQUEST-----
(448)
Saved CSR PEM to "ed25519-csr.pem"
```

View File

@ -19,7 +19,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/ */
/* Example of generating a PEM-encoded certificate signing request (CSR). */ /* Example of generating a PEM-encoded certificate signing request (CSR) using
* the Crypto Callbacks to show signing against HSM/TPM */
#ifndef WOLFSSL_USER_SETTINGS #ifndef WOLFSSL_USER_SETTINGS
#include <wolfssl/options.h> #include <wolfssl/options.h>
@ -37,8 +38,13 @@
#define DEBUG_CRYPTOCB #define DEBUG_CRYPTOCB
#if defined(WOLF_CRYPTO_CB) && defined(WOLFSSL_CERT_REQ) && \ #if defined(WOLF_CRYPTO_CB) && defined(WOLFSSL_CERT_REQ) && \
defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_CERT_GEN) defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_CERT_GEN) && \
(!defined(NO_RSA) || defined(HAVE_ECC) || defined(HAVE_ED25519))
#define ENABLE_CSR_EXAMPLE
#endif
#ifdef ENABLE_CSR_EXAMPLE
static void usage(void) static void usage(void)
{ {
printf("Invalid input supplied try one of the below examples\n"); printf("Invalid input supplied try one of the below examples\n");
@ -54,6 +60,122 @@ typedef struct {
const char* keyFilePriv; const char* keyFilePriv;
} myCryptoCbCtx; } myCryptoCbCtx;
/* Forward declarations */
static int load_key_file(const char* fname, byte* derBuf, word32* derLen,
int isPubKey);
#ifdef DEBUG_CRYPTOCB
static const char* GetAlgoTypeStr(int algo);
static const char* GetPkTypeStr(int pk);
#endif
/* Example crypto dev callback function that calls software version */
/* This is where you would plug-in calls to your own hardware crypto */
static int myCryptoDevCb(int devIdArg, wc_CryptoInfo* info, void* ctx)
{
int ret = CRYPTOCB_UNAVAILABLE; /* return this to bypass HW and use SW */
myCryptoCbCtx* myCtx = (myCryptoCbCtx*)ctx;
byte der[LARGE_TEMP_SZ];
word32 derSz;
word32 idx = 0;
if (info == NULL)
return BAD_FUNC_ARG;
ret = load_key_file(myCtx->keyFilePriv, der, &derSz, 0);
if (ret != 0) {
printf("Error %d loading %s\n", ret, myCtx->keyFilePriv);
return ret;
}
if (info->algo_type == WC_ALGO_TYPE_PK) {
#ifdef DEBUG_CRYPTOCB
printf("CryptoCb: %s %s (%d)\n", GetAlgoTypeStr(info->algo_type),
GetPkTypeStr(info->pk.type), info->pk.type);
#endif
#ifndef NO_RSA
if (info->pk.type == WC_PK_TYPE_RSA) {
RsaKey rsaPriv;
ret = wc_InitRsaKey_ex(&rsaPriv, NULL, INVALID_DEVID);
if (ret != 0) {
return ret;
}
ret = wc_RsaPrivateKeyDecode(der, &idx, &rsaPriv, derSz);
if (ret != 0) {
wc_FreeRsaKey(&rsaPriv);
return ret;
}
switch (info->pk.rsa.type) {
case RSA_PUBLIC_ENCRYPT:
case RSA_PUBLIC_DECRYPT:
/* perform software based RSA public op */
ret = wc_RsaFunction(
info->pk.rsa.in, info->pk.rsa.inLen,
info->pk.rsa.out, info->pk.rsa.outLen,
info->pk.rsa.type, &rsaPriv, info->pk.rsa.rng);
break;
case RSA_PRIVATE_ENCRYPT:
case RSA_PRIVATE_DECRYPT:
/* perform software based RSA private op */
ret = wc_RsaFunction(
info->pk.rsa.in, info->pk.rsa.inLen,
info->pk.rsa.out, info->pk.rsa.outLen,
info->pk.rsa.type, &rsaPriv, info->pk.rsa.rng);
break;
}
wc_FreeRsaKey(&rsaPriv);
}
#endif /* !NO_RSA */
#ifdef HAVE_ECC
if (info->pk.type == WC_PK_TYPE_ECDSA_SIGN) {
ecc_key eccPriv;
ret = wc_ecc_init_ex(&eccPriv, NULL, INVALID_DEVID);
if (ret == 0) {
ret = wc_EccPrivateKeyDecode(der, &idx, &eccPriv, derSz);
if (ret == 0) {
ret = wc_ecc_sign_hash(
info->pk.eccsign.in, info->pk.eccsign.inlen,
info->pk.eccsign.out, info->pk.eccsign.outlen,
info->pk.eccsign.rng, &eccPriv);
}
wc_ecc_free(&eccPriv);
}
}
#endif /* HAVE_ECC */
#ifdef HAVE_ED25519
if (info->pk.type == WC_PK_TYPE_ED25519_SIGN) {
ed25519_key edPriv;
ret = wc_ed25519_init_ex(&edPriv, NULL, INVALID_DEVID);
if (ret == 0) {
ret = wc_Ed25519PrivateKeyDecode(der, &idx, &edPriv, derSz);
if (ret == 0) {
/* calculate public key */
ret = wc_ed25519_make_public(&edPriv, edPriv.p,
ED25519_PUB_KEY_SIZE);
}
if (ret == 0) {
edPriv.pubKeySet = 1;
ret = wc_ed25519_sign_msg_ex(
info->pk.ed25519sign.in, info->pk.ed25519sign.inLen,
info->pk.ed25519sign.out, info->pk.ed25519sign.outLen,
&edPriv, info->pk.ed25519sign.type,
info->pk.ed25519sign.context,
info->pk.ed25519sign.contextLen);
}
wc_ed25519_free(&edPriv);
}
}
#endif /* HAVE_ED25519 */
}
(void)devIdArg;
(void)myCtx;
return ret;
}
#ifdef DEBUG_CRYPTOCB #ifdef DEBUG_CRYPTOCB
static const char* GetAlgoTypeStr(int algo) static const char* GetAlgoTypeStr(int algo)
{ {
@ -193,113 +315,6 @@ static int save_der_as_pem(const byte* der, word32 derSz, const char* arg1,
} }
#endif #endif
/* Example crypto dev callback function that calls software version */
/* This is where you would plug-in calls to your own hardware crypto */
static int myCryptoDevCb(int devIdArg, wc_CryptoInfo* info, void* ctx)
{
int ret = CRYPTOCB_UNAVAILABLE; /* return this to bypass HW and use SW */
myCryptoCbCtx* myCtx = (myCryptoCbCtx*)ctx;
byte der[LARGE_TEMP_SZ];
word32 derSz;
word32 idx = 0;
if (info == NULL)
return BAD_FUNC_ARG;
ret = load_key_file(myCtx->keyFilePriv, der, &derSz, 0);
if (ret != 0) {
printf("Error %d loading %s\n", ret, myCtx->keyFilePriv);
return ret;
}
if (info->algo_type == WC_ALGO_TYPE_PK) {
#ifdef DEBUG_CRYPTOCB
printf("CryptoCb: %s %s (%d)\n", GetAlgoTypeStr(info->algo_type),
GetPkTypeStr(info->pk.type), info->pk.type);
#endif
#ifndef NO_RSA
if (info->pk.type == WC_PK_TYPE_RSA) {
RsaKey rsaPriv;
ret = wc_InitRsaKey_ex(&rsaPriv, NULL, INVALID_DEVID);
if (ret != 0) {
return ret;
}
ret = wc_RsaPrivateKeyDecode(der, &idx, &rsaPriv, derSz);
if (ret != 0) {
wc_FreeRsaKey(&rsaPriv);
return ret;
}
switch (info->pk.rsa.type) {
case RSA_PUBLIC_ENCRYPT:
case RSA_PUBLIC_DECRYPT:
/* perform software based RSA public op */
ret = wc_RsaFunction(
info->pk.rsa.in, info->pk.rsa.inLen,
info->pk.rsa.out, info->pk.rsa.outLen,
info->pk.rsa.type, &rsaPriv, info->pk.rsa.rng);
break;
case RSA_PRIVATE_ENCRYPT:
case RSA_PRIVATE_DECRYPT:
/* perform software based RSA private op */
ret = wc_RsaFunction(
info->pk.rsa.in, info->pk.rsa.inLen,
info->pk.rsa.out, info->pk.rsa.outLen,
info->pk.rsa.type, &rsaPriv, info->pk.rsa.rng);
break;
}
wc_FreeRsaKey(&rsaPriv);
}
#endif /* !NO_RSA */
#ifdef HAVE_ECC
if (info->pk.type == WC_PK_TYPE_ECDSA_SIGN) {
ecc_key eccPriv;
ret = wc_ecc_init_ex(&eccPriv, NULL, INVALID_DEVID);
if (ret == 0) {
ret = wc_EccPrivateKeyDecode(der, &idx, &eccPriv, derSz);
if (ret == 0) {
ret = wc_ecc_sign_hash(
info->pk.eccsign.in, info->pk.eccsign.inlen,
info->pk.eccsign.out, info->pk.eccsign.outlen,
info->pk.eccsign.rng, &eccPriv);
}
wc_ecc_free(&eccPriv);
}
}
#endif /* HAVE_ECC */
#ifdef HAVE_ED25519
if (info->pk.type == WC_PK_TYPE_ED25519_SIGN) {
ed25519_key edPriv;
ret = wc_ed25519_init_ex(&edPriv, NULL, INVALID_DEVID);
if (ret == 0) {
ret = wc_Ed25519PrivateKeyDecode(der, &idx, &edPriv, derSz);
if (ret == 0) {
/* calculate public key */
ret = wc_ed25519_make_public(&edPriv, edPriv.p,
ED25519_PUB_KEY_SIZE);
}
if (ret == 0) {
edPriv.pubKeySet = 1;
ret = wc_ed25519_sign_msg_ex(
info->pk.ed25519sign.in, info->pk.ed25519sign.inLen,
info->pk.ed25519sign.out, info->pk.ed25519sign.outLen,
&edPriv, info->pk.ed25519sign.type,
info->pk.ed25519sign.context,
info->pk.ed25519sign.contextLen);
}
wc_ed25519_free(&edPriv);
}
}
#endif /* HAVE_ED25519 */
}
(void)devIdArg;
(void)myCtx;
return ret;
}
static int gen_csr(const char* arg1) static int gen_csr(const char* arg1)
{ {
int ret; int ret;
@ -328,8 +343,10 @@ static int gen_csr(const char* arg1)
type = ECC_TYPE; type = ECC_TYPE;
else if (XSTRNCMP(arg1, "ed25519", 7) == 0) else if (XSTRNCMP(arg1, "ed25519", 7) == 0)
type = ED25519_TYPE; type = ED25519_TYPE;
else else {
printf("Invalid argument or not compiled in (expect: rsa, ecc or ed25519)\n");
return NOT_COMPILED_IN; return NOT_COMPILED_IN;
}
wolfCrypt_Init(); wolfCrypt_Init();
@ -490,16 +507,15 @@ exit:
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
#if !defined(WOLF_CRYPTO_CB) || !defined(WOLFSSL_CERT_REQ) || \ #ifdef ENABLE_CSR_EXAMPLE
!defined(WOLFSSL_CERT_EXT) || !defined(WOLFSSL_CERT_GEN)
printf("Please compile wolfSSL with --enable-certreq --enable-certgen --enable-certext --enable-cryptocb\n");
return 0;
#else
if (argc != 2) { if (argc != 2) {
usage(); usage();
return 1; return 1;
} }
return gen_csr(argv[1]); return gen_csr(argv[1]);
#else
printf("Please compile wolfSSL with --enable-certreq --enable-certgen --enable-certext --enable-cryptocb\n");
return 0;
#endif #endif
} }