Improvements to PKCS7 crypto callback example and support for PSA (ECC only).

pull/417/head
David Garske 2024-01-18 13:24:34 -08:00
parent a944dfb8ef
commit 5b134348f4
3 changed files with 389 additions and 366 deletions

View File

@ -4,6 +4,7 @@ LIB_PATH = /usr/local
CFLAGS = -Wall -I$(LIB_PATH)/include
ZLIB =
#ZLIB += -lz
PSA_LIB = -lmbedcrypto
LIBS = -L$(LIB_PATH)/lib -lm ${ZLIB}
# option variables
@ -19,6 +20,11 @@ CFLAGS+=$(OPTIMIZE)
#LIBS+=$(STATIC_LIB)
LIBS+=$(DYN_LIB)
ifneq ($(PSA),)
LIBS+=$(PSA_LIB)
CFLAGS+=-DUSE_PSA
endif
# build targets
SRC=$(wildcard *.c)
TARGETS=$(patsubst %.c, %, $(SRC))

View File

@ -16,7 +16,7 @@ $ make
$ sudo make install
```
Note, some examples require additional features, such as "--with-libz" and
Note, some examples require additional features, such as "--with-libz" and
"--enable-pwdbased". To build wolfSSL with support for all examples, use:
```
@ -96,18 +96,18 @@ Debugging with `openssl cms`
```
$ openssl cms -inform der -in envelopedData.der -cmsout -print -noout
CMS_ContentInfo:
CMS_ContentInfo:
contentType: pkcs7-encryptedData (1.2.840.113549.1.7.6)
d.encryptedData:
d.encryptedData:
version: <ABSENT>
encryptedContentInfo:
encryptedContentInfo:
contentType: pkcs7-data (1.2.840.113549.1.7.1)
contentEncryptionAlgorithm:
contentEncryptionAlgorithm:
algorithm: aes-256-cbc (2.16.840.1.101.3.4.1.42)
parameter: OCTET STRING:
0000 - 08 83 47 90 5d 9f d6 aa-dc 25 ce b2 87 9a 10 ..G.]....%.....
000f - cf .
encryptedContent:
encryptedContent:
0000 - 3c 22 ea 61 64 fb 21 30-77 8a ce b0 5a a7 35 <".ad.!0w...Z.5
000f - de .
unprotectedAttrs:
@ -119,7 +119,7 @@ CMS_ContentInfo:
### pkcs7-verify
```
./pkcs7-verify
./pkcs7-verify
Der 1633
PKCS7 Verify Success
```
@ -518,6 +518,27 @@ Successfully encoded SignedData bundle (signedData_cryptocb_attrs.der)
Successfully verified SignedData bundle.
```
#### Enabling PSA with the PKCS7 crypto callback example
For wolfSSL PSA support see: https://github.com/wolfSSL/wolfssl/tree/master/wolfcrypt/src/port/psa
See https://github.com/wolfSSL/wolfssl/pull/4739 for details on building a PSA crypto library to test against.
Build wolfSSL with PSA enabled:
```sh
./configure --enable-psa --with-psa-lib-name=mbedcrypto --enable-cryptocb --enable-pkcallbacks CFLAGS="-DWOLFSSL_PSA_GLOBAL_LOCK"
make
sudo make install
```
Build example with PSA=1 set:
```sh
make clean
make PSA=1
```
### SignedData with Detached Signature
Example file: `signedData-DetachedSignature.c`

View File

