Skip to content

Commit

Permalink
Improvements to the PK callback example to use public key. Added RSA/…
Browse files Browse the repository at this point in the history
…PSS PK support to example.
  • Loading branch information
dgarske committed Mar 18, 2022
1 parent 2d87541 commit df21913
Show file tree
Hide file tree
Showing 4 changed files with 338 additions and 46 deletions.
4 changes: 4 additions & 0 deletions certs/ecc-client-keyPub.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEVb/0D0RQmj3Om7fwxU31cHvU7CSO
GYDsWkyiJANiLJva76I1EkOEdhbGVpUGzAGpvfZ1GkL3vamyNiJfx11/tA==
-----END PUBLIC KEY-----
9 changes: 9 additions & 0 deletions certs/server-keyPub.pem
Original file line number Diff line number Diff line change
@@ -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-----
178 changes: 159 additions & 19 deletions tls/client-tls-pkcallback.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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;

Expand Down Expand Up @@ -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 */
Expand All @@ -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);
Expand All @@ -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)
Expand Down Expand Up @@ -240,7 +364,7 @@ int main(int argc, char** argv)
/*---------------------------------*/
/* Start of wolfSSL initialization and configuration */
/*---------------------------------*/
#if 0
#if 1
wolfSSL_Debugging_ON();
#endif

Expand All @@ -263,27 +387,35 @@ 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");
#endif

/* 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;
}

Expand Down Expand Up @@ -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
Expand Down
Loading

0 comments on commit df21913

Please sign in to comment.