Improvements to the PK callback example to use public key. Added RSA/PSS PK support to example.

pull/306/head
David Garske 2022-03-18 11:32:32 -07:00
parent 2d875419b5
commit df2191396e
4 changed files with 338 additions and 46 deletions

View File

@ -0,0 +1,4 @@
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEVb/0D0RQmj3Om7fwxU31cHvU7CSO
GYDsWkyiJANiLJva76I1EkOEdhbGVpUGzAGpvfZ1GkL3vamyNiJfx11/tA==
-----END PUBLIC KEY-----

View File

@ -0,0 +1,9 @@
-----BEGIN RSA PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwJUI4VdB8nFtt9JFQScB
ZcZFrvK8JDC4lc4vTtb2HIi8fJ/7qGd//lycUXX3isoH5zUvj+G9e8AvfKtkqBf8
yl17uuAh5XIuby6G2JVz2qwbU7lfP9cZDSVP4WNjUYsLZD+tQ7ilHFw0s64AoGPF
9n8LWWh4c6aMGKkCba/DGQEuuBDjxsxAtGmjRjNph27Euxem8+jdrXO8ey8htf1m
UQy9VLPhbV8cvCNz0QkDiRTSELlkwyrQoZZKvOHUGlvHoMDBY3gPRDcwMpaAMiOV
oXe6E9KXc+JdJclqDcM5YKS0sGlCQgnp2Ai8MyCzWCKnquvE4eZhg8XSlt/Z0E+t
1wIDAQAB
-----END RSA PUBLIC KEY-----

View File