@ -1,6 +1,6 @@
/* signedData-cryptocb.c
*
* Copyright (C) 2006-2022 wolfSSL Inc.
* Copyright (C) 2006-2024 wolfSSL Inc.
*
* This file is part of wolfSSL. (formerly known as CyaSSL)
*
@ -24,258 +24,42 @@
#include <wolfssl/wolfcrypt/error-crypt.h>
#include <wolfssl/wolfcrypt/logging.h>
#include <wolfssl/wolfcrypt/cryptocb.h>
#if 0
#define CERT_FILE "../certs/client-cert.der"
#define KEY_FILE "../certs/client-key.der"
#define KEYPUB_FILE "../certs/client-keyPub.der"
#else
#define CERT_FILE "../certs/client-ecc-cert.der"
#define KEY_FILE "../certs/ecc-client-key.der"
#define KEYPUB_FILE "../certs/ecc-client-keyPub.der"
#ifdef USE_PSA
#include <wolfssl/wolfcrypt/port/psa/psa.h>
#include <psa/crypto.h>
#endif
#define encodedFileNoAttrs "signedData_cryptocb_noattrs.der"
#define encodedFileAttrs "signedData_cryptocb_attrs.der"
/* Default certificates and keys */
#define RSA_CERT_FILE "../certs/client-cert.der"
#define RSA_KEY_FILE "../certs/client-key.der"
#define RSA_KEYPUB_FILE "../certs/client-keyPub.der"
#define ECC_CERT_FILE "../certs/client-ecc-cert.der"
#define ECC_KEY_FILE "../certs/ecc-client-key.der"
#define ECC_KEYPUB_FILE "../certs/ecc-client-keyPub.der"
/* Default output file name */
#define OUTPUT_FILE "signedData_cryptocb.der"
/* Maximum temporary buffer size */
#define LARGE_TEMP_SZ 2048
#define LARGE_TEMP_SZ 4096
#if defined(HAVE_PKCS7) && defined(WOLF_CRYPTO_CB)
/* crypto callback context */
typedef struct {
const char* keyFilePriv;
#ifdef USE_PSA
psa_key_id_t key_id;
#endif
} myCryptoCbCtx;
/* test data to sign (could be CSR for example) */
static const byte data[] = { /* Hello World */
0x48,0x65,0x6c,0x6c,0x6f,0x20,0x57,0x6f,
0x72,0x6c,0x64
0x48,0x65,0x6c,0x6c,0x6f,0x20,0x57,0x6f,0x72,0x6c,0x64
};
static int load_certs(byte* cert, word32* certSz, byte* key, word32* keySz)
{
FILE* file;
/* certificate file */
file = fopen(CERT_FILE, "rb");
if (!file)
return -1;
*certSz = (word32)fread(cert, 1, *certSz, file);
fclose(file);
/* key file */
file = fopen(KEYPUB_FILE, "rb");
if (!file)
return -1;
*keySz = (word32)fread(key, 1, *keySz, file);
fclose(file);
return 0;
}
static int write_file_buffer(const char* fileName, byte* in, word32 inSz)
{
int ret;
FILE* file;
file = fopen(fileName, "wb");
if (file == NULL) {
printf("ERROR: opening file for writing: %s\n", fileName);
return -1;
}
ret = (int)fwrite(in, 1, inSz, file);
if (ret == 0) {
printf("ERROR: writing buffer to output file\n");
return -1;
}
fclose(file);
return 0;
}
static int signedData_sign_noattrs(byte* cert, word32 certSz, byte* key,
word32 keySz, byte* out, word32 outSz,
int devId)
{
int ret;
PKCS7* pkcs7;
WC_RNG rng;
/* init rng */
ret = wc_InitRng(&rng);
if (ret != 0) {
printf("ERROR: wc_InitRng() failed, ret = %d\n", ret);
return -1;
}
/* init PKCS7 */
pkcs7 = wc_PKCS7_New(NULL, devId);
if (pkcs7 == NULL) {
wc_FreeRng(&rng);
return -1;
}
ret = wc_PKCS7_InitWithCert(pkcs7, cert, certSz);
if (ret != 0) {
printf("ERROR: wc_PKCS7_InitWithCert() failed, ret = %d\n", ret);
wc_PKCS7_Free(pkcs7);
wc_FreeRng(&rng);
return -1;
}
pkcs7->rng = &rng;
pkcs7->content = (byte*)data;
pkcs7->contentSz = sizeof(data);
pkcs7->contentOID = DATA;
pkcs7->hashOID = SHA256h;
pkcs7->encryptOID = RSAk;
pkcs7->privateKey = key;
pkcs7->privateKeySz = keySz;
pkcs7->signedAttribs = NULL;
pkcs7->signedAttribsSz = 0;
/* encode signedData, returns size */
ret = wc_PKCS7_EncodeSignedData(pkcs7, out, outSz);
if (ret <= 0) {
printf("ERROR: wc_PKCS7_EncodeSignedData() failed, ret = %d\n", ret);
wc_PKCS7_Free(pkcs7);
wc_FreeRng(&rng);
return -1;
} else {
printf("Successfully encoded SignedData bundle (%s)\n",
encodedFileNoAttrs);
#ifdef DEBUG_WOLFSSL
printf("Encoded DER (%d bytes):\n", ret);
WOLFSSL_BUFFER(out, ret);
#endif
if (write_file_buffer(encodedFileNoAttrs, out, ret) != 0) {
printf("ERROR: error writing encoded to output file\n");
return -1;
}
}
wc_PKCS7_Free(pkcs7);
wc_FreeRng(&rng);
return ret;
}
static int signedData_sign_attrs(byte* cert, word32 certSz, byte* key,
word32 keySz, byte* out, word32 outSz,
int devId)
{
int ret;
PKCS7* pkcs7;
WC_RNG rng;
static byte messageTypeOid[] =
{ 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xF8, 0x45, 0x01,
0x09, 0x02 };
static byte messageType[] = { 0x13, 2, '1', '9' };
PKCS7Attrib attribs[] =
{
{ messageTypeOid, sizeof(messageTypeOid), messageType,
sizeof(messageType) }
};
/* init rng */
ret = wc_InitRng(&rng);
if (ret != 0) {
printf("ERROR: wc_InitRng() failed, ret = %d\n", ret);
return -1;
}
/* init PKCS7 */
pkcs7 = wc_PKCS7_New(NULL, devId);
if (pkcs7 == NULL) {
wc_FreeRng(&rng);
return -1;
}
ret = wc_PKCS7_InitWithCert(pkcs7, cert, certSz);
if (ret != 0) {
printf("ERROR: wc_PKCS7_InitWithCert() failed, ret = %d\n", ret);
wc_PKCS7_Free(pkcs7);
wc_FreeRng(&rng);
return -1;
}
pkcs7->rng = &rng;
pkcs7->content = (byte*)data;
pkcs7->contentSz = sizeof(data);
pkcs7->contentOID = DATA;
pkcs7->hashOID = SHA256h;
pkcs7->encryptOID = RSAk;
pkcs7->privateKey = key;
pkcs7->privateKeySz = keySz;
pkcs7->signedAttribs = attribs;
pkcs7->signedAttribsSz = sizeof(attribs)/sizeof(PKCS7Attrib);
/* encode signedData, returns size */
ret = wc_PKCS7_EncodeSignedData(pkcs7, out, outSz);
if (ret <= 0) {
printf("ERROR: wc_PKCS7_EncodeSignedData() failed, ret = %d\n", ret);
wc_PKCS7_Free(pkcs7);
wc_FreeRng(&rng);
return -1;
} else {
printf("Successfully encoded SignedData bundle (%s)\n",
encodedFileAttrs);
#ifdef DEBUG_WOLFSSL
printf("Encoded DER (%d bytes):\n", ret);
WOLFSSL_BUFFER(out, ret);
#endif
if (write_file_buffer(encodedFileAttrs, out, ret) != 0) {
printf("ERROR: error writing encoded to output file\n");
return -1;
}
}
wc_PKCS7_Free(pkcs7);
wc_FreeRng(&rng);
return ret;
}
static int signedData_verify(byte* in, word32 inSz, byte* cert,
word32 certSz, byte* key, word32 keySz,
byte* out, word32 outSz, int devId)
{
int ret;
PKCS7* pkcs7;
pkcs7 = wc_PKCS7_New(NULL, devId);
if (pkcs7 == NULL)
return -1;
/* decode signedData, returns size */
ret = wc_PKCS7_VerifySignedData(pkcs7, in, inSz);
if (ret < 0 || (pkcs7->contentSz != sizeof(data)) ||
(XMEMCMP(pkcs7->content, data, pkcs7->contentSz) != 0)) {
printf("ERROR: Failed to verify SignedData bundle, ret = %d\n", ret);
wc_PKCS7_Free(pkcs7);
return -1;
} else {
printf("Successfully verified SignedData bundle.\n");
#ifdef DEBUG_WOLFSSL
printf("Decoded content (%d bytes):\n", pkcs7->contentSz);
WOLFSSL_BUFFER(pkcs7->content, pkcs7->contentSz);
#endif
}
wc_PKCS7_Free(pkcs7);
return ret;
}
/* reads file size, allocates buffer, reads into buffer, returns buffer */
static int load_file(const char* fname, byte** buf, size_t* bufLen)
@ -323,10 +107,91 @@ static int load_file(const char* fname, byte** buf, size_t* bufLen)
return ret;
}
typedef struct {
const char* keyFilePub;
const char* keyFilePriv;
} myCryptoCbCtx;
static int write_file(const char* fileName, byte* in, word32 inSz)
{
int ret;
FILE* file;
file = fopen(fileName, "wb");
if (file == NULL) {
printf("ERROR: opening file for writing: %s\n", fileName);
return -1;
}
ret = (int)fwrite(in, 1, inSz, file);
if (ret == 0) {
printf("ERROR: writing buffer to output file\n");
return -1;
}
fclose(file);
return 0;
}
#ifdef USE_PSA
static int psa_map_hash_alg(int hash_len)
{
switch (hash_len) {
case 20:
return PSA_ALG_SHA_1;
case 28:
return PSA_ALG_SHA_224;
case 32:
return PSA_ALG_SHA_256;
case 48:
return PSA_ALG_SHA_384;
case 64:
return PSA_ALG_SHA_512;
default:
return PSA_ALG_NONE;
}
}
/* import private key helper */
static int import_ecc_key(byte* keyBuf, word32 keySz, psa_key_id_t* id)
{
int ret;
psa_key_attributes_t key_attr = { 0 };
psa_key_type_t key_type;
psa_key_id_t key_id;
psa_status_t status;
ecc_key eccPriv;
byte d[MAX_ECC_BYTES]; /* private d */
word32 dSz = (word32)sizeof(d);
memset(d, 0, sizeof(d));
ret = wc_ecc_init_ex(&eccPriv, NULL, INVALID_DEVID);
if (ret == 0) {
word32 idx = 0;
ret = wc_EccPrivateKeyDecode(keyBuf, &idx, &eccPriv, keySz);
if (ret == 0) {
ret = wc_ecc_export_private_only(&eccPriv, d, &dSz);
}
wc_ecc_free(&eccPriv);
}
if (ret == 0) {
psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_SIGN_HASH);
psa_set_key_lifetime(&key_attr, PSA_KEY_LIFETIME_VOLATILE);
psa_set_key_algorithm(&key_attr, PSA_ALG_ECDSA(PSA_ALG_SHA_256));
key_type = PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1);
psa_set_key_type(&key_attr, key_type);
psa_set_key_bits(&key_attr, (dSz * 8));
status = psa_import_key(&key_attr, d, dSz, &key_id);
if (status != PSA_SUCCESS) {
fprintf(stderr,
"ERROR: provisioning of private key failed: [%d] \n", status);
ret = WC_HW_E;
}
else {
ret = 0;
*id = key_id;
}
}
return ret;
}
#endif
/* Example crypto dev callback function that calls software versions, could
* be set up to call down to hardware module for crypto operations if
@ -393,30 +258,38 @@ static int myCryptoCb(int devIdArg, wc_CryptoInfo* info, void* ctx)
}
}
}
#ifdef WOLFSSL_KEY_GEN
else if (info->pk.type == WC_PK_TYPE_RSA_KEYGEN) {
info->pk.rsakg.key->devId = INVALID_DEVID;
ret = wc_MakeRsaKey(info->pk.rsakg.key, info->pk.rsakg.size,
info->pk.rsakg.e, info->pk.rsakg.rng);
/* reset devId */
info->pk.rsakg.key->devId = devIdArg;
}
#endif
#endif /* !NO_RSA */
#ifdef HAVE_ECC
if (info->pk.type == WC_PK_TYPE_EC_KEYGEN) {
/* set devId to invalid, so software is used */
info->pk.eckg.key->devId = INVALID_DEVID;
if (info->pk.type == WC_PK_TYPE_ECDSA_SIGN) {
#ifdef USE_PSA
uint8_t rs[MAX_ECC_BYTES * 2];
size_t rs_length;
psa_status_t status;
psa_algorithm_t hash_algo;
ret = wc_ecc_make_key_ex(info->pk.eckg.rng, info->pk.eckg.size,
info->pk.eckg.key, info->pk.eckg.curveId);
/* get the desired key ID into your callback context */
psa_key_id_t id = myCtx->key_id;
/* reset devId */
info->pk.eckg.key->devId = devIdArg;
}
else if (info->pk.type == WC_PK_TYPE_ECDSA_SIGN) {
/* Get correct hash algorithm that matches input hash length */
hash_algo = psa_map_hash_alg(info->pk.eccsign.inlen);
status = psa_sign_hash(
id,
PSA_ALG_ECDSA(hash_algo),
info->pk.eccsign.in, info->pk.eccsign.inlen,
rs, sizeof(rs),
&rs_length);
if (status == PSA_SUCCESS) {
word32 point_len = (word32)(rs_length / 2);
ret = wc_ecc_rs_raw_to_sig(
rs, point_len,
rs + point_len, point_len,
info->pk.eccsign.out, info->pk.eccsign.outlen);
}
else {
ret = WC_HW_E;
}
#else
ecc_key eccPriv;
byte* der = NULL;
size_t derSz = 0;
@ -442,6 +315,7 @@ static int myCryptoCb(int devIdArg, wc_CryptoInfo* info, void* ctx)
wc_ecc_free(&eccPriv);
if (der != NULL)
free(der);
#endif
}
else if (info->pk.type == WC_PK_TYPE_ECDSA_VERIFY) {
/* set devId to invalid, so software is used */
@ -455,64 +329,8 @@ static int myCryptoCb(int devIdArg, wc_CryptoInfo* info, void* ctx)
/* reset devId */
info->pk.eccverify.key->devId = devIdArg;
}
else if (info->pk.type == WC_PK_TYPE_ECDH) {
/* set devId to invalid, so software is used */
info->pk.ecdh.private_key->devId = INVALID_DEVID;
ret = wc_ecc_shared_secret(
info->pk.ecdh.private_key, info->pk.ecdh.public_key,
info->pk.ecdh.out, info->pk.ecdh.outlen);
/* reset devId */
info->pk.ecdh.private_key->devId = devIdArg;
}
#endif /* HAVE_ECC */
}
else if (info->algo_type == WC_ALGO_TYPE_CIPHER) {
#if !defined(NO_AES) && defined(HAVE_AESGCM)
if (info->cipher.type == WC_CIPHER_AES_GCM) {
if (info->cipher.enc) {
/* set devId to invalid, so software is used */
info->cipher.aesgcm_enc.aes->devId = INVALID_DEVID;
ret = wc_AesGcmEncrypt(
info->cipher.aesgcm_enc.aes,
info->cipher.aesgcm_enc.out,
info->cipher.aesgcm_enc.in,
info->cipher.aesgcm_enc.sz,
info->cipher.aesgcm_enc.iv,
info->cipher.aesgcm_enc.ivSz,
info->cipher.aesgcm_enc.authTag,
info->cipher.aesgcm_enc.authTagSz,
info->cipher.aesgcm_enc.authIn,
info->cipher.aesgcm_enc.authInSz);
/* reset devId */
info->cipher.aesgcm_enc.aes->devId = devIdArg;
}
else {
/* set devId to invalid, so software is used */
info->cipher.aesgcm_dec.aes->devId = INVALID_DEVID;
ret = wc_AesGcmDecrypt(
info->cipher.aesgcm_dec.aes,
info->cipher.aesgcm_dec.out,
info->cipher.aesgcm_dec.in,
info->cipher.aesgcm_dec.sz,
info->cipher.aesgcm_dec.iv,
info->cipher.aesgcm_dec.ivSz,
info->cipher.aesgcm_dec.authTag,
info->cipher.aesgcm_dec.authTagSz,
info->cipher.aesgcm_dec.authIn,
info->cipher.aesgcm_dec.authInSz);
/* reset devId */
info->cipher.aesgcm_dec.aes->devId = devIdArg;
}
}
#endif /* !NO_AES && HAVE_AESGCM */
}
(void)devIdArg;
(void)myCtx;
@ -520,17 +338,182 @@ static int myCryptoCb(int devIdArg, wc_CryptoInfo* info, void* ctx)
return ret;
}
static int signedData_sign(byte* cert, word32 certSz, byte* key,
word32 keySz, byte* out, word32 outSz,
int devId, int algOid, int hashOid)
{
int ret;
PKCS7* pkcs7;
WC_RNG rng;
/* init rng */
ret = wc_InitRng(&rng);
if (ret != 0) {
printf("ERROR: wc_InitRng() failed, ret = %d\n", ret);
return -1;
}
/* init PKCS7 */
pkcs7 = wc_PKCS7_New(NULL, devId);
if (pkcs7 == NULL) {
wc_FreeRng(&rng);
return -1;
}
ret = wc_PKCS7_InitWithCert(pkcs7, cert, certSz);
if (ret != 0) {
printf("ERROR: wc_PKCS7_InitWithCert() failed, ret = %d\n", ret);
wc_PKCS7_Free(pkcs7);
wc_FreeRng(&rng);
return -1;
}
pkcs7->rng = &rng;
pkcs7->content = (byte*)data;
pkcs7->contentSz = sizeof(data);
pkcs7->contentOID = DATA;
pkcs7->hashOID = hashOid;
pkcs7->encryptOID = algOid;
pkcs7->privateKey = key;
pkcs7->privateKeySz = keySz;
/* encode signedData, returns size */
ret = wc_PKCS7_EncodeSignedData(pkcs7, out, outSz);
if (ret <= 0) {
printf("ERROR: wc_PKCS7_EncodeSignedData() failed, ret = %d\n", ret);
wc_PKCS7_Free(pkcs7);
wc_FreeRng(&rng);
return -1;
}
else {
printf("Successfully encoded SignedData bundle\n");
#ifdef DEBUG_WOLFSSL
printf("Encoded DER (%d bytes):\n", ret);
WOLFSSL_BUFFER(out, ret);
#endif
}
wc_PKCS7_Free(pkcs7);
wc_FreeRng(&rng);
return ret;
}
static int signedData_verify(byte* in, word32 inSz, byte* cert,
word32 certSz, byte* key, word32 keySz,
byte* out, word32 outSz, int devId)
{
int ret;
PKCS7* pkcs7;
pkcs7 = wc_PKCS7_New(NULL, devId);
if (pkcs7 == NULL)
return -1;
/* decode signedData, returns size */
ret = wc_PKCS7_VerifySignedData(pkcs7, in, inSz);
if (ret < 0 || (pkcs7->contentSz != sizeof(data)) ||
(XMEMCMP(pkcs7->content, data, pkcs7->contentSz) != 0)) {
printf("ERROR: Failed to verify SignedData bundle, ret = %d\n", ret);
wc_PKCS7_Free(pkcs7);
return -1;
} else {
printf("Successfully verified SignedData bundle.\n");
#ifdef DEBUG_WOLFSSL
printf("Decoded content (%d bytes):\n", pkcs7->contentSz);
WOLFSSL_BUFFER(pkcs7->content, pkcs7->contentSz);
#endif
}
wc_PKCS7_Free(pkcs7);
return ret;
}
static void usage(void)
{
printf("Expected usage:\n");
printf("./signData-cryptocb [-ecc/-rsa] [-out=]\n");
printf("* -ecc/-rsa: Use ECC or RSA key (default is ECC)\n");
printf("* -key=file: DER formatted private key\n");
printf("* -keyPub=file: DER formatted public key\n");
printf("* -cert=file: Certificate for signing key\n");
printf("* -out=file: Generated PKCS7 file containing signed data and certificate (default %s)\n", OUTPUT_FILE);
}
int main(int argc, char** argv)
{
int ret, devId;
int encryptedSz, decryptedSz;
word32 certSz, keySz;
size_t certSz, keySz;
myCryptoCbCtx myCtx;
const char* certFile = NULL;
const char* keyFile = NULL;
const char* keyFilePub = NULL;
const char* outFile = OUTPUT_FILE;
int algOid = ECDSAk;
int hashOid = SHA256h;
byte* cert = NULL;
byte* key = NULL;
byte cert[2048];
byte key[2048];
byte encrypted[2048];
byte decrypted[2048];
byte encrypted[LARGE_TEMP_SZ];
byte decrypted[LARGE_TEMP_SZ];
if (argc >= 2) {
if (XSTRCMP(argv[1], "-?") == 0 ||
XSTRCMP(argv[1], "-h") == 0 ||
XSTRCMP(argv[1], "--help") == 0) {
usage();
return 0;
}
}
while (argc > 1) {
if (XSTRCMP(argv[argc-1], "-ecc") == 0) {
algOid = ECDSAk;
}
else if (XSTRCMP(argv[argc-1], "-rsa") == 0) {
algOid = RSAk;
}
else if (XSTRNCMP(argv[argc-1], "-cert=",
XSTRLEN("-cert=")) == 0) {
certFile = argv[argc-1] + XSTRLEN("-cert=");
}
else if (XSTRNCMP(argv[argc-1], "-key=",
XSTRLEN("-key=")) == 0) {
keyFile = argv[argc-1] + XSTRLEN("-key=");
}
else if (XSTRNCMP(argv[argc-1], "-keyPub=",
XSTRLEN("-keyPub=")) == 0) {
keyFilePub = argv[argc-1] + XSTRLEN("-keyPub=");
}
else if (XSTRNCMP(argv[argc-1], "-out=",
XSTRLEN("-out=")) == 0) {
outFile = argv[argc-1] + XSTRLEN("-out=");
}
else {
printf("Warning: Unrecognized option: %s\n", argv[argc-1]);
}
argc--;
}
if (certFile == NULL) {
if (algOid == RSAk) {
certFile = RSA_CERT_FILE;
keyFile = RSA_KEY_FILE;
keyFilePub = RSA_KEYPUB_FILE;
}
else {
certFile = ECC_CERT_FILE;
keyFile = ECC_KEY_FILE;
keyFilePub = ECC_KEYPUB_FILE;
}
}
#ifdef DEBUG_WOLFSSL
wolfSSL_Debugging_ON();
@ -543,7 +526,23 @@ int main(int argc, char** argv)
}
/* provide private key to crypto callback */
myCtx.keyFilePriv = KEY_FILE;
myCtx.keyFilePriv = keyFile;
#ifdef USE_PSA
ret = load_file(keyFile, &key, &keySz);
if (ret == 0) {
ret = import_ecc_key(key, keySz, &myCtx.key_id);
}
free(key); key = NULL;
if (ret != 0)
goto exit;
#endif
/* Load certificate and public key */
ret = load_file(certFile, &cert, &certSz);
if (ret == 0)
ret = load_file(keyFilePub, &key, &keySz);
if (ret != 0)
goto exit;
/* setting devId to something other than INVALID_DEVID, enables
* crypto callback to be used internally by wolfCrypt */
@ -551,43 +550,40 @@ int main(int argc, char** argv)
ret = wc_CryptoCb_RegisterDevice(devId, myCryptoCb, &myCtx);
if (ret != 0) {
printf("Failed to register crypto dev device, ret = %d\n", ret);
return -1;
goto exit;
}
certSz = sizeof(cert);
keySz = sizeof(key);
ret = load_certs(cert, &certSz, key, &keySz);
if (ret != 0)
return -1;
/* no attributes */
encryptedSz = signedData_sign_noattrs(cert, certSz, key, keySz,
encrypted, sizeof(encrypted), devId);
if (encryptedSz < 0)
return -1;
/* Sign bundle */
encryptedSz = signedData_sign(cert, certSz, key, keySz,
encrypted, sizeof(encrypted), devId, algOid, hashOid);
if (encryptedSz >= 0) {
if (write_file(outFile, encrypted, encryptedSz) != 0) {
printf("ERROR: error writing encoded to output file %s\n", outFile);
ret =-1;
}
else {
printf("Wrote encoded PKCS7 bundle to file %s\n", outFile);
ret = 0;
}
}
else {
ret = -1; goto exit;
}
/* Verify bundle */
decryptedSz = signedData_verify(encrypted, encryptedSz,
cert, certSz, key, keySz,
decrypted, sizeof(decrypted), devId);
if (decryptedSz < 0)
return -1;
if (decryptedSz < 0) {
ret = -1; goto exit;
}
/* default attributes + messageType attribute */
encryptedSz = signedData_sign_attrs(cert, certSz, key, keySz,
encrypted, sizeof(encrypted), devId);
if (encryptedSz < 0)
return -1;
exit:
if (cert != NULL) free(cert);
if (key != NULL) free(key);
wolfCrypt_Cleanup();
decryptedSz = signedData_verify(encrypted, encryptedSz,
cert, certSz, key, keySz,
decrypted, sizeof(decrypted), devId);
if (decryptedSz < 0)
return -1;
(void)argc;
(void)argv;
return 0;
return ret;
}
#else