From 717fd126464be0ab49788d6ca89f61a98175dbed Mon Sep 17 00:00:00 2001 From: Chris Conlon Date: Tue, 23 Oct 2018 09:40:55 -0600 Subject: [PATCH] add simple CMS examples for AuthEnvelopedData --- pkcs7/Makefile | 4 +- pkcs7/authEnvelopedData-kari.c | 231 +++++++++++++++++++++++++ pkcs7/authEnvelopedData-ktri.c | 223 +++++++++++++++++++++++++ pkcs7/authEnvelopedData-ori.c | 297 +++++++++++++++++++++++++++++++++ pkcs7/authEnvelopedData-pwri.c | 233 ++++++++++++++++++++++++++ pkcs7/encryptedData.c | 39 ++++- pkcs7/envelopedData-kari.c | 7 +- pkcs7/envelopedData-ktri.c | 7 +- pkcs7/envelopedData-ori.c | 7 +- pkcs7/envelopedData-pwri.c | 7 +- 10 files changed, 1048 insertions(+), 7 deletions(-) create mode 100644 pkcs7/authEnvelopedData-kari.c create mode 100644 pkcs7/authEnvelopedData-ktri.c create mode 100644 pkcs7/authEnvelopedData-ori.c create mode 100644 pkcs7/authEnvelopedData-pwri.c diff --git a/pkcs7/Makefile b/pkcs7/Makefile index ce0b2128..208b5805 100644 --- a/pkcs7/Makefile +++ b/pkcs7/Makefile @@ -40,4 +40,6 @@ clean: signedCompressedFPD_attrs.der signedCompressedFPD_noattrs.der \ signedEncryptedCompressedFPD_attrs.der signedEncryptedCompressedFPD_noattrs.der \ envelopedDataKTRI.der envelopedDataKARI.der \ - envelopedDataPWRI.der envelopedDataORI.der + envelopedDataPWRI.der envelopedDataORI.der \ + authEnvelopedDataKARI.der authEnvelopedDataKTRI.der \ + authEnvelopedDataORI.der authEnvelopedDataPWRI.der encryptedData.der diff --git a/pkcs7/authEnvelopedData-kari.c b/pkcs7/authEnvelopedData-kari.c new file mode 100644 index 00000000..e542f046 --- /dev/null +++ b/pkcs7/authEnvelopedData-kari.c @@ -0,0 +1,231 @@ +/* authEnvelopedData-kari.c + * + * Copyright (C) 2006-2018 wolfSSL Inc. + * + * This file is part of wolfSSL. (formerly known as CyaSSL) + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ +#include +#include +#include +#include +#include + +#define certFile "../certs/client-ecc-cert.der" +#define keyFile "../certs/ecc-client-key.der" + +#define encodedFileKARI "authEnvelopedDataKARI.der" + +static const byte data[] = { /* Hello World */ + 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(certFile, "rb"); + if (!file) { + printf("ERROR: failed to open file: %s\n", certFile); + return -1; + } + + *certSz = (word32)fread(cert, 1, *certSz, file); + fclose(file); + + /* key file */ + file = fopen(keyFile, "rb"); + if (!file) { + printf("ERROR: failed to open file: %s\n", keyFile); + 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 authEnvelopedData_encrypt(byte* cert, word32 certSz, byte* key, + word32 keySz, byte* out, word32 outSz) +{ + int ret; + PKCS7* pkcs7; + + pkcs7 = wc_PKCS7_New(NULL, INVALID_DEVID); + if (pkcs7 == NULL) + return -1; + + pkcs7->content = (byte*)data; + pkcs7->contentSz = sizeof(data); + pkcs7->contentOID = DATA; + pkcs7->encryptOID = AES256GCMb; + + /* add recipient using ECC certificate (KARI type) */ + ret = wc_PKCS7_AddRecipient_KARI(pkcs7, cert, certSz, AES256_WRAP, + dhSinglePass_stdDH_sha256kdf_scheme, + NULL, 0, 0); + if (ret < 0) { + printf("wc_PKCS7_AddRecipient_KARI() failed, ret = %d\n", ret); + wc_PKCS7_Free(pkcs7); + return -1; + } + + /* encode envelopedData, returns size */ + ret = wc_PKCS7_EncodeAuthEnvelopedData(pkcs7, out, outSz); + if (ret <= 0) { + printf("wc_PKCS7_EncodeAuthEnvelopedData() failed, ret = %d\n", ret); + wc_PKCS7_Free(pkcs7); + return -1; + + } else { + printf("Successfully encoded AuthEnvelopedData bundle (%s)\n", + encodedFileKARI); + + if (write_file_buffer(encodedFileKARI, out, ret) != 0) { + printf("ERROR: error writing encoded to output file\n"); + return -1; + } + } + + wc_PKCS7_Free(pkcs7); + + return ret; +} + +static int authEnvelopedData_decrypt(byte* in, word32 inSz, byte* cert, + word32 certSz, byte* key, word32 keySz, + byte* out, word32 outSz) +{ + int ret; + PKCS7* pkcs7; + + pkcs7 = wc_PKCS7_New(NULL, INVALID_DEVID); + if (pkcs7 == NULL) + return -1; + + /* init with recipient cert */ + ret = wc_PKCS7_InitWithCert(pkcs7, cert, certSz); + if (ret != 0) { + printf("ERROR: wc_PKCS7_InitWithCert(), ret = %d\n", ret); + wc_PKCS7_Free(pkcs7); + return -1; + } + + /* set recipient private key */ + ret = wc_PKCS7_SetKey(pkcs7, key, keySz); + if (ret != 0) { + printf("ERROR: wc_PKCS7_SetKey(), ret = %d\n", ret); + wc_PKCS7_Free(pkcs7); + return -1; + } + + /* decode envelopedData, returns size */ + ret = wc_PKCS7_DecodeAuthEnvelopedData(pkcs7, in, inSz, out, outSz); + if (ret <= 0) { + printf("ERROR: wc_PKCS7_DecodeAuthEnvelopedData(), ret = %d\n", ret); + wc_PKCS7_Free(pkcs7); + return -1; + } + + wc_PKCS7_Free(pkcs7); + + return ret; +} + +#ifdef HAVE_PKCS7 + +int main(int argc, char** argv) +{ + int ret; + int encryptedSz, decryptedSz; + word32 certSz, keySz; + + byte cert[2048]; + byte key[2048]; + byte encrypted[1024]; + byte decrypted[1024]; + +#ifdef DEBUG_WOLFSSL + wolfSSL_Debugging_ON(); +#endif + + certSz = sizeof(cert); + keySz = sizeof(key); + ret = load_certs(cert, &certSz, key, &keySz); + if (ret != 0) + return -1; + + encryptedSz = authEnvelopedData_encrypt(cert, certSz, key, keySz, + encrypted, sizeof(encrypted)); + if (encryptedSz < 0) + return -1; + +#ifdef DEBUG_WOLFSSL + printf("AuthEnvelopedData DER (%d byte):\n", encryptedSz); + WOLFSSL_BUFFER(encrypted, encryptedSz); +#endif + + decryptedSz = authEnvelopedData_decrypt(encrypted, encryptedSz, + cert, certSz, key, keySz, + decrypted, sizeof(decrypted)); + if (decryptedSz < 0) + return -1; + +#ifdef DEBUG_WOLFSSL + printf("Decrypted content (%d byte):\n", decryptedSz); + WOLFSSL_BUFFER(decrypted, decryptedSz); +#endif + + (void)argc; + (void)argv; + + return 0; +} + +#else + +int main(int argc, char** argv) +{ + printf("Must build wolfSSL using ./configure --enable-pkcs7\n"); + return 0; +} + +#endif + diff --git a/pkcs7/authEnvelopedData-ktri.c b/pkcs7/authEnvelopedData-ktri.c new file mode 100644 index 00000000..f548abab --- /dev/null +++ b/pkcs7/authEnvelopedData-ktri.c @@ -0,0 +1,223 @@ +/* authEnvelopedData-ktri.c + * + * Copyright (C) 2006-2018 wolfSSL Inc. + * + * This file is part of wolfSSL. (formerly known as CyaSSL) + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ +#include +#include +#include +#include +#include + +#define certFile "../certs/client-cert.der" +#define keyFile "../certs/client-key.der" + +#define encodedFileKTRI "authEnvelopedDataKTRI.der" + +static const byte data[] = { /* Hello World */ + 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(certFile, "rb"); + if (!file) + return -1; + + *certSz = (word32)fread(cert, 1, *certSz, file); + fclose(file); + + /* key file */ + file = fopen(keyFile, "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 authEnvelopedData_encrypt(byte* cert, word32 certSz, byte* key, + word32 keySz, byte* out, word32 outSz) +{ + int ret; + PKCS7* pkcs7; + + pkcs7 = wc_PKCS7_New(NULL, INVALID_DEVID); + if (pkcs7 == NULL) + return -1; + + pkcs7->content = (byte*)data; + pkcs7->contentSz = sizeof(data); + pkcs7->contentOID = DATA; + pkcs7->encryptOID = AES256GCMb; + + /* add recipient using RSA certificate (KTRI type) */ + ret = wc_PKCS7_AddRecipient_KTRI(pkcs7, cert, certSz, 0); + if (ret < 0) { + printf("wc_PKCS7_AddRecipient_KTRI() failed, ret = %d\n", ret); + wc_PKCS7_Free(pkcs7); + return -1; + } + + /* encode authEnvelopedData, returns size */ + ret = wc_PKCS7_EncodeAuthEnvelopedData(pkcs7, out, outSz); + if (ret <= 0) { + printf("ERROR: wc_PKCS7_EncodeAuthEnvelopedData() failed, ret = %d\n", + ret); + wc_PKCS7_Free(pkcs7); + return -1; + + } else { + printf("Successfully encoded EnvelopedData bundle (%s)\n", + encodedFileKTRI); + + if (write_file_buffer(encodedFileKTRI, out, ret) != 0) { + printf("ERROR: error writing encoded to output file\n"); + return -1; + } + } + + wc_PKCS7_Free(pkcs7); + + return ret; +} + +static int authEnvelopedData_decrypt(byte* in, word32 inSz, byte* cert, + word32 certSz, byte* key, word32 keySz, + byte* out, word32 outSz) +{ + int ret; + PKCS7* pkcs7; + + pkcs7 = wc_PKCS7_New(NULL, INVALID_DEVID); + if (pkcs7 == NULL) + return -1; + + /* init with recipient cert */ + ret = wc_PKCS7_InitWithCert(pkcs7, cert, certSz); + if (ret != 0) { + wc_PKCS7_Free(pkcs7); + return -1; + } + + /* set recipient private key */ + ret = wc_PKCS7_SetKey(pkcs7, key, keySz); + if (ret != 0) { + wc_PKCS7_Free(pkcs7); + return -1; + } + + /* decode authEnvelopedData, returns size */ + ret = wc_PKCS7_DecodeAuthEnvelopedData(pkcs7, in, inSz, out, outSz); + if (ret <= 0) { + wc_PKCS7_Free(pkcs7); + return -1; + } + + wc_PKCS7_Free(pkcs7); + + return ret; +} + +#ifdef HAVE_PKCS7 + +int main(int argc, char** argv) +{ + int ret; + int encryptedSz, decryptedSz; + word32 certSz, keySz; + + byte cert[2048]; + byte key[2048]; + byte encrypted[1024]; + byte decrypted[1024]; + +#ifdef DEBUG_WOLFSSL + wolfSSL_Debugging_ON(); +#endif + + certSz = sizeof(cert); + keySz = sizeof(key); + ret = load_certs(cert, &certSz, key, &keySz); + if (ret != 0) + return -1; + + encryptedSz = authEnvelopedData_encrypt(cert, certSz, key, keySz, + encrypted, sizeof(encrypted)); + if (encryptedSz < 0) + return -1; + +#ifdef DEBUG_WOLFSSL + printf("AuthEnvelopedData DER (%d byte):\n", encryptedSz); + WOLFSSL_BUFFER(encrypted, encryptedSz); +#endif + + decryptedSz = authEnvelopedData_decrypt(encrypted, encryptedSz, + cert, certSz, key, keySz, + decrypted, sizeof(decrypted)); + if (decryptedSz < 0) + return -1; + +#ifdef DEBUG_WOLFSSL + printf("Decrypted content (%d byte):\n", decryptedSz); + WOLFSSL_BUFFER(decrypted, decryptedSz); +#endif + + (void)argc; + (void)argv; + + return 0; +} + +#else + +int main(int argc, char** argv) +{ + printf("Must build wolfSSL using ./configure --enable-pkcs7\n"); + return 0; +} + +#endif + diff --git a/pkcs7/authEnvelopedData-ori.c b/pkcs7/authEnvelopedData-ori.c new file mode 100644 index 00000000..05155c47 --- /dev/null +++ b/pkcs7/authEnvelopedData-ori.c @@ -0,0 +1,297 @@ +/* authEnvelopedData-ori.c + * + * Copyright (C) 2006-2018 wolfSSL Inc. + * + * This file is part of wolfSSL. (formerly known as CyaSSL) + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ +#include +#include +#include +#include + +#define certFile "../certs/client-ecc-cert.der" +#define keyFile "../certs/ecc-client-key.der" + +#define encodedFileORI "authEnvelopedDataORI.der" + +static const byte data[] = { /* Hello World */ + 0x48,0x65,0x6c,0x6c,0x6f,0x20,0x57,0x6f, + 0x72,0x6c,0x64 +}; + +static const byte asnDataOid[] = { + 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x01 +}; + +static int load_certs(byte* cert, word32* certSz, byte* key, word32* keySz) +{ + FILE* file; + + /* certificate file */ + file = fopen(certFile, "rb"); + if (!file) { + printf("ERROR: failed to open file: %s\n", certFile); + return -1; + } + + *certSz = (word32)fread(cert, 1, *certSz, file); + fclose(file); + + /* key file */ + file = fopen(keyFile, "rb"); + if (!file) { + printf("ERROR: failed to open file: %s\n", keyFile); + 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; +} + +/* ORI encrypt callback, responsible for encrypting content-encryption key (CEK) + * and giving wolfCrypt the value for oriOID and oriValue to place in + * OtherRecipientInfo. + * + * Returns 0 on success, negative upon error. */ +static int myOriEncryptCb(PKCS7* pkcs7, byte* cek, word32 cekSz, byte* oriType, + word32* oriTypeSz, byte* oriValue, word32* oriValueSz, + void* ctx) +{ + int i; + + /* make sure buffers are large enough */ + if ((*oriValueSz < (2 + cekSz)) || (*oriTypeSz < sizeof(oriType))) + return -1; + + /* our simple encryption algorithm will be take the bitwise complement */ + oriValue[0] = 0x04; /*ASN OCTET STRING */ + oriValue[1] = (byte)cekSz; /* length */ + for (i = 0; i < (int)cekSz; i++) { + oriValue[2 + i] = ~cek[i]; + } + *oriValueSz = 2 + cekSz; + + /* set oriType to ASN.1 encoded data OID */ + XMEMCPY(oriType, asnDataOid, sizeof(asnDataOid)); + *oriTypeSz = sizeof(asnDataOid); + + (void)pkcs7; + (void)ctx; + + return 0; +} + +/* ORI decrypt callback, responsible for providing a decrypted content + * encryption key (CEK) placed into decryptedKey and size placed into + * decryptedKeySz. oriOID and oriValue are given to the callback to help + * in decrypting the encrypted CEK. + * + * Returns 0 on success, negative upon error. */ +static int myOriDecryptCb(PKCS7* pkcs7, byte* oriType, word32 oriTypeSz, + byte* oriValue, word32 oriValueSz, byte* decryptedKey, + word32* decryptedKeySz, void* ctx) +{ + int i; + + /* make sure oriType matches what we expect */ + if (oriTypeSz != sizeof(asnDataOid)) + return -1; + + if (XMEMCMP(oriType, asnDataOid, sizeof(asnDataOid)) != 0) + return -1; + + /* make sure decrypted buffer is large enough */ + if (*decryptedKeySz < oriValueSz) + return -1; + + /* decrypt encrypted CEK using simple bitwise complement, + only for example */ + for (i = 0; i < (int)oriValueSz - 2; i++) { + decryptedKey[i] = ~oriValue[2 + i]; + } + + *decryptedKeySz = oriValueSz - 2; + + (void)pkcs7; + (void)ctx; + + return 0; +} + +static int authEnvelopedData_encrypt(byte* cert, word32 certSz, byte* key, + word32 keySz, byte* out, word32 outSz) +{ + int ret; + PKCS7* pkcs7; + + pkcs7 = wc_PKCS7_New(NULL, INVALID_DEVID); + if (pkcs7 == NULL) + return -1; + + pkcs7->content = (byte*)data; + pkcs7->contentSz = sizeof(data); + pkcs7->contentOID = DATA; + pkcs7->encryptOID = AES256GCMb; + + /* add recipient using otherRecipientInfo (ORI) with custom encrypt + * callback to handle encryption. ORI is loosely defined, allowing + * advanced users or future protocols to extend the CMS RecipientInfo + * model. */ + ret = wc_PKCS7_AddRecipient_ORI(pkcs7, myOriEncryptCb, 0); + if (ret < 0) { + printf("wc_PKCS7_AddRecipient_ORI() failed, ret = %d\n", ret); + wc_PKCS7_Free(pkcs7); + return -1; + } + + /* encode authEnvelopedData, returns size */ + ret = wc_PKCS7_EncodeAuthEnvelopedData(pkcs7, out, outSz); + if (ret <= 0) { + printf("wc_PKCS7_EncodeAuthEnvelopedData() failed, ret = %d\n", ret); + wc_PKCS7_Free(pkcs7); + return -1; + + } else { + printf("Successfully encoded AuthEnvelopedData bundle (%s)\n", + encodedFileORI); + + if (write_file_buffer(encodedFileORI, out, ret) != 0) { + printf("ERROR: error writing encoded to output file\n"); + return -1; + } + } + + wc_PKCS7_Free(pkcs7); + + return ret; +} + +static int authEnvelopedData_decrypt(byte* in, word32 inSz, byte* cert, + word32 certSz, byte* key, word32 keySz, + byte* out, word32 outSz) +{ + int ret; + PKCS7* pkcs7; + + pkcs7 = wc_PKCS7_New(NULL, INVALID_DEVID); + if (pkcs7 == NULL) + return -1; + + /* set decrypt callback for decryption */ + ret = wc_PKCS7_SetOriDecryptCb(pkcs7, myOriDecryptCb); + if (ret != 0) { + printf("ERROR: wc_PKCS7_SetOriDecryptCb(), ret = %d\n", ret); + wc_PKCS7_Free(pkcs7); + return -1; + } + + /* decode authEnvelopedData, returns size */ + ret = wc_PKCS7_DecodeAuthEnvelopedData(pkcs7, in, inSz, out, outSz); + if (ret <= 0) { + printf("ERROR: wc_PKCS7_DecodeAuthEnvelopedData(), ret = %d\n", ret); + wc_PKCS7_Free(pkcs7); + return -1; + } + + wc_PKCS7_Free(pkcs7); + + return ret; +} + +#ifdef HAVE_PKCS7 + +int main(int argc, char** argv) +{ + int ret; + int encryptedSz, decryptedSz; + word32 certSz, keySz; + + byte cert[2048]; + byte key[2048]; + byte encrypted[1024]; + byte decrypted[1024]; + +#ifdef DEBUG_WOLFSSL + wolfSSL_Debugging_ON(); +#endif + + certSz = sizeof(cert); + keySz = sizeof(key); + ret = load_certs(cert, &certSz, key, &keySz); + if (ret != 0) + return -1; + + encryptedSz = authEnvelopedData_encrypt(cert, certSz, key, keySz, + encrypted, sizeof(encrypted)); + if (encryptedSz < 0) + return -1; + +#ifdef DEBUG_WOLFSSL + printf("AuthEnvelopedData DER (%d byte):\n", encryptedSz); + WOLFSSL_BUFFER(encrypted, encryptedSz); +#endif + + decryptedSz = authEnvelopedData_decrypt(encrypted, encryptedSz, + cert, certSz, key, keySz, + decrypted, sizeof(decrypted)); + if (decryptedSz < 0) + return -1; + +#ifdef DEBUG_WOLFSSL + printf("Decrypted content (%d byte):\n", decryptedSz); + WOLFSSL_BUFFER(decrypted, decryptedSz); +#endif + + (void)argc; + (void)argv; + + return 0; +} + +#else + +int main(int argc, char** argv) +{ + printf("Must build wolfSSL using ./configure --enable-pkcs7\n"); + return 0; +} + +#endif + diff --git a/pkcs7/authEnvelopedData-pwri.c b/pkcs7/authEnvelopedData-pwri.c new file mode 100644 index 00000000..601a1f46 --- /dev/null +++ b/pkcs7/authEnvelopedData-pwri.c @@ -0,0 +1,233 @@ +/* authEnvelopedData-pwri.c + * + * Copyright (C) 2006-2018 wolfSSL Inc. + * + * This file is part of wolfSSL. (formerly known as CyaSSL) + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ +#include +#include +#include +#include + +#define certFile "../certs/client-ecc-cert.der" +#define keyFile "../certs/ecc-client-key.der" + +#define encodedFilePWRI "authEnvelopedDataPWRI.der" + +static const byte data[] = { /* Hello World */ + 0x48,0x65,0x6c,0x6c,0x6f,0x20,0x57,0x6f, + 0x72,0x6c,0x64 +}; + +const char password[] = "wolfsslPassword"; + +static int load_certs(byte* cert, word32* certSz, byte* key, word32* keySz) +{ + FILE* file; + + /* certificate file */ + file = fopen(certFile, "rb"); + if (!file) { + printf("ERROR: failed to open file: %s\n", certFile); + return -1; + } + + *certSz = (word32)fread(cert, 1, *certSz, file); + fclose(file); + + /* key file */ + file = fopen(keyFile, "rb"); + if (!file) { + printf("ERROR: failed to open file: %s\n", keyFile); + 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 authEnvelopedData_encrypt(byte* cert, word32 certSz, byte* key, + word32 keySz, byte* out, word32 outSz) +{ + int ret; + PKCS7* pkcs7; + + int kdfIterations = 5; + + byte salt[] = { + 0x12, 0x34, 0x56, 0x78, 0x56, 0x34, 0x12 + }; + + pkcs7 = wc_PKCS7_New(NULL, INVALID_DEVID); + if (pkcs7 == NULL) + return -1; + + pkcs7->content = (byte*)data; + pkcs7->contentSz = sizeof(data); + pkcs7->contentOID = DATA; + pkcs7->encryptOID = AES256GCMb; + + /* add recipient using password (PWRI type) */ + ret = wc_PKCS7_AddRecipient_PWRI(pkcs7, (byte*)password, + (word32)XSTRLEN(password), + salt, sizeof(salt), + PBKDF2_OID, WC_SHA, kdfIterations, + AES256CBCb, 0); + if (ret < 0) { + printf("wc_PKCS7_AddRecipient_PWRI() failed, ret = %d\n", ret); + wc_PKCS7_Free(pkcs7); + return -1; + } + + /* encode authEnvelopedData, returns size */ + ret = wc_PKCS7_EncodeAuthEnvelopedData(pkcs7, out, outSz); + if (ret <= 0) { + printf("wc_PKCS7_EncodeAuthEnvelopedData() failed, ret = %d\n", ret); + wc_PKCS7_Free(pkcs7); + return -1; + + } else { + printf("Successfully encoded AuthEnvelopedData bundle (%s)\n", + encodedFilePWRI); + + if (write_file_buffer(encodedFilePWRI, out, ret) != 0) { + printf("ERROR: error writing encoded to output file\n"); + return -1; + } + } + + wc_PKCS7_Free(pkcs7); + + return ret; +} + +static int authEnvelopedData_decrypt(byte* in, word32 inSz, byte* cert, + word32 certSz, byte* key, word32 keySz, + byte* out, word32 outSz) +{ + int ret; + PKCS7* pkcs7; + + pkcs7 = wc_PKCS7_New(NULL, INVALID_DEVID); + if (pkcs7 == NULL) + return -1; + + /* set password, for decryption */ + ret = wc_PKCS7_SetPassword(pkcs7, (byte*)password, + (word32)XSTRLEN(password)); + if (ret != 0) { + printf("ERROR: wc_PKCS7_SetPassword(), ret = %d\n", ret); + wc_PKCS7_Free(pkcs7); + return -1; + } + + /* decode authEnvelopedData, returns size */ + ret = wc_PKCS7_DecodeAuthEnvelopedData(pkcs7, in, inSz, out, outSz); + if (ret <= 0) { + printf("ERROR: wc_PKCS7_DecodeAuthEnvelopedData(), ret = %d\n", ret); + wc_PKCS7_Free(pkcs7); + return -1; + } + + wc_PKCS7_Free(pkcs7); + + return ret; +} + +#ifdef HAVE_PKCS7 + +int main(int argc, char** argv) +{ + int ret; + int encryptedSz, decryptedSz; + word32 certSz, keySz; + + byte cert[2048]; + byte key[2048]; + byte encrypted[1024]; + byte decrypted[1024]; + +#ifdef DEBUG_WOLFSSL + wolfSSL_Debugging_ON(); +#endif + + certSz = sizeof(cert); + keySz = sizeof(key); + ret = load_certs(cert, &certSz, key, &keySz); + if (ret != 0) + return -1; + + encryptedSz = authEnvelopedData_encrypt(cert, certSz, key, keySz, + encrypted, sizeof(encrypted)); + if (encryptedSz < 0) + return -1; + +#ifdef DEBUG_WOLFSSL + printf("AuthEnvelopedData DER (%d byte):\n", encryptedSz); + WOLFSSL_BUFFER(encrypted, encryptedSz); +#endif + + decryptedSz = authEnvelopedData_decrypt(encrypted, encryptedSz, + cert, certSz, key, keySz, + decrypted, sizeof(decrypted)); + if (decryptedSz < 0) + return -1; + +#ifdef DEBUG_WOLFSSL + printf("Decrypted content (%d byte):\n", decryptedSz); + WOLFSSL_BUFFER(decrypted, decryptedSz); +#endif + + (void)argc; + (void)argv; + + return 0; +} + +#else + +int main(int argc, char** argv) +{ + printf("Must build wolfSSL using ./configure --enable-pkcs7\n"); + return 0; +} + +#endif + diff --git a/pkcs7/encryptedData.c b/pkcs7/encryptedData.c index c624297a..767f172d 100644 --- a/pkcs7/encryptedData.c +++ b/pkcs7/encryptedData.c @@ -24,6 +24,8 @@ #include #include +#define encryptedFile "encryptedData.der" + static const byte data[] = { /* Hello World */ 0x48,0x65,0x6c,0x6c,0x6f,0x20,0x57,0x6f, 0x72,0x6c,0x64 @@ -36,6 +38,27 @@ static const byte aes256Key[] = { 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08 }; +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 encryptedData_encrypt(byte* out, word32 outSz) { int ret; @@ -57,6 +80,14 @@ static int encryptedData_encrypt(byte* out, word32 outSz) if (ret <= 0) { wc_PKCS7_Free(pkcs7); return -1; + } else { + printf("Successfully encoded EncryptedData bundle (%s)\n", + encryptedFile); + + if (write_file_buffer(encryptedFile, out, ret) != 0) { + printf("ERROR: error writing encoded to output file\n"); + return -1; + } } wc_PKCS7_Free(pkcs7); @@ -104,16 +135,20 @@ int main(int argc, char** argv) if (encryptedSz < 0) return -1; - printf("EncryptedData DER (%d byte):\n", encryptedSz); +#ifdef DEBUG_WOLFSSL + printf("EncryptedData DER (%d bytes):\n", encryptedSz); WOLFSSL_BUFFER(encrypted, encryptedSz); +#endif decryptedSz = encryptedData_decrypt(encrypted, encryptedSz, decrypted, sizeof(decrypted)); if (decryptedSz < 0) return -1; - printf("DecryptedData DER (%d byte):\n", decryptedSz); +#ifdef DEBUG_WOLFSSL + printf("DecryptedData DER (%d bytes):\n", decryptedSz); WOLFSSL_BUFFER(decrypted, decryptedSz); +#endif (void)argc; (void)argv; diff --git a/pkcs7/envelopedData-kari.c b/pkcs7/envelopedData-kari.c index 9d752b9f..5d470d14 100644 --- a/pkcs7/envelopedData-kari.c +++ b/pkcs7/envelopedData-kari.c @@ -115,7 +115,8 @@ static int envelopedData_encrypt(byte* cert, word32 certSz, byte* key, return -1; } else { - printf("Successfully encoded EnvelopedData bundle.\n"); + printf("Successfully encoded EnvelopedData bundle (%s)\n", + encodedFileKARI); if (write_file_buffer(encodedFileKARI, out, ret) != 0) { printf("ERROR: error writing encoded to output file\n"); @@ -196,8 +197,10 @@ int main(int argc, char** argv) if (encryptedSz < 0) return -1; +#ifdef DEBUG_WOLFSSL printf("EnvelopedData DER (%d byte):\n", encryptedSz); WOLFSSL_BUFFER(encrypted, encryptedSz); +#endif decryptedSz = envelopedData_decrypt(encrypted, encryptedSz, cert, certSz, key, keySz, @@ -205,8 +208,10 @@ int main(int argc, char** argv) if (decryptedSz < 0) return -1; +#ifdef DEBUG_WOLFSSL printf("Decrypted content (%d byte):\n", decryptedSz); WOLFSSL_BUFFER(decrypted, decryptedSz); +#endif (void)argc; (void)argv; diff --git a/pkcs7/envelopedData-ktri.c b/pkcs7/envelopedData-ktri.c index cbd8cb8b..99ff8621 100644 --- a/pkcs7/envelopedData-ktri.c +++ b/pkcs7/envelopedData-ktri.c @@ -109,7 +109,8 @@ static int envelopedData_encrypt(byte* cert, word32 certSz, byte* key, return -1; } else { - printf("Successfully encoded EnvelopedData bundle.\n"); + printf("Successfully encoded EnvelopedData bundle (%s)\n", + encodedFileKTRI); if (write_file_buffer(encodedFileKTRI, out, ret) != 0) { printf("ERROR: error writing encoded to output file\n"); @@ -187,8 +188,10 @@ int main(int argc, char** argv) if (encryptedSz < 0) return -1; +#ifdef DEBUG_WOLFSSL printf("EnvelopedData DER (%d byte):\n", encryptedSz); WOLFSSL_BUFFER(encrypted, encryptedSz); +#endif decryptedSz = envelopedData_decrypt(encrypted, encryptedSz, cert, certSz, key, keySz, @@ -196,8 +199,10 @@ int main(int argc, char** argv) if (decryptedSz < 0) return -1; +#ifdef DEBUG_WOLFSSL printf("Decrypted content (%d byte):\n", decryptedSz); WOLFSSL_BUFFER(decrypted, decryptedSz); +#endif (void)argc; (void)argv; diff --git a/pkcs7/envelopedData-ori.c b/pkcs7/envelopedData-ori.c index 1a218606..c63153bb 100644 --- a/pkcs7/envelopedData-ori.c +++ b/pkcs7/envelopedData-ori.c @@ -189,7 +189,8 @@ static int envelopedData_encrypt(byte* cert, word32 certSz, byte* key, return -1; } else { - printf("Successfully encoded EnvelopedData bundle.\n"); + printf("Successfully encoded EnvelopedData bundle (%s)\n", + encodedFileORI); if (write_file_buffer(encodedFileORI, out, ret) != 0) { printf("ERROR: error writing encoded to output file\n"); @@ -262,8 +263,10 @@ int main(int argc, char** argv) if (encryptedSz < 0) return -1; +#ifdef DEBUG_WOLFSSL printf("EnvelopedData DER (%d byte):\n", encryptedSz); WOLFSSL_BUFFER(encrypted, encryptedSz); +#endif decryptedSz = envelopedData_decrypt(encrypted, encryptedSz, cert, certSz, key, keySz, @@ -271,8 +274,10 @@ int main(int argc, char** argv) if (decryptedSz < 0) return -1; +#ifdef DEBUG_WOLFSSL printf("Decrypted content (%d byte):\n", decryptedSz); WOLFSSL_BUFFER(decrypted, decryptedSz); +#endif (void)argc; (void)argv; diff --git a/pkcs7/envelopedData-pwri.c b/pkcs7/envelopedData-pwri.c index 9fc1b0e7..27f49e39 100644 --- a/pkcs7/envelopedData-pwri.c +++ b/pkcs7/envelopedData-pwri.c @@ -124,7 +124,8 @@ static int envelopedData_encrypt(byte* cert, word32 certSz, byte* key, return -1; } else { - printf("Successfully encoded EnvelopedData bundle.\n"); + printf("Successfully encoded EnvelopedData bundle (%s)\n", + encodedFilePWRI); if (write_file_buffer(encodedFilePWRI, out, ret) != 0) { printf("ERROR: error writing encoded to output file\n"); @@ -198,8 +199,10 @@ int main(int argc, char** argv) if (encryptedSz < 0) return -1; +#ifdef DEBUG_WOLFSSL printf("EnvelopedData DER (%d byte):\n", encryptedSz); WOLFSSL_BUFFER(encrypted, encryptedSz); +#endif decryptedSz = envelopedData_decrypt(encrypted, encryptedSz, cert, certSz, key, keySz, @@ -207,8 +210,10 @@ int main(int argc, char** argv) if (decryptedSz < 0) return -1; +#ifdef DEBUG_WOLFSSL printf("Decrypted content (%d byte):\n", decryptedSz); WOLFSSL_BUFFER(decrypted, decryptedSz); +#endif (void)argc; (void)argv;