@ -39,6 +39,8 @@
#include <wolfssl/wolfcrypt/sha256.h>
#include <wolfssl/wolfcrypt/cryptocb.h>
#include <wolfssl/wolfcrypt/ecc.h>
#include <wolfssl/wolfcrypt/rsa.h>
#include <wolfssl/wolfcrypt/asn.h>
#include <wolfssl/wolfcrypt/error-crypt.h>
#define DEFAULT_PORT 11111
@ -47,18 +49,25 @@
#define USE_TLSV13
#ifdef USE_ECDHE_ECDSA
#define CERT_FILE "../certs/client-ecc-cert.pem"
#define KEY_FILE "../certs/ecc-client-key.pem"
#define CA_FILE "../certs/ca-ecc-cert.pem"
#define CERT_FILE "../certs/client-ecc-cert.pem"
#define KEY_FILE "../certs/ecc-client-key.pem"
#define KEYPUB_FILE "../certs/ecc-client-keyPub.pem"
#define CA_FILE "../certs/ca-ecc-cert.pem"
#else
#define CERT_FILE "../certs/client-cert.pem"
#define KEY_FILE "../certs/client-key.pem"
#define CA_FILE "../certs/ca-cert.pem"
#define CERT_FILE "../certs/client-cert.pem"
#define KEY_FILE "../certs/client-key.pem"
#define KEYPUB_FILE "../certs/client-keyPub.pem"
#define CA_FILE "../certs/ca-cert.pem"
#endif
typedef struct {
const char* keyFile;
ecc_key key;
#ifdef HAVE_ECC
ecc_key keyEcc;
#endif
#ifndef NO_RSA
RsaKey keyRsa;
#endif
int state;
} PkCbInfo;
@ -137,6 +146,7 @@ static int load_key_file(const char* fname, byte** derBuf, word32* derLen)
return 0;
}
#ifdef HAVE_ECC
/* This function is performing a sign using a private key for testing. In a
* real-world use case this would be sent to HSM / TPM hardware for processing
* and return WC_PENDING_E to give this thread time to do other work */
@ -159,17 +169,18 @@ static int myEccSign(WOLFSSL* ssl, const byte* in, word32 inSz,
ret = load_key_file(cbInfo->keyFile, &keyBuf, &keySz);
if (ret == 0) {
ret = wc_ecc_init(&cbInfo->key);
ret = wc_ecc_init(&cbInfo->keyEcc);
if (ret == 0) {
word32 idx = 0;
ret = wc_EccPrivateKeyDecode(keyBuf, &idx, &cbInfo->key, keySz);
ret = wc_EccPrivateKeyDecode(keyBuf, &idx, &cbInfo->keyEcc, keySz);
if (ret == 0) {
WC_RNG *rng = wolfSSL_GetRNG(ssl);
printf("PK ECC Sign: Curve ID %d\n", cbInfo->key.dp->id);
ret = wc_ecc_sign_hash(in, inSz, out, outSz, rng, &cbInfo->key);
printf("PK ECC Sign: Curve ID %d\n", cbInfo->keyEcc.dp->id);
ret = wc_ecc_sign_hash(in, inSz, out, outSz, rng,
&cbInfo->keyEcc);
}
wc_ecc_free(&cbInfo->key);
wc_ecc_free(&cbInfo->keyEcc);
}
}
free(keyBuf);
@ -182,6 +193,119 @@ static int myEccSign(WOLFSSL* ssl, const byte* in, word32 inSz,
return ret;
}
#endif
#ifndef NO_RSA
static int myRsaSign(WOLFSSL* ssl, const byte* in, word32 inSz,
byte* out, word32* outSz, const byte* key, word32 keySz, void* ctx)
{
int ret;
word32 idx = 0;
byte* keyBuf = (byte*)key;
PkCbInfo* cbInfo = (PkCbInfo*)ctx;
(void)ssl;
(void)cbInfo;
printf("PK RSA Sign: inSz %u, keySz %u\n", inSz, keySz);
#ifdef WOLFSSL_ASYNC_CRYPT
if (cbInfo->state == 0) {
cbInfo->state++;
printf("PK ECC Sign: Async Simulate\n");
return WC_PENDING_E;
}
#endif
ret = load_key_file(cbInfo->keyFile, &keyBuf, &keySz);
if (ret != 0)
return ret;
ret = wc_InitRsaKey(&cbInfo->keyRsa, NULL);
if (ret == 0) {
ret = wc_RsaPrivateKeyDecode(keyBuf, &idx, &cbInfo->keyRsa, keySz);
if (ret == 0) {
WC_RNG *rng = wolfSSL_GetRNG(ssl);
ret = wc_RsaSSL_Sign(in, inSz, out, *outSz, &cbInfo->keyRsa, rng);
}
if (ret > 0) { /* save and convert to 0 success */
*outSz = ret;
ret = 0;
}
wc_FreeRsaKey(&cbInfo->keyRsa);
}
free(keyBuf);
#ifdef WOLFSSL_ASYNC_CRYPT
cbInfo->state = 0;
#endif
printf("PK RSA Sign: ret %d, outSz %u\n", ret, *outSz);
return ret;
}
#ifdef WC_RSA_PSS
static int myRsaPssSign(WOLFSSL* ssl, const byte* in, word32 inSz,
byte* out, word32* outSz, int hash, int mgf, const byte* key,
word32 keySz, void* ctx)
{
enum wc_HashType hashType = WC_HASH_TYPE_NONE;
int ret;
word32 idx = 0;
byte* keyBuf = (byte*)key;
PkCbInfo* cbInfo = (PkCbInfo*)ctx;
(void)ssl;
(void)cbInfo;
printf("PK RSA PSS Sign: inSz %u, hash %d, mgf %d, keySz %u\n",
inSz, hash, mgf, keySz);
ret = load_key_file(cbInfo->keyFile, &keyBuf, &keySz);
if (ret != 0)
return ret;
switch (hash) {
#ifndef NO_SHA256
case SHA256h:
hashType = WC_HASH_TYPE_SHA256;
break;
#endif
#ifdef WOLFSSL_SHA384
case SHA384h:
hashType = WC_HASH_TYPE_SHA384;
break;
#endif
#ifdef WOLFSSL_SHA512
case SHA512h:
hashType = WC_HASH_TYPE_SHA512;
break;
#endif
}
ret = wc_InitRsaKey(&cbInfo->keyRsa, NULL);
if (ret == 0) {
ret = wc_RsaPrivateKeyDecode(keyBuf, &idx, &cbInfo->keyRsa, keySz);
if (ret == 0) {
WC_RNG *rng = wolfSSL_GetRNG(ssl);
ret = wc_RsaPSS_Sign(in, inSz, out, *outSz, hashType, mgf,
&cbInfo->keyRsa, rng);
}
if (ret > 0) { /* save and convert to 0 success */
*outSz = ret;
ret = 0;
}
wc_FreeRsaKey(&cbInfo->keyRsa);
}
free(keyBuf);
printf("PK RSA PSS Sign: ret %d, outSz %u\n", ret, *outSz);
return ret;
}
#endif
#endif
#endif /* HAVE_PK_CALLBACKS */
int main(int argc, char** argv)
@ -240,7 +364,7 @@ int main(int argc, char** argv)
/*---------------------------------*/
/* Start of wolfSSL initialization and configuration */
/*---------------------------------*/
#if 0
#if 1
wolfSSL_Debugging_ON();
#endif
@ -263,8 +387,16 @@ int main(int argc, char** argv)
}
#ifdef HAVE_PK_CALLBACKS
/* register an ECC sign callback for the long term key */
/* register a sign callbacks for the long term key */
#ifdef HAVE_ECC
wolfSSL_CTX_SetEccSignCb(ctx, myEccSign);
#endif
#ifndef NO_RSA
wolfSSL_CTX_SetRsaSignCb(ctx, myRsaSign);
#ifdef WC_RSA_PSS
wolfSSL_CTX_SetRsaPssSignCb(ctx, myRsaPssSign);
#endif
#endif
#else
printf("Warning: PK not compiled in! Please configure wolfSSL with "
" --enable-pkcallbacks and try again\n");
@ -272,18 +404,18 @@ int main(int argc, char** argv)
/* Mutual Authentication */
/* Load client certificate into WOLFSSL_CTX */
if ((ret = wolfSSL_CTX_use_certificate_file(ctx, CERT_FILE, WOLFSSL_FILETYPE_PEM))
!= WOLFSSL_SUCCESS) {
if ((ret = wolfSSL_CTX_use_certificate_file(ctx, CERT_FILE,
WOLFSSL_FILETYPE_PEM)) != WOLFSSL_SUCCESS) {
fprintf(stderr, "ERROR: failed to load %s, please check the file.\n",
CERT_FILE);
goto exit;
}
/* Load client key into WOLFSSL_CTX */
if ((ret = wolfSSL_CTX_use_PrivateKey_file(ctx, KEY_FILE, WOLFSSL_FILETYPE_PEM))
!= WOLFSSL_SUCCESS) {
if ((ret = wolfSSL_CTX_use_PrivateKey_file(ctx, KEYPUB_FILE,
WOLFSSL_FILETYPE_PEM)) != WOLFSSL_SUCCESS) {
fprintf(stderr, "ERROR: failed to load %s, please check the file.\n",
KEY_FILE);
KEYPUB_FILE);
goto exit;
}
@ -313,7 +445,15 @@ int main(int argc, char** argv)
#ifdef HAVE_PK_CALLBACKS
/* setup the PK context */
#ifdef HAVE_ECC
wolfSSL_SetEccSignCtx(ssl, &myCtx);
#endif
#ifndef NO_RSA
wolfSSL_SetRsaSignCtx(ssl, &myCtx);
#ifdef WC_RSA_PSS
wolfSSL_SetRsaPssSignCtx(ssl, &myCtx);
#endif
#endif
#else
(void)myCtx; /* not used */
#endif

View File

@ -39,6 +39,8 @@
#include <wolfssl/wolfcrypt/sha256.h>
#include <wolfssl/wolfcrypt/cryptocb.h>
#include <wolfssl/wolfcrypt/ecc.h>
#include <wolfssl/wolfcrypt/rsa.h>
#include <wolfssl/wolfcrypt/asn.h>
#include <wolfssl/wolfcrypt/error-crypt.h>
#define DEFAULT_PORT 11111
@ -47,18 +49,25 @@
#define USE_TLSV13
#ifdef USE_ECDHE_ECDSA
#define CERT_FILE "../certs/server-ecc.pem"
#define KEY_FILE "../certs/ecc-key.pem"
#define CA_FILE "../certs/client-ecc-cert.pem"
#define CERT_FILE "../certs/server-ecc.pem"
#define KEY_FILE "../certs/ecc-key.pem"
#define KEYPUB_FILE "../certs/ecc-keyPub.pem"
#define CA_FILE "../certs/client-ecc-cert.pem"
#else
#define CERT_FILE "../certs/server-cert.pem"
#define KEY_FILE "../certs/server-key.pem"
#define CA_FILE "../certs/client-cert.pem"
#define CERT_FILE "../certs/server-cert.pem"
#define KEY_FILE "../certs/server-key.pem"
#define KEYPUB_FILE "../certs/server-keyPub.pem"
#define CA_FILE "../certs/client-cert.pem"
#endif
typedef struct {
const char* keyFile;
ecc_key key;
#ifdef HAVE_ECC
ecc_key keyEcc;
#endif
#ifndef NO_RSA
RsaKey keyRsa;
#endif
int state;
} PkCbInfo;
@ -137,6 +146,7 @@ static int load_key_file(const char* fname, byte** derBuf, word32* derLen)
return 0;
}
#ifdef HAVE_ECC
/* This function is performing a sign using a private key for testing. In a
* real-world use case this would be sent to HSM / TPM hardware for processing
* and return WC_PENDING_E to give this thread time to do other work */
@ -159,17 +169,18 @@ static int myEccSign(WOLFSSL* ssl, const byte* in, word32 inSz,
ret = load_key_file(cbInfo->keyFile, &keyBuf, &keySz);
if (ret == 0) {
ret = wc_ecc_init(&cbInfo->key);
ret = wc_ecc_init(&cbInfo->keyEcc);
if (ret == 0) {
word32 idx = 0;
ret = wc_EccPrivateKeyDecode(keyBuf, &idx, &cbInfo->key, keySz);
ret = wc_EccPrivateKeyDecode(keyBuf, &idx, &cbInfo->keyEcc, keySz);
if (ret == 0) {
WC_RNG *rng = wolfSSL_GetRNG(ssl);
printf("PK ECC Sign: Curve ID %d\n", cbInfo->key.dp->id);
ret = wc_ecc_sign_hash(in, inSz, out, outSz, rng, &cbInfo->key);
printf("PK ECC Sign: Curve ID %d\n", cbInfo->keyEcc.dp->id);
ret = wc_ecc_sign_hash(in, inSz, out, outSz, rng,
&cbInfo->keyEcc);
}
wc_ecc_free(&cbInfo->key);
wc_ecc_free(&cbInfo->keyEcc);
}
}
free(keyBuf);
@ -181,6 +192,119 @@ static int myEccSign(WOLFSSL* ssl, const byte* in, word32 inSz,
return ret;
}
#endif
#ifndef NO_RSA
static int myRsaSign(WOLFSSL* ssl, const byte* in, word32 inSz,
byte* out, word32* outSz, const byte* key, word32 keySz, void* ctx)
{
int ret;
word32 idx = 0;
byte* keyBuf = (byte*)key;
PkCbInfo* cbInfo = (PkCbInfo*)ctx;
(void)ssl;
(void)cbInfo;
printf("PK RSA Sign: inSz %u, keySz %u\n", inSz, keySz);
#ifdef WOLFSSL_ASYNC_CRYPT
if (cbInfo->state == 0) {
cbInfo->state++;
printf("PK ECC Sign: Async Simulate\n");
return WC_PENDING_E;
}
#endif
ret = load_key_file(cbInfo->keyFile, &keyBuf, &keySz);
if (ret != 0)
return ret;
ret = wc_InitRsaKey(&cbInfo->keyRsa, NULL);
if (ret == 0) {
ret = wc_RsaPrivateKeyDecode(keyBuf, &idx, &cbInfo->keyRsa, keySz);
if (ret == 0) {
WC_RNG *rng = wolfSSL_GetRNG(ssl);
ret = wc_RsaSSL_Sign(in, inSz, out, *outSz, &cbInfo->keyRsa, rng);
}
if (ret > 0) { /* save and convert to 0 success */
*outSz = ret;
ret = 0;
}
wc_FreeRsaKey(&cbInfo->keyRsa);
}
free(keyBuf);
#ifdef WOLFSSL_ASYNC_CRYPT
cbInfo->state = 0;
#endif
printf("PK RSA Sign: ret %d, outSz %u\n", ret, *outSz);
return ret;
}
#ifdef WC_RSA_PSS
static int myRsaPssSign(WOLFSSL* ssl, const byte* in, word32 inSz,
byte* out, word32* outSz, int hash, int mgf, const byte* key,
word32 keySz, void* ctx)
{
enum wc_HashType hashType = WC_HASH_TYPE_NONE;
int ret;
word32 idx = 0;
byte* keyBuf = (byte*)key;
PkCbInfo* cbInfo = (PkCbInfo*)ctx;
(void)ssl;
(void)cbInfo;
printf("PK RSA PSS Sign: inSz %u, hash %d, mgf %d, keySz %u\n",
inSz, hash, mgf, keySz);
ret = load_key_file(cbInfo->keyFile, &keyBuf, &keySz);
if (ret != 0)
return ret;
switch (hash) {
#ifndef NO_SHA256
case SHA256h:
hashType = WC_HASH_TYPE_SHA256;
break;
#endif
#ifdef WOLFSSL_SHA384
case SHA384h:
hashType = WC_HASH_TYPE_SHA384;
break;
#endif
#ifdef WOLFSSL_SHA512
case SHA512h:
hashType = WC_HASH_TYPE_SHA512;
break;
#endif
}
ret = wc_InitRsaKey(&cbInfo->keyRsa, NULL);
if (ret == 0) {
ret = wc_RsaPrivateKeyDecode(keyBuf, &idx, &cbInfo->keyRsa, keySz);
if (ret == 0) {
WC_RNG *rng = wolfSSL_GetRNG(ssl);
ret = wc_RsaPSS_Sign(in, inSz, out, *outSz, hashType, mgf,
&cbInfo->keyRsa, rng);
}
if (ret > 0) { /* save and convert to 0 success */
*outSz = ret;
ret = 0;
}
wc_FreeRsaKey(&cbInfo->keyRsa);
}
free(keyBuf);
printf("PK RSA PSS Sign: ret %d, outSz %u\n", ret, *outSz);
return ret;
}
#endif
#endif
#endif /* HAVE_PK_CALLBACKS */
int main(int argc, char** argv)
@ -252,7 +376,7 @@ int main(int argc, char** argv)
/*---------------------------------*/
/* Start of wolfSSL initialization and configuration */
/*---------------------------------*/
#if 0
#if 1
wolfSSL_Debugging_ON();
#endif
@ -271,19 +395,35 @@ int main(int argc, char** argv)
goto exit;
}
#ifdef HAVE_PK_CALLBACKS
/* register a sign callbacks for the long term key */
#ifdef HAVE_ECC
wolfSSL_CTX_SetEccSignCb(ctx, myEccSign);
#endif
#ifndef NO_RSA
wolfSSL_CTX_SetRsaSignCb(ctx, myRsaSign);
#ifdef WC_RSA_PSS
wolfSSL_CTX_SetRsaPssSignCb(ctx, myRsaPssSign);
#endif
#endif
#else
printf("Warning: PK not compiled in! Please configure wolfSSL with "
" --enable-pkcallbacks and try again\n");
#endif
/* Load server certificates into WOLFSSL_CTX */
if ((ret = wolfSSL_CTX_use_certificate_file(ctx, CERT_FILE, SSL_FILETYPE_PEM))
!= WOLFSSL_SUCCESS) {
if ((ret = wolfSSL_CTX_use_certificate_file(ctx, CERT_FILE,
WOLFSSL_FILETYPE_PEM)) != WOLFSSL_SUCCESS) {
fprintf(stderr, "ERROR: failed to load %s, please check the file.\n",
CERT_FILE);
goto exit;
}
/* Load server key into WOLFSSL_CTX */
if ((ret = wolfSSL_CTX_use_PrivateKey_file(ctx, KEY_FILE, SSL_FILETYPE_PEM))
!= WOLFSSL_SUCCESS) {
if ((ret = wolfSSL_CTX_use_PrivateKey_file(ctx, KEYPUB_FILE,
WOLFSSL_FILETYPE_PEM)) != WOLFSSL_SUCCESS) {
fprintf(stderr, "ERROR: failed to load %s, please check the file.\n",
KEY_FILE);
KEYPUB_FILE);
goto exit;
}
@ -299,15 +439,6 @@ int main(int argc, char** argv)
wolfSSL_CTX_set_verify(ctx,
WOLFSSL_VERIFY_PEER | WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
#ifdef HAVE_PK_CALLBACKS
/* register an ECC sign callback for the long term key */
wolfSSL_CTX_SetEccSignCb(ctx, myEccSign);
#else
printf("Warning: PK not compiled in! Please configure wolfSSL with "
" --enable-pkcallbacks and try again\n");
#endif
/* Continue to accept clients until shutdown is issued */
while (!shutdown) {
printf("Waiting for a connection...\n");
@ -332,7 +463,15 @@ int main(int argc, char** argv)
#ifdef HAVE_PK_CALLBACKS
/* setup the PK context */
#ifdef HAVE_ECC
wolfSSL_SetEccSignCtx(ssl, &myCtx);
#endif
#ifndef NO_RSA
wolfSSL_SetRsaSignCtx(ssl, &myCtx);
#ifdef WC_RSA_PSS
wolfSSL_SetRsaPssSignCtx(ssl, &myCtx);
#endif
#endif
#else
(void)myCtx; /* not used */
#endif