Xuyi Wang / wolfSSL

Dependents:   OS

Committer:
wolfSSL
Date:
Sat Aug 18 22:20:43 2018 +0000
Revision:
15:117db924cf7c
wolfSSL 3.15.3

Who changed what in which revision?

UserRevisionLine numberNew contents of line
wolfSSL 15:117db924cf7c 1 /* pkcs7.c
wolfSSL 15:117db924cf7c 2 *
wolfSSL 15:117db924cf7c 3 * Copyright (C) 2006-2017 wolfSSL Inc.
wolfSSL 15:117db924cf7c 4 *
wolfSSL 15:117db924cf7c 5 * This file is part of wolfSSL.
wolfSSL 15:117db924cf7c 6 *
wolfSSL 15:117db924cf7c 7 * wolfSSL is free software; you can redistribute it and/or modify
wolfSSL 15:117db924cf7c 8 * it under the terms of the GNU General Public License as published by
wolfSSL 15:117db924cf7c 9 * the Free Software Foundation; either version 2 of the License, or
wolfSSL 15:117db924cf7c 10 * (at your option) any later version.
wolfSSL 15:117db924cf7c 11 *
wolfSSL 15:117db924cf7c 12 * wolfSSL is distributed in the hope that it will be useful,
wolfSSL 15:117db924cf7c 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
wolfSSL 15:117db924cf7c 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
wolfSSL 15:117db924cf7c 15 * GNU General Public License for more details.
wolfSSL 15:117db924cf7c 16 *
wolfSSL 15:117db924cf7c 17 * You should have received a copy of the GNU General Public License
wolfSSL 15:117db924cf7c 18 * along with this program; if not, write to the Free Software
wolfSSL 15:117db924cf7c 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
wolfSSL 15:117db924cf7c 20 */
wolfSSL 15:117db924cf7c 21
wolfSSL 15:117db924cf7c 22
wolfSSL 15:117db924cf7c 23 #ifdef HAVE_CONFIG_H
wolfSSL 15:117db924cf7c 24 #include <config.h>
wolfSSL 15:117db924cf7c 25 #endif
wolfSSL 15:117db924cf7c 26
wolfSSL 15:117db924cf7c 27 #include <wolfssl/wolfcrypt/settings.h>
wolfSSL 15:117db924cf7c 28
wolfSSL 15:117db924cf7c 29 #ifdef HAVE_PKCS7
wolfSSL 15:117db924cf7c 30
wolfSSL 15:117db924cf7c 31 #include <wolfssl/wolfcrypt/pkcs7.h>
wolfSSL 15:117db924cf7c 32 #include <wolfssl/wolfcrypt/error-crypt.h>
wolfSSL 15:117db924cf7c 33 #include <wolfssl/wolfcrypt/logging.h>
wolfSSL 15:117db924cf7c 34 #include <wolfssl/wolfcrypt/hash.h>
wolfSSL 15:117db924cf7c 35 #ifndef NO_RSA
wolfSSL 15:117db924cf7c 36 #include <wolfssl/wolfcrypt/rsa.h>
wolfSSL 15:117db924cf7c 37 #endif
wolfSSL 15:117db924cf7c 38 #ifdef HAVE_ECC
wolfSSL 15:117db924cf7c 39 #include <wolfssl/wolfcrypt/ecc.h>
wolfSSL 15:117db924cf7c 40 #endif
wolfSSL 15:117db924cf7c 41 #ifdef NO_INLINE
wolfSSL 15:117db924cf7c 42 #include <wolfssl/wolfcrypt/misc.h>
wolfSSL 15:117db924cf7c 43 #else
wolfSSL 15:117db924cf7c 44 #define WOLFSSL_MISC_INCLUDED
wolfSSL 15:117db924cf7c 45 #include <wolfcrypt/src/misc.c>
wolfSSL 15:117db924cf7c 46 #endif
wolfSSL 15:117db924cf7c 47
wolfSSL 15:117db924cf7c 48
wolfSSL 15:117db924cf7c 49 /* direction for processing, encoding or decoding */
wolfSSL 15:117db924cf7c 50 typedef enum {
wolfSSL 15:117db924cf7c 51 WC_PKCS7_ENCODE,
wolfSSL 15:117db924cf7c 52 WC_PKCS7_DECODE
wolfSSL 15:117db924cf7c 53 } pkcs7Direction;
wolfSSL 15:117db924cf7c 54
wolfSSL 15:117db924cf7c 55 #define MAX_PKCS7_DIGEST_SZ (MAX_SEQ_SZ + MAX_ALGO_SZ + \
wolfSSL 15:117db924cf7c 56 MAX_OCTET_STR_SZ + WC_MAX_DIGEST_SIZE)
wolfSSL 15:117db924cf7c 57
wolfSSL 15:117db924cf7c 58
wolfSSL 15:117db924cf7c 59 /* placed ASN.1 contentType OID into *output, return idx on success,
wolfSSL 15:117db924cf7c 60 * 0 upon failure */
wolfSSL 15:117db924cf7c 61 static int wc_SetContentType(int pkcs7TypeOID, byte* output)
wolfSSL 15:117db924cf7c 62 {
wolfSSL 15:117db924cf7c 63 /* PKCS#7 content types, RFC 2315, section 14 */
wolfSSL 15:117db924cf7c 64 const byte pkcs7[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7,
wolfSSL 15:117db924cf7c 65 0x0D, 0x01, 0x07 };
wolfSSL 15:117db924cf7c 66 const byte data[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7,
wolfSSL 15:117db924cf7c 67 0x0D, 0x01, 0x07, 0x01 };
wolfSSL 15:117db924cf7c 68 const byte signedData[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7,
wolfSSL 15:117db924cf7c 69 0x0D, 0x01, 0x07, 0x02};
wolfSSL 15:117db924cf7c 70 const byte envelopedData[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7,
wolfSSL 15:117db924cf7c 71 0x0D, 0x01, 0x07, 0x03 };
wolfSSL 15:117db924cf7c 72 const byte signedAndEnveloped[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7,
wolfSSL 15:117db924cf7c 73 0x0D, 0x01, 0x07, 0x04 };
wolfSSL 15:117db924cf7c 74 const byte digestedData[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7,
wolfSSL 15:117db924cf7c 75 0x0D, 0x01, 0x07, 0x05 };
wolfSSL 15:117db924cf7c 76
wolfSSL 15:117db924cf7c 77 #ifndef NO_PKCS7_ENCRYPTED_DATA
wolfSSL 15:117db924cf7c 78 const byte encryptedData[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7,
wolfSSL 15:117db924cf7c 79 0x0D, 0x01, 0x07, 0x06 };
wolfSSL 15:117db924cf7c 80 #endif
wolfSSL 15:117db924cf7c 81
wolfSSL 15:117db924cf7c 82 int idSz;
wolfSSL 15:117db924cf7c 83 int typeSz = 0, idx = 0;
wolfSSL 15:117db924cf7c 84 const byte* typeName = 0;
wolfSSL 15:117db924cf7c 85 byte ID_Length[MAX_LENGTH_SZ];
wolfSSL 15:117db924cf7c 86
wolfSSL 15:117db924cf7c 87 switch (pkcs7TypeOID) {
wolfSSL 15:117db924cf7c 88 case PKCS7_MSG:
wolfSSL 15:117db924cf7c 89 typeSz = sizeof(pkcs7);
wolfSSL 15:117db924cf7c 90 typeName = pkcs7;
wolfSSL 15:117db924cf7c 91 break;
wolfSSL 15:117db924cf7c 92
wolfSSL 15:117db924cf7c 93 case DATA:
wolfSSL 15:117db924cf7c 94 typeSz = sizeof(data);
wolfSSL 15:117db924cf7c 95 typeName = data;
wolfSSL 15:117db924cf7c 96 break;
wolfSSL 15:117db924cf7c 97
wolfSSL 15:117db924cf7c 98 case SIGNED_DATA:
wolfSSL 15:117db924cf7c 99 typeSz = sizeof(signedData);
wolfSSL 15:117db924cf7c 100 typeName = signedData;
wolfSSL 15:117db924cf7c 101 break;
wolfSSL 15:117db924cf7c 102
wolfSSL 15:117db924cf7c 103 case ENVELOPED_DATA:
wolfSSL 15:117db924cf7c 104 typeSz = sizeof(envelopedData);
wolfSSL 15:117db924cf7c 105 typeName = envelopedData;
wolfSSL 15:117db924cf7c 106 break;
wolfSSL 15:117db924cf7c 107
wolfSSL 15:117db924cf7c 108 case SIGNED_AND_ENVELOPED_DATA:
wolfSSL 15:117db924cf7c 109 typeSz = sizeof(signedAndEnveloped);
wolfSSL 15:117db924cf7c 110 typeName = signedAndEnveloped;
wolfSSL 15:117db924cf7c 111 break;
wolfSSL 15:117db924cf7c 112
wolfSSL 15:117db924cf7c 113 case DIGESTED_DATA:
wolfSSL 15:117db924cf7c 114 typeSz = sizeof(digestedData);
wolfSSL 15:117db924cf7c 115 typeName = digestedData;
wolfSSL 15:117db924cf7c 116 break;
wolfSSL 15:117db924cf7c 117
wolfSSL 15:117db924cf7c 118 #ifndef NO_PKCS7_ENCRYPTED_DATA
wolfSSL 15:117db924cf7c 119 case ENCRYPTED_DATA:
wolfSSL 15:117db924cf7c 120 typeSz = sizeof(encryptedData);
wolfSSL 15:117db924cf7c 121 typeName = encryptedData;
wolfSSL 15:117db924cf7c 122 break;
wolfSSL 15:117db924cf7c 123 #endif
wolfSSL 15:117db924cf7c 124
wolfSSL 15:117db924cf7c 125 default:
wolfSSL 15:117db924cf7c 126 WOLFSSL_MSG("Unknown PKCS#7 Type");
wolfSSL 15:117db924cf7c 127 return 0;
wolfSSL 15:117db924cf7c 128 };
wolfSSL 15:117db924cf7c 129
wolfSSL 15:117db924cf7c 130 idSz = SetLength(typeSz, ID_Length);
wolfSSL 15:117db924cf7c 131 output[idx++] = ASN_OBJECT_ID;
wolfSSL 15:117db924cf7c 132 XMEMCPY(output + idx, ID_Length, idSz);
wolfSSL 15:117db924cf7c 133 idx += idSz;
wolfSSL 15:117db924cf7c 134 XMEMCPY(output + idx, typeName, typeSz);
wolfSSL 15:117db924cf7c 135 idx += typeSz;
wolfSSL 15:117db924cf7c 136
wolfSSL 15:117db924cf7c 137 return idx;
wolfSSL 15:117db924cf7c 138 }
wolfSSL 15:117db924cf7c 139
wolfSSL 15:117db924cf7c 140
wolfSSL 15:117db924cf7c 141 /* get ASN.1 contentType OID sum, return 0 on success, <0 on failure */
wolfSSL 15:117db924cf7c 142 static int wc_GetContentType(const byte* input, word32* inOutIdx, word32* oid,
wolfSSL 15:117db924cf7c 143 word32 maxIdx)
wolfSSL 15:117db924cf7c 144 {
wolfSSL 15:117db924cf7c 145 WOLFSSL_ENTER("wc_GetContentType");
wolfSSL 15:117db924cf7c 146 if (GetObjectId(input, inOutIdx, oid, oidIgnoreType, maxIdx) < 0)
wolfSSL 15:117db924cf7c 147 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 148
wolfSSL 15:117db924cf7c 149 return 0;
wolfSSL 15:117db924cf7c 150 }
wolfSSL 15:117db924cf7c 151
wolfSSL 15:117db924cf7c 152
wolfSSL 15:117db924cf7c 153 /* return block size for algorithm represented by oid, or <0 on error */
wolfSSL 15:117db924cf7c 154 static int wc_PKCS7_GetOIDBlockSize(int oid)
wolfSSL 15:117db924cf7c 155 {
wolfSSL 15:117db924cf7c 156 int blockSz;
wolfSSL 15:117db924cf7c 157
wolfSSL 15:117db924cf7c 158 switch (oid) {
wolfSSL 15:117db924cf7c 159 #ifndef NO_AES
wolfSSL 15:117db924cf7c 160 #ifdef WOLFSSL_AES_128
wolfSSL 15:117db924cf7c 161 case AES128CBCb:
wolfSSL 15:117db924cf7c 162 #endif
wolfSSL 15:117db924cf7c 163 #ifdef WOLFSSL_AES_192
wolfSSL 15:117db924cf7c 164 case AES192CBCb:
wolfSSL 15:117db924cf7c 165 #endif
wolfSSL 15:117db924cf7c 166 #ifdef WOLFSSL_AES_256
wolfSSL 15:117db924cf7c 167 case AES256CBCb:
wolfSSL 15:117db924cf7c 168 #endif
wolfSSL 15:117db924cf7c 169 blockSz = AES_BLOCK_SIZE;
wolfSSL 15:117db924cf7c 170 break;
wolfSSL 15:117db924cf7c 171 #endif
wolfSSL 15:117db924cf7c 172 #ifndef NO_DES3
wolfSSL 15:117db924cf7c 173 case DESb:
wolfSSL 15:117db924cf7c 174 case DES3b:
wolfSSL 15:117db924cf7c 175 blockSz = DES_BLOCK_SIZE;
wolfSSL 15:117db924cf7c 176 break;
wolfSSL 15:117db924cf7c 177 #endif
wolfSSL 15:117db924cf7c 178 default:
wolfSSL 15:117db924cf7c 179 WOLFSSL_MSG("Unsupported content cipher type");
wolfSSL 15:117db924cf7c 180 return ALGO_ID_E;
wolfSSL 15:117db924cf7c 181 };
wolfSSL 15:117db924cf7c 182
wolfSSL 15:117db924cf7c 183 return blockSz;
wolfSSL 15:117db924cf7c 184 }
wolfSSL 15:117db924cf7c 185
wolfSSL 15:117db924cf7c 186
wolfSSL 15:117db924cf7c 187 /* get key size for algorithm represented by oid, or <0 on error */
wolfSSL 15:117db924cf7c 188 static int wc_PKCS7_GetOIDKeySize(int oid)
wolfSSL 15:117db924cf7c 189 {
wolfSSL 15:117db924cf7c 190 int blockKeySz;
wolfSSL 15:117db924cf7c 191
wolfSSL 15:117db924cf7c 192 switch (oid) {
wolfSSL 15:117db924cf7c 193 #ifndef NO_AES
wolfSSL 15:117db924cf7c 194 #ifdef WOLFSSL_AES_128
wolfSSL 15:117db924cf7c 195 case AES128CBCb:
wolfSSL 15:117db924cf7c 196 case AES128_WRAP:
wolfSSL 15:117db924cf7c 197 blockKeySz = 16;
wolfSSL 15:117db924cf7c 198 break;
wolfSSL 15:117db924cf7c 199 #endif
wolfSSL 15:117db924cf7c 200 #ifdef WOLFSSL_AES_192
wolfSSL 15:117db924cf7c 201 case AES192CBCb:
wolfSSL 15:117db924cf7c 202 case AES192_WRAP:
wolfSSL 15:117db924cf7c 203 blockKeySz = 24;
wolfSSL 15:117db924cf7c 204 break;
wolfSSL 15:117db924cf7c 205 #endif
wolfSSL 15:117db924cf7c 206 #ifdef WOLFSSL_AES_256
wolfSSL 15:117db924cf7c 207 case AES256CBCb:
wolfSSL 15:117db924cf7c 208 case AES256_WRAP:
wolfSSL 15:117db924cf7c 209 blockKeySz = 32;
wolfSSL 15:117db924cf7c 210 break;
wolfSSL 15:117db924cf7c 211 #endif
wolfSSL 15:117db924cf7c 212 #endif
wolfSSL 15:117db924cf7c 213 #ifndef NO_DES3
wolfSSL 15:117db924cf7c 214 case DESb:
wolfSSL 15:117db924cf7c 215 blockKeySz = DES_KEYLEN;
wolfSSL 15:117db924cf7c 216 break;
wolfSSL 15:117db924cf7c 217
wolfSSL 15:117db924cf7c 218 case DES3b:
wolfSSL 15:117db924cf7c 219 blockKeySz = DES3_KEYLEN;
wolfSSL 15:117db924cf7c 220 break;
wolfSSL 15:117db924cf7c 221 #endif
wolfSSL 15:117db924cf7c 222 default:
wolfSSL 15:117db924cf7c 223 WOLFSSL_MSG("Unsupported content cipher type");
wolfSSL 15:117db924cf7c 224 return ALGO_ID_E;
wolfSSL 15:117db924cf7c 225 };
wolfSSL 15:117db924cf7c 226
wolfSSL 15:117db924cf7c 227 return blockKeySz;
wolfSSL 15:117db924cf7c 228 }
wolfSSL 15:117db924cf7c 229
wolfSSL 15:117db924cf7c 230
wolfSSL 15:117db924cf7c 231 PKCS7* wc_PKCS7_New(void* heap, int devId)
wolfSSL 15:117db924cf7c 232 {
wolfSSL 15:117db924cf7c 233 PKCS7* pkcs7 = (PKCS7*)XMALLOC(sizeof(PKCS7), heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 234 if (pkcs7) {
wolfSSL 15:117db924cf7c 235 XMEMSET(pkcs7, 0, sizeof(PKCS7));
wolfSSL 15:117db924cf7c 236 if (wc_PKCS7_Init(pkcs7, heap, devId) == 0) {
wolfSSL 15:117db924cf7c 237 pkcs7->isDynamic = 1;
wolfSSL 15:117db924cf7c 238 }
wolfSSL 15:117db924cf7c 239 else {
wolfSSL 15:117db924cf7c 240 XFREE(pkcs7, heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 241 pkcs7 = NULL;
wolfSSL 15:117db924cf7c 242 }
wolfSSL 15:117db924cf7c 243 }
wolfSSL 15:117db924cf7c 244 return pkcs7;
wolfSSL 15:117db924cf7c 245 }
wolfSSL 15:117db924cf7c 246
wolfSSL 15:117db924cf7c 247 /* This is to initialize a PKCS7 structure. It sets all values to 0 and can be
wolfSSL 15:117db924cf7c 248 * used to set the heap hint.
wolfSSL 15:117db924cf7c 249 *
wolfSSL 15:117db924cf7c 250 * pkcs7 PKCS7 structure to initialize
wolfSSL 15:117db924cf7c 251 * heap memory heap hint for PKCS7 structure to use
wolfSSL 15:117db924cf7c 252 * devId currently not used but a place holder for async operations
wolfSSL 15:117db924cf7c 253 *
wolfSSL 15:117db924cf7c 254 * returns 0 on success or a negative value for failure
wolfSSL 15:117db924cf7c 255 */
wolfSSL 15:117db924cf7c 256 int wc_PKCS7_Init(PKCS7* pkcs7, void* heap, int devId)
wolfSSL 15:117db924cf7c 257 {
wolfSSL 15:117db924cf7c 258 WOLFSSL_ENTER("wc_PKCS7_Init");
wolfSSL 15:117db924cf7c 259
wolfSSL 15:117db924cf7c 260 if (pkcs7 == NULL) {
wolfSSL 15:117db924cf7c 261 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 262 }
wolfSSL 15:117db924cf7c 263
wolfSSL 15:117db924cf7c 264 XMEMSET(pkcs7, 0, sizeof(PKCS7));
wolfSSL 15:117db924cf7c 265 #ifdef WOLFSSL_HEAP_TEST
wolfSSL 15:117db924cf7c 266 pkcs7->heap = (void*)WOLFSSL_HEAP_TEST;
wolfSSL 15:117db924cf7c 267 #else
wolfSSL 15:117db924cf7c 268 pkcs7->heap = heap;
wolfSSL 15:117db924cf7c 269 #endif
wolfSSL 15:117db924cf7c 270 pkcs7->devId = devId;
wolfSSL 15:117db924cf7c 271
wolfSSL 15:117db924cf7c 272 return 0;
wolfSSL 15:117db924cf7c 273 }
wolfSSL 15:117db924cf7c 274
wolfSSL 15:117db924cf7c 275
wolfSSL 15:117db924cf7c 276 /* init PKCS7 struct with recipient cert, decode into DecodedCert
wolfSSL 15:117db924cf7c 277 * NOTE: keeps previously set pkcs7 heap hint, devId and isDynamic */
wolfSSL 15:117db924cf7c 278 int wc_PKCS7_InitWithCert(PKCS7* pkcs7, byte* cert, word32 certSz)
wolfSSL 15:117db924cf7c 279 {
wolfSSL 15:117db924cf7c 280 int ret = 0;
wolfSSL 15:117db924cf7c 281 void* heap;
wolfSSL 15:117db924cf7c 282 int devId;
wolfSSL 15:117db924cf7c 283 word16 isDynamic;
wolfSSL 15:117db924cf7c 284
wolfSSL 15:117db924cf7c 285 if (pkcs7 == NULL || (cert == NULL && certSz != 0)) {
wolfSSL 15:117db924cf7c 286 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 287 }
wolfSSL 15:117db924cf7c 288
wolfSSL 15:117db924cf7c 289 heap = pkcs7->heap;
wolfSSL 15:117db924cf7c 290 devId = pkcs7->devId;
wolfSSL 15:117db924cf7c 291 isDynamic = pkcs7->isDynamic;
wolfSSL 15:117db924cf7c 292 ret = wc_PKCS7_Init(pkcs7, heap, devId);
wolfSSL 15:117db924cf7c 293 if (ret != 0)
wolfSSL 15:117db924cf7c 294 return ret;
wolfSSL 15:117db924cf7c 295 pkcs7->isDynamic = isDynamic;
wolfSSL 15:117db924cf7c 296
wolfSSL 15:117db924cf7c 297 if (cert != NULL && certSz > 0) {
wolfSSL 15:117db924cf7c 298 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 299 DecodedCert* dCert;
wolfSSL 15:117db924cf7c 300
wolfSSL 15:117db924cf7c 301 dCert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), pkcs7->heap,
wolfSSL 15:117db924cf7c 302 DYNAMIC_TYPE_DCERT);
wolfSSL 15:117db924cf7c 303 if (dCert == NULL)
wolfSSL 15:117db924cf7c 304 return MEMORY_E;
wolfSSL 15:117db924cf7c 305 #else
wolfSSL 15:117db924cf7c 306 DecodedCert stack_dCert;
wolfSSL 15:117db924cf7c 307 DecodedCert* dCert = &stack_dCert;
wolfSSL 15:117db924cf7c 308 #endif
wolfSSL 15:117db924cf7c 309
wolfSSL 15:117db924cf7c 310 pkcs7->singleCert = cert;
wolfSSL 15:117db924cf7c 311 pkcs7->singleCertSz = certSz;
wolfSSL 15:117db924cf7c 312 InitDecodedCert(dCert, cert, certSz, pkcs7->heap);
wolfSSL 15:117db924cf7c 313
wolfSSL 15:117db924cf7c 314 ret = ParseCert(dCert, CA_TYPE, NO_VERIFY, 0);
wolfSSL 15:117db924cf7c 315 if (ret < 0) {
wolfSSL 15:117db924cf7c 316 FreeDecodedCert(dCert);
wolfSSL 15:117db924cf7c 317 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 318 XFREE(dCert, pkcs7->heap, DYNAMIC_TYPE_DCERT);
wolfSSL 15:117db924cf7c 319 #endif
wolfSSL 15:117db924cf7c 320 return ret;
wolfSSL 15:117db924cf7c 321 }
wolfSSL 15:117db924cf7c 322
wolfSSL 15:117db924cf7c 323 XMEMCPY(pkcs7->publicKey, dCert->publicKey, dCert->pubKeySize);
wolfSSL 15:117db924cf7c 324 pkcs7->publicKeySz = dCert->pubKeySize;
wolfSSL 15:117db924cf7c 325 pkcs7->publicKeyOID = dCert->keyOID;
wolfSSL 15:117db924cf7c 326 XMEMCPY(pkcs7->issuerHash, dCert->issuerHash, KEYID_SIZE);
wolfSSL 15:117db924cf7c 327 pkcs7->issuer = dCert->issuerRaw;
wolfSSL 15:117db924cf7c 328 pkcs7->issuerSz = dCert->issuerRawLen;
wolfSSL 15:117db924cf7c 329 XMEMCPY(pkcs7->issuerSn, dCert->serial, dCert->serialSz);
wolfSSL 15:117db924cf7c 330 pkcs7->issuerSnSz = dCert->serialSz;
wolfSSL 15:117db924cf7c 331 FreeDecodedCert(dCert);
wolfSSL 15:117db924cf7c 332
wolfSSL 15:117db924cf7c 333 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 334 XFREE(dCert, pkcs7->heap, DYNAMIC_TYPE_DCERT);
wolfSSL 15:117db924cf7c 335 #endif
wolfSSL 15:117db924cf7c 336 }
wolfSSL 15:117db924cf7c 337
wolfSSL 15:117db924cf7c 338 return ret;
wolfSSL 15:117db924cf7c 339 }
wolfSSL 15:117db924cf7c 340
wolfSSL 15:117db924cf7c 341
wolfSSL 15:117db924cf7c 342 /* free linked list of PKCS7DecodedAttrib structs */
wolfSSL 15:117db924cf7c 343 static void wc_PKCS7_FreeDecodedAttrib(PKCS7DecodedAttrib* attrib, void* heap)
wolfSSL 15:117db924cf7c 344 {
wolfSSL 15:117db924cf7c 345 PKCS7DecodedAttrib* current;
wolfSSL 15:117db924cf7c 346
wolfSSL 15:117db924cf7c 347 if (attrib == NULL) {
wolfSSL 15:117db924cf7c 348 return;
wolfSSL 15:117db924cf7c 349 }
wolfSSL 15:117db924cf7c 350
wolfSSL 15:117db924cf7c 351 current = attrib;
wolfSSL 15:117db924cf7c 352 while (current != NULL) {
wolfSSL 15:117db924cf7c 353 PKCS7DecodedAttrib* next = current->next;
wolfSSL 15:117db924cf7c 354 if (current->oid != NULL) {
wolfSSL 15:117db924cf7c 355 XFREE(current->oid, heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 356 }
wolfSSL 15:117db924cf7c 357 if (current->value != NULL) {
wolfSSL 15:117db924cf7c 358 XFREE(current->value, heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 359 }
wolfSSL 15:117db924cf7c 360 XFREE(current, heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 361 current = next;
wolfSSL 15:117db924cf7c 362 }
wolfSSL 15:117db924cf7c 363
wolfSSL 15:117db924cf7c 364 (void)heap;
wolfSSL 15:117db924cf7c 365 }
wolfSSL 15:117db924cf7c 366
wolfSSL 15:117db924cf7c 367
wolfSSL 15:117db924cf7c 368 /* releases any memory allocated by a PKCS7 initializer */
wolfSSL 15:117db924cf7c 369 void wc_PKCS7_Free(PKCS7* pkcs7)
wolfSSL 15:117db924cf7c 370 {
wolfSSL 15:117db924cf7c 371 if (pkcs7 == NULL)
wolfSSL 15:117db924cf7c 372 return;
wolfSSL 15:117db924cf7c 373
wolfSSL 15:117db924cf7c 374 wc_PKCS7_FreeDecodedAttrib(pkcs7->decodedAttrib, pkcs7->heap);
wolfSSL 15:117db924cf7c 375
wolfSSL 15:117db924cf7c 376 #ifdef ASN_BER_TO_DER
wolfSSL 15:117db924cf7c 377 if (pkcs7->der != NULL)
wolfSSL 15:117db924cf7c 378 XFREE(pkcs7->der, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 379 #endif
wolfSSL 15:117db924cf7c 380
wolfSSL 15:117db924cf7c 381 if (pkcs7->isDynamic) {
wolfSSL 15:117db924cf7c 382 pkcs7->isDynamic = 0;
wolfSSL 15:117db924cf7c 383 XFREE(pkcs7, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 384 }
wolfSSL 15:117db924cf7c 385 }
wolfSSL 15:117db924cf7c 386
wolfSSL 15:117db924cf7c 387
wolfSSL 15:117db924cf7c 388 /* helper function for parsing through attributes and finding a specific one.
wolfSSL 15:117db924cf7c 389 * returns PKCS7DecodedAttrib pointer on success */
wolfSSL 15:117db924cf7c 390 static PKCS7DecodedAttrib* findAttrib(PKCS7* pkcs7, const byte* oid, word32 oidSz)
wolfSSL 15:117db924cf7c 391 {
wolfSSL 15:117db924cf7c 392 PKCS7DecodedAttrib* list;
wolfSSL 15:117db924cf7c 393
wolfSSL 15:117db924cf7c 394 if (pkcs7 == NULL || oid == NULL) {
wolfSSL 15:117db924cf7c 395 return NULL;
wolfSSL 15:117db924cf7c 396 }
wolfSSL 15:117db924cf7c 397
wolfSSL 15:117db924cf7c 398 /* search attributes for pkiStatus */
wolfSSL 15:117db924cf7c 399 list = pkcs7->decodedAttrib;
wolfSSL 15:117db924cf7c 400 while (list != NULL) {
wolfSSL 15:117db924cf7c 401 word32 sz = oidSz;
wolfSSL 15:117db924cf7c 402 word32 idx = 0;
wolfSSL 15:117db924cf7c 403 int length = 0;
wolfSSL 15:117db924cf7c 404
wolfSSL 15:117db924cf7c 405 if (list->oid[idx++] != ASN_OBJECT_ID) {
wolfSSL 15:117db924cf7c 406 WOLFSSL_MSG("Bad attribute ASN1 syntax");
wolfSSL 15:117db924cf7c 407 return NULL;
wolfSSL 15:117db924cf7c 408 }
wolfSSL 15:117db924cf7c 409
wolfSSL 15:117db924cf7c 410 if (GetLength(list->oid, &idx, &length, list->oidSz) < 0) {
wolfSSL 15:117db924cf7c 411 WOLFSSL_MSG("Bad attribute length");
wolfSSL 15:117db924cf7c 412 return NULL;
wolfSSL 15:117db924cf7c 413 }
wolfSSL 15:117db924cf7c 414
wolfSSL 15:117db924cf7c 415 sz = (sz < (word32)length)? sz : (word32)length;
wolfSSL 15:117db924cf7c 416 if (XMEMCMP(oid, list->oid + idx, sz) == 0) {
wolfSSL 15:117db924cf7c 417 return list;
wolfSSL 15:117db924cf7c 418 }
wolfSSL 15:117db924cf7c 419 list = list->next;
wolfSSL 15:117db924cf7c 420 }
wolfSSL 15:117db924cf7c 421 return NULL;
wolfSSL 15:117db924cf7c 422 }
wolfSSL 15:117db924cf7c 423
wolfSSL 15:117db924cf7c 424
wolfSSL 15:117db924cf7c 425 /* Searches through decoded attributes and returns the value for the first one
wolfSSL 15:117db924cf7c 426 * matching the oid passed in. Note that this value includes the leading ASN1
wolfSSL 15:117db924cf7c 427 * syntax. So for a printable string of "3" this would be something like
wolfSSL 15:117db924cf7c 428 *
wolfSSL 15:117db924cf7c 429 * 0x13, 0x01, 0x33
wolfSSL 15:117db924cf7c 430 * ID SIZE "3"
wolfSSL 15:117db924cf7c 431 *
wolfSSL 15:117db924cf7c 432 * pkcs7 structure to get value from
wolfSSL 15:117db924cf7c 433 * oid OID value to search for with attributes
wolfSSL 15:117db924cf7c 434 * oidSz size of oid buffer
wolfSSL 15:117db924cf7c 435 * out buffer to hold result
wolfSSL 15:117db924cf7c 436 * outSz size of out buffer (if out is NULL this is set to needed size and
wolfSSL 15:117db924cf7c 437 LENGTH_ONLY_E is returned)
wolfSSL 15:117db924cf7c 438 *
wolfSSL 15:117db924cf7c 439 * returns size of value on success
wolfSSL 15:117db924cf7c 440 */
wolfSSL 15:117db924cf7c 441 int wc_PKCS7_GetAttributeValue(PKCS7* pkcs7, const byte* oid, word32 oidSz,
wolfSSL 15:117db924cf7c 442 byte* out, word32* outSz)
wolfSSL 15:117db924cf7c 443 {
wolfSSL 15:117db924cf7c 444 PKCS7DecodedAttrib* attrib;
wolfSSL 15:117db924cf7c 445
wolfSSL 15:117db924cf7c 446 if (pkcs7 == NULL || oid == NULL || outSz == NULL) {
wolfSSL 15:117db924cf7c 447 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 448 }
wolfSSL 15:117db924cf7c 449
wolfSSL 15:117db924cf7c 450 attrib = findAttrib(pkcs7, oid, oidSz);
wolfSSL 15:117db924cf7c 451 if (attrib == NULL) {
wolfSSL 15:117db924cf7c 452 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 453 }
wolfSSL 15:117db924cf7c 454
wolfSSL 15:117db924cf7c 455 if (out == NULL) {
wolfSSL 15:117db924cf7c 456 *outSz = attrib->valueSz;
wolfSSL 15:117db924cf7c 457 return LENGTH_ONLY_E;
wolfSSL 15:117db924cf7c 458 }
wolfSSL 15:117db924cf7c 459
wolfSSL 15:117db924cf7c 460 if (*outSz < attrib->valueSz) {
wolfSSL 15:117db924cf7c 461 return BUFFER_E;
wolfSSL 15:117db924cf7c 462 }
wolfSSL 15:117db924cf7c 463
wolfSSL 15:117db924cf7c 464 XMEMCPY(out, attrib->value, attrib->valueSz);
wolfSSL 15:117db924cf7c 465 return attrib->valueSz;
wolfSSL 15:117db924cf7c 466 }
wolfSSL 15:117db924cf7c 467
wolfSSL 15:117db924cf7c 468
wolfSSL 15:117db924cf7c 469 /* build PKCS#7 data content type */
wolfSSL 15:117db924cf7c 470 int wc_PKCS7_EncodeData(PKCS7* pkcs7, byte* output, word32 outputSz)
wolfSSL 15:117db924cf7c 471 {
wolfSSL 15:117db924cf7c 472 static const byte oid[] =
wolfSSL 15:117db924cf7c 473 { ASN_OBJECT_ID, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01,
wolfSSL 15:117db924cf7c 474 0x07, 0x01 };
wolfSSL 15:117db924cf7c 475 byte seq[MAX_SEQ_SZ];
wolfSSL 15:117db924cf7c 476 byte octetStr[MAX_OCTET_STR_SZ];
wolfSSL 15:117db924cf7c 477 word32 seqSz;
wolfSSL 15:117db924cf7c 478 word32 octetStrSz;
wolfSSL 15:117db924cf7c 479 word32 oidSz = (word32)sizeof(oid);
wolfSSL 15:117db924cf7c 480 int idx = 0;
wolfSSL 15:117db924cf7c 481
wolfSSL 15:117db924cf7c 482 if (pkcs7 == NULL || output == NULL) {
wolfSSL 15:117db924cf7c 483 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 484 }
wolfSSL 15:117db924cf7c 485
wolfSSL 15:117db924cf7c 486 octetStrSz = SetOctetString(pkcs7->contentSz, octetStr);
wolfSSL 15:117db924cf7c 487 seqSz = SetSequence(pkcs7->contentSz + octetStrSz + oidSz, seq);
wolfSSL 15:117db924cf7c 488
wolfSSL 15:117db924cf7c 489 if (outputSz < pkcs7->contentSz + octetStrSz + oidSz + seqSz)
wolfSSL 15:117db924cf7c 490 return BUFFER_E;
wolfSSL 15:117db924cf7c 491
wolfSSL 15:117db924cf7c 492 XMEMCPY(output, seq, seqSz);
wolfSSL 15:117db924cf7c 493 idx += seqSz;
wolfSSL 15:117db924cf7c 494 XMEMCPY(output + idx, oid, oidSz);
wolfSSL 15:117db924cf7c 495 idx += oidSz;
wolfSSL 15:117db924cf7c 496 XMEMCPY(output + idx, octetStr, octetStrSz);
wolfSSL 15:117db924cf7c 497 idx += octetStrSz;
wolfSSL 15:117db924cf7c 498 XMEMCPY(output + idx, pkcs7->content, pkcs7->contentSz);
wolfSSL 15:117db924cf7c 499 idx += pkcs7->contentSz;
wolfSSL 15:117db924cf7c 500
wolfSSL 15:117db924cf7c 501 return idx;
wolfSSL 15:117db924cf7c 502 }
wolfSSL 15:117db924cf7c 503
wolfSSL 15:117db924cf7c 504
wolfSSL 15:117db924cf7c 505 typedef struct EncodedAttrib {
wolfSSL 15:117db924cf7c 506 byte valueSeq[MAX_SEQ_SZ];
wolfSSL 15:117db924cf7c 507 const byte* oid;
wolfSSL 15:117db924cf7c 508 byte valueSet[MAX_SET_SZ];
wolfSSL 15:117db924cf7c 509 const byte* value;
wolfSSL 15:117db924cf7c 510 word32 valueSeqSz, oidSz, idSz, valueSetSz, valueSz, totalSz;
wolfSSL 15:117db924cf7c 511 } EncodedAttrib;
wolfSSL 15:117db924cf7c 512
wolfSSL 15:117db924cf7c 513
wolfSSL 15:117db924cf7c 514 typedef struct ESD {
wolfSSL 15:117db924cf7c 515 wc_HashAlg hash;
wolfSSL 15:117db924cf7c 516 enum wc_HashType hashType;
wolfSSL 15:117db924cf7c 517 byte contentDigest[WC_MAX_DIGEST_SIZE + 2]; /* content only + ASN.1 heading */
wolfSSL 15:117db924cf7c 518 byte contentAttribsDigest[WC_MAX_DIGEST_SIZE];
wolfSSL 15:117db924cf7c 519 byte encContentDigest[MAX_ENCRYPTED_KEY_SZ];
wolfSSL 15:117db924cf7c 520
wolfSSL 15:117db924cf7c 521 byte outerSeq[MAX_SEQ_SZ];
wolfSSL 15:117db924cf7c 522 byte outerContent[MAX_EXP_SZ];
wolfSSL 15:117db924cf7c 523 byte innerSeq[MAX_SEQ_SZ];
wolfSSL 15:117db924cf7c 524 byte version[MAX_VERSION_SZ];
wolfSSL 15:117db924cf7c 525 byte digAlgoIdSet[MAX_SET_SZ];
wolfSSL 15:117db924cf7c 526 byte singleDigAlgoId[MAX_ALGO_SZ];
wolfSSL 15:117db924cf7c 527
wolfSSL 15:117db924cf7c 528 byte contentInfoSeq[MAX_SEQ_SZ];
wolfSSL 15:117db924cf7c 529 byte innerContSeq[MAX_EXP_SZ];
wolfSSL 15:117db924cf7c 530 byte innerOctets[MAX_OCTET_STR_SZ];
wolfSSL 15:117db924cf7c 531
wolfSSL 15:117db924cf7c 532 byte certsSet[MAX_SET_SZ];
wolfSSL 15:117db924cf7c 533
wolfSSL 15:117db924cf7c 534 byte signerInfoSet[MAX_SET_SZ];
wolfSSL 15:117db924cf7c 535 byte signerInfoSeq[MAX_SEQ_SZ];
wolfSSL 15:117db924cf7c 536 byte signerVersion[MAX_VERSION_SZ];
wolfSSL 15:117db924cf7c 537 byte issuerSnSeq[MAX_SEQ_SZ];
wolfSSL 15:117db924cf7c 538 byte issuerName[MAX_SEQ_SZ];
wolfSSL 15:117db924cf7c 539 byte issuerSn[MAX_SN_SZ];
wolfSSL 15:117db924cf7c 540 byte signerDigAlgoId[MAX_ALGO_SZ];
wolfSSL 15:117db924cf7c 541 byte digEncAlgoId[MAX_ALGO_SZ];
wolfSSL 15:117db924cf7c 542 byte signedAttribSet[MAX_SET_SZ];
wolfSSL 15:117db924cf7c 543 EncodedAttrib signedAttribs[6];
wolfSSL 15:117db924cf7c 544 byte signerDigest[MAX_OCTET_STR_SZ];
wolfSSL 15:117db924cf7c 545 word32 innerOctetsSz, innerContSeqSz, contentInfoSeqSz;
wolfSSL 15:117db924cf7c 546 word32 outerSeqSz, outerContentSz, innerSeqSz, versionSz, digAlgoIdSetSz,
wolfSSL 15:117db924cf7c 547 singleDigAlgoIdSz, certsSetSz;
wolfSSL 15:117db924cf7c 548 word32 signerInfoSetSz, signerInfoSeqSz, signerVersionSz,
wolfSSL 15:117db924cf7c 549 issuerSnSeqSz, issuerNameSz, issuerSnSz,
wolfSSL 15:117db924cf7c 550 signerDigAlgoIdSz, digEncAlgoIdSz, signerDigestSz;
wolfSSL 15:117db924cf7c 551 word32 encContentDigestSz, signedAttribsSz, signedAttribsCount,
wolfSSL 15:117db924cf7c 552 signedAttribSetSz;
wolfSSL 15:117db924cf7c 553 } ESD;
wolfSSL 15:117db924cf7c 554
wolfSSL 15:117db924cf7c 555
wolfSSL 15:117db924cf7c 556 static int EncodeAttributes(EncodedAttrib* ea, int eaSz,
wolfSSL 15:117db924cf7c 557 PKCS7Attrib* attribs, int attribsSz)
wolfSSL 15:117db924cf7c 558 {
wolfSSL 15:117db924cf7c 559 int i;
wolfSSL 15:117db924cf7c 560 int maxSz = min(eaSz, attribsSz);
wolfSSL 15:117db924cf7c 561 int allAttribsSz = 0;
wolfSSL 15:117db924cf7c 562
wolfSSL 15:117db924cf7c 563 for (i = 0; i < maxSz; i++)
wolfSSL 15:117db924cf7c 564 {
wolfSSL 15:117db924cf7c 565 int attribSz = 0;
wolfSSL 15:117db924cf7c 566
wolfSSL 15:117db924cf7c 567 ea[i].value = attribs[i].value;
wolfSSL 15:117db924cf7c 568 ea[i].valueSz = attribs[i].valueSz;
wolfSSL 15:117db924cf7c 569 attribSz += ea[i].valueSz;
wolfSSL 15:117db924cf7c 570 ea[i].valueSetSz = SetSet(attribSz, ea[i].valueSet);
wolfSSL 15:117db924cf7c 571 attribSz += ea[i].valueSetSz;
wolfSSL 15:117db924cf7c 572 ea[i].oid = attribs[i].oid;
wolfSSL 15:117db924cf7c 573 ea[i].oidSz = attribs[i].oidSz;
wolfSSL 15:117db924cf7c 574 attribSz += ea[i].oidSz;
wolfSSL 15:117db924cf7c 575 ea[i].valueSeqSz = SetSequence(attribSz, ea[i].valueSeq);
wolfSSL 15:117db924cf7c 576 attribSz += ea[i].valueSeqSz;
wolfSSL 15:117db924cf7c 577 ea[i].totalSz = attribSz;
wolfSSL 15:117db924cf7c 578
wolfSSL 15:117db924cf7c 579 allAttribsSz += attribSz;
wolfSSL 15:117db924cf7c 580 }
wolfSSL 15:117db924cf7c 581 return allAttribsSz;
wolfSSL 15:117db924cf7c 582 }
wolfSSL 15:117db924cf7c 583
wolfSSL 15:117db924cf7c 584
wolfSSL 15:117db924cf7c 585 static int FlattenAttributes(byte* output, EncodedAttrib* ea, int eaSz)
wolfSSL 15:117db924cf7c 586 {
wolfSSL 15:117db924cf7c 587 int i, idx;
wolfSSL 15:117db924cf7c 588
wolfSSL 15:117db924cf7c 589 idx = 0;
wolfSSL 15:117db924cf7c 590 for (i = 0; i < eaSz; i++) {
wolfSSL 15:117db924cf7c 591 XMEMCPY(output + idx, ea[i].valueSeq, ea[i].valueSeqSz);
wolfSSL 15:117db924cf7c 592 idx += ea[i].valueSeqSz;
wolfSSL 15:117db924cf7c 593 XMEMCPY(output + idx, ea[i].oid, ea[i].oidSz);
wolfSSL 15:117db924cf7c 594 idx += ea[i].oidSz;
wolfSSL 15:117db924cf7c 595 XMEMCPY(output + idx, ea[i].valueSet, ea[i].valueSetSz);
wolfSSL 15:117db924cf7c 596 idx += ea[i].valueSetSz;
wolfSSL 15:117db924cf7c 597 XMEMCPY(output + idx, ea[i].value, ea[i].valueSz);
wolfSSL 15:117db924cf7c 598 idx += ea[i].valueSz;
wolfSSL 15:117db924cf7c 599 }
wolfSSL 15:117db924cf7c 600 return 0;
wolfSSL 15:117db924cf7c 601 }
wolfSSL 15:117db924cf7c 602
wolfSSL 15:117db924cf7c 603
wolfSSL 15:117db924cf7c 604 #ifndef NO_RSA
wolfSSL 15:117db924cf7c 605
wolfSSL 15:117db924cf7c 606 /* returns size of signature put into out, negative on error */
wolfSSL 15:117db924cf7c 607 static int wc_PKCS7_RsaSign(PKCS7* pkcs7, byte* in, word32 inSz, ESD* esd)
wolfSSL 15:117db924cf7c 608 {
wolfSSL 15:117db924cf7c 609 int ret;
wolfSSL 15:117db924cf7c 610 word32 idx;
wolfSSL 15:117db924cf7c 611 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 612 RsaKey* privKey;
wolfSSL 15:117db924cf7c 613 #else
wolfSSL 15:117db924cf7c 614 RsaKey stack_privKey;
wolfSSL 15:117db924cf7c 615 RsaKey* privKey = &stack_privKey;
wolfSSL 15:117db924cf7c 616 #endif
wolfSSL 15:117db924cf7c 617
wolfSSL 15:117db924cf7c 618 if (pkcs7 == NULL || pkcs7->rng == NULL || in == NULL || esd == NULL) {
wolfSSL 15:117db924cf7c 619 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 620 }
wolfSSL 15:117db924cf7c 621
wolfSSL 15:117db924cf7c 622 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 623 privKey = (RsaKey*)XMALLOC(sizeof(RsaKey), pkcs7->heap,
wolfSSL 15:117db924cf7c 624 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 625 if (privKey == NULL)
wolfSSL 15:117db924cf7c 626 return MEMORY_E;
wolfSSL 15:117db924cf7c 627 #endif
wolfSSL 15:117db924cf7c 628
wolfSSL 15:117db924cf7c 629 ret = wc_InitRsaKey_ex(privKey, pkcs7->heap, pkcs7->devId);
wolfSSL 15:117db924cf7c 630 if (ret == 0) {
wolfSSL 15:117db924cf7c 631 if (pkcs7->privateKey != NULL && pkcs7->privateKeySz > 0) {
wolfSSL 15:117db924cf7c 632 idx = 0;
wolfSSL 15:117db924cf7c 633 ret = wc_RsaPrivateKeyDecode(pkcs7->privateKey, &idx, privKey,
wolfSSL 15:117db924cf7c 634 pkcs7->privateKeySz);
wolfSSL 15:117db924cf7c 635 }
wolfSSL 15:117db924cf7c 636 else if (pkcs7->devId == INVALID_DEVID) {
wolfSSL 15:117db924cf7c 637 ret = BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 638 }
wolfSSL 15:117db924cf7c 639 }
wolfSSL 15:117db924cf7c 640 if (ret == 0) {
wolfSSL 15:117db924cf7c 641 ret = wc_RsaSSL_Sign(in, inSz, esd->encContentDigest,
wolfSSL 15:117db924cf7c 642 sizeof(esd->encContentDigest),
wolfSSL 15:117db924cf7c 643 privKey, pkcs7->rng);
wolfSSL 15:117db924cf7c 644 }
wolfSSL 15:117db924cf7c 645
wolfSSL 15:117db924cf7c 646 wc_FreeRsaKey(privKey);
wolfSSL 15:117db924cf7c 647 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 648 XFREE(privKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 649 #endif
wolfSSL 15:117db924cf7c 650
wolfSSL 15:117db924cf7c 651 return ret;
wolfSSL 15:117db924cf7c 652 }
wolfSSL 15:117db924cf7c 653
wolfSSL 15:117db924cf7c 654 #endif /* NO_RSA */
wolfSSL 15:117db924cf7c 655
wolfSSL 15:117db924cf7c 656
wolfSSL 15:117db924cf7c 657 #ifdef HAVE_ECC
wolfSSL 15:117db924cf7c 658
wolfSSL 15:117db924cf7c 659 /* returns size of signature put into out, negative on error */
wolfSSL 15:117db924cf7c 660 static int wc_PKCS7_EcdsaSign(PKCS7* pkcs7, byte* in, word32 inSz, ESD* esd)
wolfSSL 15:117db924cf7c 661 {
wolfSSL 15:117db924cf7c 662 int ret;
wolfSSL 15:117db924cf7c 663 word32 outSz, idx;
wolfSSL 15:117db924cf7c 664 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 665 ecc_key* privKey;
wolfSSL 15:117db924cf7c 666 #else
wolfSSL 15:117db924cf7c 667 ecc_key stack_privKey;
wolfSSL 15:117db924cf7c 668 ecc_key* privKey = &stack_privKey;
wolfSSL 15:117db924cf7c 669 #endif
wolfSSL 15:117db924cf7c 670
wolfSSL 15:117db924cf7c 671 if (pkcs7 == NULL || pkcs7->rng == NULL || in == NULL || esd == NULL) {
wolfSSL 15:117db924cf7c 672 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 673 }
wolfSSL 15:117db924cf7c 674
wolfSSL 15:117db924cf7c 675 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 676 privKey = (ecc_key*)XMALLOC(sizeof(ecc_key), pkcs7->heap,
wolfSSL 15:117db924cf7c 677 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 678 if (privKey == NULL)
wolfSSL 15:117db924cf7c 679 return MEMORY_E;
wolfSSL 15:117db924cf7c 680 #endif
wolfSSL 15:117db924cf7c 681
wolfSSL 15:117db924cf7c 682 ret = wc_ecc_init_ex(privKey, pkcs7->heap, pkcs7->devId);
wolfSSL 15:117db924cf7c 683 if (ret == 0) {
wolfSSL 15:117db924cf7c 684 if (pkcs7->privateKey != NULL && pkcs7->privateKeySz > 0) {
wolfSSL 15:117db924cf7c 685 idx = 0;
wolfSSL 15:117db924cf7c 686 ret = wc_EccPrivateKeyDecode(pkcs7->privateKey, &idx, privKey,
wolfSSL 15:117db924cf7c 687 pkcs7->privateKeySz);
wolfSSL 15:117db924cf7c 688 }
wolfSSL 15:117db924cf7c 689 else if (pkcs7->devId == INVALID_DEVID) {
wolfSSL 15:117db924cf7c 690 ret = BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 691 }
wolfSSL 15:117db924cf7c 692 }
wolfSSL 15:117db924cf7c 693 if (ret == 0) {
wolfSSL 15:117db924cf7c 694 outSz = sizeof(esd->encContentDigest);
wolfSSL 15:117db924cf7c 695 ret = wc_ecc_sign_hash(in, inSz, esd->encContentDigest,
wolfSSL 15:117db924cf7c 696 &outSz, pkcs7->rng, privKey);
wolfSSL 15:117db924cf7c 697 if (ret == 0)
wolfSSL 15:117db924cf7c 698 ret = (int)outSz;
wolfSSL 15:117db924cf7c 699 }
wolfSSL 15:117db924cf7c 700
wolfSSL 15:117db924cf7c 701 wc_ecc_free(privKey);
wolfSSL 15:117db924cf7c 702 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 703 XFREE(privKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 704 #endif
wolfSSL 15:117db924cf7c 705
wolfSSL 15:117db924cf7c 706 return ret;
wolfSSL 15:117db924cf7c 707 }
wolfSSL 15:117db924cf7c 708
wolfSSL 15:117db924cf7c 709 #endif /* HAVE_ECC */
wolfSSL 15:117db924cf7c 710
wolfSSL 15:117db924cf7c 711
wolfSSL 15:117db924cf7c 712 /* builds up SignedData signed attributes, including default ones.
wolfSSL 15:117db924cf7c 713 *
wolfSSL 15:117db924cf7c 714 * pkcs7 - pointer to initialized PKCS7 structure
wolfSSL 15:117db924cf7c 715 * esd - pointer to initialized ESD structure, used for output
wolfSSL 15:117db924cf7c 716 *
wolfSSL 15:117db924cf7c 717 * return 0 on success, negative on error */
wolfSSL 15:117db924cf7c 718 static int wc_PKCS7_BuildSignedAttributes(PKCS7* pkcs7, ESD* esd,
wolfSSL 15:117db924cf7c 719 byte* contentTypeOid, word32 contentTypeOidSz,
wolfSSL 15:117db924cf7c 720 byte* contentType, word32 contentTypeSz,
wolfSSL 15:117db924cf7c 721 byte* messageDigestOid, word32 messageDigestOidSz)
wolfSSL 15:117db924cf7c 722 {
wolfSSL 15:117db924cf7c 723 int hashSz;
wolfSSL 15:117db924cf7c 724
wolfSSL 15:117db924cf7c 725 PKCS7Attrib cannedAttribs[2];
wolfSSL 15:117db924cf7c 726 word32 cannedAttribsCount;
wolfSSL 15:117db924cf7c 727
wolfSSL 15:117db924cf7c 728 if (pkcs7 == NULL || esd == NULL || contentTypeOid == NULL ||
wolfSSL 15:117db924cf7c 729 contentType == NULL || messageDigestOid == NULL)
wolfSSL 15:117db924cf7c 730 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 731
wolfSSL 15:117db924cf7c 732 hashSz = wc_HashGetDigestSize(esd->hashType);
wolfSSL 15:117db924cf7c 733 if (hashSz < 0)
wolfSSL 15:117db924cf7c 734 return hashSz;
wolfSSL 15:117db924cf7c 735
wolfSSL 15:117db924cf7c 736 cannedAttribsCount = sizeof(cannedAttribs)/sizeof(PKCS7Attrib);
wolfSSL 15:117db924cf7c 737
wolfSSL 15:117db924cf7c 738 cannedAttribs[0].oid = contentTypeOid;
wolfSSL 15:117db924cf7c 739 cannedAttribs[0].oidSz = contentTypeOidSz;
wolfSSL 15:117db924cf7c 740 cannedAttribs[0].value = contentType;
wolfSSL 15:117db924cf7c 741 cannedAttribs[0].valueSz = contentTypeSz;
wolfSSL 15:117db924cf7c 742 cannedAttribs[1].oid = messageDigestOid;
wolfSSL 15:117db924cf7c 743 cannedAttribs[1].oidSz = messageDigestOidSz;
wolfSSL 15:117db924cf7c 744 cannedAttribs[1].value = esd->contentDigest;
wolfSSL 15:117db924cf7c 745 cannedAttribs[1].valueSz = hashSz + 2; /* ASN.1 heading */
wolfSSL 15:117db924cf7c 746
wolfSSL 15:117db924cf7c 747 esd->signedAttribsCount += cannedAttribsCount;
wolfSSL 15:117db924cf7c 748 esd->signedAttribsSz += EncodeAttributes(&esd->signedAttribs[0], 2,
wolfSSL 15:117db924cf7c 749 cannedAttribs, cannedAttribsCount);
wolfSSL 15:117db924cf7c 750
wolfSSL 15:117db924cf7c 751 esd->signedAttribsCount += pkcs7->signedAttribsSz;
wolfSSL 15:117db924cf7c 752 esd->signedAttribsSz += EncodeAttributes(&esd->signedAttribs[2], 4,
wolfSSL 15:117db924cf7c 753 pkcs7->signedAttribs, pkcs7->signedAttribsSz);
wolfSSL 15:117db924cf7c 754
wolfSSL 15:117db924cf7c 755 return 0;
wolfSSL 15:117db924cf7c 756 }
wolfSSL 15:117db924cf7c 757
wolfSSL 15:117db924cf7c 758
wolfSSL 15:117db924cf7c 759 /* gets correct encryption algo ID for SignedData, either CTC_<hash>wRSA or
wolfSSL 15:117db924cf7c 760 * CTC_<hash>wECDSA, from pkcs7->publicKeyOID and pkcs7->hashOID.
wolfSSL 15:117db924cf7c 761 *
wolfSSL 15:117db924cf7c 762 * pkcs7 - pointer to PKCS7 structure
wolfSSL 15:117db924cf7c 763 * digEncAlgoId - [OUT] output int to store correct algo ID in
wolfSSL 15:117db924cf7c 764 * digEncAlgoType - [OUT] output for algo ID type
wolfSSL 15:117db924cf7c 765 *
wolfSSL 15:117db924cf7c 766 * return 0 on success, negative on error */
wolfSSL 15:117db924cf7c 767 static int wc_PKCS7_SignedDataGetEncAlgoId(PKCS7* pkcs7, int* digEncAlgoId,
wolfSSL 15:117db924cf7c 768 int* digEncAlgoType)
wolfSSL 15:117db924cf7c 769 {
wolfSSL 15:117db924cf7c 770 int algoId = 0;
wolfSSL 15:117db924cf7c 771 int algoType = 0;
wolfSSL 15:117db924cf7c 772
wolfSSL 15:117db924cf7c 773 if (pkcs7 == NULL || digEncAlgoId == NULL || digEncAlgoType == NULL)
wolfSSL 15:117db924cf7c 774 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 775
wolfSSL 15:117db924cf7c 776 if (pkcs7->publicKeyOID == RSAk) {
wolfSSL 15:117db924cf7c 777
wolfSSL 15:117db924cf7c 778 algoType = oidSigType;
wolfSSL 15:117db924cf7c 779
wolfSSL 15:117db924cf7c 780 switch (pkcs7->hashOID) {
wolfSSL 15:117db924cf7c 781 #ifndef NO_SHA
wolfSSL 15:117db924cf7c 782 case SHAh:
wolfSSL 15:117db924cf7c 783 algoId = CTC_SHAwRSA;
wolfSSL 15:117db924cf7c 784 break;
wolfSSL 15:117db924cf7c 785 #endif
wolfSSL 15:117db924cf7c 786 #ifdef WOLFSSL_SHA224
wolfSSL 15:117db924cf7c 787 case SHA224h:
wolfSSL 15:117db924cf7c 788 algoId = CTC_SHA224wRSA;
wolfSSL 15:117db924cf7c 789 break;
wolfSSL 15:117db924cf7c 790 #endif
wolfSSL 15:117db924cf7c 791 #ifndef NO_SHA256
wolfSSL 15:117db924cf7c 792 case SHA256h:
wolfSSL 15:117db924cf7c 793 algoId = CTC_SHA256wRSA;
wolfSSL 15:117db924cf7c 794 break;
wolfSSL 15:117db924cf7c 795 #endif
wolfSSL 15:117db924cf7c 796 #ifdef WOLFSSL_SHA384
wolfSSL 15:117db924cf7c 797 case SHA384h:
wolfSSL 15:117db924cf7c 798 algoId = CTC_SHA384wRSA;
wolfSSL 15:117db924cf7c 799 break;
wolfSSL 15:117db924cf7c 800 #endif
wolfSSL 15:117db924cf7c 801 #ifdef WOLFSSL_SHA512
wolfSSL 15:117db924cf7c 802 case SHA512h:
wolfSSL 15:117db924cf7c 803 algoId = CTC_SHA512wRSA;
wolfSSL 15:117db924cf7c 804 break;
wolfSSL 15:117db924cf7c 805 #endif
wolfSSL 15:117db924cf7c 806 }
wolfSSL 15:117db924cf7c 807
wolfSSL 15:117db924cf7c 808 }
wolfSSL 15:117db924cf7c 809 #ifdef HAVE_ECC
wolfSSL 15:117db924cf7c 810 else if (pkcs7->publicKeyOID == ECDSAk) {
wolfSSL 15:117db924cf7c 811
wolfSSL 15:117db924cf7c 812 algoType = oidSigType;
wolfSSL 15:117db924cf7c 813
wolfSSL 15:117db924cf7c 814 switch (pkcs7->hashOID) {
wolfSSL 15:117db924cf7c 815 #ifndef NO_SHA
wolfSSL 15:117db924cf7c 816 case SHAh:
wolfSSL 15:117db924cf7c 817 algoId = CTC_SHAwECDSA;
wolfSSL 15:117db924cf7c 818 break;
wolfSSL 15:117db924cf7c 819 #endif
wolfSSL 15:117db924cf7c 820 #ifdef WOLFSSL_SHA224
wolfSSL 15:117db924cf7c 821 case SHA224h:
wolfSSL 15:117db924cf7c 822 algoId = CTC_SHA224wECDSA;
wolfSSL 15:117db924cf7c 823 break;
wolfSSL 15:117db924cf7c 824 #endif
wolfSSL 15:117db924cf7c 825 #ifndef NO_SHA256
wolfSSL 15:117db924cf7c 826 case SHA256h:
wolfSSL 15:117db924cf7c 827 algoId = CTC_SHA256wECDSA;
wolfSSL 15:117db924cf7c 828 break;
wolfSSL 15:117db924cf7c 829 #endif
wolfSSL 15:117db924cf7c 830 #ifdef WOLFSSL_SHA384
wolfSSL 15:117db924cf7c 831 case SHA384h:
wolfSSL 15:117db924cf7c 832 algoId = CTC_SHA384wECDSA;
wolfSSL 15:117db924cf7c 833 break;
wolfSSL 15:117db924cf7c 834 #endif
wolfSSL 15:117db924cf7c 835 #ifdef WOLFSSL_SHA512
wolfSSL 15:117db924cf7c 836 case SHA512h:
wolfSSL 15:117db924cf7c 837 algoId = CTC_SHA512wECDSA;
wolfSSL 15:117db924cf7c 838 break;
wolfSSL 15:117db924cf7c 839 #endif
wolfSSL 15:117db924cf7c 840 }
wolfSSL 15:117db924cf7c 841 }
wolfSSL 15:117db924cf7c 842 #endif /* HAVE_ECC */
wolfSSL 15:117db924cf7c 843
wolfSSL 15:117db924cf7c 844 if (algoId == 0) {
wolfSSL 15:117db924cf7c 845 WOLFSSL_MSG("Invalid signature algorithm type");
wolfSSL 15:117db924cf7c 846 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 847 }
wolfSSL 15:117db924cf7c 848
wolfSSL 15:117db924cf7c 849 *digEncAlgoId = algoId;
wolfSSL 15:117db924cf7c 850 *digEncAlgoType = algoType;
wolfSSL 15:117db924cf7c 851
wolfSSL 15:117db924cf7c 852 return 0;
wolfSSL 15:117db924cf7c 853 }
wolfSSL 15:117db924cf7c 854
wolfSSL 15:117db924cf7c 855
wolfSSL 15:117db924cf7c 856 /* build SignedData DigestInfo for use with PKCS#7/RSA
wolfSSL 15:117db924cf7c 857 *
wolfSSL 15:117db924cf7c 858 * pkcs7 - pointer to initialized PKCS7 struct
wolfSSL 15:117db924cf7c 859 * flatSignedAttribs - flattened, signed attributes
wolfSSL 15:117db924cf7c 860 * flatSignedAttrbsSz - size of flatSignedAttribs, octets
wolfSSL 15:117db924cf7c 861 * esd - pointer to initialized ESD struct
wolfSSL 15:117db924cf7c 862 * digestInfo - [OUT] output array for DigestInfo
wolfSSL 15:117db924cf7c 863 * digestInfoSz - [IN/OUT] - input size of array, size of digestInfo
wolfSSL 15:117db924cf7c 864 *
wolfSSL 15:117db924cf7c 865 * return 0 on success, negative on error */
wolfSSL 15:117db924cf7c 866 static int wc_PKCS7_BuildDigestInfo(PKCS7* pkcs7, byte* flatSignedAttribs,
wolfSSL 15:117db924cf7c 867 word32 flatSignedAttribsSz, ESD* esd,
wolfSSL 15:117db924cf7c 868 byte* digestInfo, word32* digestInfoSz)
wolfSSL 15:117db924cf7c 869 {
wolfSSL 15:117db924cf7c 870 int ret, hashSz, digIdx = 0;
wolfSSL 15:117db924cf7c 871 byte digestInfoSeq[MAX_SEQ_SZ];
wolfSSL 15:117db924cf7c 872 byte digestStr[MAX_OCTET_STR_SZ];
wolfSSL 15:117db924cf7c 873 byte attribSet[MAX_SET_SZ];
wolfSSL 15:117db924cf7c 874 byte algoId[MAX_ALGO_SZ];
wolfSSL 15:117db924cf7c 875 word32 digestInfoSeqSz, digestStrSz, algoIdSz;
wolfSSL 15:117db924cf7c 876 word32 attribSetSz;
wolfSSL 15:117db924cf7c 877
wolfSSL 15:117db924cf7c 878 if (pkcs7 == NULL || esd == NULL || digestInfo == NULL ||
wolfSSL 15:117db924cf7c 879 digestInfoSz == NULL) {
wolfSSL 15:117db924cf7c 880 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 881 }
wolfSSL 15:117db924cf7c 882
wolfSSL 15:117db924cf7c 883 hashSz = wc_HashGetDigestSize(esd->hashType);
wolfSSL 15:117db924cf7c 884 if (hashSz < 0)
wolfSSL 15:117db924cf7c 885 return hashSz;
wolfSSL 15:117db924cf7c 886
wolfSSL 15:117db924cf7c 887 if (pkcs7->signedAttribsSz != 0) {
wolfSSL 15:117db924cf7c 888
wolfSSL 15:117db924cf7c 889 if (flatSignedAttribs == NULL)
wolfSSL 15:117db924cf7c 890 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 891
wolfSSL 15:117db924cf7c 892 attribSetSz = SetSet(flatSignedAttribsSz, attribSet);
wolfSSL 15:117db924cf7c 893
wolfSSL 15:117db924cf7c 894 ret = wc_HashInit(&esd->hash, esd->hashType);
wolfSSL 15:117db924cf7c 895 if (ret < 0)
wolfSSL 15:117db924cf7c 896 return ret;
wolfSSL 15:117db924cf7c 897
wolfSSL 15:117db924cf7c 898 ret = wc_HashUpdate(&esd->hash, esd->hashType,
wolfSSL 15:117db924cf7c 899 attribSet, attribSetSz);
wolfSSL 15:117db924cf7c 900 if (ret < 0)
wolfSSL 15:117db924cf7c 901 return ret;
wolfSSL 15:117db924cf7c 902
wolfSSL 15:117db924cf7c 903 ret = wc_HashUpdate(&esd->hash, esd->hashType,
wolfSSL 15:117db924cf7c 904 flatSignedAttribs, flatSignedAttribsSz);
wolfSSL 15:117db924cf7c 905 if (ret < 0)
wolfSSL 15:117db924cf7c 906 return ret;
wolfSSL 15:117db924cf7c 907
wolfSSL 15:117db924cf7c 908 ret = wc_HashFinal(&esd->hash, esd->hashType,
wolfSSL 15:117db924cf7c 909 esd->contentAttribsDigest);
wolfSSL 15:117db924cf7c 910 if (ret < 0)
wolfSSL 15:117db924cf7c 911 return ret;
wolfSSL 15:117db924cf7c 912
wolfSSL 15:117db924cf7c 913 } else {
wolfSSL 15:117db924cf7c 914 /* when no attrs, digest is contentDigest without tag and length */
wolfSSL 15:117db924cf7c 915 XMEMCPY(esd->contentAttribsDigest, esd->contentDigest + 2, hashSz);
wolfSSL 15:117db924cf7c 916 }
wolfSSL 15:117db924cf7c 917
wolfSSL 15:117db924cf7c 918 /* set algoID, with NULL attributes */
wolfSSL 15:117db924cf7c 919 algoIdSz = SetAlgoID(pkcs7->hashOID, algoId, oidHashType, 0);
wolfSSL 15:117db924cf7c 920
wolfSSL 15:117db924cf7c 921 digestStrSz = SetOctetString(hashSz, digestStr);
wolfSSL 15:117db924cf7c 922 digestInfoSeqSz = SetSequence(algoIdSz + digestStrSz + hashSz,
wolfSSL 15:117db924cf7c 923 digestInfoSeq);
wolfSSL 15:117db924cf7c 924
wolfSSL 15:117db924cf7c 925 if (*digestInfoSz < (digestInfoSeqSz + algoIdSz + digestStrSz + hashSz)) {
wolfSSL 15:117db924cf7c 926 return BUFFER_E;
wolfSSL 15:117db924cf7c 927 }
wolfSSL 15:117db924cf7c 928
wolfSSL 15:117db924cf7c 929 XMEMCPY(digestInfo + digIdx, digestInfoSeq, digestInfoSeqSz);
wolfSSL 15:117db924cf7c 930 digIdx += digestInfoSeqSz;
wolfSSL 15:117db924cf7c 931 XMEMCPY(digestInfo + digIdx, algoId, algoIdSz);
wolfSSL 15:117db924cf7c 932 digIdx += algoIdSz;
wolfSSL 15:117db924cf7c 933 XMEMCPY(digestInfo + digIdx, digestStr, digestStrSz);
wolfSSL 15:117db924cf7c 934 digIdx += digestStrSz;
wolfSSL 15:117db924cf7c 935 XMEMCPY(digestInfo + digIdx, esd->contentAttribsDigest, hashSz);
wolfSSL 15:117db924cf7c 936 digIdx += hashSz;
wolfSSL 15:117db924cf7c 937
wolfSSL 15:117db924cf7c 938 *digestInfoSz = digIdx;
wolfSSL 15:117db924cf7c 939
wolfSSL 15:117db924cf7c 940 return 0;
wolfSSL 15:117db924cf7c 941 }
wolfSSL 15:117db924cf7c 942
wolfSSL 15:117db924cf7c 943
wolfSSL 15:117db924cf7c 944 /* build SignedData signature over DigestInfo or content digest
wolfSSL 15:117db924cf7c 945 *
wolfSSL 15:117db924cf7c 946 * pkcs7 - pointer to initizlied PKCS7 struct
wolfSSL 15:117db924cf7c 947 * flatSignedAttribs - flattened, signed attributes
wolfSSL 15:117db924cf7c 948 * flatSignedAttribsSz - size of flatSignedAttribs, octets
wolfSSL 15:117db924cf7c 949 * esd - pointer to initialized ESD struct
wolfSSL 15:117db924cf7c 950 *
wolfSSL 15:117db924cf7c 951 * returns length of signature on success, negative on error */
wolfSSL 15:117db924cf7c 952 static int wc_PKCS7_SignedDataBuildSignature(PKCS7* pkcs7,
wolfSSL 15:117db924cf7c 953 byte* flatSignedAttribs,
wolfSSL 15:117db924cf7c 954 word32 flatSignedAttribsSz,
wolfSSL 15:117db924cf7c 955 ESD* esd)
wolfSSL 15:117db924cf7c 956 {
wolfSSL 15:117db924cf7c 957 int ret;
wolfSSL 15:117db924cf7c 958 #ifdef HAVE_ECC
wolfSSL 15:117db924cf7c 959 int hashSz;
wolfSSL 15:117db924cf7c 960 #endif
wolfSSL 15:117db924cf7c 961 word32 digestInfoSz = MAX_PKCS7_DIGEST_SZ;
wolfSSL 15:117db924cf7c 962 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 963 byte* digestInfo;
wolfSSL 15:117db924cf7c 964 #else
wolfSSL 15:117db924cf7c 965 byte digestInfo[MAX_PKCS7_DIGEST_SZ];
wolfSSL 15:117db924cf7c 966 #endif
wolfSSL 15:117db924cf7c 967
wolfSSL 15:117db924cf7c 968 if (pkcs7 == NULL || esd == NULL)
wolfSSL 15:117db924cf7c 969 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 970
wolfSSL 15:117db924cf7c 971 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 972 digestInfo = (byte*)XMALLOC(digestInfoSz, pkcs7->heap,
wolfSSL 15:117db924cf7c 973 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 974 if (digestInfo == NULL) {
wolfSSL 15:117db924cf7c 975 return MEMORY_E;
wolfSSL 15:117db924cf7c 976 }
wolfSSL 15:117db924cf7c 977 #endif
wolfSSL 15:117db924cf7c 978
wolfSSL 15:117db924cf7c 979 ret = wc_PKCS7_BuildDigestInfo(pkcs7, flatSignedAttribs,
wolfSSL 15:117db924cf7c 980 flatSignedAttribsSz, esd, digestInfo,
wolfSSL 15:117db924cf7c 981 &digestInfoSz);
wolfSSL 15:117db924cf7c 982 if (ret < 0) {
wolfSSL 15:117db924cf7c 983 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 984 XFREE(digestInfo, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 985 #endif
wolfSSL 15:117db924cf7c 986 return ret;
wolfSSL 15:117db924cf7c 987 }
wolfSSL 15:117db924cf7c 988
wolfSSL 15:117db924cf7c 989 /* sign digestInfo */
wolfSSL 15:117db924cf7c 990 switch (pkcs7->publicKeyOID) {
wolfSSL 15:117db924cf7c 991
wolfSSL 15:117db924cf7c 992 #ifndef NO_RSA
wolfSSL 15:117db924cf7c 993 case RSAk:
wolfSSL 15:117db924cf7c 994 ret = wc_PKCS7_RsaSign(pkcs7, digestInfo, digestInfoSz, esd);
wolfSSL 15:117db924cf7c 995 break;
wolfSSL 15:117db924cf7c 996 #endif
wolfSSL 15:117db924cf7c 997
wolfSSL 15:117db924cf7c 998 #ifdef HAVE_ECC
wolfSSL 15:117db924cf7c 999 case ECDSAk:
wolfSSL 15:117db924cf7c 1000 /* CMS with ECDSA does not sign DigestInfo structure
wolfSSL 15:117db924cf7c 1001 * like PKCS#7 with RSA does */
wolfSSL 15:117db924cf7c 1002 hashSz = wc_HashGetDigestSize(esd->hashType);
wolfSSL 15:117db924cf7c 1003 if (hashSz < 0) {
wolfSSL 15:117db924cf7c 1004 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 1005 XFREE(digestInfo, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1006 #endif
wolfSSL 15:117db924cf7c 1007 return hashSz;
wolfSSL 15:117db924cf7c 1008 }
wolfSSL 15:117db924cf7c 1009
wolfSSL 15:117db924cf7c 1010 ret = wc_PKCS7_EcdsaSign(pkcs7, esd->contentAttribsDigest,
wolfSSL 15:117db924cf7c 1011 hashSz, esd);
wolfSSL 15:117db924cf7c 1012 break;
wolfSSL 15:117db924cf7c 1013 #endif
wolfSSL 15:117db924cf7c 1014
wolfSSL 15:117db924cf7c 1015 default:
wolfSSL 15:117db924cf7c 1016 WOLFSSL_MSG("Unsupported public key type");
wolfSSL 15:117db924cf7c 1017 ret = BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 1018 }
wolfSSL 15:117db924cf7c 1019
wolfSSL 15:117db924cf7c 1020 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 1021 XFREE(digestInfo, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1022 #endif
wolfSSL 15:117db924cf7c 1023
wolfSSL 15:117db924cf7c 1024 if (ret >= 0) {
wolfSSL 15:117db924cf7c 1025 esd->encContentDigestSz = (word32)ret;
wolfSSL 15:117db924cf7c 1026 }
wolfSSL 15:117db924cf7c 1027
wolfSSL 15:117db924cf7c 1028 return ret;
wolfSSL 15:117db924cf7c 1029 }
wolfSSL 15:117db924cf7c 1030
wolfSSL 15:117db924cf7c 1031 /* build PKCS#7 signedData content type */
wolfSSL 15:117db924cf7c 1032 int wc_PKCS7_EncodeSignedData(PKCS7* pkcs7, byte* output, word32 outputSz)
wolfSSL 15:117db924cf7c 1033 {
wolfSSL 15:117db924cf7c 1034 static const byte outerOid[] =
wolfSSL 15:117db924cf7c 1035 { ASN_OBJECT_ID, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01,
wolfSSL 15:117db924cf7c 1036 0x07, 0x02 };
wolfSSL 15:117db924cf7c 1037 static const byte innerOid[] =
wolfSSL 15:117db924cf7c 1038 { ASN_OBJECT_ID, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01,
wolfSSL 15:117db924cf7c 1039 0x07, 0x01 };
wolfSSL 15:117db924cf7c 1040
wolfSSL 15:117db924cf7c 1041 byte contentTypeOid[] =
wolfSSL 15:117db924cf7c 1042 { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xF7, 0x0d, 0x01,
wolfSSL 15:117db924cf7c 1043 0x09, 0x03 };
wolfSSL 15:117db924cf7c 1044 byte contentType[] =
wolfSSL 15:117db924cf7c 1045 { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
wolfSSL 15:117db924cf7c 1046 0x07, 0x01 };
wolfSSL 15:117db924cf7c 1047 byte messageDigestOid[] =
wolfSSL 15:117db924cf7c 1048 { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
wolfSSL 15:117db924cf7c 1049 0x09, 0x04 };
wolfSSL 15:117db924cf7c 1050
wolfSSL 15:117db924cf7c 1051 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 1052 ESD* esd = NULL;
wolfSSL 15:117db924cf7c 1053 #else
wolfSSL 15:117db924cf7c 1054 ESD stack_esd;
wolfSSL 15:117db924cf7c 1055 ESD* esd = &stack_esd;
wolfSSL 15:117db924cf7c 1056 #endif
wolfSSL 15:117db924cf7c 1057
wolfSSL 15:117db924cf7c 1058 word32 signerInfoSz = 0;
wolfSSL 15:117db924cf7c 1059 word32 totalSz = 0;
wolfSSL 15:117db924cf7c 1060 int idx = 0, ret = 0;
wolfSSL 15:117db924cf7c 1061 int digEncAlgoId, digEncAlgoType, hashSz;
wolfSSL 15:117db924cf7c 1062 byte* flatSignedAttribs = NULL;
wolfSSL 15:117db924cf7c 1063 word32 flatSignedAttribsSz = 0;
wolfSSL 15:117db924cf7c 1064 word32 innerOidSz = sizeof(innerOid);
wolfSSL 15:117db924cf7c 1065 word32 outerOidSz = sizeof(outerOid);
wolfSSL 15:117db924cf7c 1066
wolfSSL 15:117db924cf7c 1067 if (pkcs7 == NULL || pkcs7->content == NULL || pkcs7->contentSz == 0 ||
wolfSSL 15:117db924cf7c 1068 pkcs7->encryptOID == 0 || pkcs7->hashOID == 0 || pkcs7->rng == 0 ||
wolfSSL 15:117db924cf7c 1069 pkcs7->singleCert == NULL || pkcs7->singleCertSz == 0 ||
wolfSSL 15:117db924cf7c 1070 output == NULL || outputSz == 0) {
wolfSSL 15:117db924cf7c 1071 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 1072 }
wolfSSL 15:117db924cf7c 1073
wolfSSL 15:117db924cf7c 1074 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 1075 esd = (ESD*)XMALLOC(sizeof(ESD), pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1076 if (esd == NULL)
wolfSSL 15:117db924cf7c 1077 return MEMORY_E;
wolfSSL 15:117db924cf7c 1078 #endif
wolfSSL 15:117db924cf7c 1079
wolfSSL 15:117db924cf7c 1080 XMEMSET(esd, 0, sizeof(ESD));
wolfSSL 15:117db924cf7c 1081
wolfSSL 15:117db924cf7c 1082 esd->hashType = wc_OidGetHash(pkcs7->hashOID);
wolfSSL 15:117db924cf7c 1083 ret = wc_HashGetDigestSize(esd->hashType);
wolfSSL 15:117db924cf7c 1084 if (ret < 0) {
wolfSSL 15:117db924cf7c 1085 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 1086 XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1087 #endif
wolfSSL 15:117db924cf7c 1088 return ret;
wolfSSL 15:117db924cf7c 1089 }
wolfSSL 15:117db924cf7c 1090 hashSz = ret;
wolfSSL 15:117db924cf7c 1091
wolfSSL 15:117db924cf7c 1092 ret = wc_HashInit(&esd->hash, esd->hashType);
wolfSSL 15:117db924cf7c 1093 if (ret != 0) {
wolfSSL 15:117db924cf7c 1094 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 1095 XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1096 #endif
wolfSSL 15:117db924cf7c 1097 return ret;
wolfSSL 15:117db924cf7c 1098 }
wolfSSL 15:117db924cf7c 1099
wolfSSL 15:117db924cf7c 1100 if (pkcs7->contentSz != 0)
wolfSSL 15:117db924cf7c 1101 {
wolfSSL 15:117db924cf7c 1102 ret = wc_HashUpdate(&esd->hash, esd->hashType,
wolfSSL 15:117db924cf7c 1103 pkcs7->content, pkcs7->contentSz);
wolfSSL 15:117db924cf7c 1104 if (ret < 0) {
wolfSSL 15:117db924cf7c 1105 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 1106 XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1107 #endif
wolfSSL 15:117db924cf7c 1108 return ret;
wolfSSL 15:117db924cf7c 1109 }
wolfSSL 15:117db924cf7c 1110 esd->contentDigest[0] = ASN_OCTET_STRING;
wolfSSL 15:117db924cf7c 1111 esd->contentDigest[1] = (byte)hashSz;
wolfSSL 15:117db924cf7c 1112 ret = wc_HashFinal(&esd->hash, esd->hashType,
wolfSSL 15:117db924cf7c 1113 &esd->contentDigest[2]);
wolfSSL 15:117db924cf7c 1114 if (ret < 0) {
wolfSSL 15:117db924cf7c 1115 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 1116 XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1117 #endif
wolfSSL 15:117db924cf7c 1118 return ret;
wolfSSL 15:117db924cf7c 1119 }
wolfSSL 15:117db924cf7c 1120 }
wolfSSL 15:117db924cf7c 1121
wolfSSL 15:117db924cf7c 1122 esd->innerOctetsSz = SetOctetString(pkcs7->contentSz, esd->innerOctets);
wolfSSL 15:117db924cf7c 1123 esd->innerContSeqSz = SetExplicit(0, esd->innerOctetsSz + pkcs7->contentSz,
wolfSSL 15:117db924cf7c 1124 esd->innerContSeq);
wolfSSL 15:117db924cf7c 1125 esd->contentInfoSeqSz = SetSequence(pkcs7->contentSz + esd->innerOctetsSz +
wolfSSL 15:117db924cf7c 1126 innerOidSz + esd->innerContSeqSz,
wolfSSL 15:117db924cf7c 1127 esd->contentInfoSeq);
wolfSSL 15:117db924cf7c 1128
wolfSSL 15:117db924cf7c 1129 esd->issuerSnSz = SetSerialNumber(pkcs7->issuerSn, pkcs7->issuerSnSz,
wolfSSL 15:117db924cf7c 1130 esd->issuerSn, MAX_SN_SZ);
wolfSSL 15:117db924cf7c 1131 signerInfoSz += esd->issuerSnSz;
wolfSSL 15:117db924cf7c 1132 esd->issuerNameSz = SetSequence(pkcs7->issuerSz, esd->issuerName);
wolfSSL 15:117db924cf7c 1133 signerInfoSz += esd->issuerNameSz + pkcs7->issuerSz;
wolfSSL 15:117db924cf7c 1134 esd->issuerSnSeqSz = SetSequence(signerInfoSz, esd->issuerSnSeq);
wolfSSL 15:117db924cf7c 1135 signerInfoSz += esd->issuerSnSeqSz;
wolfSSL 15:117db924cf7c 1136 esd->signerVersionSz = SetMyVersion(1, esd->signerVersion, 0);
wolfSSL 15:117db924cf7c 1137 signerInfoSz += esd->signerVersionSz;
wolfSSL 15:117db924cf7c 1138 esd->signerDigAlgoIdSz = SetAlgoID(pkcs7->hashOID, esd->signerDigAlgoId,
wolfSSL 15:117db924cf7c 1139 oidHashType, 0);
wolfSSL 15:117db924cf7c 1140 signerInfoSz += esd->signerDigAlgoIdSz;
wolfSSL 15:117db924cf7c 1141
wolfSSL 15:117db924cf7c 1142 /* set signatureAlgorithm */
wolfSSL 15:117db924cf7c 1143 ret = wc_PKCS7_SignedDataGetEncAlgoId(pkcs7, &digEncAlgoId,
wolfSSL 15:117db924cf7c 1144 &digEncAlgoType);
wolfSSL 15:117db924cf7c 1145 if (ret < 0) {
wolfSSL 15:117db924cf7c 1146 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 1147 XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1148 #endif
wolfSSL 15:117db924cf7c 1149 return ret;
wolfSSL 15:117db924cf7c 1150 }
wolfSSL 15:117db924cf7c 1151 esd->digEncAlgoIdSz = SetAlgoID(digEncAlgoId, esd->digEncAlgoId,
wolfSSL 15:117db924cf7c 1152 digEncAlgoType, 0);
wolfSSL 15:117db924cf7c 1153 signerInfoSz += esd->digEncAlgoIdSz;
wolfSSL 15:117db924cf7c 1154
wolfSSL 15:117db924cf7c 1155 if (pkcs7->signedAttribsSz != 0) {
wolfSSL 15:117db924cf7c 1156
wolfSSL 15:117db924cf7c 1157 /* build up signed attributes */
wolfSSL 15:117db924cf7c 1158 ret = wc_PKCS7_BuildSignedAttributes(pkcs7, esd,
wolfSSL 15:117db924cf7c 1159 contentTypeOid, sizeof(contentTypeOid),
wolfSSL 15:117db924cf7c 1160 contentType, sizeof(contentType),
wolfSSL 15:117db924cf7c 1161 messageDigestOid, sizeof(messageDigestOid));
wolfSSL 15:117db924cf7c 1162 if (ret < 0) {
wolfSSL 15:117db924cf7c 1163 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 1164 XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1165 #endif
wolfSSL 15:117db924cf7c 1166 return MEMORY_E;
wolfSSL 15:117db924cf7c 1167 }
wolfSSL 15:117db924cf7c 1168
wolfSSL 15:117db924cf7c 1169 flatSignedAttribs = (byte*)XMALLOC(esd->signedAttribsSz, pkcs7->heap,
wolfSSL 15:117db924cf7c 1170 DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 1171 flatSignedAttribsSz = esd->signedAttribsSz;
wolfSSL 15:117db924cf7c 1172 if (flatSignedAttribs == NULL) {
wolfSSL 15:117db924cf7c 1173 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 1174 XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1175 #endif
wolfSSL 15:117db924cf7c 1176 return MEMORY_E;
wolfSSL 15:117db924cf7c 1177 }
wolfSSL 15:117db924cf7c 1178
wolfSSL 15:117db924cf7c 1179 FlattenAttributes(flatSignedAttribs,
wolfSSL 15:117db924cf7c 1180 esd->signedAttribs, esd->signedAttribsCount);
wolfSSL 15:117db924cf7c 1181 esd->signedAttribSetSz = SetImplicit(ASN_SET, 0, esd->signedAttribsSz,
wolfSSL 15:117db924cf7c 1182 esd->signedAttribSet);
wolfSSL 15:117db924cf7c 1183 }
wolfSSL 15:117db924cf7c 1184
wolfSSL 15:117db924cf7c 1185 /* Calculate the final hash and encrypt it. */
wolfSSL 15:117db924cf7c 1186 ret = wc_PKCS7_SignedDataBuildSignature(pkcs7, flatSignedAttribs,
wolfSSL 15:117db924cf7c 1187 flatSignedAttribsSz, esd);
wolfSSL 15:117db924cf7c 1188 if (ret < 0) {
wolfSSL 15:117db924cf7c 1189 if (pkcs7->signedAttribsSz != 0)
wolfSSL 15:117db924cf7c 1190 XFREE(flatSignedAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 1191 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 1192 XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1193 #endif
wolfSSL 15:117db924cf7c 1194 return ret;
wolfSSL 15:117db924cf7c 1195 }
wolfSSL 15:117db924cf7c 1196
wolfSSL 15:117db924cf7c 1197 signerInfoSz += flatSignedAttribsSz + esd->signedAttribSetSz;
wolfSSL 15:117db924cf7c 1198
wolfSSL 15:117db924cf7c 1199 esd->signerDigestSz = SetOctetString(esd->encContentDigestSz,
wolfSSL 15:117db924cf7c 1200 esd->signerDigest);
wolfSSL 15:117db924cf7c 1201 signerInfoSz += esd->signerDigestSz + esd->encContentDigestSz;
wolfSSL 15:117db924cf7c 1202
wolfSSL 15:117db924cf7c 1203 esd->signerInfoSeqSz = SetSequence(signerInfoSz, esd->signerInfoSeq);
wolfSSL 15:117db924cf7c 1204 signerInfoSz += esd->signerInfoSeqSz;
wolfSSL 15:117db924cf7c 1205 esd->signerInfoSetSz = SetSet(signerInfoSz, esd->signerInfoSet);
wolfSSL 15:117db924cf7c 1206 signerInfoSz += esd->signerInfoSetSz;
wolfSSL 15:117db924cf7c 1207
wolfSSL 15:117db924cf7c 1208 esd->certsSetSz = SetImplicit(ASN_SET, 0, pkcs7->singleCertSz,
wolfSSL 15:117db924cf7c 1209 esd->certsSet);
wolfSSL 15:117db924cf7c 1210
wolfSSL 15:117db924cf7c 1211 esd->singleDigAlgoIdSz = SetAlgoID(pkcs7->hashOID, esd->singleDigAlgoId,
wolfSSL 15:117db924cf7c 1212 oidHashType, 0);
wolfSSL 15:117db924cf7c 1213 esd->digAlgoIdSetSz = SetSet(esd->singleDigAlgoIdSz, esd->digAlgoIdSet);
wolfSSL 15:117db924cf7c 1214
wolfSSL 15:117db924cf7c 1215
wolfSSL 15:117db924cf7c 1216 esd->versionSz = SetMyVersion(1, esd->version, 0);
wolfSSL 15:117db924cf7c 1217
wolfSSL 15:117db924cf7c 1218 totalSz = esd->versionSz + esd->singleDigAlgoIdSz + esd->digAlgoIdSetSz +
wolfSSL 15:117db924cf7c 1219 esd->contentInfoSeqSz + esd->certsSetSz + pkcs7->singleCertSz +
wolfSSL 15:117db924cf7c 1220 esd->innerOctetsSz + esd->innerContSeqSz +
wolfSSL 15:117db924cf7c 1221 innerOidSz + pkcs7->contentSz +
wolfSSL 15:117db924cf7c 1222 signerInfoSz;
wolfSSL 15:117db924cf7c 1223 esd->innerSeqSz = SetSequence(totalSz, esd->innerSeq);
wolfSSL 15:117db924cf7c 1224 totalSz += esd->innerSeqSz;
wolfSSL 15:117db924cf7c 1225 esd->outerContentSz = SetExplicit(0, totalSz, esd->outerContent);
wolfSSL 15:117db924cf7c 1226 totalSz += esd->outerContentSz + outerOidSz;
wolfSSL 15:117db924cf7c 1227 esd->outerSeqSz = SetSequence(totalSz, esd->outerSeq);
wolfSSL 15:117db924cf7c 1228 totalSz += esd->outerSeqSz;
wolfSSL 15:117db924cf7c 1229
wolfSSL 15:117db924cf7c 1230 if (outputSz < totalSz) {
wolfSSL 15:117db924cf7c 1231 if (pkcs7->signedAttribsSz != 0)
wolfSSL 15:117db924cf7c 1232 XFREE(flatSignedAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 1233 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 1234 XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1235 #endif
wolfSSL 15:117db924cf7c 1236 return BUFFER_E;
wolfSSL 15:117db924cf7c 1237 }
wolfSSL 15:117db924cf7c 1238
wolfSSL 15:117db924cf7c 1239 idx = 0;
wolfSSL 15:117db924cf7c 1240 XMEMCPY(output + idx, esd->outerSeq, esd->outerSeqSz);
wolfSSL 15:117db924cf7c 1241 idx += esd->outerSeqSz;
wolfSSL 15:117db924cf7c 1242 XMEMCPY(output + idx, outerOid, outerOidSz);
wolfSSL 15:117db924cf7c 1243 idx += outerOidSz;
wolfSSL 15:117db924cf7c 1244 XMEMCPY(output + idx, esd->outerContent, esd->outerContentSz);
wolfSSL 15:117db924cf7c 1245 idx += esd->outerContentSz;
wolfSSL 15:117db924cf7c 1246 XMEMCPY(output + idx, esd->innerSeq, esd->innerSeqSz);
wolfSSL 15:117db924cf7c 1247 idx += esd->innerSeqSz;
wolfSSL 15:117db924cf7c 1248 XMEMCPY(output + idx, esd->version, esd->versionSz);
wolfSSL 15:117db924cf7c 1249 idx += esd->versionSz;
wolfSSL 15:117db924cf7c 1250 XMEMCPY(output + idx, esd->digAlgoIdSet, esd->digAlgoIdSetSz);
wolfSSL 15:117db924cf7c 1251 idx += esd->digAlgoIdSetSz;
wolfSSL 15:117db924cf7c 1252 XMEMCPY(output + idx, esd->singleDigAlgoId, esd->singleDigAlgoIdSz);
wolfSSL 15:117db924cf7c 1253 idx += esd->singleDigAlgoIdSz;
wolfSSL 15:117db924cf7c 1254 XMEMCPY(output + idx, esd->contentInfoSeq, esd->contentInfoSeqSz);
wolfSSL 15:117db924cf7c 1255 idx += esd->contentInfoSeqSz;
wolfSSL 15:117db924cf7c 1256 XMEMCPY(output + idx, innerOid, innerOidSz);
wolfSSL 15:117db924cf7c 1257 idx += innerOidSz;
wolfSSL 15:117db924cf7c 1258 XMEMCPY(output + idx, esd->innerContSeq, esd->innerContSeqSz);
wolfSSL 15:117db924cf7c 1259 idx += esd->innerContSeqSz;
wolfSSL 15:117db924cf7c 1260 XMEMCPY(output + idx, esd->innerOctets, esd->innerOctetsSz);
wolfSSL 15:117db924cf7c 1261 idx += esd->innerOctetsSz;
wolfSSL 15:117db924cf7c 1262 XMEMCPY(output + idx, pkcs7->content, pkcs7->contentSz);
wolfSSL 15:117db924cf7c 1263 idx += pkcs7->contentSz;
wolfSSL 15:117db924cf7c 1264 XMEMCPY(output + idx, esd->certsSet, esd->certsSetSz);
wolfSSL 15:117db924cf7c 1265 idx += esd->certsSetSz;
wolfSSL 15:117db924cf7c 1266 XMEMCPY(output + idx, pkcs7->singleCert, pkcs7->singleCertSz);
wolfSSL 15:117db924cf7c 1267 idx += pkcs7->singleCertSz;
wolfSSL 15:117db924cf7c 1268 XMEMCPY(output + idx, esd->signerInfoSet, esd->signerInfoSetSz);
wolfSSL 15:117db924cf7c 1269 idx += esd->signerInfoSetSz;
wolfSSL 15:117db924cf7c 1270 XMEMCPY(output + idx, esd->signerInfoSeq, esd->signerInfoSeqSz);
wolfSSL 15:117db924cf7c 1271 idx += esd->signerInfoSeqSz;
wolfSSL 15:117db924cf7c 1272 XMEMCPY(output + idx, esd->signerVersion, esd->signerVersionSz);
wolfSSL 15:117db924cf7c 1273 idx += esd->signerVersionSz;
wolfSSL 15:117db924cf7c 1274 XMEMCPY(output + idx, esd->issuerSnSeq, esd->issuerSnSeqSz);
wolfSSL 15:117db924cf7c 1275 idx += esd->issuerSnSeqSz;
wolfSSL 15:117db924cf7c 1276 XMEMCPY(output + idx, esd->issuerName, esd->issuerNameSz);
wolfSSL 15:117db924cf7c 1277 idx += esd->issuerNameSz;
wolfSSL 15:117db924cf7c 1278 XMEMCPY(output + idx, pkcs7->issuer, pkcs7->issuerSz);
wolfSSL 15:117db924cf7c 1279 idx += pkcs7->issuerSz;
wolfSSL 15:117db924cf7c 1280 XMEMCPY(output + idx, esd->issuerSn, esd->issuerSnSz);
wolfSSL 15:117db924cf7c 1281 idx += esd->issuerSnSz;
wolfSSL 15:117db924cf7c 1282 XMEMCPY(output + idx, esd->signerDigAlgoId, esd->signerDigAlgoIdSz);
wolfSSL 15:117db924cf7c 1283 idx += esd->signerDigAlgoIdSz;
wolfSSL 15:117db924cf7c 1284
wolfSSL 15:117db924cf7c 1285 /* SignerInfo:Attributes */
wolfSSL 15:117db924cf7c 1286 if (flatSignedAttribsSz > 0) {
wolfSSL 15:117db924cf7c 1287 XMEMCPY(output + idx, esd->signedAttribSet, esd->signedAttribSetSz);
wolfSSL 15:117db924cf7c 1288 idx += esd->signedAttribSetSz;
wolfSSL 15:117db924cf7c 1289 XMEMCPY(output + idx, flatSignedAttribs, flatSignedAttribsSz);
wolfSSL 15:117db924cf7c 1290 idx += flatSignedAttribsSz;
wolfSSL 15:117db924cf7c 1291 XFREE(flatSignedAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 1292 }
wolfSSL 15:117db924cf7c 1293
wolfSSL 15:117db924cf7c 1294 XMEMCPY(output + idx, esd->digEncAlgoId, esd->digEncAlgoIdSz);
wolfSSL 15:117db924cf7c 1295 idx += esd->digEncAlgoIdSz;
wolfSSL 15:117db924cf7c 1296 XMEMCPY(output + idx, esd->signerDigest, esd->signerDigestSz);
wolfSSL 15:117db924cf7c 1297 idx += esd->signerDigestSz;
wolfSSL 15:117db924cf7c 1298 XMEMCPY(output + idx, esd->encContentDigest, esd->encContentDigestSz);
wolfSSL 15:117db924cf7c 1299 idx += esd->encContentDigestSz;
wolfSSL 15:117db924cf7c 1300
wolfSSL 15:117db924cf7c 1301 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 1302 XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1303 #endif
wolfSSL 15:117db924cf7c 1304
wolfSSL 15:117db924cf7c 1305 return idx;
wolfSSL 15:117db924cf7c 1306 }
wolfSSL 15:117db924cf7c 1307
wolfSSL 15:117db924cf7c 1308
wolfSSL 15:117db924cf7c 1309 #ifndef NO_RSA
wolfSSL 15:117db924cf7c 1310
wolfSSL 15:117db924cf7c 1311 /* returns size of signature put into out, negative on error */
wolfSSL 15:117db924cf7c 1312 static int wc_PKCS7_RsaVerify(PKCS7* pkcs7, byte* sig, int sigSz,
wolfSSL 15:117db924cf7c 1313 byte* hash, word32 hashSz)
wolfSSL 15:117db924cf7c 1314 {
wolfSSL 15:117db924cf7c 1315 int ret = 0;
wolfSSL 15:117db924cf7c 1316 word32 scratch = 0;
wolfSSL 15:117db924cf7c 1317 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 1318 byte* digest;
wolfSSL 15:117db924cf7c 1319 RsaKey* key;
wolfSSL 15:117db924cf7c 1320 #else
wolfSSL 15:117db924cf7c 1321 byte digest[MAX_PKCS7_DIGEST_SZ];
wolfSSL 15:117db924cf7c 1322 RsaKey stack_key;
wolfSSL 15:117db924cf7c 1323 RsaKey* key = &stack_key;
wolfSSL 15:117db924cf7c 1324 #endif
wolfSSL 15:117db924cf7c 1325
wolfSSL 15:117db924cf7c 1326 if (pkcs7 == NULL || sig == NULL || hash == NULL) {
wolfSSL 15:117db924cf7c 1327 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 1328 }
wolfSSL 15:117db924cf7c 1329
wolfSSL 15:117db924cf7c 1330 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 1331 digest = (byte*)XMALLOC(MAX_PKCS7_DIGEST_SZ, pkcs7->heap,
wolfSSL 15:117db924cf7c 1332 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1333
wolfSSL 15:117db924cf7c 1334 if (digest == NULL)
wolfSSL 15:117db924cf7c 1335 return MEMORY_E;
wolfSSL 15:117db924cf7c 1336
wolfSSL 15:117db924cf7c 1337 key = (RsaKey*)XMALLOC(sizeof(RsaKey), pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1338 if (key == NULL) {
wolfSSL 15:117db924cf7c 1339 XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1340 return MEMORY_E;
wolfSSL 15:117db924cf7c 1341 }
wolfSSL 15:117db924cf7c 1342 #endif
wolfSSL 15:117db924cf7c 1343
wolfSSL 15:117db924cf7c 1344 XMEMSET(digest, 0, MAX_PKCS7_DIGEST_SZ);
wolfSSL 15:117db924cf7c 1345
wolfSSL 15:117db924cf7c 1346 ret = wc_InitRsaKey_ex(key, pkcs7->heap, pkcs7->devId);
wolfSSL 15:117db924cf7c 1347 if (ret != 0) {
wolfSSL 15:117db924cf7c 1348 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 1349 XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1350 XFREE(key, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1351 #endif
wolfSSL 15:117db924cf7c 1352 return ret;
wolfSSL 15:117db924cf7c 1353 }
wolfSSL 15:117db924cf7c 1354
wolfSSL 15:117db924cf7c 1355 if (wc_RsaPublicKeyDecode(pkcs7->publicKey, &scratch, key,
wolfSSL 15:117db924cf7c 1356 pkcs7->publicKeySz) < 0) {
wolfSSL 15:117db924cf7c 1357 WOLFSSL_MSG("ASN RSA key decode error");
wolfSSL 15:117db924cf7c 1358 wc_FreeRsaKey(key);
wolfSSL 15:117db924cf7c 1359 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 1360 XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1361 XFREE(key, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1362 #endif
wolfSSL 15:117db924cf7c 1363 return PUBLIC_KEY_E;
wolfSSL 15:117db924cf7c 1364 }
wolfSSL 15:117db924cf7c 1365
wolfSSL 15:117db924cf7c 1366 ret = wc_RsaSSL_Verify(sig, sigSz, digest, MAX_PKCS7_DIGEST_SZ, key);
wolfSSL 15:117db924cf7c 1367
wolfSSL 15:117db924cf7c 1368 wc_FreeRsaKey(key);
wolfSSL 15:117db924cf7c 1369
wolfSSL 15:117db924cf7c 1370 if (((int)hashSz != ret) || (XMEMCMP(digest, hash, ret) != 0)) {
wolfSSL 15:117db924cf7c 1371 ret = SIG_VERIFY_E;
wolfSSL 15:117db924cf7c 1372 }
wolfSSL 15:117db924cf7c 1373
wolfSSL 15:117db924cf7c 1374 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 1375 XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1376 XFREE(key, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1377 #endif
wolfSSL 15:117db924cf7c 1378
wolfSSL 15:117db924cf7c 1379 return ret;
wolfSSL 15:117db924cf7c 1380 }
wolfSSL 15:117db924cf7c 1381
wolfSSL 15:117db924cf7c 1382 #endif /* NO_RSA */
wolfSSL 15:117db924cf7c 1383
wolfSSL 15:117db924cf7c 1384
wolfSSL 15:117db924cf7c 1385 #ifdef HAVE_ECC
wolfSSL 15:117db924cf7c 1386
wolfSSL 15:117db924cf7c 1387 /* returns size of signature put into out, negative on error */
wolfSSL 15:117db924cf7c 1388 static int wc_PKCS7_EcdsaVerify(PKCS7* pkcs7, byte* sig, int sigSz,
wolfSSL 15:117db924cf7c 1389 byte* hash, word32 hashSz)
wolfSSL 15:117db924cf7c 1390 {
wolfSSL 15:117db924cf7c 1391 int ret = 0;
wolfSSL 15:117db924cf7c 1392 int res = 0;
wolfSSL 15:117db924cf7c 1393 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 1394 byte* digest;
wolfSSL 15:117db924cf7c 1395 ecc_key* key;
wolfSSL 15:117db924cf7c 1396 #else
wolfSSL 15:117db924cf7c 1397 byte digest[MAX_PKCS7_DIGEST_SZ];
wolfSSL 15:117db924cf7c 1398 ecc_key stack_key;
wolfSSL 15:117db924cf7c 1399 ecc_key* key = &stack_key;
wolfSSL 15:117db924cf7c 1400 #endif
wolfSSL 15:117db924cf7c 1401 word32 idx = 0;
wolfSSL 15:117db924cf7c 1402
wolfSSL 15:117db924cf7c 1403 if (pkcs7 == NULL || sig == NULL)
wolfSSL 15:117db924cf7c 1404 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 1405
wolfSSL 15:117db924cf7c 1406 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 1407 digest = (byte*)XMALLOC(MAX_PKCS7_DIGEST_SZ, pkcs7->heap,
wolfSSL 15:117db924cf7c 1408 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1409
wolfSSL 15:117db924cf7c 1410 if (digest == NULL)
wolfSSL 15:117db924cf7c 1411 return MEMORY_E;
wolfSSL 15:117db924cf7c 1412
wolfSSL 15:117db924cf7c 1413 key = (ecc_key*)XMALLOC(sizeof(ecc_key), pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1414 if (key == NULL) {
wolfSSL 15:117db924cf7c 1415 XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1416 return MEMORY_E;
wolfSSL 15:117db924cf7c 1417 }
wolfSSL 15:117db924cf7c 1418 #endif
wolfSSL 15:117db924cf7c 1419
wolfSSL 15:117db924cf7c 1420 XMEMSET(digest, 0, MAX_PKCS7_DIGEST_SZ);
wolfSSL 15:117db924cf7c 1421
wolfSSL 15:117db924cf7c 1422 ret = wc_ecc_init_ex(key, pkcs7->heap, pkcs7->devId);
wolfSSL 15:117db924cf7c 1423 if (ret != 0) {
wolfSSL 15:117db924cf7c 1424 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 1425 XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1426 XFREE(key, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1427 #endif
wolfSSL 15:117db924cf7c 1428 return ret;
wolfSSL 15:117db924cf7c 1429 }
wolfSSL 15:117db924cf7c 1430
wolfSSL 15:117db924cf7c 1431 if (wc_EccPublicKeyDecode(pkcs7->publicKey, &idx, key,
wolfSSL 15:117db924cf7c 1432 pkcs7->publicKeySz) < 0) {
wolfSSL 15:117db924cf7c 1433 WOLFSSL_MSG("ASN ECDSA key decode error");
wolfSSL 15:117db924cf7c 1434 wc_ecc_free(key);
wolfSSL 15:117db924cf7c 1435 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 1436 XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1437 XFREE(key, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1438 #endif
wolfSSL 15:117db924cf7c 1439 return PUBLIC_KEY_E;
wolfSSL 15:117db924cf7c 1440 }
wolfSSL 15:117db924cf7c 1441
wolfSSL 15:117db924cf7c 1442 ret = wc_ecc_verify_hash(sig, sigSz, hash, hashSz, &res, key);
wolfSSL 15:117db924cf7c 1443
wolfSSL 15:117db924cf7c 1444 wc_ecc_free(key);
wolfSSL 15:117db924cf7c 1445
wolfSSL 15:117db924cf7c 1446 if (ret == 0 && res != 1) {
wolfSSL 15:117db924cf7c 1447 ret = SIG_VERIFY_E;
wolfSSL 15:117db924cf7c 1448 }
wolfSSL 15:117db924cf7c 1449
wolfSSL 15:117db924cf7c 1450 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 1451 XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1452 XFREE(key, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1453 #endif
wolfSSL 15:117db924cf7c 1454
wolfSSL 15:117db924cf7c 1455 return ret;
wolfSSL 15:117db924cf7c 1456 }
wolfSSL 15:117db924cf7c 1457
wolfSSL 15:117db924cf7c 1458 #endif /* HAVE_ECC */
wolfSSL 15:117db924cf7c 1459
wolfSSL 15:117db924cf7c 1460
wolfSSL 15:117db924cf7c 1461 /* build SignedData digest, both in PKCS#7 DigestInfo format and
wolfSSL 15:117db924cf7c 1462 * as plain digest for CMS.
wolfSSL 15:117db924cf7c 1463 *
wolfSSL 15:117db924cf7c 1464 * pkcs7 - pointer to initialized PKCS7 struct
wolfSSL 15:117db924cf7c 1465 * signedAttrib - signed attributes
wolfSSL 15:117db924cf7c 1466 * signedAttribSz - size of signedAttrib, octets
wolfSSL 15:117db924cf7c 1467 * pkcs7Digest - [OUT] PKCS#7 DigestInfo
wolfSSL 15:117db924cf7c 1468 * pkcs7DigestSz - [IN/OUT] size of pkcs7Digest
wolfSSL 15:117db924cf7c 1469 * plainDigest - [OUT] pointer to plain digest, offset into pkcs7Digest
wolfSSL 15:117db924cf7c 1470 * plainDigestSz - [OUT] size of digest at plainDigest
wolfSSL 15:117db924cf7c 1471 *
wolfSSL 15:117db924cf7c 1472 * returns 0 on success, negative on error */
wolfSSL 15:117db924cf7c 1473 static int wc_PKCS7_BuildSignedDataDigest(PKCS7* pkcs7, byte* signedAttrib,
wolfSSL 15:117db924cf7c 1474 word32 signedAttribSz, byte* pkcs7Digest,
wolfSSL 15:117db924cf7c 1475 word32* pkcs7DigestSz, byte** plainDigest,
wolfSSL 15:117db924cf7c 1476 word32* plainDigestSz)
wolfSSL 15:117db924cf7c 1477 {
wolfSSL 15:117db924cf7c 1478 int ret = 0, digIdx = 0, hashSz;
wolfSSL 15:117db924cf7c 1479 word32 attribSetSz;
wolfSSL 15:117db924cf7c 1480 byte attribSet[MAX_SET_SZ];
wolfSSL 15:117db924cf7c 1481 byte digest[WC_MAX_DIGEST_SIZE];
wolfSSL 15:117db924cf7c 1482 byte digestInfoSeq[MAX_SEQ_SZ];
wolfSSL 15:117db924cf7c 1483 byte digestStr[MAX_OCTET_STR_SZ];
wolfSSL 15:117db924cf7c 1484 byte algoId[MAX_ALGO_SZ];
wolfSSL 15:117db924cf7c 1485 word32 digestInfoSeqSz, digestStrSz, algoIdSz;
wolfSSL 15:117db924cf7c 1486 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 1487 byte* digestInfo;
wolfSSL 15:117db924cf7c 1488 #else
wolfSSL 15:117db924cf7c 1489 byte digestInfo[MAX_PKCS7_DIGEST_SZ];
wolfSSL 15:117db924cf7c 1490 #endif
wolfSSL 15:117db924cf7c 1491
wolfSSL 15:117db924cf7c 1492 wc_HashAlg hash;
wolfSSL 15:117db924cf7c 1493 enum wc_HashType hashType;
wolfSSL 15:117db924cf7c 1494
wolfSSL 15:117db924cf7c 1495 if (pkcs7 == NULL || pkcs7Digest == NULL ||
wolfSSL 15:117db924cf7c 1496 pkcs7DigestSz == NULL || plainDigest == NULL) {
wolfSSL 15:117db924cf7c 1497 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 1498 }
wolfSSL 15:117db924cf7c 1499
wolfSSL 15:117db924cf7c 1500 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 1501 digestInfo = (byte*)XMALLOC(MAX_PKCS7_DIGEST_SZ, pkcs7->heap,
wolfSSL 15:117db924cf7c 1502 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1503 if (digestInfo == NULL)
wolfSSL 15:117db924cf7c 1504 return MEMORY_E;
wolfSSL 15:117db924cf7c 1505 #endif
wolfSSL 15:117db924cf7c 1506
wolfSSL 15:117db924cf7c 1507 XMEMSET(pkcs7Digest, 0, *pkcs7DigestSz);
wolfSSL 15:117db924cf7c 1508 XMEMSET(digest, 0, WC_MAX_DIGEST_SIZE);
wolfSSL 15:117db924cf7c 1509 XMEMSET(digestInfo, 0, MAX_PKCS7_DIGEST_SZ);
wolfSSL 15:117db924cf7c 1510
wolfSSL 15:117db924cf7c 1511 hashType = wc_OidGetHash(pkcs7->hashOID);
wolfSSL 15:117db924cf7c 1512 ret = wc_HashGetDigestSize(hashType);
wolfSSL 15:117db924cf7c 1513 if (ret < 0) {
wolfSSL 15:117db924cf7c 1514 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 1515 XFREE(digestInfo, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1516 #endif
wolfSSL 15:117db924cf7c 1517 return ret;
wolfSSL 15:117db924cf7c 1518 }
wolfSSL 15:117db924cf7c 1519 hashSz = ret;
wolfSSL 15:117db924cf7c 1520
wolfSSL 15:117db924cf7c 1521 /* calculate digest */
wolfSSL 15:117db924cf7c 1522 ret = wc_HashInit(&hash, hashType);
wolfSSL 15:117db924cf7c 1523 if (ret < 0) {
wolfSSL 15:117db924cf7c 1524 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 1525 XFREE(digestInfo, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1526 #endif
wolfSSL 15:117db924cf7c 1527 return ret;
wolfSSL 15:117db924cf7c 1528 }
wolfSSL 15:117db924cf7c 1529
wolfSSL 15:117db924cf7c 1530 if (signedAttribSz > 0) {
wolfSSL 15:117db924cf7c 1531
wolfSSL 15:117db924cf7c 1532 if (signedAttrib == NULL) {
wolfSSL 15:117db924cf7c 1533 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 1534 XFREE(digestInfo, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1535 #endif
wolfSSL 15:117db924cf7c 1536 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 1537 }
wolfSSL 15:117db924cf7c 1538
wolfSSL 15:117db924cf7c 1539 attribSetSz = SetSet(signedAttribSz, attribSet);
wolfSSL 15:117db924cf7c 1540 ret = wc_HashUpdate(&hash, hashType, attribSet, attribSetSz);
wolfSSL 15:117db924cf7c 1541 if (ret < 0) {
wolfSSL 15:117db924cf7c 1542 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 1543 XFREE(digestInfo, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1544 #endif
wolfSSL 15:117db924cf7c 1545 return ret;
wolfSSL 15:117db924cf7c 1546 }
wolfSSL 15:117db924cf7c 1547
wolfSSL 15:117db924cf7c 1548 ret = wc_HashUpdate(&hash, hashType, signedAttrib, signedAttribSz);
wolfSSL 15:117db924cf7c 1549 if (ret < 0) {
wolfSSL 15:117db924cf7c 1550 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 1551 XFREE(digestInfo, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1552 #endif
wolfSSL 15:117db924cf7c 1553 return ret;
wolfSSL 15:117db924cf7c 1554 }
wolfSSL 15:117db924cf7c 1555
wolfSSL 15:117db924cf7c 1556 ret = wc_HashFinal(&hash, hashType, digest);
wolfSSL 15:117db924cf7c 1557 if (ret < 0) {
wolfSSL 15:117db924cf7c 1558 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 1559 XFREE(digestInfo, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1560 #endif
wolfSSL 15:117db924cf7c 1561 return ret;
wolfSSL 15:117db924cf7c 1562 }
wolfSSL 15:117db924cf7c 1563
wolfSSL 15:117db924cf7c 1564 } else {
wolfSSL 15:117db924cf7c 1565
wolfSSL 15:117db924cf7c 1566 if (pkcs7->content == NULL) {
wolfSSL 15:117db924cf7c 1567 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 1568 XFREE(digestInfo, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1569 #endif
wolfSSL 15:117db924cf7c 1570 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 1571 }
wolfSSL 15:117db924cf7c 1572
wolfSSL 15:117db924cf7c 1573 ret = wc_HashUpdate(&hash, hashType, pkcs7->content, pkcs7->contentSz);
wolfSSL 15:117db924cf7c 1574 if (ret < 0) {
wolfSSL 15:117db924cf7c 1575 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 1576 XFREE(digestInfo, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1577 #endif
wolfSSL 15:117db924cf7c 1578 return ret;
wolfSSL 15:117db924cf7c 1579 }
wolfSSL 15:117db924cf7c 1580
wolfSSL 15:117db924cf7c 1581 ret = wc_HashFinal(&hash, hashType, digest);
wolfSSL 15:117db924cf7c 1582 if (ret < 0) {
wolfSSL 15:117db924cf7c 1583 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 1584 XFREE(digestInfo, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1585 #endif
wolfSSL 15:117db924cf7c 1586 return ret;
wolfSSL 15:117db924cf7c 1587 }
wolfSSL 15:117db924cf7c 1588 }
wolfSSL 15:117db924cf7c 1589
wolfSSL 15:117db924cf7c 1590 /* Set algoID, with NULL attributes */
wolfSSL 15:117db924cf7c 1591 algoIdSz = SetAlgoID(pkcs7->hashOID, algoId, oidHashType, 0);
wolfSSL 15:117db924cf7c 1592
wolfSSL 15:117db924cf7c 1593 digestStrSz = SetOctetString(hashSz, digestStr);
wolfSSL 15:117db924cf7c 1594 digestInfoSeqSz = SetSequence(algoIdSz + digestStrSz + hashSz,
wolfSSL 15:117db924cf7c 1595 digestInfoSeq);
wolfSSL 15:117db924cf7c 1596
wolfSSL 15:117db924cf7c 1597 XMEMCPY(digestInfo + digIdx, digestInfoSeq, digestInfoSeqSz);
wolfSSL 15:117db924cf7c 1598 digIdx += digestInfoSeqSz;
wolfSSL 15:117db924cf7c 1599 XMEMCPY(digestInfo + digIdx, algoId, algoIdSz);
wolfSSL 15:117db924cf7c 1600 digIdx += algoIdSz;
wolfSSL 15:117db924cf7c 1601 XMEMCPY(digestInfo + digIdx, digestStr, digestStrSz);
wolfSSL 15:117db924cf7c 1602 digIdx += digestStrSz;
wolfSSL 15:117db924cf7c 1603 XMEMCPY(digestInfo + digIdx, digest, hashSz);
wolfSSL 15:117db924cf7c 1604 digIdx += hashSz;
wolfSSL 15:117db924cf7c 1605
wolfSSL 15:117db924cf7c 1606 XMEMCPY(pkcs7Digest, digestInfo, digIdx);
wolfSSL 15:117db924cf7c 1607 *pkcs7DigestSz = digIdx;
wolfSSL 15:117db924cf7c 1608
wolfSSL 15:117db924cf7c 1609 /* set plain digest pointer */
wolfSSL 15:117db924cf7c 1610 *plainDigest = pkcs7Digest + digIdx - hashSz;
wolfSSL 15:117db924cf7c 1611 *plainDigestSz = hashSz;
wolfSSL 15:117db924cf7c 1612
wolfSSL 15:117db924cf7c 1613 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 1614 XFREE(digestInfo, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1615 #endif
wolfSSL 15:117db924cf7c 1616 return 0;
wolfSSL 15:117db924cf7c 1617 }
wolfSSL 15:117db924cf7c 1618
wolfSSL 15:117db924cf7c 1619
wolfSSL 15:117db924cf7c 1620 /* verifies SignedData signature, over either PKCS#7 DigestInfo or
wolfSSL 15:117db924cf7c 1621 * content digest.
wolfSSL 15:117db924cf7c 1622 *
wolfSSL 15:117db924cf7c 1623 * pkcs7 - pointer to initialized PKCS7 struct
wolfSSL 15:117db924cf7c 1624 * sig - signature to verify
wolfSSL 15:117db924cf7c 1625 * sigSz - size of sig
wolfSSL 15:117db924cf7c 1626 * signedAttrib - signed attributes, or null if empty
wolfSSL 15:117db924cf7c 1627 * signedAttribSz - size of signedAttributes
wolfSSL 15:117db924cf7c 1628 *
wolfSSL 15:117db924cf7c 1629 * return 0 on success, negative on error */
wolfSSL 15:117db924cf7c 1630 static int wc_PKCS7_SignedDataVerifySignature(PKCS7* pkcs7, byte* sig,
wolfSSL 15:117db924cf7c 1631 word32 sigSz, byte* signedAttrib,
wolfSSL 15:117db924cf7c 1632 word32 signedAttribSz)
wolfSSL 15:117db924cf7c 1633 {
wolfSSL 15:117db924cf7c 1634 int ret = 0;
wolfSSL 15:117db924cf7c 1635 word32 plainDigestSz = 0, pkcs7DigestSz;
wolfSSL 15:117db924cf7c 1636 byte* plainDigest = NULL; /* offset into pkcs7Digest */
wolfSSL 15:117db924cf7c 1637 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 1638 byte* pkcs7Digest;
wolfSSL 15:117db924cf7c 1639 #else
wolfSSL 15:117db924cf7c 1640 byte pkcs7Digest[MAX_PKCS7_DIGEST_SZ];
wolfSSL 15:117db924cf7c 1641 #endif
wolfSSL 15:117db924cf7c 1642
wolfSSL 15:117db924cf7c 1643 if (pkcs7 == NULL)
wolfSSL 15:117db924cf7c 1644 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 1645
wolfSSL 15:117db924cf7c 1646 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 1647 pkcs7Digest = (byte*)XMALLOC(MAX_PKCS7_DIGEST_SZ, pkcs7->heap,
wolfSSL 15:117db924cf7c 1648 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1649 if (pkcs7Digest == NULL)
wolfSSL 15:117db924cf7c 1650 return MEMORY_E;
wolfSSL 15:117db924cf7c 1651 #endif
wolfSSL 15:117db924cf7c 1652
wolfSSL 15:117db924cf7c 1653 /* build hash to verify against */
wolfSSL 15:117db924cf7c 1654 pkcs7DigestSz = MAX_PKCS7_DIGEST_SZ;
wolfSSL 15:117db924cf7c 1655 ret = wc_PKCS7_BuildSignedDataDigest(pkcs7, signedAttrib,
wolfSSL 15:117db924cf7c 1656 signedAttribSz, pkcs7Digest,
wolfSSL 15:117db924cf7c 1657 &pkcs7DigestSz, &plainDigest,
wolfSSL 15:117db924cf7c 1658 &plainDigestSz);
wolfSSL 15:117db924cf7c 1659 if (ret < 0) {
wolfSSL 15:117db924cf7c 1660 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 1661 XFREE(pkcs7Digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1662 #endif
wolfSSL 15:117db924cf7c 1663 return ret;
wolfSSL 15:117db924cf7c 1664 }
wolfSSL 15:117db924cf7c 1665
wolfSSL 15:117db924cf7c 1666 switch (pkcs7->publicKeyOID) {
wolfSSL 15:117db924cf7c 1667
wolfSSL 15:117db924cf7c 1668 #ifndef NO_RSA
wolfSSL 15:117db924cf7c 1669 case RSAk:
wolfSSL 15:117db924cf7c 1670 ret = wc_PKCS7_RsaVerify(pkcs7, sig, sigSz, pkcs7Digest,
wolfSSL 15:117db924cf7c 1671 pkcs7DigestSz);
wolfSSL 15:117db924cf7c 1672 if (ret < 0) {
wolfSSL 15:117db924cf7c 1673 WOLFSSL_MSG("PKCS#7 verification failed, trying CMS");
wolfSSL 15:117db924cf7c 1674 ret = wc_PKCS7_RsaVerify(pkcs7, sig, sigSz, plainDigest,
wolfSSL 15:117db924cf7c 1675 plainDigestSz);
wolfSSL 15:117db924cf7c 1676 }
wolfSSL 15:117db924cf7c 1677 break;
wolfSSL 15:117db924cf7c 1678 #endif
wolfSSL 15:117db924cf7c 1679
wolfSSL 15:117db924cf7c 1680 #ifdef HAVE_ECC
wolfSSL 15:117db924cf7c 1681 case ECDSAk:
wolfSSL 15:117db924cf7c 1682 ret = wc_PKCS7_EcdsaVerify(pkcs7, sig, sigSz, plainDigest,
wolfSSL 15:117db924cf7c 1683 plainDigestSz);
wolfSSL 15:117db924cf7c 1684 break;
wolfSSL 15:117db924cf7c 1685 #endif
wolfSSL 15:117db924cf7c 1686
wolfSSL 15:117db924cf7c 1687 default:
wolfSSL 15:117db924cf7c 1688 WOLFSSL_MSG("Unsupported public key type");
wolfSSL 15:117db924cf7c 1689 ret = BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 1690 }
wolfSSL 15:117db924cf7c 1691
wolfSSL 15:117db924cf7c 1692 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 1693 XFREE(pkcs7Digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1694 #endif
wolfSSL 15:117db924cf7c 1695 return ret;
wolfSSL 15:117db924cf7c 1696 }
wolfSSL 15:117db924cf7c 1697
wolfSSL 15:117db924cf7c 1698
wolfSSL 15:117db924cf7c 1699 /* set correct public key OID based on signature OID, stores in
wolfSSL 15:117db924cf7c 1700 * pkcs7->publicKeyOID and returns same value */
wolfSSL 15:117db924cf7c 1701 static int wc_PKCS7_SetPublicKeyOID(PKCS7* pkcs7, int sigOID)
wolfSSL 15:117db924cf7c 1702 {
wolfSSL 15:117db924cf7c 1703 if (pkcs7 == NULL)
wolfSSL 15:117db924cf7c 1704 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 1705
wolfSSL 15:117db924cf7c 1706 pkcs7->publicKeyOID = 0;
wolfSSL 15:117db924cf7c 1707
wolfSSL 15:117db924cf7c 1708 switch (sigOID) {
wolfSSL 15:117db924cf7c 1709
wolfSSL 15:117db924cf7c 1710 #ifndef NO_RSA
wolfSSL 15:117db924cf7c 1711 /* RSA signature types */
wolfSSL 15:117db924cf7c 1712 case CTC_MD2wRSA:
wolfSSL 15:117db924cf7c 1713 case CTC_MD5wRSA:
wolfSSL 15:117db924cf7c 1714 case CTC_SHAwRSA:
wolfSSL 15:117db924cf7c 1715 case CTC_SHA224wRSA:
wolfSSL 15:117db924cf7c 1716 case CTC_SHA256wRSA:
wolfSSL 15:117db924cf7c 1717 case CTC_SHA384wRSA:
wolfSSL 15:117db924cf7c 1718 case CTC_SHA512wRSA:
wolfSSL 15:117db924cf7c 1719 pkcs7->publicKeyOID = RSAk;
wolfSSL 15:117db924cf7c 1720 break;
wolfSSL 15:117db924cf7c 1721
wolfSSL 15:117db924cf7c 1722 /* if sigOID is already RSAk */
wolfSSL 15:117db924cf7c 1723 case RSAk:
wolfSSL 15:117db924cf7c 1724 pkcs7->publicKeyOID = sigOID;
wolfSSL 15:117db924cf7c 1725 break;
wolfSSL 15:117db924cf7c 1726 #endif
wolfSSL 15:117db924cf7c 1727
wolfSSL 15:117db924cf7c 1728 #ifndef NO_DSA
wolfSSL 15:117db924cf7c 1729 /* DSA signature types */
wolfSSL 15:117db924cf7c 1730 case CTC_SHAwDSA:
wolfSSL 15:117db924cf7c 1731 pkcs7->publicKeyOID = DSAk;
wolfSSL 15:117db924cf7c 1732 break;
wolfSSL 15:117db924cf7c 1733
wolfSSL 15:117db924cf7c 1734 /* if sigOID is already DSAk */
wolfSSL 15:117db924cf7c 1735 case DSAk:
wolfSSL 15:117db924cf7c 1736 pkcs7->publicKeyOID = sigOID;
wolfSSL 15:117db924cf7c 1737 break;
wolfSSL 15:117db924cf7c 1738 #endif
wolfSSL 15:117db924cf7c 1739
wolfSSL 15:117db924cf7c 1740 #ifdef HAVE_ECC
wolfSSL 15:117db924cf7c 1741 /* ECDSA signature types */
wolfSSL 15:117db924cf7c 1742 case CTC_SHAwECDSA:
wolfSSL 15:117db924cf7c 1743 case CTC_SHA224wECDSA:
wolfSSL 15:117db924cf7c 1744 case CTC_SHA256wECDSA:
wolfSSL 15:117db924cf7c 1745 case CTC_SHA384wECDSA:
wolfSSL 15:117db924cf7c 1746 case CTC_SHA512wECDSA:
wolfSSL 15:117db924cf7c 1747 pkcs7->publicKeyOID = ECDSAk;
wolfSSL 15:117db924cf7c 1748 break;
wolfSSL 15:117db924cf7c 1749
wolfSSL 15:117db924cf7c 1750 /* if sigOID is already ECDSAk */
wolfSSL 15:117db924cf7c 1751 case ECDSAk:
wolfSSL 15:117db924cf7c 1752 pkcs7->publicKeyOID = sigOID;
wolfSSL 15:117db924cf7c 1753 break;
wolfSSL 15:117db924cf7c 1754 #endif
wolfSSL 15:117db924cf7c 1755
wolfSSL 15:117db924cf7c 1756 default:
wolfSSL 15:117db924cf7c 1757 WOLFSSL_MSG("Unsupported public key algorithm");
wolfSSL 15:117db924cf7c 1758 return ASN_SIG_KEY_E;
wolfSSL 15:117db924cf7c 1759 }
wolfSSL 15:117db924cf7c 1760
wolfSSL 15:117db924cf7c 1761 return pkcs7->publicKeyOID;
wolfSSL 15:117db924cf7c 1762 }
wolfSSL 15:117db924cf7c 1763
wolfSSL 15:117db924cf7c 1764
wolfSSL 15:117db924cf7c 1765 /* Parses through the attributes and adds them to the PKCS7 structure
wolfSSL 15:117db924cf7c 1766 * Creates dynamic attribute structures that are free'd with calling
wolfSSL 15:117db924cf7c 1767 * wc_PKCS7_Free()
wolfSSL 15:117db924cf7c 1768 *
wolfSSL 15:117db924cf7c 1769 * NOTE: An attribute has the ASN1 format of
wolfSSL 15:117db924cf7c 1770 ** Sequence
wolfSSL 15:117db924cf7c 1771 ****** Object ID
wolfSSL 15:117db924cf7c 1772 ****** Set
wolfSSL 15:117db924cf7c 1773 ********** {PritnableString, UTCTime, OCTET STRING ...}
wolfSSL 15:117db924cf7c 1774 *
wolfSSL 15:117db924cf7c 1775 * pkcs7 the PKCS7 structure to put the parsed attributes into
wolfSSL 15:117db924cf7c 1776 * in buffer holding all attributes
wolfSSL 15:117db924cf7c 1777 * inSz size of in buffer
wolfSSL 15:117db924cf7c 1778 *
wolfSSL 15:117db924cf7c 1779 * returns the number of attributes parsed on success
wolfSSL 15:117db924cf7c 1780 */
wolfSSL 15:117db924cf7c 1781 static int wc_PKCS7_ParseAttribs(PKCS7* pkcs7, byte* in, int inSz)
wolfSSL 15:117db924cf7c 1782 {
wolfSSL 15:117db924cf7c 1783 int found = 0;
wolfSSL 15:117db924cf7c 1784 word32 idx = 0;
wolfSSL 15:117db924cf7c 1785 word32 oid;
wolfSSL 15:117db924cf7c 1786
wolfSSL 15:117db924cf7c 1787 if (pkcs7 == NULL || in == NULL || inSz < 0) {
wolfSSL 15:117db924cf7c 1788 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 1789 }
wolfSSL 15:117db924cf7c 1790
wolfSSL 15:117db924cf7c 1791 while (idx < (word32)inSz) {
wolfSSL 15:117db924cf7c 1792 int length = 0;
wolfSSL 15:117db924cf7c 1793 int oidIdx;
wolfSSL 15:117db924cf7c 1794 PKCS7DecodedAttrib* attrib;
wolfSSL 15:117db924cf7c 1795
wolfSSL 15:117db924cf7c 1796 if (GetSequence(in, &idx, &length, inSz) < 0)
wolfSSL 15:117db924cf7c 1797 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 1798
wolfSSL 15:117db924cf7c 1799 attrib = (PKCS7DecodedAttrib*)XMALLOC(sizeof(PKCS7DecodedAttrib),
wolfSSL 15:117db924cf7c 1800 pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 1801 if (attrib == NULL) {
wolfSSL 15:117db924cf7c 1802 return MEMORY_E;
wolfSSL 15:117db924cf7c 1803 }
wolfSSL 15:117db924cf7c 1804 XMEMSET(attrib, 0, sizeof(PKCS7DecodedAttrib));
wolfSSL 15:117db924cf7c 1805
wolfSSL 15:117db924cf7c 1806 oidIdx = idx;
wolfSSL 15:117db924cf7c 1807 if (GetObjectId(in, &idx, &oid, oidIgnoreType, inSz)
wolfSSL 15:117db924cf7c 1808 < 0) {
wolfSSL 15:117db924cf7c 1809 XFREE(attrib, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 1810 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 1811 }
wolfSSL 15:117db924cf7c 1812 attrib->oidSz = idx - oidIdx;
wolfSSL 15:117db924cf7c 1813 attrib->oid = (byte*)XMALLOC(attrib->oidSz, pkcs7->heap,
wolfSSL 15:117db924cf7c 1814 DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 1815 if (attrib->oid == NULL) {
wolfSSL 15:117db924cf7c 1816 XFREE(attrib, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 1817 return MEMORY_E;
wolfSSL 15:117db924cf7c 1818 }
wolfSSL 15:117db924cf7c 1819 XMEMCPY(attrib->oid, in + oidIdx, attrib->oidSz);
wolfSSL 15:117db924cf7c 1820
wolfSSL 15:117db924cf7c 1821
wolfSSL 15:117db924cf7c 1822 /* Get Set that contains the printable string value */
wolfSSL 15:117db924cf7c 1823 if (GetSet(in, &idx, &length, inSz) < 0) {
wolfSSL 15:117db924cf7c 1824 XFREE(attrib->oid, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 1825 XFREE(attrib, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 1826 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 1827 }
wolfSSL 15:117db924cf7c 1828
wolfSSL 15:117db924cf7c 1829 if ((inSz - idx) < (word32)length) {
wolfSSL 15:117db924cf7c 1830 XFREE(attrib->oid, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 1831 XFREE(attrib, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 1832 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 1833 }
wolfSSL 15:117db924cf7c 1834
wolfSSL 15:117db924cf7c 1835 attrib->valueSz = (word32)length;
wolfSSL 15:117db924cf7c 1836 attrib->value = (byte*)XMALLOC(attrib->valueSz, pkcs7->heap,
wolfSSL 15:117db924cf7c 1837 DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 1838 if (attrib->value == NULL) {
wolfSSL 15:117db924cf7c 1839 XFREE(attrib->oid, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 1840 XFREE(attrib, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 1841 return MEMORY_E;
wolfSSL 15:117db924cf7c 1842 }
wolfSSL 15:117db924cf7c 1843 XMEMCPY(attrib->value, in + idx, attrib->valueSz);
wolfSSL 15:117db924cf7c 1844 idx += length;
wolfSSL 15:117db924cf7c 1845
wolfSSL 15:117db924cf7c 1846 /* store attribute in linked list */
wolfSSL 15:117db924cf7c 1847 if (pkcs7->decodedAttrib != NULL) {
wolfSSL 15:117db924cf7c 1848 attrib->next = pkcs7->decodedAttrib;
wolfSSL 15:117db924cf7c 1849 pkcs7->decodedAttrib = attrib;
wolfSSL 15:117db924cf7c 1850 } else {
wolfSSL 15:117db924cf7c 1851 pkcs7->decodedAttrib = attrib;
wolfSSL 15:117db924cf7c 1852 }
wolfSSL 15:117db924cf7c 1853 found++;
wolfSSL 15:117db924cf7c 1854 }
wolfSSL 15:117db924cf7c 1855
wolfSSL 15:117db924cf7c 1856 return found;
wolfSSL 15:117db924cf7c 1857 }
wolfSSL 15:117db924cf7c 1858
wolfSSL 15:117db924cf7c 1859
wolfSSL 15:117db924cf7c 1860 /* Finds the certificates in the message and saves it. */
wolfSSL 15:117db924cf7c 1861 int wc_PKCS7_VerifySignedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz)
wolfSSL 15:117db924cf7c 1862 {
wolfSSL 15:117db924cf7c 1863 word32 idx, contentType, hashOID, sigOID;
wolfSSL 15:117db924cf7c 1864 int length, version, ret;
wolfSSL 15:117db924cf7c 1865 byte* content = NULL;
wolfSSL 15:117db924cf7c 1866 byte* sig = NULL;
wolfSSL 15:117db924cf7c 1867 byte* cert = NULL;
wolfSSL 15:117db924cf7c 1868 byte* signedAttrib = NULL;
wolfSSL 15:117db924cf7c 1869 int contentSz = 0, sigSz = 0, certSz = 0, signedAttribSz = 0;
wolfSSL 15:117db924cf7c 1870 byte degenerate;
wolfSSL 15:117db924cf7c 1871 #ifdef ASN_BER_TO_DER
wolfSSL 15:117db924cf7c 1872 byte* der;
wolfSSL 15:117db924cf7c 1873 #endif
wolfSSL 15:117db924cf7c 1874
wolfSSL 15:117db924cf7c 1875 if (pkcs7 == NULL || pkiMsg == NULL || pkiMsgSz == 0)
wolfSSL 15:117db924cf7c 1876 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 1877
wolfSSL 15:117db924cf7c 1878 idx = 0;
wolfSSL 15:117db924cf7c 1879
wolfSSL 15:117db924cf7c 1880 /* Get the contentInfo sequence */
wolfSSL 15:117db924cf7c 1881 if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 1882 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 1883
wolfSSL 15:117db924cf7c 1884 if (length == 0 && pkiMsg[idx-1] == 0x80) {
wolfSSL 15:117db924cf7c 1885 #ifdef ASN_BER_TO_DER
wolfSSL 15:117db924cf7c 1886 word32 len = 0;
wolfSSL 15:117db924cf7c 1887
wolfSSL 15:117db924cf7c 1888 ret = wc_BerToDer(pkiMsg, pkiMsgSz, NULL, &len);
wolfSSL 15:117db924cf7c 1889 if (ret != LENGTH_ONLY_E)
wolfSSL 15:117db924cf7c 1890 return ret;
wolfSSL 15:117db924cf7c 1891 pkcs7->der = (byte*)XMALLOC(len, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 1892 if (pkcs7->der == NULL)
wolfSSL 15:117db924cf7c 1893 return MEMORY_E;
wolfSSL 15:117db924cf7c 1894 ret = wc_BerToDer(pkiMsg, pkiMsgSz, pkcs7->der, &len);
wolfSSL 15:117db924cf7c 1895 if (ret < 0)
wolfSSL 15:117db924cf7c 1896 return ret;
wolfSSL 15:117db924cf7c 1897
wolfSSL 15:117db924cf7c 1898 pkiMsg = pkcs7->der;
wolfSSL 15:117db924cf7c 1899 pkiMsgSz = len;
wolfSSL 15:117db924cf7c 1900 idx = 0;
wolfSSL 15:117db924cf7c 1901 if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 1902 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 1903 #else
wolfSSL 15:117db924cf7c 1904 return BER_INDEF_E;
wolfSSL 15:117db924cf7c 1905 #endif
wolfSSL 15:117db924cf7c 1906 }
wolfSSL 15:117db924cf7c 1907
wolfSSL 15:117db924cf7c 1908 /* Get the contentInfo contentType */
wolfSSL 15:117db924cf7c 1909 if (wc_GetContentType(pkiMsg, &idx, &contentType, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 1910 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 1911
wolfSSL 15:117db924cf7c 1912 if (contentType != SIGNED_DATA) {
wolfSSL 15:117db924cf7c 1913 WOLFSSL_MSG("PKCS#7 input not of type SignedData");
wolfSSL 15:117db924cf7c 1914 return PKCS7_OID_E;
wolfSSL 15:117db924cf7c 1915 }
wolfSSL 15:117db924cf7c 1916
wolfSSL 15:117db924cf7c 1917 /* get the ContentInfo content */
wolfSSL 15:117db924cf7c 1918 if (pkiMsg[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
wolfSSL 15:117db924cf7c 1919 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 1920
wolfSSL 15:117db924cf7c 1921 if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 1922 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 1923
wolfSSL 15:117db924cf7c 1924 /* Get the signedData sequence */
wolfSSL 15:117db924cf7c 1925 if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 1926 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 1927
wolfSSL 15:117db924cf7c 1928 /* Get the version */
wolfSSL 15:117db924cf7c 1929 if (GetMyVersion(pkiMsg, &idx, &version, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 1930 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 1931
wolfSSL 15:117db924cf7c 1932 if (version != 1) {
wolfSSL 15:117db924cf7c 1933 WOLFSSL_MSG("PKCS#7 signedData needs to be of version 1");
wolfSSL 15:117db924cf7c 1934 return ASN_VERSION_E;
wolfSSL 15:117db924cf7c 1935 }
wolfSSL 15:117db924cf7c 1936
wolfSSL 15:117db924cf7c 1937 /* Get the set of DigestAlgorithmIdentifiers */
wolfSSL 15:117db924cf7c 1938 if (GetSet(pkiMsg, &idx, &length, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 1939 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 1940
wolfSSL 15:117db924cf7c 1941 /* Skip the set. */
wolfSSL 15:117db924cf7c 1942 idx += length;
wolfSSL 15:117db924cf7c 1943 degenerate = (length == 0)? 1 : 0;
wolfSSL 15:117db924cf7c 1944
wolfSSL 15:117db924cf7c 1945 /* Get the inner ContentInfo sequence */
wolfSSL 15:117db924cf7c 1946 if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 1947 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 1948
wolfSSL 15:117db924cf7c 1949 /* Get the inner ContentInfo contentType */
wolfSSL 15:117db924cf7c 1950 if (wc_GetContentType(pkiMsg, &idx, &contentType, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 1951 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 1952
wolfSSL 15:117db924cf7c 1953 if (contentType != DATA) {
wolfSSL 15:117db924cf7c 1954 WOLFSSL_MSG("PKCS#7 inner input not of type Data");
wolfSSL 15:117db924cf7c 1955 return PKCS7_OID_E;
wolfSSL 15:117db924cf7c 1956 }
wolfSSL 15:117db924cf7c 1957
wolfSSL 15:117db924cf7c 1958 /* Check for content info, it could be omitted when degenerate */
wolfSSL 15:117db924cf7c 1959 {
wolfSSL 15:117db924cf7c 1960 word32 localIdx = idx;
wolfSSL 15:117db924cf7c 1961 ret = 0;
wolfSSL 15:117db924cf7c 1962 if (pkiMsg[localIdx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
wolfSSL 15:117db924cf7c 1963 ret = ASN_PARSE_E;
wolfSSL 15:117db924cf7c 1964
wolfSSL 15:117db924cf7c 1965 if (ret == 0 && GetLength(pkiMsg, &localIdx, &length, pkiMsgSz) <= 0)
wolfSSL 15:117db924cf7c 1966 ret = ASN_PARSE_E;
wolfSSL 15:117db924cf7c 1967
wolfSSL 15:117db924cf7c 1968 if (ret == 0 && pkiMsg[localIdx++] != ASN_OCTET_STRING)
wolfSSL 15:117db924cf7c 1969 ret = ASN_PARSE_E;
wolfSSL 15:117db924cf7c 1970
wolfSSL 15:117db924cf7c 1971 if (ret == 0 && GetLength(pkiMsg, &localIdx, &length, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 1972 ret = ASN_PARSE_E;
wolfSSL 15:117db924cf7c 1973
wolfSSL 15:117db924cf7c 1974 /* Save the inner data as the content. */
wolfSSL 15:117db924cf7c 1975 if (length > 0) {
wolfSSL 15:117db924cf7c 1976 /* Local pointer for calculating hashes later */
wolfSSL 15:117db924cf7c 1977 content = &pkiMsg[localIdx];
wolfSSL 15:117db924cf7c 1978 contentSz = length;
wolfSSL 15:117db924cf7c 1979 localIdx += length;
wolfSSL 15:117db924cf7c 1980 }
wolfSSL 15:117db924cf7c 1981
wolfSSL 15:117db924cf7c 1982 /* update idx if successful */
wolfSSL 15:117db924cf7c 1983 if (ret == 0) {
wolfSSL 15:117db924cf7c 1984 idx = localIdx;
wolfSSL 15:117db924cf7c 1985 }
wolfSSL 15:117db924cf7c 1986 }
wolfSSL 15:117db924cf7c 1987
wolfSSL 15:117db924cf7c 1988 /* If getting the content info failed with non degenerate then return the
wolfSSL 15:117db924cf7c 1989 * error case. Otherwise with a degenerate it is ok if the content
wolfSSL 15:117db924cf7c 1990 * info was omitted */
wolfSSL 15:117db924cf7c 1991 if (!degenerate && ret != 0) {
wolfSSL 15:117db924cf7c 1992 return ret;
wolfSSL 15:117db924cf7c 1993 }
wolfSSL 15:117db924cf7c 1994
wolfSSL 15:117db924cf7c 1995 /* Get the implicit[0] set of certificates */
wolfSSL 15:117db924cf7c 1996 if (pkiMsg[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) {
wolfSSL 15:117db924cf7c 1997 idx++;
wolfSSL 15:117db924cf7c 1998 if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 1999 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 2000
wolfSSL 15:117db924cf7c 2001 if (length > 0) {
wolfSSL 15:117db924cf7c 2002 /* At this point, idx is at the first certificate in
wolfSSL 15:117db924cf7c 2003 * a set of certificates. There may be more than one,
wolfSSL 15:117db924cf7c 2004 * or none, or they may be a PKCS 6 extended
wolfSSL 15:117db924cf7c 2005 * certificate. We want to save the first cert if it
wolfSSL 15:117db924cf7c 2006 * is X.509. */
wolfSSL 15:117db924cf7c 2007
wolfSSL 15:117db924cf7c 2008 word32 certIdx = idx;
wolfSSL 15:117db924cf7c 2009
wolfSSL 15:117db924cf7c 2010 if (pkiMsg[certIdx++] == (ASN_CONSTRUCTED | ASN_SEQUENCE)) {
wolfSSL 15:117db924cf7c 2011 if (GetLength(pkiMsg, &certIdx, &certSz, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 2012 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 2013
wolfSSL 15:117db924cf7c 2014 cert = &pkiMsg[idx];
wolfSSL 15:117db924cf7c 2015 certSz += (certIdx - idx);
wolfSSL 15:117db924cf7c 2016 }
wolfSSL 15:117db924cf7c 2017
wolfSSL 15:117db924cf7c 2018 #ifdef ASN_BER_TO_DER
wolfSSL 15:117db924cf7c 2019 der = pkcs7->der;
wolfSSL 15:117db924cf7c 2020 #endif
wolfSSL 15:117db924cf7c 2021 /* This will reset PKCS7 structure and then set the certificate */
wolfSSL 15:117db924cf7c 2022 wc_PKCS7_InitWithCert(pkcs7, cert, certSz);
wolfSSL 15:117db924cf7c 2023 #ifdef ASN_BER_TO_DER
wolfSSL 15:117db924cf7c 2024 pkcs7->der = der;
wolfSSL 15:117db924cf7c 2025 #endif
wolfSSL 15:117db924cf7c 2026
wolfSSL 15:117db924cf7c 2027 /* iterate through any additional certificates */
wolfSSL 15:117db924cf7c 2028 if (MAX_PKCS7_CERTS > 0) {
wolfSSL 15:117db924cf7c 2029 word32 localIdx;
wolfSSL 15:117db924cf7c 2030 int sz = 0;
wolfSSL 15:117db924cf7c 2031 int i;
wolfSSL 15:117db924cf7c 2032
wolfSSL 15:117db924cf7c 2033 pkcs7->cert[0] = cert;
wolfSSL 15:117db924cf7c 2034 pkcs7->certSz[0] = certSz;
wolfSSL 15:117db924cf7c 2035 certIdx = idx + certSz;
wolfSSL 15:117db924cf7c 2036
wolfSSL 15:117db924cf7c 2037 for (i = 1; i < MAX_PKCS7_CERTS && certIdx + 1 < pkiMsgSz; i++) {
wolfSSL 15:117db924cf7c 2038 localIdx = certIdx;
wolfSSL 15:117db924cf7c 2039
wolfSSL 15:117db924cf7c 2040 if (pkiMsg[certIdx++] == (ASN_CONSTRUCTED | ASN_SEQUENCE)) {
wolfSSL 15:117db924cf7c 2041 if (GetLength(pkiMsg, &certIdx, &sz, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 2042 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 2043
wolfSSL 15:117db924cf7c 2044 pkcs7->cert[i] = &pkiMsg[localIdx];
wolfSSL 15:117db924cf7c 2045 pkcs7->certSz[i] = sz + (certIdx - localIdx);
wolfSSL 15:117db924cf7c 2046 certIdx += sz;
wolfSSL 15:117db924cf7c 2047 }
wolfSSL 15:117db924cf7c 2048 }
wolfSSL 15:117db924cf7c 2049 }
wolfSSL 15:117db924cf7c 2050 }
wolfSSL 15:117db924cf7c 2051 idx += length;
wolfSSL 15:117db924cf7c 2052 }
wolfSSL 15:117db924cf7c 2053
wolfSSL 15:117db924cf7c 2054 /* set content and size after init of PKCS7 structure */
wolfSSL 15:117db924cf7c 2055 pkcs7->content = content;
wolfSSL 15:117db924cf7c 2056 pkcs7->contentSz = contentSz;
wolfSSL 15:117db924cf7c 2057
wolfSSL 15:117db924cf7c 2058 /* Get the implicit[1] set of crls */
wolfSSL 15:117db924cf7c 2059 if (pkiMsg[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) {
wolfSSL 15:117db924cf7c 2060 idx++;
wolfSSL 15:117db924cf7c 2061 if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 2062 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 2063
wolfSSL 15:117db924cf7c 2064 /* Skip the set */
wolfSSL 15:117db924cf7c 2065 idx += length;
wolfSSL 15:117db924cf7c 2066 }
wolfSSL 15:117db924cf7c 2067
wolfSSL 15:117db924cf7c 2068 /* Get the set of signerInfos */
wolfSSL 15:117db924cf7c 2069 if (GetSet(pkiMsg, &idx, &length, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 2070 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 2071
wolfSSL 15:117db924cf7c 2072 if (length > 0) {
wolfSSL 15:117db924cf7c 2073 /* Get the sequence of the first signerInfo */
wolfSSL 15:117db924cf7c 2074 if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 2075 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 2076
wolfSSL 15:117db924cf7c 2077 /* Get the version */
wolfSSL 15:117db924cf7c 2078 if (GetMyVersion(pkiMsg, &idx, &version, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 2079 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 2080
wolfSSL 15:117db924cf7c 2081 if (version != 1) {
wolfSSL 15:117db924cf7c 2082 WOLFSSL_MSG("PKCS#7 signerInfo needs to be of version 1");
wolfSSL 15:117db924cf7c 2083 return ASN_VERSION_E;
wolfSSL 15:117db924cf7c 2084 }
wolfSSL 15:117db924cf7c 2085
wolfSSL 15:117db924cf7c 2086 /* Get the sequence of IssuerAndSerialNumber */
wolfSSL 15:117db924cf7c 2087 if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 2088 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 2089
wolfSSL 15:117db924cf7c 2090 /* Skip it */
wolfSSL 15:117db924cf7c 2091 idx += length;
wolfSSL 15:117db924cf7c 2092
wolfSSL 15:117db924cf7c 2093 /* Get the sequence of digestAlgorithm */
wolfSSL 15:117db924cf7c 2094 if (GetAlgoId(pkiMsg, &idx, &hashOID, oidHashType, pkiMsgSz) < 0) {
wolfSSL 15:117db924cf7c 2095 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 2096 }
wolfSSL 15:117db924cf7c 2097 pkcs7->hashOID = (int)hashOID;
wolfSSL 15:117db924cf7c 2098
wolfSSL 15:117db924cf7c 2099 /* Get the IMPLICIT[0] SET OF signedAttributes */
wolfSSL 15:117db924cf7c 2100 if (pkiMsg[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) {
wolfSSL 15:117db924cf7c 2101 idx++;
wolfSSL 15:117db924cf7c 2102
wolfSSL 15:117db924cf7c 2103 if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 2104 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 2105
wolfSSL 15:117db924cf7c 2106 /* save pointer and length */
wolfSSL 15:117db924cf7c 2107 signedAttrib = &pkiMsg[idx];
wolfSSL 15:117db924cf7c 2108 signedAttribSz = length;
wolfSSL 15:117db924cf7c 2109
wolfSSL 15:117db924cf7c 2110 if (wc_PKCS7_ParseAttribs(pkcs7, signedAttrib, signedAttribSz) <0) {
wolfSSL 15:117db924cf7c 2111 WOLFSSL_MSG("Error parsing signed attributes");
wolfSSL 15:117db924cf7c 2112 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 2113 }
wolfSSL 15:117db924cf7c 2114
wolfSSL 15:117db924cf7c 2115 idx += length;
wolfSSL 15:117db924cf7c 2116 }
wolfSSL 15:117db924cf7c 2117
wolfSSL 15:117db924cf7c 2118 /* Get digestEncryptionAlgorithm */
wolfSSL 15:117db924cf7c 2119 if (GetAlgoId(pkiMsg, &idx, &sigOID, oidSigType, pkiMsgSz) < 0) {
wolfSSL 15:117db924cf7c 2120 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 2121 }
wolfSSL 15:117db924cf7c 2122
wolfSSL 15:117db924cf7c 2123 /* store public key type based on digestEncryptionAlgorithm */
wolfSSL 15:117db924cf7c 2124 ret = wc_PKCS7_SetPublicKeyOID(pkcs7, sigOID);
wolfSSL 15:117db924cf7c 2125 if (ret <= 0) {
wolfSSL 15:117db924cf7c 2126 WOLFSSL_MSG("Failed to set public key OID from signature");
wolfSSL 15:117db924cf7c 2127 return ret;
wolfSSL 15:117db924cf7c 2128 }
wolfSSL 15:117db924cf7c 2129
wolfSSL 15:117db924cf7c 2130 /* Get the signature */
wolfSSL 15:117db924cf7c 2131 if (pkiMsg[idx] == ASN_OCTET_STRING) {
wolfSSL 15:117db924cf7c 2132 idx++;
wolfSSL 15:117db924cf7c 2133
wolfSSL 15:117db924cf7c 2134 if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 2135 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 2136
wolfSSL 15:117db924cf7c 2137 /* save pointer and length */
wolfSSL 15:117db924cf7c 2138 sig = &pkiMsg[idx];
wolfSSL 15:117db924cf7c 2139 sigSz = length;
wolfSSL 15:117db924cf7c 2140
wolfSSL 15:117db924cf7c 2141 idx += length;
wolfSSL 15:117db924cf7c 2142 }
wolfSSL 15:117db924cf7c 2143
wolfSSL 15:117db924cf7c 2144 pkcs7->content = content;
wolfSSL 15:117db924cf7c 2145 pkcs7->contentSz = contentSz;
wolfSSL 15:117db924cf7c 2146
wolfSSL 15:117db924cf7c 2147 ret = wc_PKCS7_SignedDataVerifySignature(pkcs7, sig, sigSz,
wolfSSL 15:117db924cf7c 2148 signedAttrib, signedAttribSz);
wolfSSL 15:117db924cf7c 2149 if (ret < 0)
wolfSSL 15:117db924cf7c 2150 return ret;
wolfSSL 15:117db924cf7c 2151 }
wolfSSL 15:117db924cf7c 2152
wolfSSL 15:117db924cf7c 2153 return 0;
wolfSSL 15:117db924cf7c 2154 }
wolfSSL 15:117db924cf7c 2155
wolfSSL 15:117db924cf7c 2156
wolfSSL 15:117db924cf7c 2157 #ifdef HAVE_ECC
wolfSSL 15:117db924cf7c 2158
wolfSSL 15:117db924cf7c 2159 /* KARI == KeyAgreeRecipientInfo (key agreement) */
wolfSSL 15:117db924cf7c 2160 typedef struct WC_PKCS7_KARI {
wolfSSL 15:117db924cf7c 2161 DecodedCert* decoded; /* decoded recip cert */
wolfSSL 15:117db924cf7c 2162 void* heap; /* user heap, points to PKCS7->heap */
wolfSSL 15:117db924cf7c 2163 int devId; /* device ID for HW based private key */
wolfSSL 15:117db924cf7c 2164 ecc_key* recipKey; /* recip key (pub | priv) */
wolfSSL 15:117db924cf7c 2165 ecc_key* senderKey; /* sender key (pub | priv) */
wolfSSL 15:117db924cf7c 2166 byte* senderKeyExport; /* sender ephemeral key DER */
wolfSSL 15:117db924cf7c 2167 byte* kek; /* key encryption key */
wolfSSL 15:117db924cf7c 2168 byte* ukm; /* OPTIONAL user keying material */
wolfSSL 15:117db924cf7c 2169 byte* sharedInfo; /* ECC-CMS-SharedInfo ASN.1 encoded blob */
wolfSSL 15:117db924cf7c 2170 word32 senderKeyExportSz; /* size of sender ephemeral key DER */
wolfSSL 15:117db924cf7c 2171 word32 kekSz; /* size of key encryption key */
wolfSSL 15:117db924cf7c 2172 word32 ukmSz; /* size of user keying material */
wolfSSL 15:117db924cf7c 2173 word32 sharedInfoSz; /* size of ECC-CMS-SharedInfo encoded */
wolfSSL 15:117db924cf7c 2174 byte ukmOwner; /* do we own ukm buffer? 1:yes, 0:no */
wolfSSL 15:117db924cf7c 2175 byte direction; /* WC_PKCS7_ENCODE | WC_PKCS7_DECODE */
wolfSSL 15:117db924cf7c 2176 byte decodedInit : 1; /* indicates decoded was initialized */
wolfSSL 15:117db924cf7c 2177 byte recipKeyInit : 1; /* indicates recipKey was initialized */
wolfSSL 15:117db924cf7c 2178 byte senderKeyInit : 1; /* indicates senderKey was initialized */
wolfSSL 15:117db924cf7c 2179 } WC_PKCS7_KARI;
wolfSSL 15:117db924cf7c 2180
wolfSSL 15:117db924cf7c 2181
wolfSSL 15:117db924cf7c 2182 /* wrap CEK (content encryption key) with KEK, 0 on success, < 0 on error */
wolfSSL 15:117db924cf7c 2183 static int wc_PKCS7_KariKeyWrap(byte* cek, word32 cekSz, byte* kek,
wolfSSL 15:117db924cf7c 2184 word32 kekSz, byte* out, word32 outSz,
wolfSSL 15:117db924cf7c 2185 int keyWrapAlgo, int direction)
wolfSSL 15:117db924cf7c 2186 {
wolfSSL 15:117db924cf7c 2187 int ret;
wolfSSL 15:117db924cf7c 2188
wolfSSL 15:117db924cf7c 2189 if (cek == NULL || kek == NULL || out == NULL)
wolfSSL 15:117db924cf7c 2190 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 2191
wolfSSL 15:117db924cf7c 2192 switch (keyWrapAlgo) {
wolfSSL 15:117db924cf7c 2193 #ifndef NO_AES
wolfSSL 15:117db924cf7c 2194 #ifdef WOLFSSL_AES_128
wolfSSL 15:117db924cf7c 2195 case AES128_WRAP:
wolfSSL 15:117db924cf7c 2196 #endif
wolfSSL 15:117db924cf7c 2197 #ifdef WOLFSSL_AES_192
wolfSSL 15:117db924cf7c 2198 case AES192_WRAP:
wolfSSL 15:117db924cf7c 2199 #endif
wolfSSL 15:117db924cf7c 2200 #ifdef WOLFSSL_AES_256
wolfSSL 15:117db924cf7c 2201 case AES256_WRAP:
wolfSSL 15:117db924cf7c 2202 #endif
wolfSSL 15:117db924cf7c 2203
wolfSSL 15:117db924cf7c 2204 if (direction == AES_ENCRYPTION) {
wolfSSL 15:117db924cf7c 2205
wolfSSL 15:117db924cf7c 2206 ret = wc_AesKeyWrap(kek, kekSz, cek, cekSz,
wolfSSL 15:117db924cf7c 2207 out, outSz, NULL);
wolfSSL 15:117db924cf7c 2208
wolfSSL 15:117db924cf7c 2209 } else if (direction == AES_DECRYPTION) {
wolfSSL 15:117db924cf7c 2210
wolfSSL 15:117db924cf7c 2211 ret = wc_AesKeyUnWrap(kek, kekSz, cek, cekSz,
wolfSSL 15:117db924cf7c 2212 out, outSz, NULL);
wolfSSL 15:117db924cf7c 2213 } else {
wolfSSL 15:117db924cf7c 2214 WOLFSSL_MSG("Bad key un/wrap direction");
wolfSSL 15:117db924cf7c 2215 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 2216 }
wolfSSL 15:117db924cf7c 2217
wolfSSL 15:117db924cf7c 2218 if (ret <= 0)
wolfSSL 15:117db924cf7c 2219 return ret;
wolfSSL 15:117db924cf7c 2220
wolfSSL 15:117db924cf7c 2221 break;
wolfSSL 15:117db924cf7c 2222 #endif /* NO_AES */
wolfSSL 15:117db924cf7c 2223
wolfSSL 15:117db924cf7c 2224 default:
wolfSSL 15:117db924cf7c 2225 WOLFSSL_MSG("Unsupported key wrap algorithm");
wolfSSL 15:117db924cf7c 2226 return BAD_KEYWRAP_ALG_E;
wolfSSL 15:117db924cf7c 2227 };
wolfSSL 15:117db924cf7c 2228
wolfSSL 15:117db924cf7c 2229 (void)cekSz;
wolfSSL 15:117db924cf7c 2230 (void)kekSz;
wolfSSL 15:117db924cf7c 2231 (void)outSz;
wolfSSL 15:117db924cf7c 2232 (void)direction;
wolfSSL 15:117db924cf7c 2233 return ret;
wolfSSL 15:117db924cf7c 2234 }
wolfSSL 15:117db924cf7c 2235
wolfSSL 15:117db924cf7c 2236
wolfSSL 15:117db924cf7c 2237 /* allocate and create new WC_PKCS7_KARI struct,
wolfSSL 15:117db924cf7c 2238 * returns struct pointer on success, NULL on failure */
wolfSSL 15:117db924cf7c 2239 static WC_PKCS7_KARI* wc_PKCS7_KariNew(PKCS7* pkcs7, byte direction)
wolfSSL 15:117db924cf7c 2240 {
wolfSSL 15:117db924cf7c 2241 WC_PKCS7_KARI* kari = NULL;
wolfSSL 15:117db924cf7c 2242
wolfSSL 15:117db924cf7c 2243 if (pkcs7 == NULL)
wolfSSL 15:117db924cf7c 2244 return NULL;
wolfSSL 15:117db924cf7c 2245
wolfSSL 15:117db924cf7c 2246 kari = (WC_PKCS7_KARI*)XMALLOC(sizeof(WC_PKCS7_KARI), pkcs7->heap,
wolfSSL 15:117db924cf7c 2247 DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 2248 if (kari == NULL) {
wolfSSL 15:117db924cf7c 2249 WOLFSSL_MSG("Failed to allocate WC_PKCS7_KARI");
wolfSSL 15:117db924cf7c 2250 return NULL;
wolfSSL 15:117db924cf7c 2251 }
wolfSSL 15:117db924cf7c 2252
wolfSSL 15:117db924cf7c 2253 kari->decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), pkcs7->heap,
wolfSSL 15:117db924cf7c 2254 DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 2255 if (kari->decoded == NULL) {
wolfSSL 15:117db924cf7c 2256 WOLFSSL_MSG("Failed to allocate DecodedCert");
wolfSSL 15:117db924cf7c 2257 XFREE(kari, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 2258 return NULL;
wolfSSL 15:117db924cf7c 2259 }
wolfSSL 15:117db924cf7c 2260
wolfSSL 15:117db924cf7c 2261 kari->recipKey = (ecc_key*)XMALLOC(sizeof(ecc_key), pkcs7->heap,
wolfSSL 15:117db924cf7c 2262 DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 2263 if (kari->recipKey == NULL) {
wolfSSL 15:117db924cf7c 2264 WOLFSSL_MSG("Failed to allocate recipient ecc_key");
wolfSSL 15:117db924cf7c 2265 XFREE(kari->decoded, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 2266 XFREE(kari, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 2267 return NULL;
wolfSSL 15:117db924cf7c 2268 }
wolfSSL 15:117db924cf7c 2269
wolfSSL 15:117db924cf7c 2270 kari->senderKey = (ecc_key*)XMALLOC(sizeof(ecc_key), pkcs7->heap,
wolfSSL 15:117db924cf7c 2271 DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 2272 if (kari->senderKey == NULL) {
wolfSSL 15:117db924cf7c 2273 WOLFSSL_MSG("Failed to allocate sender ecc_key");
wolfSSL 15:117db924cf7c 2274 XFREE(kari->recipKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 2275 XFREE(kari->decoded, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 2276 XFREE(kari, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 2277 return NULL;
wolfSSL 15:117db924cf7c 2278 }
wolfSSL 15:117db924cf7c 2279
wolfSSL 15:117db924cf7c 2280 kari->senderKeyExport = NULL;
wolfSSL 15:117db924cf7c 2281 kari->senderKeyExportSz = 0;
wolfSSL 15:117db924cf7c 2282 kari->kek = NULL;
wolfSSL 15:117db924cf7c 2283 kari->kekSz = 0;
wolfSSL 15:117db924cf7c 2284 kari->ukm = NULL;
wolfSSL 15:117db924cf7c 2285 kari->ukmSz = 0;
wolfSSL 15:117db924cf7c 2286 kari->ukmOwner = 0;
wolfSSL 15:117db924cf7c 2287 kari->sharedInfo = NULL;
wolfSSL 15:117db924cf7c 2288 kari->sharedInfoSz = 0;
wolfSSL 15:117db924cf7c 2289 kari->direction = direction;
wolfSSL 15:117db924cf7c 2290 kari->decodedInit = 0;
wolfSSL 15:117db924cf7c 2291 kari->recipKeyInit = 0;
wolfSSL 15:117db924cf7c 2292 kari->senderKeyInit = 0;
wolfSSL 15:117db924cf7c 2293
wolfSSL 15:117db924cf7c 2294 kari->heap = pkcs7->heap;
wolfSSL 15:117db924cf7c 2295 kari->devId = pkcs7->devId;
wolfSSL 15:117db924cf7c 2296
wolfSSL 15:117db924cf7c 2297 return kari;
wolfSSL 15:117db924cf7c 2298 }
wolfSSL 15:117db924cf7c 2299
wolfSSL 15:117db924cf7c 2300
wolfSSL 15:117db924cf7c 2301 /* free WC_PKCS7_KARI struct, return 0 on success */
wolfSSL 15:117db924cf7c 2302 static int wc_PKCS7_KariFree(WC_PKCS7_KARI* kari)
wolfSSL 15:117db924cf7c 2303 {
wolfSSL 15:117db924cf7c 2304 void* heap;
wolfSSL 15:117db924cf7c 2305
wolfSSL 15:117db924cf7c 2306 if (kari) {
wolfSSL 15:117db924cf7c 2307 heap = kari->heap;
wolfSSL 15:117db924cf7c 2308
wolfSSL 15:117db924cf7c 2309 if (kari->decoded) {
wolfSSL 15:117db924cf7c 2310 if (kari->decodedInit)
wolfSSL 15:117db924cf7c 2311 FreeDecodedCert(kari->decoded);
wolfSSL 15:117db924cf7c 2312 XFREE(kari->decoded, heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 2313 }
wolfSSL 15:117db924cf7c 2314 if (kari->senderKey) {
wolfSSL 15:117db924cf7c 2315 if (kari->senderKeyInit)
wolfSSL 15:117db924cf7c 2316 wc_ecc_free(kari->senderKey);
wolfSSL 15:117db924cf7c 2317 XFREE(kari->senderKey, heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 2318 }
wolfSSL 15:117db924cf7c 2319 if (kari->recipKey) {
wolfSSL 15:117db924cf7c 2320 if (kari->recipKeyInit)
wolfSSL 15:117db924cf7c 2321 wc_ecc_free(kari->recipKey);
wolfSSL 15:117db924cf7c 2322 XFREE(kari->recipKey, heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 2323 }
wolfSSL 15:117db924cf7c 2324 if (kari->senderKeyExport) {
wolfSSL 15:117db924cf7c 2325 ForceZero(kari->senderKeyExport, kari->senderKeyExportSz);
wolfSSL 15:117db924cf7c 2326 XFREE(kari->senderKeyExport, heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 2327 kari->senderKeyExportSz = 0;
wolfSSL 15:117db924cf7c 2328 }
wolfSSL 15:117db924cf7c 2329 if (kari->kek) {
wolfSSL 15:117db924cf7c 2330 ForceZero(kari->kek, kari->kekSz);
wolfSSL 15:117db924cf7c 2331 XFREE(kari->kek, heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 2332 kari->kekSz = 0;
wolfSSL 15:117db924cf7c 2333 }
wolfSSL 15:117db924cf7c 2334 if (kari->ukm) {
wolfSSL 15:117db924cf7c 2335 if (kari->ukmOwner == 1) {
wolfSSL 15:117db924cf7c 2336 XFREE(kari->ukm, heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 2337 }
wolfSSL 15:117db924cf7c 2338 kari->ukmSz = 0;
wolfSSL 15:117db924cf7c 2339 }
wolfSSL 15:117db924cf7c 2340 if (kari->sharedInfo) {
wolfSSL 15:117db924cf7c 2341 ForceZero(kari->sharedInfo, kari->sharedInfoSz);
wolfSSL 15:117db924cf7c 2342 XFREE(kari->sharedInfo, heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 2343 kari->sharedInfoSz = 0;
wolfSSL 15:117db924cf7c 2344 }
wolfSSL 15:117db924cf7c 2345 XFREE(kari, heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 2346 }
wolfSSL 15:117db924cf7c 2347
wolfSSL 15:117db924cf7c 2348 (void)heap;
wolfSSL 15:117db924cf7c 2349
wolfSSL 15:117db924cf7c 2350 return 0;
wolfSSL 15:117db924cf7c 2351 }
wolfSSL 15:117db924cf7c 2352
wolfSSL 15:117db924cf7c 2353
wolfSSL 15:117db924cf7c 2354 /* parse recipient cert/key, return 0 on success, negative on error
wolfSSL 15:117db924cf7c 2355 * key/keySz only needed during decoding (WC_PKCS7_DECODE) */
wolfSSL 15:117db924cf7c 2356 static int wc_PKCS7_KariParseRecipCert(WC_PKCS7_KARI* kari, const byte* cert,
wolfSSL 15:117db924cf7c 2357 word32 certSz, const byte* key,
wolfSSL 15:117db924cf7c 2358 word32 keySz)
wolfSSL 15:117db924cf7c 2359 {
wolfSSL 15:117db924cf7c 2360 int ret;
wolfSSL 15:117db924cf7c 2361 word32 idx;
wolfSSL 15:117db924cf7c 2362
wolfSSL 15:117db924cf7c 2363 if (kari == NULL || kari->decoded == NULL ||
wolfSSL 15:117db924cf7c 2364 cert == NULL || certSz == 0)
wolfSSL 15:117db924cf7c 2365 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 2366
wolfSSL 15:117db924cf7c 2367 /* decode certificate */
wolfSSL 15:117db924cf7c 2368 InitDecodedCert(kari->decoded, (byte*)cert, certSz, kari->heap);
wolfSSL 15:117db924cf7c 2369 kari->decodedInit = 1;
wolfSSL 15:117db924cf7c 2370 ret = ParseCert(kari->decoded, CA_TYPE, NO_VERIFY, 0);
wolfSSL 15:117db924cf7c 2371 if (ret < 0)
wolfSSL 15:117db924cf7c 2372 return ret;
wolfSSL 15:117db924cf7c 2373
wolfSSL 15:117db924cf7c 2374 /* make sure subject key id was read from cert */
wolfSSL 15:117db924cf7c 2375 if (kari->decoded->extSubjKeyIdSet == 0) {
wolfSSL 15:117db924cf7c 2376 WOLFSSL_MSG("Failed to read subject key ID from recipient cert");
wolfSSL 15:117db924cf7c 2377 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 2378 }
wolfSSL 15:117db924cf7c 2379
wolfSSL 15:117db924cf7c 2380 ret = wc_ecc_init_ex(kari->recipKey, kari->heap, kari->devId);
wolfSSL 15:117db924cf7c 2381 if (ret != 0)
wolfSSL 15:117db924cf7c 2382 return ret;
wolfSSL 15:117db924cf7c 2383
wolfSSL 15:117db924cf7c 2384 kari->recipKeyInit = 1;
wolfSSL 15:117db924cf7c 2385
wolfSSL 15:117db924cf7c 2386 /* get recip public key */
wolfSSL 15:117db924cf7c 2387 if (kari->direction == WC_PKCS7_ENCODE) {
wolfSSL 15:117db924cf7c 2388
wolfSSL 15:117db924cf7c 2389 idx = 0;
wolfSSL 15:117db924cf7c 2390 ret = wc_EccPublicKeyDecode(kari->decoded->publicKey, &idx,
wolfSSL 15:117db924cf7c 2391 kari->recipKey, kari->decoded->pubKeySize);
wolfSSL 15:117db924cf7c 2392 if (ret != 0)
wolfSSL 15:117db924cf7c 2393 return ret;
wolfSSL 15:117db924cf7c 2394 }
wolfSSL 15:117db924cf7c 2395 /* get recip private key */
wolfSSL 15:117db924cf7c 2396 else if (kari->direction == WC_PKCS7_DECODE) {
wolfSSL 15:117db924cf7c 2397 if (key != NULL && keySz > 0) {
wolfSSL 15:117db924cf7c 2398 idx = 0;
wolfSSL 15:117db924cf7c 2399 ret = wc_EccPrivateKeyDecode(key, &idx, kari->recipKey, keySz);
wolfSSL 15:117db924cf7c 2400 }
wolfSSL 15:117db924cf7c 2401 else if (kari->devId == INVALID_DEVID) {
wolfSSL 15:117db924cf7c 2402 ret = BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 2403 }
wolfSSL 15:117db924cf7c 2404 if (ret != 0)
wolfSSL 15:117db924cf7c 2405 return ret;
wolfSSL 15:117db924cf7c 2406
wolfSSL 15:117db924cf7c 2407 } else {
wolfSSL 15:117db924cf7c 2408 /* bad direction */
wolfSSL 15:117db924cf7c 2409 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 2410 }
wolfSSL 15:117db924cf7c 2411
wolfSSL 15:117db924cf7c 2412 (void)idx;
wolfSSL 15:117db924cf7c 2413
wolfSSL 15:117db924cf7c 2414 return 0;
wolfSSL 15:117db924cf7c 2415 }
wolfSSL 15:117db924cf7c 2416
wolfSSL 15:117db924cf7c 2417
wolfSSL 15:117db924cf7c 2418 /* create ephemeral ECC key, places ecc_key in kari->senderKey,
wolfSSL 15:117db924cf7c 2419 * DER encoded in kari->senderKeyExport. return 0 on success,
wolfSSL 15:117db924cf7c 2420 * negative on error */
wolfSSL 15:117db924cf7c 2421 static int wc_PKCS7_KariGenerateEphemeralKey(WC_PKCS7_KARI* kari, WC_RNG* rng)
wolfSSL 15:117db924cf7c 2422 {
wolfSSL 15:117db924cf7c 2423 int ret;
wolfSSL 15:117db924cf7c 2424
wolfSSL 15:117db924cf7c 2425 if (kari == NULL || kari->decoded == NULL ||
wolfSSL 15:117db924cf7c 2426 kari->recipKey == NULL || kari->recipKey->dp == NULL ||
wolfSSL 15:117db924cf7c 2427 rng == NULL)
wolfSSL 15:117db924cf7c 2428 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 2429
wolfSSL 15:117db924cf7c 2430 kari->senderKeyExport = (byte*)XMALLOC(kari->decoded->pubKeySize,
wolfSSL 15:117db924cf7c 2431 kari->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 2432 if (kari->senderKeyExport == NULL)
wolfSSL 15:117db924cf7c 2433 return MEMORY_E;
wolfSSL 15:117db924cf7c 2434
wolfSSL 15:117db924cf7c 2435 kari->senderKeyExportSz = kari->decoded->pubKeySize;
wolfSSL 15:117db924cf7c 2436
wolfSSL 15:117db924cf7c 2437 ret = wc_ecc_init_ex(kari->senderKey, kari->heap, kari->devId);
wolfSSL 15:117db924cf7c 2438 if (ret != 0)
wolfSSL 15:117db924cf7c 2439 return ret;
wolfSSL 15:117db924cf7c 2440
wolfSSL 15:117db924cf7c 2441 kari->senderKeyInit = 1;
wolfSSL 15:117db924cf7c 2442
wolfSSL 15:117db924cf7c 2443 ret = wc_ecc_make_key_ex(rng, kari->recipKey->dp->size,
wolfSSL 15:117db924cf7c 2444 kari->senderKey, kari->recipKey->dp->id);
wolfSSL 15:117db924cf7c 2445 if (ret != 0)
wolfSSL 15:117db924cf7c 2446 return ret;
wolfSSL 15:117db924cf7c 2447
wolfSSL 15:117db924cf7c 2448 /* dump generated key to X.963 DER for output in CMS bundle */
wolfSSL 15:117db924cf7c 2449 ret = wc_ecc_export_x963(kari->senderKey, kari->senderKeyExport,
wolfSSL 15:117db924cf7c 2450 &kari->senderKeyExportSz);
wolfSSL 15:117db924cf7c 2451 if (ret != 0)
wolfSSL 15:117db924cf7c 2452 return ret;
wolfSSL 15:117db924cf7c 2453
wolfSSL 15:117db924cf7c 2454 return 0;
wolfSSL 15:117db924cf7c 2455 }
wolfSSL 15:117db924cf7c 2456
wolfSSL 15:117db924cf7c 2457
wolfSSL 15:117db924cf7c 2458 /* create ASN.1 encoded ECC-CMS-SharedInfo using specified key wrap algorithm,
wolfSSL 15:117db924cf7c 2459 * place in kari->sharedInfo. returns 0 on success, negative on error */
wolfSSL 15:117db924cf7c 2460 static int wc_PKCS7_KariGenerateSharedInfo(WC_PKCS7_KARI* kari, int keyWrapOID)
wolfSSL 15:117db924cf7c 2461 {
wolfSSL 15:117db924cf7c 2462 int idx = 0;
wolfSSL 15:117db924cf7c 2463 int sharedInfoSeqSz = 0;
wolfSSL 15:117db924cf7c 2464 int keyInfoSz = 0;
wolfSSL 15:117db924cf7c 2465 int suppPubInfoSeqSz = 0;
wolfSSL 15:117db924cf7c 2466 int entityUInfoOctetSz = 0;
wolfSSL 15:117db924cf7c 2467 int entityUInfoExplicitSz = 0;
wolfSSL 15:117db924cf7c 2468 int kekOctetSz = 0;
wolfSSL 15:117db924cf7c 2469 int sharedInfoSz = 0;
wolfSSL 15:117db924cf7c 2470
wolfSSL 15:117db924cf7c 2471 word32 kekBitSz = 0;
wolfSSL 15:117db924cf7c 2472
wolfSSL 15:117db924cf7c 2473 byte sharedInfoSeq[MAX_SEQ_SZ];
wolfSSL 15:117db924cf7c 2474 byte keyInfo[MAX_ALGO_SZ];
wolfSSL 15:117db924cf7c 2475 byte suppPubInfoSeq[MAX_SEQ_SZ];
wolfSSL 15:117db924cf7c 2476 byte entityUInfoOctet[MAX_OCTET_STR_SZ];
wolfSSL 15:117db924cf7c 2477 byte entityUInfoExplicitSeq[MAX_SEQ_SZ];
wolfSSL 15:117db924cf7c 2478 byte kekOctet[MAX_OCTET_STR_SZ];
wolfSSL 15:117db924cf7c 2479
wolfSSL 15:117db924cf7c 2480 if (kari == NULL)
wolfSSL 15:117db924cf7c 2481 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 2482
wolfSSL 15:117db924cf7c 2483 if ((kari->ukmSz > 0) && (kari->ukm == NULL))
wolfSSL 15:117db924cf7c 2484 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 2485
wolfSSL 15:117db924cf7c 2486 /* kekOctet */
wolfSSL 15:117db924cf7c 2487 kekOctetSz = SetOctetString(sizeof(word32), kekOctet);
wolfSSL 15:117db924cf7c 2488 sharedInfoSz += (kekOctetSz + sizeof(word32));
wolfSSL 15:117db924cf7c 2489
wolfSSL 15:117db924cf7c 2490 /* suppPubInfo */
wolfSSL 15:117db924cf7c 2491 suppPubInfoSeqSz = SetImplicit(ASN_SEQUENCE, 2,
wolfSSL 15:117db924cf7c 2492 kekOctetSz + sizeof(word32),
wolfSSL 15:117db924cf7c 2493 suppPubInfoSeq);
wolfSSL 15:117db924cf7c 2494 sharedInfoSz += suppPubInfoSeqSz;
wolfSSL 15:117db924cf7c 2495
wolfSSL 15:117db924cf7c 2496 /* optional ukm/entityInfo */
wolfSSL 15:117db924cf7c 2497 if (kari->ukmSz > 0) {
wolfSSL 15:117db924cf7c 2498 entityUInfoOctetSz = SetOctetString(kari->ukmSz, entityUInfoOctet);
wolfSSL 15:117db924cf7c 2499 sharedInfoSz += (entityUInfoOctetSz + kari->ukmSz);
wolfSSL 15:117db924cf7c 2500
wolfSSL 15:117db924cf7c 2501 entityUInfoExplicitSz = SetExplicit(0, entityUInfoOctetSz +
wolfSSL 15:117db924cf7c 2502 kari->ukmSz,
wolfSSL 15:117db924cf7c 2503 entityUInfoExplicitSeq);
wolfSSL 15:117db924cf7c 2504 sharedInfoSz += entityUInfoExplicitSz;
wolfSSL 15:117db924cf7c 2505 }
wolfSSL 15:117db924cf7c 2506
wolfSSL 15:117db924cf7c 2507 /* keyInfo */
wolfSSL 15:117db924cf7c 2508 keyInfoSz = SetAlgoID(keyWrapOID, keyInfo, oidKeyWrapType, 0);
wolfSSL 15:117db924cf7c 2509 sharedInfoSz += keyInfoSz;
wolfSSL 15:117db924cf7c 2510
wolfSSL 15:117db924cf7c 2511 /* sharedInfo */
wolfSSL 15:117db924cf7c 2512 sharedInfoSeqSz = SetSequence(sharedInfoSz, sharedInfoSeq);
wolfSSL 15:117db924cf7c 2513 sharedInfoSz += sharedInfoSeqSz;
wolfSSL 15:117db924cf7c 2514
wolfSSL 15:117db924cf7c 2515 kari->sharedInfo = (byte*)XMALLOC(sharedInfoSz, kari->heap,
wolfSSL 15:117db924cf7c 2516 DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 2517 if (kari->sharedInfo == NULL)
wolfSSL 15:117db924cf7c 2518 return MEMORY_E;
wolfSSL 15:117db924cf7c 2519
wolfSSL 15:117db924cf7c 2520 kari->sharedInfoSz = sharedInfoSz;
wolfSSL 15:117db924cf7c 2521
wolfSSL 15:117db924cf7c 2522 XMEMCPY(kari->sharedInfo + idx, sharedInfoSeq, sharedInfoSeqSz);
wolfSSL 15:117db924cf7c 2523 idx += sharedInfoSeqSz;
wolfSSL 15:117db924cf7c 2524 XMEMCPY(kari->sharedInfo + idx, keyInfo, keyInfoSz);
wolfSSL 15:117db924cf7c 2525 idx += keyInfoSz;
wolfSSL 15:117db924cf7c 2526 if (kari->ukmSz > 0) {
wolfSSL 15:117db924cf7c 2527 XMEMCPY(kari->sharedInfo + idx, entityUInfoExplicitSeq,
wolfSSL 15:117db924cf7c 2528 entityUInfoExplicitSz);
wolfSSL 15:117db924cf7c 2529 idx += entityUInfoExplicitSz;
wolfSSL 15:117db924cf7c 2530 XMEMCPY(kari->sharedInfo + idx, entityUInfoOctet, entityUInfoOctetSz);
wolfSSL 15:117db924cf7c 2531 idx += entityUInfoOctetSz;
wolfSSL 15:117db924cf7c 2532 XMEMCPY(kari->sharedInfo + idx, kari->ukm, kari->ukmSz);
wolfSSL 15:117db924cf7c 2533 idx += kari->ukmSz;
wolfSSL 15:117db924cf7c 2534 }
wolfSSL 15:117db924cf7c 2535 XMEMCPY(kari->sharedInfo + idx, suppPubInfoSeq, suppPubInfoSeqSz);
wolfSSL 15:117db924cf7c 2536 idx += suppPubInfoSeqSz;
wolfSSL 15:117db924cf7c 2537 XMEMCPY(kari->sharedInfo + idx, kekOctet, kekOctetSz);
wolfSSL 15:117db924cf7c 2538 idx += kekOctetSz;
wolfSSL 15:117db924cf7c 2539
wolfSSL 15:117db924cf7c 2540 kekBitSz = (kari->kekSz) * 8; /* convert to bits */
wolfSSL 15:117db924cf7c 2541 #ifdef LITTLE_ENDIAN_ORDER
wolfSSL 15:117db924cf7c 2542 kekBitSz = ByteReverseWord32(kekBitSz); /* network byte order */
wolfSSL 15:117db924cf7c 2543 #endif
wolfSSL 15:117db924cf7c 2544 XMEMCPY(kari->sharedInfo + idx, &kekBitSz, sizeof(kekBitSz));
wolfSSL 15:117db924cf7c 2545
wolfSSL 15:117db924cf7c 2546 return 0;
wolfSSL 15:117db924cf7c 2547 }
wolfSSL 15:117db924cf7c 2548
wolfSSL 15:117db924cf7c 2549
wolfSSL 15:117db924cf7c 2550 /* create key encryption key (KEK) using key wrap algorithm and key encryption
wolfSSL 15:117db924cf7c 2551 * algorithm, place in kari->kek. return 0 on success, <0 on error. */
wolfSSL 15:117db924cf7c 2552 static int wc_PKCS7_KariGenerateKEK(WC_PKCS7_KARI* kari,
wolfSSL 15:117db924cf7c 2553 int keyWrapOID, int keyEncOID)
wolfSSL 15:117db924cf7c 2554 {
wolfSSL 15:117db924cf7c 2555 int ret;
wolfSSL 15:117db924cf7c 2556 int kSz;
wolfSSL 15:117db924cf7c 2557 enum wc_HashType kdfType;
wolfSSL 15:117db924cf7c 2558 byte* secret;
wolfSSL 15:117db924cf7c 2559 word32 secretSz;
wolfSSL 15:117db924cf7c 2560
wolfSSL 15:117db924cf7c 2561 if (kari == NULL || kari->recipKey == NULL ||
wolfSSL 15:117db924cf7c 2562 kari->senderKey == NULL || kari->senderKey->dp == NULL)
wolfSSL 15:117db924cf7c 2563 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 2564
wolfSSL 15:117db924cf7c 2565 /* get KEK size, allocate buff */
wolfSSL 15:117db924cf7c 2566 kSz = wc_PKCS7_GetOIDKeySize(keyWrapOID);
wolfSSL 15:117db924cf7c 2567 if (kSz < 0)
wolfSSL 15:117db924cf7c 2568 return kSz;
wolfSSL 15:117db924cf7c 2569
wolfSSL 15:117db924cf7c 2570 kari->kek = (byte*)XMALLOC(kSz, kari->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 2571 if (kari->kek == NULL)
wolfSSL 15:117db924cf7c 2572 return MEMORY_E;
wolfSSL 15:117db924cf7c 2573
wolfSSL 15:117db924cf7c 2574 kari->kekSz = (word32)kSz;
wolfSSL 15:117db924cf7c 2575
wolfSSL 15:117db924cf7c 2576 /* generate ECC-CMS-SharedInfo */
wolfSSL 15:117db924cf7c 2577 ret = wc_PKCS7_KariGenerateSharedInfo(kari, keyWrapOID);
wolfSSL 15:117db924cf7c 2578 if (ret != 0)
wolfSSL 15:117db924cf7c 2579 return ret;
wolfSSL 15:117db924cf7c 2580
wolfSSL 15:117db924cf7c 2581 /* generate shared secret */
wolfSSL 15:117db924cf7c 2582 secretSz = kari->senderKey->dp->size;
wolfSSL 15:117db924cf7c 2583 secret = (byte*)XMALLOC(secretSz, kari->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 2584 if (secret == NULL)
wolfSSL 15:117db924cf7c 2585 return MEMORY_E;
wolfSSL 15:117db924cf7c 2586
wolfSSL 15:117db924cf7c 2587 if (kari->direction == WC_PKCS7_ENCODE) {
wolfSSL 15:117db924cf7c 2588
wolfSSL 15:117db924cf7c 2589 ret = wc_ecc_shared_secret(kari->senderKey, kari->recipKey,
wolfSSL 15:117db924cf7c 2590 secret, &secretSz);
wolfSSL 15:117db924cf7c 2591
wolfSSL 15:117db924cf7c 2592 } else if (kari->direction == WC_PKCS7_DECODE) {
wolfSSL 15:117db924cf7c 2593
wolfSSL 15:117db924cf7c 2594 ret = wc_ecc_shared_secret(kari->recipKey, kari->senderKey,
wolfSSL 15:117db924cf7c 2595 secret, &secretSz);
wolfSSL 15:117db924cf7c 2596
wolfSSL 15:117db924cf7c 2597 } else {
wolfSSL 15:117db924cf7c 2598 /* bad direction */
wolfSSL 15:117db924cf7c 2599 XFREE(secret, kari->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 2600 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 2601 }
wolfSSL 15:117db924cf7c 2602
wolfSSL 15:117db924cf7c 2603 if (ret != 0) {
wolfSSL 15:117db924cf7c 2604 XFREE(secret, kari->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 2605 return ret;
wolfSSL 15:117db924cf7c 2606 }
wolfSSL 15:117db924cf7c 2607
wolfSSL 15:117db924cf7c 2608 /* run through KDF */
wolfSSL 15:117db924cf7c 2609 switch (keyEncOID) {
wolfSSL 15:117db924cf7c 2610
wolfSSL 15:117db924cf7c 2611 #ifndef NO_SHA
wolfSSL 15:117db924cf7c 2612 case dhSinglePass_stdDH_sha1kdf_scheme:
wolfSSL 15:117db924cf7c 2613 kdfType = WC_HASH_TYPE_SHA;
wolfSSL 15:117db924cf7c 2614 break;
wolfSSL 15:117db924cf7c 2615 #endif
wolfSSL 15:117db924cf7c 2616 #ifndef WOLFSSL_SHA224
wolfSSL 15:117db924cf7c 2617 case dhSinglePass_stdDH_sha224kdf_scheme:
wolfSSL 15:117db924cf7c 2618 kdfType = WC_HASH_TYPE_SHA224;
wolfSSL 15:117db924cf7c 2619 break;
wolfSSL 15:117db924cf7c 2620 #endif
wolfSSL 15:117db924cf7c 2621 #ifndef NO_SHA256
wolfSSL 15:117db924cf7c 2622 case dhSinglePass_stdDH_sha256kdf_scheme:
wolfSSL 15:117db924cf7c 2623 kdfType = WC_HASH_TYPE_SHA256;
wolfSSL 15:117db924cf7c 2624 break;
wolfSSL 15:117db924cf7c 2625 #endif
wolfSSL 15:117db924cf7c 2626 #ifdef WOLFSSL_SHA384
wolfSSL 15:117db924cf7c 2627 case dhSinglePass_stdDH_sha384kdf_scheme:
wolfSSL 15:117db924cf7c 2628 kdfType = WC_HASH_TYPE_SHA384;
wolfSSL 15:117db924cf7c 2629 break;
wolfSSL 15:117db924cf7c 2630 #endif
wolfSSL 15:117db924cf7c 2631 #ifdef WOLFSSL_SHA512
wolfSSL 15:117db924cf7c 2632 case dhSinglePass_stdDH_sha512kdf_scheme:
wolfSSL 15:117db924cf7c 2633 kdfType = WC_HASH_TYPE_SHA512;
wolfSSL 15:117db924cf7c 2634 break;
wolfSSL 15:117db924cf7c 2635 #endif
wolfSSL 15:117db924cf7c 2636 default:
wolfSSL 15:117db924cf7c 2637 WOLFSSL_MSG("Unsupported key agreement algorithm");
wolfSSL 15:117db924cf7c 2638 XFREE(secret, kari->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 2639 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 2640 };
wolfSSL 15:117db924cf7c 2641
wolfSSL 15:117db924cf7c 2642 ret = wc_X963_KDF(kdfType, secret, secretSz, kari->sharedInfo,
wolfSSL 15:117db924cf7c 2643 kari->sharedInfoSz, kari->kek, kari->kekSz);
wolfSSL 15:117db924cf7c 2644 if (ret != 0) {
wolfSSL 15:117db924cf7c 2645 XFREE(secret, kari->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 2646 return ret;
wolfSSL 15:117db924cf7c 2647 }
wolfSSL 15:117db924cf7c 2648
wolfSSL 15:117db924cf7c 2649 XFREE(secret, kari->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 2650
wolfSSL 15:117db924cf7c 2651 return 0;
wolfSSL 15:117db924cf7c 2652 }
wolfSSL 15:117db924cf7c 2653
wolfSSL 15:117db924cf7c 2654
wolfSSL 15:117db924cf7c 2655 /* create ASN.1 formatted KeyAgreeRecipientInfo (kari) for use with ECDH,
wolfSSL 15:117db924cf7c 2656 * return sequence size or negative on error */
wolfSSL 15:117db924cf7c 2657 static int wc_CreateKeyAgreeRecipientInfo(PKCS7* pkcs7, const byte* cert,
wolfSSL 15:117db924cf7c 2658 word32 certSz, int keyAgreeAlgo, int blockKeySz,
wolfSSL 15:117db924cf7c 2659 int keyWrapAlgo, int keyEncAlgo, WC_RNG* rng,
wolfSSL 15:117db924cf7c 2660 byte* contentKeyPlain, byte* contentKeyEnc,
wolfSSL 15:117db924cf7c 2661 int* keyEncSz, byte* out, word32 outSz)
wolfSSL 15:117db924cf7c 2662 {
wolfSSL 15:117db924cf7c 2663 int ret = 0, idx = 0;
wolfSSL 15:117db924cf7c 2664 int keySz, direction = 0;
wolfSSL 15:117db924cf7c 2665
wolfSSL 15:117db924cf7c 2666 /* ASN.1 layout */
wolfSSL 15:117db924cf7c 2667 int totalSz = 0;
wolfSSL 15:117db924cf7c 2668 int kariSeqSz = 0;
wolfSSL 15:117db924cf7c 2669 byte kariSeq[MAX_SEQ_SZ]; /* IMPLICIT [1] */
wolfSSL 15:117db924cf7c 2670 int verSz = 0;
wolfSSL 15:117db924cf7c 2671 byte ver[MAX_VERSION_SZ];
wolfSSL 15:117db924cf7c 2672
wolfSSL 15:117db924cf7c 2673 int origIdOrKeySeqSz = 0;
wolfSSL 15:117db924cf7c 2674 byte origIdOrKeySeq[MAX_SEQ_SZ]; /* IMPLICIT [0] */
wolfSSL 15:117db924cf7c 2675 int origPubKeySeqSz = 0;
wolfSSL 15:117db924cf7c 2676 byte origPubKeySeq[MAX_SEQ_SZ]; /* IMPLICIT [1] */
wolfSSL 15:117db924cf7c 2677 int origAlgIdSz = 0;
wolfSSL 15:117db924cf7c 2678 byte origAlgId[MAX_ALGO_SZ];
wolfSSL 15:117db924cf7c 2679 int origPubKeyStrSz = 0;
wolfSSL 15:117db924cf7c 2680 byte origPubKeyStr[MAX_OCTET_STR_SZ];
wolfSSL 15:117db924cf7c 2681
wolfSSL 15:117db924cf7c 2682 /* optional user keying material */
wolfSSL 15:117db924cf7c 2683 int ukmOctetSz = 0;
wolfSSL 15:117db924cf7c 2684 byte ukmOctetStr[MAX_OCTET_STR_SZ];
wolfSSL 15:117db924cf7c 2685 int ukmExplicitSz = 0;
wolfSSL 15:117db924cf7c 2686 byte ukmExplicitSeq[MAX_SEQ_SZ];
wolfSSL 15:117db924cf7c 2687
wolfSSL 15:117db924cf7c 2688 int keyEncryptAlgoIdSz = 0;
wolfSSL 15:117db924cf7c 2689 byte keyEncryptAlgoId[MAX_ALGO_SZ];
wolfSSL 15:117db924cf7c 2690 int keyWrapAlgSz = 0;
wolfSSL 15:117db924cf7c 2691 byte keyWrapAlg[MAX_ALGO_SZ];
wolfSSL 15:117db924cf7c 2692
wolfSSL 15:117db924cf7c 2693 int recipEncKeysSeqSz = 0;
wolfSSL 15:117db924cf7c 2694 byte recipEncKeysSeq[MAX_SEQ_SZ];
wolfSSL 15:117db924cf7c 2695 int recipEncKeySeqSz = 0;
wolfSSL 15:117db924cf7c 2696 byte recipEncKeySeq[MAX_SEQ_SZ];
wolfSSL 15:117db924cf7c 2697 int recipKeyIdSeqSz = 0;
wolfSSL 15:117db924cf7c 2698 byte recipKeyIdSeq[MAX_SEQ_SZ]; /* IMPLICIT [0] */
wolfSSL 15:117db924cf7c 2699 int subjKeyIdOctetSz = 0;
wolfSSL 15:117db924cf7c 2700 byte subjKeyIdOctet[MAX_OCTET_STR_SZ];
wolfSSL 15:117db924cf7c 2701 int encryptedKeyOctetSz = 0;
wolfSSL 15:117db924cf7c 2702 byte encryptedKeyOctet[MAX_OCTET_STR_SZ];
wolfSSL 15:117db924cf7c 2703
wolfSSL 15:117db924cf7c 2704 WC_PKCS7_KARI* kari;
wolfSSL 15:117db924cf7c 2705
wolfSSL 15:117db924cf7c 2706 /* only supports ECDSA for now */
wolfSSL 15:117db924cf7c 2707 if (keyAgreeAlgo != ECDSAk)
wolfSSL 15:117db924cf7c 2708 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 2709
wolfSSL 15:117db924cf7c 2710 /* set direction based on keyWrapAlgo */
wolfSSL 15:117db924cf7c 2711 switch (keyWrapAlgo) {
wolfSSL 15:117db924cf7c 2712 #ifndef NO_AES
wolfSSL 15:117db924cf7c 2713 #ifdef WOLFSSL_AES_128
wolfSSL 15:117db924cf7c 2714 case AES128_WRAP:
wolfSSL 15:117db924cf7c 2715 #endif
wolfSSL 15:117db924cf7c 2716 #ifdef WOLFSSL_AES_192
wolfSSL 15:117db924cf7c 2717 case AES192_WRAP:
wolfSSL 15:117db924cf7c 2718 #endif
wolfSSL 15:117db924cf7c 2719 #ifdef WOLFSSL_AES_256
wolfSSL 15:117db924cf7c 2720 case AES256_WRAP:
wolfSSL 15:117db924cf7c 2721 #endif
wolfSSL 15:117db924cf7c 2722 direction = AES_ENCRYPTION;
wolfSSL 15:117db924cf7c 2723 break;
wolfSSL 15:117db924cf7c 2724 #endif
wolfSSL 15:117db924cf7c 2725 default:
wolfSSL 15:117db924cf7c 2726 WOLFSSL_MSG("Unsupported key wrap algorithm");
wolfSSL 15:117db924cf7c 2727 return BAD_KEYWRAP_ALG_E;
wolfSSL 15:117db924cf7c 2728 }
wolfSSL 15:117db924cf7c 2729
wolfSSL 15:117db924cf7c 2730 kari = wc_PKCS7_KariNew(pkcs7, WC_PKCS7_ENCODE);
wolfSSL 15:117db924cf7c 2731 if (kari == NULL)
wolfSSL 15:117db924cf7c 2732 return MEMORY_E;
wolfSSL 15:117db924cf7c 2733
wolfSSL 15:117db924cf7c 2734 /* set user keying material if available */
wolfSSL 15:117db924cf7c 2735 if ((pkcs7->ukmSz > 0) && (pkcs7->ukm != NULL)) {
wolfSSL 15:117db924cf7c 2736 kari->ukm = pkcs7->ukm;
wolfSSL 15:117db924cf7c 2737 kari->ukmSz = pkcs7->ukmSz;
wolfSSL 15:117db924cf7c 2738 kari->ukmOwner = 0;
wolfSSL 15:117db924cf7c 2739 }
wolfSSL 15:117db924cf7c 2740
wolfSSL 15:117db924cf7c 2741 /* parse recipient cert, get public key */
wolfSSL 15:117db924cf7c 2742 ret = wc_PKCS7_KariParseRecipCert(kari, cert, certSz, NULL, 0);
wolfSSL 15:117db924cf7c 2743 if (ret != 0) {
wolfSSL 15:117db924cf7c 2744 wc_PKCS7_KariFree(kari);
wolfSSL 15:117db924cf7c 2745 return ret;
wolfSSL 15:117db924cf7c 2746 }
wolfSSL 15:117db924cf7c 2747
wolfSSL 15:117db924cf7c 2748 /* generate sender ephemeral ECC key */
wolfSSL 15:117db924cf7c 2749 ret = wc_PKCS7_KariGenerateEphemeralKey(kari, rng);
wolfSSL 15:117db924cf7c 2750 if (ret != 0) {
wolfSSL 15:117db924cf7c 2751 wc_PKCS7_KariFree(kari);
wolfSSL 15:117db924cf7c 2752 return ret;
wolfSSL 15:117db924cf7c 2753 }
wolfSSL 15:117db924cf7c 2754
wolfSSL 15:117db924cf7c 2755 /* generate KEK (key encryption key) */
wolfSSL 15:117db924cf7c 2756 ret = wc_PKCS7_KariGenerateKEK(kari, keyWrapAlgo, keyEncAlgo);
wolfSSL 15:117db924cf7c 2757 if (ret != 0) {
wolfSSL 15:117db924cf7c 2758 wc_PKCS7_KariFree(kari);
wolfSSL 15:117db924cf7c 2759 return ret;
wolfSSL 15:117db924cf7c 2760 }
wolfSSL 15:117db924cf7c 2761
wolfSSL 15:117db924cf7c 2762 /* encrypt CEK with KEK */
wolfSSL 15:117db924cf7c 2763 keySz = wc_PKCS7_KariKeyWrap(contentKeyPlain, blockKeySz, kari->kek,
wolfSSL 15:117db924cf7c 2764 kari->kekSz, contentKeyEnc, *keyEncSz, keyWrapAlgo,
wolfSSL 15:117db924cf7c 2765 direction);
wolfSSL 15:117db924cf7c 2766 if (keySz <= 0) {
wolfSSL 15:117db924cf7c 2767 wc_PKCS7_KariFree(kari);
wolfSSL 15:117db924cf7c 2768 return ret;
wolfSSL 15:117db924cf7c 2769 }
wolfSSL 15:117db924cf7c 2770 *keyEncSz = (word32)keySz;
wolfSSL 15:117db924cf7c 2771
wolfSSL 15:117db924cf7c 2772 /* Start of RecipientEncryptedKeys */
wolfSSL 15:117db924cf7c 2773
wolfSSL 15:117db924cf7c 2774 /* EncryptedKey */
wolfSSL 15:117db924cf7c 2775 encryptedKeyOctetSz = SetOctetString(*keyEncSz, encryptedKeyOctet);
wolfSSL 15:117db924cf7c 2776 totalSz += (encryptedKeyOctetSz + *keyEncSz);
wolfSSL 15:117db924cf7c 2777
wolfSSL 15:117db924cf7c 2778 /* SubjectKeyIdentifier */
wolfSSL 15:117db924cf7c 2779 subjKeyIdOctetSz = SetOctetString(KEYID_SIZE, subjKeyIdOctet);
wolfSSL 15:117db924cf7c 2780 totalSz += (subjKeyIdOctetSz + KEYID_SIZE);
wolfSSL 15:117db924cf7c 2781
wolfSSL 15:117db924cf7c 2782 /* RecipientKeyIdentifier IMPLICIT [0] */
wolfSSL 15:117db924cf7c 2783 recipKeyIdSeqSz = SetImplicit(ASN_SEQUENCE, 0, subjKeyIdOctetSz +
wolfSSL 15:117db924cf7c 2784 KEYID_SIZE, recipKeyIdSeq);
wolfSSL 15:117db924cf7c 2785 totalSz += recipKeyIdSeqSz;
wolfSSL 15:117db924cf7c 2786
wolfSSL 15:117db924cf7c 2787 /* RecipientEncryptedKey */
wolfSSL 15:117db924cf7c 2788 recipEncKeySeqSz = SetSequence(totalSz, recipEncKeySeq);
wolfSSL 15:117db924cf7c 2789 totalSz += recipEncKeySeqSz;
wolfSSL 15:117db924cf7c 2790
wolfSSL 15:117db924cf7c 2791 /* RecipientEncryptedKeys */
wolfSSL 15:117db924cf7c 2792 recipEncKeysSeqSz = SetSequence(totalSz, recipEncKeysSeq);
wolfSSL 15:117db924cf7c 2793 totalSz += recipEncKeysSeqSz;
wolfSSL 15:117db924cf7c 2794
wolfSSL 15:117db924cf7c 2795 /* Start of optional UserKeyingMaterial */
wolfSSL 15:117db924cf7c 2796
wolfSSL 15:117db924cf7c 2797 if (kari->ukmSz > 0) {
wolfSSL 15:117db924cf7c 2798 ukmOctetSz = SetOctetString(kari->ukmSz, ukmOctetStr);
wolfSSL 15:117db924cf7c 2799 totalSz += (ukmOctetSz + kari->ukmSz);
wolfSSL 15:117db924cf7c 2800
wolfSSL 15:117db924cf7c 2801 ukmExplicitSz = SetExplicit(1, ukmOctetSz + kari->ukmSz,
wolfSSL 15:117db924cf7c 2802 ukmExplicitSeq);
wolfSSL 15:117db924cf7c 2803 totalSz += ukmExplicitSz;
wolfSSL 15:117db924cf7c 2804 }
wolfSSL 15:117db924cf7c 2805
wolfSSL 15:117db924cf7c 2806 /* Start of KeyEncryptionAlgorithmIdentifier */
wolfSSL 15:117db924cf7c 2807
wolfSSL 15:117db924cf7c 2808 /* KeyWrapAlgorithm */
wolfSSL 15:117db924cf7c 2809 keyWrapAlgSz = SetAlgoID(keyWrapAlgo, keyWrapAlg, oidKeyWrapType, 0);
wolfSSL 15:117db924cf7c 2810 totalSz += keyWrapAlgSz;
wolfSSL 15:117db924cf7c 2811
wolfSSL 15:117db924cf7c 2812 /* KeyEncryptionAlgorithmIdentifier */
wolfSSL 15:117db924cf7c 2813 keyEncryptAlgoIdSz = SetAlgoID(keyEncAlgo, keyEncryptAlgoId,
wolfSSL 15:117db924cf7c 2814 oidCmsKeyAgreeType, keyWrapAlgSz);
wolfSSL 15:117db924cf7c 2815 totalSz += keyEncryptAlgoIdSz;
wolfSSL 15:117db924cf7c 2816
wolfSSL 15:117db924cf7c 2817 /* Start of OriginatorIdentifierOrKey */
wolfSSL 15:117db924cf7c 2818
wolfSSL 15:117db924cf7c 2819 /* recipient ECPoint, public key */
wolfSSL 15:117db924cf7c 2820 XMEMSET(origPubKeyStr, 0, sizeof(origPubKeyStr)); /* no unused bits */
wolfSSL 15:117db924cf7c 2821 origPubKeyStr[0] = ASN_BIT_STRING;
wolfSSL 15:117db924cf7c 2822 origPubKeyStrSz = SetLength(kari->senderKeyExportSz + 1,
wolfSSL 15:117db924cf7c 2823 origPubKeyStr + 1) + 2;
wolfSSL 15:117db924cf7c 2824 totalSz += (origPubKeyStrSz + kari->senderKeyExportSz);
wolfSSL 15:117db924cf7c 2825
wolfSSL 15:117db924cf7c 2826 /* Originator AlgorithmIdentifier */
wolfSSL 15:117db924cf7c 2827 origAlgIdSz = SetAlgoID(ECDSAk, origAlgId, oidKeyType, 0);
wolfSSL 15:117db924cf7c 2828 totalSz += origAlgIdSz;
wolfSSL 15:117db924cf7c 2829
wolfSSL 15:117db924cf7c 2830 /* outer OriginatorPublicKey IMPLICIT [1] */
wolfSSL 15:117db924cf7c 2831 origPubKeySeqSz = SetImplicit(ASN_SEQUENCE, 1,
wolfSSL 15:117db924cf7c 2832 origAlgIdSz + origPubKeyStrSz +
wolfSSL 15:117db924cf7c 2833 kari->senderKeyExportSz, origPubKeySeq);
wolfSSL 15:117db924cf7c 2834 totalSz += origPubKeySeqSz;
wolfSSL 15:117db924cf7c 2835
wolfSSL 15:117db924cf7c 2836 /* outer OriginatorIdentiferOrKey IMPLICIT [0] */
wolfSSL 15:117db924cf7c 2837 origIdOrKeySeqSz = SetImplicit(ASN_SEQUENCE, 0,
wolfSSL 15:117db924cf7c 2838 origPubKeySeqSz + origAlgIdSz +
wolfSSL 15:117db924cf7c 2839 origPubKeyStrSz + kari->senderKeyExportSz,
wolfSSL 15:117db924cf7c 2840 origIdOrKeySeq);
wolfSSL 15:117db924cf7c 2841 totalSz += origIdOrKeySeqSz;
wolfSSL 15:117db924cf7c 2842
wolfSSL 15:117db924cf7c 2843 /* version, always 3 */
wolfSSL 15:117db924cf7c 2844 verSz = SetMyVersion(3, ver, 0);
wolfSSL 15:117db924cf7c 2845 totalSz += verSz;
wolfSSL 15:117db924cf7c 2846
wolfSSL 15:117db924cf7c 2847 /* outer IMPLICIT [1] kari */
wolfSSL 15:117db924cf7c 2848 kariSeqSz = SetImplicit(ASN_SEQUENCE, 1, totalSz, kariSeq);
wolfSSL 15:117db924cf7c 2849 totalSz += kariSeqSz;
wolfSSL 15:117db924cf7c 2850
wolfSSL 15:117db924cf7c 2851 if ((word32)totalSz > outSz) {
wolfSSL 15:117db924cf7c 2852 WOLFSSL_MSG("KeyAgreeRecipientInfo output buffer too small");
wolfSSL 15:117db924cf7c 2853 wc_PKCS7_KariFree(kari);
wolfSSL 15:117db924cf7c 2854
wolfSSL 15:117db924cf7c 2855 return BUFFER_E;
wolfSSL 15:117db924cf7c 2856 }
wolfSSL 15:117db924cf7c 2857
wolfSSL 15:117db924cf7c 2858 XMEMCPY(out + idx, kariSeq, kariSeqSz);
wolfSSL 15:117db924cf7c 2859 idx += kariSeqSz;
wolfSSL 15:117db924cf7c 2860 XMEMCPY(out + idx, ver, verSz);
wolfSSL 15:117db924cf7c 2861 idx += verSz;
wolfSSL 15:117db924cf7c 2862
wolfSSL 15:117db924cf7c 2863 XMEMCPY(out + idx, origIdOrKeySeq, origIdOrKeySeqSz);
wolfSSL 15:117db924cf7c 2864 idx += origIdOrKeySeqSz;
wolfSSL 15:117db924cf7c 2865 XMEMCPY(out + idx, origPubKeySeq, origPubKeySeqSz);
wolfSSL 15:117db924cf7c 2866 idx += origPubKeySeqSz;
wolfSSL 15:117db924cf7c 2867 XMEMCPY(out + idx, origAlgId, origAlgIdSz);
wolfSSL 15:117db924cf7c 2868 idx += origAlgIdSz;
wolfSSL 15:117db924cf7c 2869 XMEMCPY(out + idx, origPubKeyStr, origPubKeyStrSz);
wolfSSL 15:117db924cf7c 2870 idx += origPubKeyStrSz;
wolfSSL 15:117db924cf7c 2871 /* ephemeral public key */
wolfSSL 15:117db924cf7c 2872 XMEMCPY(out + idx, kari->senderKeyExport, kari->senderKeyExportSz);
wolfSSL 15:117db924cf7c 2873 idx += kari->senderKeyExportSz;
wolfSSL 15:117db924cf7c 2874
wolfSSL 15:117db924cf7c 2875 if (kari->ukmSz > 0) {
wolfSSL 15:117db924cf7c 2876 XMEMCPY(out + idx, ukmExplicitSeq, ukmExplicitSz);
wolfSSL 15:117db924cf7c 2877 idx += ukmExplicitSz;
wolfSSL 15:117db924cf7c 2878 XMEMCPY(out + idx, ukmOctetStr, ukmOctetSz);
wolfSSL 15:117db924cf7c 2879 idx += ukmOctetSz;
wolfSSL 15:117db924cf7c 2880 XMEMCPY(out + idx, kari->ukm, kari->ukmSz);
wolfSSL 15:117db924cf7c 2881 idx += kari->ukmSz;
wolfSSL 15:117db924cf7c 2882 }
wolfSSL 15:117db924cf7c 2883
wolfSSL 15:117db924cf7c 2884 XMEMCPY(out + idx, keyEncryptAlgoId, keyEncryptAlgoIdSz);
wolfSSL 15:117db924cf7c 2885 idx += keyEncryptAlgoIdSz;
wolfSSL 15:117db924cf7c 2886 XMEMCPY(out + idx, keyWrapAlg, keyWrapAlgSz);
wolfSSL 15:117db924cf7c 2887 idx += keyWrapAlgSz;
wolfSSL 15:117db924cf7c 2888
wolfSSL 15:117db924cf7c 2889 XMEMCPY(out + idx, recipEncKeysSeq, recipEncKeysSeqSz);
wolfSSL 15:117db924cf7c 2890 idx += recipEncKeysSeqSz;
wolfSSL 15:117db924cf7c 2891 XMEMCPY(out + idx, recipEncKeySeq, recipEncKeySeqSz);
wolfSSL 15:117db924cf7c 2892 idx += recipEncKeySeqSz;
wolfSSL 15:117db924cf7c 2893 XMEMCPY(out + idx, recipKeyIdSeq, recipKeyIdSeqSz);
wolfSSL 15:117db924cf7c 2894 idx += recipKeyIdSeqSz;
wolfSSL 15:117db924cf7c 2895 XMEMCPY(out + idx, subjKeyIdOctet, subjKeyIdOctetSz);
wolfSSL 15:117db924cf7c 2896 idx += subjKeyIdOctetSz;
wolfSSL 15:117db924cf7c 2897 /* subject key id */
wolfSSL 15:117db924cf7c 2898 XMEMCPY(out + idx, kari->decoded->extSubjKeyId, KEYID_SIZE);
wolfSSL 15:117db924cf7c 2899 idx += KEYID_SIZE;
wolfSSL 15:117db924cf7c 2900 XMEMCPY(out + idx, encryptedKeyOctet, encryptedKeyOctetSz);
wolfSSL 15:117db924cf7c 2901 idx += encryptedKeyOctetSz;
wolfSSL 15:117db924cf7c 2902 /* encrypted CEK */
wolfSSL 15:117db924cf7c 2903 XMEMCPY(out + idx, contentKeyEnc, *keyEncSz);
wolfSSL 15:117db924cf7c 2904 idx += *keyEncSz;
wolfSSL 15:117db924cf7c 2905
wolfSSL 15:117db924cf7c 2906 wc_PKCS7_KariFree(kari);
wolfSSL 15:117db924cf7c 2907
wolfSSL 15:117db924cf7c 2908 return idx;
wolfSSL 15:117db924cf7c 2909 }
wolfSSL 15:117db924cf7c 2910
wolfSSL 15:117db924cf7c 2911 #endif /* HAVE_ECC */
wolfSSL 15:117db924cf7c 2912
wolfSSL 15:117db924cf7c 2913 #ifndef NO_RSA
wolfSSL 15:117db924cf7c 2914
wolfSSL 15:117db924cf7c 2915 /* create ASN.1 formatted RecipientInfo structure, returns sequence size */
wolfSSL 15:117db924cf7c 2916 static int wc_CreateRecipientInfo(const byte* cert, word32 certSz,
wolfSSL 15:117db924cf7c 2917 int keyEncAlgo, int blockKeySz,
wolfSSL 15:117db924cf7c 2918 WC_RNG* rng, byte* contentKeyPlain,
wolfSSL 15:117db924cf7c 2919 byte* contentKeyEnc, int* keyEncSz,
wolfSSL 15:117db924cf7c 2920 byte* out, word32 outSz, void* heap)
wolfSSL 15:117db924cf7c 2921 {
wolfSSL 15:117db924cf7c 2922 word32 idx = 0;
wolfSSL 15:117db924cf7c 2923 int ret = 0, totalSz = 0;
wolfSSL 15:117db924cf7c 2924 int verSz, issuerSz, snSz, keyEncAlgSz;
wolfSSL 15:117db924cf7c 2925 int issuerSeqSz, recipSeqSz, issuerSerialSeqSz;
wolfSSL 15:117db924cf7c 2926 int encKeyOctetStrSz;
wolfSSL 15:117db924cf7c 2927
wolfSSL 15:117db924cf7c 2928 byte ver[MAX_VERSION_SZ];
wolfSSL 15:117db924cf7c 2929 byte issuerSerialSeq[MAX_SEQ_SZ];
wolfSSL 15:117db924cf7c 2930 byte recipSeq[MAX_SEQ_SZ];
wolfSSL 15:117db924cf7c 2931 byte issuerSeq[MAX_SEQ_SZ];
wolfSSL 15:117db924cf7c 2932 byte encKeyOctetStr[MAX_OCTET_STR_SZ];
wolfSSL 15:117db924cf7c 2933
wolfSSL 15:117db924cf7c 2934 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 2935 byte *serial;
wolfSSL 15:117db924cf7c 2936 byte *keyAlgArray;
wolfSSL 15:117db924cf7c 2937
wolfSSL 15:117db924cf7c 2938 RsaKey* pubKey;
wolfSSL 15:117db924cf7c 2939 DecodedCert* decoded;
wolfSSL 15:117db924cf7c 2940
wolfSSL 15:117db924cf7c 2941 serial = (byte*)XMALLOC(MAX_SN_SZ, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 2942 keyAlgArray = (byte*)XMALLOC(MAX_SN_SZ, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 2943 decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), heap,
wolfSSL 15:117db924cf7c 2944 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 2945
wolfSSL 15:117db924cf7c 2946 if (decoded == NULL || serial == NULL || keyAlgArray == NULL) {
wolfSSL 15:117db924cf7c 2947 if (serial) XFREE(serial, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 2948 if (keyAlgArray) XFREE(keyAlgArray, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 2949 if (decoded) XFREE(decoded, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 2950 return MEMORY_E;
wolfSSL 15:117db924cf7c 2951 }
wolfSSL 15:117db924cf7c 2952
wolfSSL 15:117db924cf7c 2953 #else
wolfSSL 15:117db924cf7c 2954 byte serial[MAX_SN_SZ];
wolfSSL 15:117db924cf7c 2955 byte keyAlgArray[MAX_ALGO_SZ];
wolfSSL 15:117db924cf7c 2956
wolfSSL 15:117db924cf7c 2957 RsaKey stack_pubKey;
wolfSSL 15:117db924cf7c 2958 RsaKey* pubKey = &stack_pubKey;
wolfSSL 15:117db924cf7c 2959 DecodedCert stack_decoded;
wolfSSL 15:117db924cf7c 2960 DecodedCert* decoded = &stack_decoded;
wolfSSL 15:117db924cf7c 2961 #endif
wolfSSL 15:117db924cf7c 2962
wolfSSL 15:117db924cf7c 2963 InitDecodedCert(decoded, (byte*)cert, certSz, heap);
wolfSSL 15:117db924cf7c 2964 ret = ParseCert(decoded, CA_TYPE, NO_VERIFY, 0);
wolfSSL 15:117db924cf7c 2965 if (ret < 0) {
wolfSSL 15:117db924cf7c 2966 FreeDecodedCert(decoded);
wolfSSL 15:117db924cf7c 2967 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 2968 XFREE(serial, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 2969 XFREE(keyAlgArray, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 2970 XFREE(decoded, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 2971 #endif
wolfSSL 15:117db924cf7c 2972 return ret;
wolfSSL 15:117db924cf7c 2973 }
wolfSSL 15:117db924cf7c 2974
wolfSSL 15:117db924cf7c 2975 /* version */
wolfSSL 15:117db924cf7c 2976 verSz = SetMyVersion(0, ver, 0);
wolfSSL 15:117db924cf7c 2977
wolfSSL 15:117db924cf7c 2978 /* IssuerAndSerialNumber */
wolfSSL 15:117db924cf7c 2979 if (decoded->issuerRaw == NULL || decoded->issuerRawLen == 0) {
wolfSSL 15:117db924cf7c 2980 WOLFSSL_MSG("DecodedCert lacks raw issuer pointer and length");
wolfSSL 15:117db924cf7c 2981 FreeDecodedCert(decoded);
wolfSSL 15:117db924cf7c 2982 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 2983 XFREE(serial, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 2984 XFREE(keyAlgArray, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 2985 XFREE(decoded, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 2986 #endif
wolfSSL 15:117db924cf7c 2987 return -1;
wolfSSL 15:117db924cf7c 2988 }
wolfSSL 15:117db924cf7c 2989 issuerSz = decoded->issuerRawLen;
wolfSSL 15:117db924cf7c 2990 issuerSeqSz = SetSequence(issuerSz, issuerSeq);
wolfSSL 15:117db924cf7c 2991
wolfSSL 15:117db924cf7c 2992 if (decoded->serialSz == 0) {
wolfSSL 15:117db924cf7c 2993 WOLFSSL_MSG("DecodedCert missing serial number");
wolfSSL 15:117db924cf7c 2994 FreeDecodedCert(decoded);
wolfSSL 15:117db924cf7c 2995 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 2996 XFREE(serial, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 2997 XFREE(keyAlgArray, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 2998 XFREE(decoded, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 2999 #endif
wolfSSL 15:117db924cf7c 3000 return -1;
wolfSSL 15:117db924cf7c 3001 }
wolfSSL 15:117db924cf7c 3002 snSz = SetSerialNumber(decoded->serial, decoded->serialSz, serial, MAX_SN_SZ);
wolfSSL 15:117db924cf7c 3003
wolfSSL 15:117db924cf7c 3004 issuerSerialSeqSz = SetSequence(issuerSeqSz + issuerSz + snSz,
wolfSSL 15:117db924cf7c 3005 issuerSerialSeq);
wolfSSL 15:117db924cf7c 3006
wolfSSL 15:117db924cf7c 3007 /* KeyEncryptionAlgorithmIdentifier, only support RSA now */
wolfSSL 15:117db924cf7c 3008 if (keyEncAlgo != RSAk) {
wolfSSL 15:117db924cf7c 3009 FreeDecodedCert(decoded);
wolfSSL 15:117db924cf7c 3010 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 3011 XFREE(serial, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3012 XFREE(keyAlgArray, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3013 XFREE(decoded, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3014 #endif
wolfSSL 15:117db924cf7c 3015 return ALGO_ID_E;
wolfSSL 15:117db924cf7c 3016 }
wolfSSL 15:117db924cf7c 3017
wolfSSL 15:117db924cf7c 3018 keyEncAlgSz = SetAlgoID(keyEncAlgo, keyAlgArray, oidKeyType, 0);
wolfSSL 15:117db924cf7c 3019 if (keyEncAlgSz == 0) {
wolfSSL 15:117db924cf7c 3020 FreeDecodedCert(decoded);
wolfSSL 15:117db924cf7c 3021 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 3022 XFREE(serial, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3023 XFREE(keyAlgArray, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3024 XFREE(decoded, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3025 #endif
wolfSSL 15:117db924cf7c 3026 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 3027 }
wolfSSL 15:117db924cf7c 3028
wolfSSL 15:117db924cf7c 3029 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 3030 pubKey = (RsaKey*)XMALLOC(sizeof(RsaKey), heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3031 if (pubKey == NULL) {
wolfSSL 15:117db924cf7c 3032 FreeDecodedCert(decoded);
wolfSSL 15:117db924cf7c 3033 XFREE(serial, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3034 XFREE(keyAlgArray, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3035 XFREE(decoded, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3036 return MEMORY_E;
wolfSSL 15:117db924cf7c 3037 }
wolfSSL 15:117db924cf7c 3038 #endif
wolfSSL 15:117db924cf7c 3039
wolfSSL 15:117db924cf7c 3040 /* EncryptedKey */
wolfSSL 15:117db924cf7c 3041 ret = wc_InitRsaKey_ex(pubKey, heap, INVALID_DEVID);
wolfSSL 15:117db924cf7c 3042 if (ret != 0) {
wolfSSL 15:117db924cf7c 3043 FreeDecodedCert(decoded);
wolfSSL 15:117db924cf7c 3044 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 3045 XFREE(pubKey, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3046 XFREE(serial, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3047 XFREE(keyAlgArray, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3048 XFREE(decoded, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3049 #endif
wolfSSL 15:117db924cf7c 3050 return ret;
wolfSSL 15:117db924cf7c 3051 }
wolfSSL 15:117db924cf7c 3052
wolfSSL 15:117db924cf7c 3053 if (wc_RsaPublicKeyDecode(decoded->publicKey, &idx, pubKey,
wolfSSL 15:117db924cf7c 3054 decoded->pubKeySize) < 0) {
wolfSSL 15:117db924cf7c 3055 WOLFSSL_MSG("ASN RSA key decode error");
wolfSSL 15:117db924cf7c 3056 wc_FreeRsaKey(pubKey);
wolfSSL 15:117db924cf7c 3057 FreeDecodedCert(decoded);
wolfSSL 15:117db924cf7c 3058 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 3059 XFREE(pubKey, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3060 XFREE(serial, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3061 XFREE(keyAlgArray, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3062 XFREE(decoded, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3063 #endif
wolfSSL 15:117db924cf7c 3064 return PUBLIC_KEY_E;
wolfSSL 15:117db924cf7c 3065 }
wolfSSL 15:117db924cf7c 3066
wolfSSL 15:117db924cf7c 3067 *keyEncSz = wc_RsaPublicEncrypt(contentKeyPlain, blockKeySz, contentKeyEnc,
wolfSSL 15:117db924cf7c 3068 MAX_ENCRYPTED_KEY_SZ, pubKey, rng);
wolfSSL 15:117db924cf7c 3069 wc_FreeRsaKey(pubKey);
wolfSSL 15:117db924cf7c 3070
wolfSSL 15:117db924cf7c 3071 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 3072 XFREE(pubKey, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3073 #endif
wolfSSL 15:117db924cf7c 3074
wolfSSL 15:117db924cf7c 3075 if (*keyEncSz < 0) {
wolfSSL 15:117db924cf7c 3076 WOLFSSL_MSG("RSA Public Encrypt failed");
wolfSSL 15:117db924cf7c 3077 FreeDecodedCert(decoded);
wolfSSL 15:117db924cf7c 3078 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 3079 XFREE(serial, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3080 XFREE(keyAlgArray, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3081 XFREE(decoded, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3082 #endif
wolfSSL 15:117db924cf7c 3083 return *keyEncSz;
wolfSSL 15:117db924cf7c 3084 }
wolfSSL 15:117db924cf7c 3085
wolfSSL 15:117db924cf7c 3086 encKeyOctetStrSz = SetOctetString(*keyEncSz, encKeyOctetStr);
wolfSSL 15:117db924cf7c 3087
wolfSSL 15:117db924cf7c 3088 /* RecipientInfo */
wolfSSL 15:117db924cf7c 3089 recipSeqSz = SetSequence(verSz + issuerSerialSeqSz + issuerSeqSz +
wolfSSL 15:117db924cf7c 3090 issuerSz + snSz + keyEncAlgSz + encKeyOctetStrSz +
wolfSSL 15:117db924cf7c 3091 *keyEncSz, recipSeq);
wolfSSL 15:117db924cf7c 3092
wolfSSL 15:117db924cf7c 3093 if (recipSeqSz + verSz + issuerSerialSeqSz + issuerSeqSz + snSz +
wolfSSL 15:117db924cf7c 3094 keyEncAlgSz + encKeyOctetStrSz + *keyEncSz > (int)outSz) {
wolfSSL 15:117db924cf7c 3095 WOLFSSL_MSG("RecipientInfo output buffer too small");
wolfSSL 15:117db924cf7c 3096 FreeDecodedCert(decoded);
wolfSSL 15:117db924cf7c 3097 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 3098 XFREE(serial, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3099 XFREE(keyAlgArray, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3100 XFREE(decoded, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3101 #endif
wolfSSL 15:117db924cf7c 3102 return BUFFER_E;
wolfSSL 15:117db924cf7c 3103 }
wolfSSL 15:117db924cf7c 3104
wolfSSL 15:117db924cf7c 3105 XMEMCPY(out + totalSz, recipSeq, recipSeqSz);
wolfSSL 15:117db924cf7c 3106 totalSz += recipSeqSz;
wolfSSL 15:117db924cf7c 3107 XMEMCPY(out + totalSz, ver, verSz);
wolfSSL 15:117db924cf7c 3108 totalSz += verSz;
wolfSSL 15:117db924cf7c 3109 XMEMCPY(out + totalSz, issuerSerialSeq, issuerSerialSeqSz);
wolfSSL 15:117db924cf7c 3110 totalSz += issuerSerialSeqSz;
wolfSSL 15:117db924cf7c 3111 XMEMCPY(out + totalSz, issuerSeq, issuerSeqSz);
wolfSSL 15:117db924cf7c 3112 totalSz += issuerSeqSz;
wolfSSL 15:117db924cf7c 3113 XMEMCPY(out + totalSz, decoded->issuerRaw, issuerSz);
wolfSSL 15:117db924cf7c 3114 totalSz += issuerSz;
wolfSSL 15:117db924cf7c 3115 XMEMCPY(out + totalSz, serial, snSz);
wolfSSL 15:117db924cf7c 3116 totalSz += snSz;
wolfSSL 15:117db924cf7c 3117 XMEMCPY(out + totalSz, keyAlgArray, keyEncAlgSz);
wolfSSL 15:117db924cf7c 3118 totalSz += keyEncAlgSz;
wolfSSL 15:117db924cf7c 3119 XMEMCPY(out + totalSz, encKeyOctetStr, encKeyOctetStrSz);
wolfSSL 15:117db924cf7c 3120 totalSz += encKeyOctetStrSz;
wolfSSL 15:117db924cf7c 3121 XMEMCPY(out + totalSz, contentKeyEnc, *keyEncSz);
wolfSSL 15:117db924cf7c 3122 totalSz += *keyEncSz;
wolfSSL 15:117db924cf7c 3123
wolfSSL 15:117db924cf7c 3124 FreeDecodedCert(decoded);
wolfSSL 15:117db924cf7c 3125
wolfSSL 15:117db924cf7c 3126 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 3127 XFREE(serial, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3128 XFREE(keyAlgArray, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3129 XFREE(decoded, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3130 #endif
wolfSSL 15:117db924cf7c 3131
wolfSSL 15:117db924cf7c 3132 return totalSz;
wolfSSL 15:117db924cf7c 3133 }
wolfSSL 15:117db924cf7c 3134 #endif /* !NO_RSA */
wolfSSL 15:117db924cf7c 3135
wolfSSL 15:117db924cf7c 3136
wolfSSL 15:117db924cf7c 3137 /* encrypt content using encryptOID algo */
wolfSSL 15:117db924cf7c 3138 static int wc_PKCS7_EncryptContent(int encryptOID, byte* key, int keySz,
wolfSSL 15:117db924cf7c 3139 byte* iv, int ivSz, byte* in, int inSz,
wolfSSL 15:117db924cf7c 3140 byte* out)
wolfSSL 15:117db924cf7c 3141 {
wolfSSL 15:117db924cf7c 3142 int ret;
wolfSSL 15:117db924cf7c 3143 #ifndef NO_AES
wolfSSL 15:117db924cf7c 3144 Aes aes;
wolfSSL 15:117db924cf7c 3145 #endif
wolfSSL 15:117db924cf7c 3146 #ifndef NO_DES3
wolfSSL 15:117db924cf7c 3147 Des des;
wolfSSL 15:117db924cf7c 3148 Des3 des3;
wolfSSL 15:117db924cf7c 3149 #endif
wolfSSL 15:117db924cf7c 3150
wolfSSL 15:117db924cf7c 3151 if (key == NULL || iv == NULL || in == NULL || out == NULL)
wolfSSL 15:117db924cf7c 3152 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 3153
wolfSSL 15:117db924cf7c 3154 switch (encryptOID) {
wolfSSL 15:117db924cf7c 3155 #ifndef NO_AES
wolfSSL 15:117db924cf7c 3156 #ifdef WOLFSSL_AES_128
wolfSSL 15:117db924cf7c 3157 case AES128CBCb:
wolfSSL 15:117db924cf7c 3158 #endif
wolfSSL 15:117db924cf7c 3159 #ifdef WOLFSSL_AES_192
wolfSSL 15:117db924cf7c 3160 case AES192CBCb:
wolfSSL 15:117db924cf7c 3161 #endif
wolfSSL 15:117db924cf7c 3162 #ifdef WOLFSSL_AES_256
wolfSSL 15:117db924cf7c 3163 case AES256CBCb:
wolfSSL 15:117db924cf7c 3164 #endif
wolfSSL 15:117db924cf7c 3165 if (
wolfSSL 15:117db924cf7c 3166 #ifdef WOLFSSL_AES_128
wolfSSL 15:117db924cf7c 3167 (encryptOID == AES128CBCb && keySz != 16 ) ||
wolfSSL 15:117db924cf7c 3168 #endif
wolfSSL 15:117db924cf7c 3169 #ifdef WOLFSSL_AES_192
wolfSSL 15:117db924cf7c 3170 (encryptOID == AES192CBCb && keySz != 24 ) ||
wolfSSL 15:117db924cf7c 3171 #endif
wolfSSL 15:117db924cf7c 3172 #ifdef WOLFSSL_AES_256
wolfSSL 15:117db924cf7c 3173 (encryptOID == AES256CBCb && keySz != 32 ) ||
wolfSSL 15:117db924cf7c 3174 #endif
wolfSSL 15:117db924cf7c 3175 (ivSz != AES_BLOCK_SIZE) )
wolfSSL 15:117db924cf7c 3176 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 3177
wolfSSL 15:117db924cf7c 3178 ret = wc_AesSetKey(&aes, key, keySz, iv, AES_ENCRYPTION);
wolfSSL 15:117db924cf7c 3179 if (ret == 0)
wolfSSL 15:117db924cf7c 3180 ret = wc_AesCbcEncrypt(&aes, out, in, inSz);
wolfSSL 15:117db924cf7c 3181
wolfSSL 15:117db924cf7c 3182 break;
wolfSSL 15:117db924cf7c 3183 #endif
wolfSSL 15:117db924cf7c 3184 #ifndef NO_DES3
wolfSSL 15:117db924cf7c 3185 case DESb:
wolfSSL 15:117db924cf7c 3186 if (keySz != DES_KEYLEN || ivSz != DES_BLOCK_SIZE)
wolfSSL 15:117db924cf7c 3187 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 3188
wolfSSL 15:117db924cf7c 3189 ret = wc_Des_SetKey(&des, key, iv, DES_ENCRYPTION);
wolfSSL 15:117db924cf7c 3190 if (ret == 0)
wolfSSL 15:117db924cf7c 3191 ret = wc_Des_CbcEncrypt(&des, out, in, inSz);
wolfSSL 15:117db924cf7c 3192
wolfSSL 15:117db924cf7c 3193 break;
wolfSSL 15:117db924cf7c 3194
wolfSSL 15:117db924cf7c 3195 case DES3b:
wolfSSL 15:117db924cf7c 3196 if (keySz != DES3_KEYLEN || ivSz != DES_BLOCK_SIZE)
wolfSSL 15:117db924cf7c 3197 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 3198
wolfSSL 15:117db924cf7c 3199 ret = wc_Des3_SetKey(&des3, key, iv, DES_ENCRYPTION);
wolfSSL 15:117db924cf7c 3200 if (ret == 0)
wolfSSL 15:117db924cf7c 3201 ret = wc_Des3_CbcEncrypt(&des3, out, in, inSz);
wolfSSL 15:117db924cf7c 3202
wolfSSL 15:117db924cf7c 3203 break;
wolfSSL 15:117db924cf7c 3204 #endif
wolfSSL 15:117db924cf7c 3205 default:
wolfSSL 15:117db924cf7c 3206 WOLFSSL_MSG("Unsupported content cipher type");
wolfSSL 15:117db924cf7c 3207 return ALGO_ID_E;
wolfSSL 15:117db924cf7c 3208 };
wolfSSL 15:117db924cf7c 3209
wolfSSL 15:117db924cf7c 3210 return ret;
wolfSSL 15:117db924cf7c 3211 }
wolfSSL 15:117db924cf7c 3212
wolfSSL 15:117db924cf7c 3213
wolfSSL 15:117db924cf7c 3214 /* decrypt content using encryptOID algo */
wolfSSL 15:117db924cf7c 3215 static int wc_PKCS7_DecryptContent(int encryptOID, byte* key, int keySz,
wolfSSL 15:117db924cf7c 3216 byte* iv, int ivSz, byte* in, int inSz,
wolfSSL 15:117db924cf7c 3217 byte* out)
wolfSSL 15:117db924cf7c 3218 {
wolfSSL 15:117db924cf7c 3219 int ret;
wolfSSL 15:117db924cf7c 3220 #ifndef NO_AES
wolfSSL 15:117db924cf7c 3221 Aes aes;
wolfSSL 15:117db924cf7c 3222 #endif
wolfSSL 15:117db924cf7c 3223 #ifndef NO_DES3
wolfSSL 15:117db924cf7c 3224 Des des;
wolfSSL 15:117db924cf7c 3225 Des3 des3;
wolfSSL 15:117db924cf7c 3226 #endif
wolfSSL 15:117db924cf7c 3227
wolfSSL 15:117db924cf7c 3228 if (key == NULL || iv == NULL || in == NULL || out == NULL)
wolfSSL 15:117db924cf7c 3229 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 3230
wolfSSL 15:117db924cf7c 3231 switch (encryptOID) {
wolfSSL 15:117db924cf7c 3232 #ifndef NO_AES
wolfSSL 15:117db924cf7c 3233 #ifdef WOLFSSL_AES_128
wolfSSL 15:117db924cf7c 3234 case AES128CBCb:
wolfSSL 15:117db924cf7c 3235 #endif
wolfSSL 15:117db924cf7c 3236 #ifdef WOLFSSL_AES_192
wolfSSL 15:117db924cf7c 3237 case AES192CBCb:
wolfSSL 15:117db924cf7c 3238 #endif
wolfSSL 15:117db924cf7c 3239 #ifdef WOLFSSL_AES_256
wolfSSL 15:117db924cf7c 3240 case AES256CBCb:
wolfSSL 15:117db924cf7c 3241 #endif
wolfSSL 15:117db924cf7c 3242 if (
wolfSSL 15:117db924cf7c 3243 #ifdef WOLFSSL_AES_128
wolfSSL 15:117db924cf7c 3244 (encryptOID == AES128CBCb && keySz != 16 ) ||
wolfSSL 15:117db924cf7c 3245 #endif
wolfSSL 15:117db924cf7c 3246 #ifdef WOLFSSL_AES_192
wolfSSL 15:117db924cf7c 3247 (encryptOID == AES192CBCb && keySz != 24 ) ||
wolfSSL 15:117db924cf7c 3248 #endif
wolfSSL 15:117db924cf7c 3249 #ifdef WOLFSSL_AES_256
wolfSSL 15:117db924cf7c 3250 (encryptOID == AES256CBCb && keySz != 32 ) ||
wolfSSL 15:117db924cf7c 3251 #endif
wolfSSL 15:117db924cf7c 3252 (ivSz != AES_BLOCK_SIZE) )
wolfSSL 15:117db924cf7c 3253 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 3254
wolfSSL 15:117db924cf7c 3255 ret = wc_AesSetKey(&aes, key, keySz, iv, AES_DECRYPTION);
wolfSSL 15:117db924cf7c 3256 if (ret == 0)
wolfSSL 15:117db924cf7c 3257 ret = wc_AesCbcDecrypt(&aes, out, in, inSz);
wolfSSL 15:117db924cf7c 3258
wolfSSL 15:117db924cf7c 3259 break;
wolfSSL 15:117db924cf7c 3260 #endif
wolfSSL 15:117db924cf7c 3261 #ifndef NO_DES3
wolfSSL 15:117db924cf7c 3262 case DESb:
wolfSSL 15:117db924cf7c 3263 if (keySz != DES_KEYLEN || ivSz != DES_BLOCK_SIZE)
wolfSSL 15:117db924cf7c 3264 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 3265
wolfSSL 15:117db924cf7c 3266 ret = wc_Des_SetKey(&des, key, iv, DES_DECRYPTION);
wolfSSL 15:117db924cf7c 3267 if (ret == 0)
wolfSSL 15:117db924cf7c 3268 ret = wc_Des_CbcDecrypt(&des, out, in, inSz);
wolfSSL 15:117db924cf7c 3269
wolfSSL 15:117db924cf7c 3270 break;
wolfSSL 15:117db924cf7c 3271 case DES3b:
wolfSSL 15:117db924cf7c 3272 if (keySz != DES3_KEYLEN || ivSz != DES_BLOCK_SIZE)
wolfSSL 15:117db924cf7c 3273 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 3274
wolfSSL 15:117db924cf7c 3275 ret = wc_Des3_SetKey(&des3, key, iv, DES_DECRYPTION);
wolfSSL 15:117db924cf7c 3276 if (ret == 0)
wolfSSL 15:117db924cf7c 3277 ret = wc_Des3_CbcDecrypt(&des3, out, in, inSz);
wolfSSL 15:117db924cf7c 3278
wolfSSL 15:117db924cf7c 3279 break;
wolfSSL 15:117db924cf7c 3280 #endif
wolfSSL 15:117db924cf7c 3281 default:
wolfSSL 15:117db924cf7c 3282 WOLFSSL_MSG("Unsupported content cipher type");
wolfSSL 15:117db924cf7c 3283 return ALGO_ID_E;
wolfSSL 15:117db924cf7c 3284 };
wolfSSL 15:117db924cf7c 3285
wolfSSL 15:117db924cf7c 3286 return ret;
wolfSSL 15:117db924cf7c 3287 }
wolfSSL 15:117db924cf7c 3288
wolfSSL 15:117db924cf7c 3289
wolfSSL 15:117db924cf7c 3290 /* generate random IV, place in iv, return 0 on success negative on error */
wolfSSL 15:117db924cf7c 3291 static int wc_PKCS7_GenerateIV(PKCS7* pkcs7, WC_RNG* rng, byte* iv, word32 ivSz)
wolfSSL 15:117db924cf7c 3292 {
wolfSSL 15:117db924cf7c 3293 int ret;
wolfSSL 15:117db924cf7c 3294 WC_RNG* rnd = NULL;
wolfSSL 15:117db924cf7c 3295
wolfSSL 15:117db924cf7c 3296 if (iv == NULL || ivSz == 0)
wolfSSL 15:117db924cf7c 3297 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 3298
wolfSSL 15:117db924cf7c 3299 /* input RNG is optional, init local one if input rng is NULL */
wolfSSL 15:117db924cf7c 3300 if (rng == NULL) {
wolfSSL 15:117db924cf7c 3301 rnd = (WC_RNG*)XMALLOC(sizeof(WC_RNG), pkcs7->heap, DYNAMIC_TYPE_RNG);
wolfSSL 15:117db924cf7c 3302 if (rnd == NULL)
wolfSSL 15:117db924cf7c 3303 return MEMORY_E;
wolfSSL 15:117db924cf7c 3304
wolfSSL 15:117db924cf7c 3305 ret = wc_InitRng_ex(rnd, pkcs7->heap, pkcs7->devId);
wolfSSL 15:117db924cf7c 3306 if (ret != 0) {
wolfSSL 15:117db924cf7c 3307 XFREE(rnd, pkcs7->heap, DYNAMIC_TYPE_RNG);
wolfSSL 15:117db924cf7c 3308 return ret;
wolfSSL 15:117db924cf7c 3309 }
wolfSSL 15:117db924cf7c 3310
wolfSSL 15:117db924cf7c 3311 } else {
wolfSSL 15:117db924cf7c 3312 rnd = rng;
wolfSSL 15:117db924cf7c 3313 }
wolfSSL 15:117db924cf7c 3314
wolfSSL 15:117db924cf7c 3315 ret = wc_RNG_GenerateBlock(rnd, iv, ivSz);
wolfSSL 15:117db924cf7c 3316
wolfSSL 15:117db924cf7c 3317 if (rng == NULL) {
wolfSSL 15:117db924cf7c 3318 wc_FreeRng(rnd);
wolfSSL 15:117db924cf7c 3319 XFREE(rnd, pkcs7->heap, DYNAMIC_TYPE_RNG);
wolfSSL 15:117db924cf7c 3320 }
wolfSSL 15:117db924cf7c 3321
wolfSSL 15:117db924cf7c 3322 return ret;
wolfSSL 15:117db924cf7c 3323 }
wolfSSL 15:117db924cf7c 3324
wolfSSL 15:117db924cf7c 3325
wolfSSL 15:117db924cf7c 3326 /* return size of padded data, padded to blockSz chunks, or negative on error */
wolfSSL 15:117db924cf7c 3327 int wc_PKCS7_GetPadSize(word32 inputSz, word32 blockSz)
wolfSSL 15:117db924cf7c 3328 {
wolfSSL 15:117db924cf7c 3329 int padSz;
wolfSSL 15:117db924cf7c 3330
wolfSSL 15:117db924cf7c 3331 if (blockSz == 0)
wolfSSL 15:117db924cf7c 3332 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 3333
wolfSSL 15:117db924cf7c 3334 padSz = blockSz - (inputSz % blockSz);
wolfSSL 15:117db924cf7c 3335
wolfSSL 15:117db924cf7c 3336 return padSz;
wolfSSL 15:117db924cf7c 3337 }
wolfSSL 15:117db924cf7c 3338
wolfSSL 15:117db924cf7c 3339
wolfSSL 15:117db924cf7c 3340 /* pad input data to blockSz chunk, place in outSz. out must be big enough
wolfSSL 15:117db924cf7c 3341 * for input + pad bytes. See wc_PKCS7_GetPadSize() helper. */
wolfSSL 15:117db924cf7c 3342 int wc_PKCS7_PadData(byte* in, word32 inSz, byte* out, word32 outSz,
wolfSSL 15:117db924cf7c 3343 word32 blockSz)
wolfSSL 15:117db924cf7c 3344 {
wolfSSL 15:117db924cf7c 3345 int i, padSz;
wolfSSL 15:117db924cf7c 3346
wolfSSL 15:117db924cf7c 3347 if (in == NULL || inSz == 0 ||
wolfSSL 15:117db924cf7c 3348 out == NULL || outSz == 0)
wolfSSL 15:117db924cf7c 3349 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 3350
wolfSSL 15:117db924cf7c 3351 padSz = wc_PKCS7_GetPadSize(inSz, blockSz);
wolfSSL 15:117db924cf7c 3352
wolfSSL 15:117db924cf7c 3353 if (outSz < (inSz + padSz))
wolfSSL 15:117db924cf7c 3354 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 3355
wolfSSL 15:117db924cf7c 3356 XMEMCPY(out, in, inSz);
wolfSSL 15:117db924cf7c 3357
wolfSSL 15:117db924cf7c 3358 for (i = 0; i < padSz; i++) {
wolfSSL 15:117db924cf7c 3359 out[inSz + i] = (byte)padSz;
wolfSSL 15:117db924cf7c 3360 }
wolfSSL 15:117db924cf7c 3361
wolfSSL 15:117db924cf7c 3362 return inSz + padSz;
wolfSSL 15:117db924cf7c 3363 }
wolfSSL 15:117db924cf7c 3364
wolfSSL 15:117db924cf7c 3365
wolfSSL 15:117db924cf7c 3366 /* build PKCS#7 envelopedData content type, return enveloped size */
wolfSSL 15:117db924cf7c 3367 int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz)
wolfSSL 15:117db924cf7c 3368 {
wolfSSL 15:117db924cf7c 3369 int ret, idx = 0;
wolfSSL 15:117db924cf7c 3370 int totalSz, padSz, encryptedOutSz;
wolfSSL 15:117db924cf7c 3371
wolfSSL 15:117db924cf7c 3372 int contentInfoSeqSz, outerContentTypeSz, outerContentSz;
wolfSSL 15:117db924cf7c 3373 byte contentInfoSeq[MAX_SEQ_SZ];
wolfSSL 15:117db924cf7c 3374 byte outerContentType[MAX_ALGO_SZ];
wolfSSL 15:117db924cf7c 3375 byte outerContent[MAX_SEQ_SZ];
wolfSSL 15:117db924cf7c 3376
wolfSSL 15:117db924cf7c 3377 int envDataSeqSz, verSz;
wolfSSL 15:117db924cf7c 3378 byte envDataSeq[MAX_SEQ_SZ];
wolfSSL 15:117db924cf7c 3379 byte ver[MAX_VERSION_SZ];
wolfSSL 15:117db924cf7c 3380
wolfSSL 15:117db924cf7c 3381 WC_RNG rng;
wolfSSL 15:117db924cf7c 3382 int contentKeyEncSz, blockSz, blockKeySz;
wolfSSL 15:117db924cf7c 3383 byte contentKeyPlain[MAX_CONTENT_KEY_LEN];
wolfSSL 15:117db924cf7c 3384 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 3385 byte* contentKeyEnc;
wolfSSL 15:117db924cf7c 3386 #else
wolfSSL 15:117db924cf7c 3387 byte contentKeyEnc[MAX_ENCRYPTED_KEY_SZ];
wolfSSL 15:117db924cf7c 3388 #endif
wolfSSL 15:117db924cf7c 3389 byte* plain;
wolfSSL 15:117db924cf7c 3390 byte* encryptedContent;
wolfSSL 15:117db924cf7c 3391
wolfSSL 15:117db924cf7c 3392 int recipSz, recipSetSz;
wolfSSL 15:117db924cf7c 3393 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 3394 byte* recip;
wolfSSL 15:117db924cf7c 3395 #else
wolfSSL 15:117db924cf7c 3396 byte recip[MAX_RECIP_SZ];
wolfSSL 15:117db924cf7c 3397 #endif
wolfSSL 15:117db924cf7c 3398 byte recipSet[MAX_SET_SZ];
wolfSSL 15:117db924cf7c 3399
wolfSSL 15:117db924cf7c 3400 int encContentOctetSz, encContentSeqSz, contentTypeSz;
wolfSSL 15:117db924cf7c 3401 int contentEncAlgoSz, ivOctetStringSz;
wolfSSL 15:117db924cf7c 3402 byte encContentSeq[MAX_SEQ_SZ];
wolfSSL 15:117db924cf7c 3403 byte contentType[MAX_ALGO_SZ];
wolfSSL 15:117db924cf7c 3404 byte contentEncAlgo[MAX_ALGO_SZ];
wolfSSL 15:117db924cf7c 3405 byte tmpIv[MAX_CONTENT_IV_SIZE];
wolfSSL 15:117db924cf7c 3406 byte ivOctetString[MAX_OCTET_STR_SZ];
wolfSSL 15:117db924cf7c 3407 byte encContentOctet[MAX_OCTET_STR_SZ];
wolfSSL 15:117db924cf7c 3408
wolfSSL 15:117db924cf7c 3409 if (pkcs7 == NULL || pkcs7->content == NULL || pkcs7->contentSz == 0 ||
wolfSSL 15:117db924cf7c 3410 pkcs7->encryptOID == 0 || pkcs7->singleCert == NULL ||
wolfSSL 15:117db924cf7c 3411 pkcs7->publicKeyOID == 0)
wolfSSL 15:117db924cf7c 3412 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 3413
wolfSSL 15:117db924cf7c 3414 if (output == NULL || outputSz == 0)
wolfSSL 15:117db924cf7c 3415 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 3416
wolfSSL 15:117db924cf7c 3417 blockKeySz = wc_PKCS7_GetOIDKeySize(pkcs7->encryptOID);
wolfSSL 15:117db924cf7c 3418 if (blockKeySz < 0)
wolfSSL 15:117db924cf7c 3419 return blockKeySz;
wolfSSL 15:117db924cf7c 3420
wolfSSL 15:117db924cf7c 3421 blockSz = wc_PKCS7_GetOIDBlockSize(pkcs7->encryptOID);
wolfSSL 15:117db924cf7c 3422 if (blockSz < 0)
wolfSSL 15:117db924cf7c 3423 return blockSz;
wolfSSL 15:117db924cf7c 3424
wolfSSL 15:117db924cf7c 3425 /* outer content type */
wolfSSL 15:117db924cf7c 3426 outerContentTypeSz = wc_SetContentType(ENVELOPED_DATA, outerContentType);
wolfSSL 15:117db924cf7c 3427
wolfSSL 15:117db924cf7c 3428 /* version, defined as 0 in RFC 2315 */
wolfSSL 15:117db924cf7c 3429 #ifdef HAVE_ECC
wolfSSL 15:117db924cf7c 3430 if (pkcs7->publicKeyOID == ECDSAk) {
wolfSSL 15:117db924cf7c 3431 verSz = SetMyVersion(2, ver, 0);
wolfSSL 15:117db924cf7c 3432 } else
wolfSSL 15:117db924cf7c 3433 #endif
wolfSSL 15:117db924cf7c 3434 {
wolfSSL 15:117db924cf7c 3435 verSz = SetMyVersion(0, ver, 0);
wolfSSL 15:117db924cf7c 3436 }
wolfSSL 15:117db924cf7c 3437
wolfSSL 15:117db924cf7c 3438 /* generate random content encryption key */
wolfSSL 15:117db924cf7c 3439 ret = wc_InitRng_ex(&rng, pkcs7->heap, pkcs7->devId);
wolfSSL 15:117db924cf7c 3440 if (ret != 0)
wolfSSL 15:117db924cf7c 3441 return ret;
wolfSSL 15:117db924cf7c 3442
wolfSSL 15:117db924cf7c 3443 ret = wc_RNG_GenerateBlock(&rng, contentKeyPlain, blockKeySz);
wolfSSL 15:117db924cf7c 3444 if (ret != 0) {
wolfSSL 15:117db924cf7c 3445 wc_FreeRng(&rng);
wolfSSL 15:117db924cf7c 3446 return ret;
wolfSSL 15:117db924cf7c 3447 }
wolfSSL 15:117db924cf7c 3448
wolfSSL 15:117db924cf7c 3449 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 3450 recip = (byte*)XMALLOC(MAX_RECIP_SZ, pkcs7->heap,
wolfSSL 15:117db924cf7c 3451 DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 3452 contentKeyEnc = (byte*)XMALLOC(MAX_ENCRYPTED_KEY_SZ, pkcs7->heap,
wolfSSL 15:117db924cf7c 3453 DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 3454 if (contentKeyEnc == NULL || recip == NULL) {
wolfSSL 15:117db924cf7c 3455 if (recip) XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 3456 if (contentKeyEnc) XFREE(contentKeyEnc, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 3457 wc_FreeRng(&rng);
wolfSSL 15:117db924cf7c 3458 return MEMORY_E;
wolfSSL 15:117db924cf7c 3459 }
wolfSSL 15:117db924cf7c 3460 #endif
wolfSSL 15:117db924cf7c 3461 contentKeyEncSz = MAX_ENCRYPTED_KEY_SZ;
wolfSSL 15:117db924cf7c 3462
wolfSSL 15:117db924cf7c 3463 /* build RecipientInfo, only handle 1 for now */
wolfSSL 15:117db924cf7c 3464 switch (pkcs7->publicKeyOID) {
wolfSSL 15:117db924cf7c 3465 #ifndef NO_RSA
wolfSSL 15:117db924cf7c 3466 case RSAk:
wolfSSL 15:117db924cf7c 3467 recipSz = wc_CreateRecipientInfo(pkcs7->singleCert,
wolfSSL 15:117db924cf7c 3468 pkcs7->singleCertSz,
wolfSSL 15:117db924cf7c 3469 pkcs7->publicKeyOID,
wolfSSL 15:117db924cf7c 3470 blockKeySz, &rng, contentKeyPlain,
wolfSSL 15:117db924cf7c 3471 contentKeyEnc, &contentKeyEncSz, recip,
wolfSSL 15:117db924cf7c 3472 MAX_RECIP_SZ, pkcs7->heap);
wolfSSL 15:117db924cf7c 3473 break;
wolfSSL 15:117db924cf7c 3474 #endif
wolfSSL 15:117db924cf7c 3475 #ifdef HAVE_ECC
wolfSSL 15:117db924cf7c 3476 case ECDSAk:
wolfSSL 15:117db924cf7c 3477 recipSz = wc_CreateKeyAgreeRecipientInfo(pkcs7, pkcs7->singleCert,
wolfSSL 15:117db924cf7c 3478 pkcs7->singleCertSz,
wolfSSL 15:117db924cf7c 3479 pkcs7->publicKeyOID,
wolfSSL 15:117db924cf7c 3480 blockKeySz, pkcs7->keyWrapOID,
wolfSSL 15:117db924cf7c 3481 pkcs7->keyAgreeOID, &rng,
wolfSSL 15:117db924cf7c 3482 contentKeyPlain, contentKeyEnc,
wolfSSL 15:117db924cf7c 3483 &contentKeyEncSz, recip, MAX_RECIP_SZ);
wolfSSL 15:117db924cf7c 3484 break;
wolfSSL 15:117db924cf7c 3485 #endif
wolfSSL 15:117db924cf7c 3486
wolfSSL 15:117db924cf7c 3487 default:
wolfSSL 15:117db924cf7c 3488 WOLFSSL_MSG("Unsupported RecipientInfo public key type");
wolfSSL 15:117db924cf7c 3489 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 3490 };
wolfSSL 15:117db924cf7c 3491
wolfSSL 15:117db924cf7c 3492 ForceZero(contentKeyEnc, MAX_ENCRYPTED_KEY_SZ);
wolfSSL 15:117db924cf7c 3493
wolfSSL 15:117db924cf7c 3494 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 3495 XFREE(contentKeyEnc, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 3496 #endif
wolfSSL 15:117db924cf7c 3497
wolfSSL 15:117db924cf7c 3498 if (recipSz < 0) {
wolfSSL 15:117db924cf7c 3499 WOLFSSL_MSG("Failed to create RecipientInfo");
wolfSSL 15:117db924cf7c 3500 wc_FreeRng(&rng);
wolfSSL 15:117db924cf7c 3501 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 3502 XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3503 #endif
wolfSSL 15:117db924cf7c 3504 return recipSz;
wolfSSL 15:117db924cf7c 3505 }
wolfSSL 15:117db924cf7c 3506 recipSetSz = SetSet(recipSz, recipSet);
wolfSSL 15:117db924cf7c 3507
wolfSSL 15:117db924cf7c 3508 /* generate IV for block cipher */
wolfSSL 15:117db924cf7c 3509 ret = wc_PKCS7_GenerateIV(pkcs7, &rng, tmpIv, blockSz);
wolfSSL 15:117db924cf7c 3510 wc_FreeRng(&rng);
wolfSSL 15:117db924cf7c 3511 if (ret != 0) {
wolfSSL 15:117db924cf7c 3512 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 3513 XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3514 #endif
wolfSSL 15:117db924cf7c 3515 return ret;
wolfSSL 15:117db924cf7c 3516 }
wolfSSL 15:117db924cf7c 3517
wolfSSL 15:117db924cf7c 3518 /* EncryptedContentInfo */
wolfSSL 15:117db924cf7c 3519 contentTypeSz = wc_SetContentType(pkcs7->contentOID, contentType);
wolfSSL 15:117db924cf7c 3520 if (contentTypeSz == 0) {
wolfSSL 15:117db924cf7c 3521 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 3522 XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3523 #endif
wolfSSL 15:117db924cf7c 3524 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 3525 }
wolfSSL 15:117db924cf7c 3526
wolfSSL 15:117db924cf7c 3527 /* allocate encrypted content buffer and PKCS#7 padding */
wolfSSL 15:117db924cf7c 3528 padSz = wc_PKCS7_GetPadSize(pkcs7->contentSz, blockSz);
wolfSSL 15:117db924cf7c 3529 if (padSz < 0)
wolfSSL 15:117db924cf7c 3530 return padSz;
wolfSSL 15:117db924cf7c 3531
wolfSSL 15:117db924cf7c 3532 encryptedOutSz = pkcs7->contentSz + padSz;
wolfSSL 15:117db924cf7c 3533
wolfSSL 15:117db924cf7c 3534 plain = (byte*)XMALLOC(encryptedOutSz, pkcs7->heap,
wolfSSL 15:117db924cf7c 3535 DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 3536 if (plain == NULL)
wolfSSL 15:117db924cf7c 3537 return MEMORY_E;
wolfSSL 15:117db924cf7c 3538
wolfSSL 15:117db924cf7c 3539 ret = wc_PKCS7_PadData(pkcs7->content, pkcs7->contentSz, plain,
wolfSSL 15:117db924cf7c 3540 encryptedOutSz, blockSz);
wolfSSL 15:117db924cf7c 3541 if (ret < 0) {
wolfSSL 15:117db924cf7c 3542 XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 3543 return ret;
wolfSSL 15:117db924cf7c 3544 }
wolfSSL 15:117db924cf7c 3545
wolfSSL 15:117db924cf7c 3546 encryptedContent = (byte*)XMALLOC(encryptedOutSz, pkcs7->heap,
wolfSSL 15:117db924cf7c 3547 DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 3548 if (encryptedContent == NULL) {
wolfSSL 15:117db924cf7c 3549 XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 3550 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 3551 XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3552 #endif
wolfSSL 15:117db924cf7c 3553 return MEMORY_E;
wolfSSL 15:117db924cf7c 3554 }
wolfSSL 15:117db924cf7c 3555
wolfSSL 15:117db924cf7c 3556 /* put together IV OCTET STRING */
wolfSSL 15:117db924cf7c 3557 ivOctetStringSz = SetOctetString(blockSz, ivOctetString);
wolfSSL 15:117db924cf7c 3558
wolfSSL 15:117db924cf7c 3559 /* build up our ContentEncryptionAlgorithmIdentifier sequence,
wolfSSL 15:117db924cf7c 3560 * adding (ivOctetStringSz + blockSz) for IV OCTET STRING */
wolfSSL 15:117db924cf7c 3561 contentEncAlgoSz = SetAlgoID(pkcs7->encryptOID, contentEncAlgo,
wolfSSL 15:117db924cf7c 3562 oidBlkType, ivOctetStringSz + blockSz);
wolfSSL 15:117db924cf7c 3563
wolfSSL 15:117db924cf7c 3564 if (contentEncAlgoSz == 0) {
wolfSSL 15:117db924cf7c 3565 XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 3566 XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 3567 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 3568 XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 3569 #endif
wolfSSL 15:117db924cf7c 3570 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 3571 }
wolfSSL 15:117db924cf7c 3572
wolfSSL 15:117db924cf7c 3573 /* encrypt content */
wolfSSL 15:117db924cf7c 3574 ret = wc_PKCS7_EncryptContent(pkcs7->encryptOID, contentKeyPlain,
wolfSSL 15:117db924cf7c 3575 blockKeySz, tmpIv, blockSz, plain, encryptedOutSz,
wolfSSL 15:117db924cf7c 3576 encryptedContent);
wolfSSL 15:117db924cf7c 3577
wolfSSL 15:117db924cf7c 3578 if (ret != 0) {
wolfSSL 15:117db924cf7c 3579 XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 3580 XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 3581 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 3582 XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 3583 #endif
wolfSSL 15:117db924cf7c 3584 return ret;
wolfSSL 15:117db924cf7c 3585 }
wolfSSL 15:117db924cf7c 3586
wolfSSL 15:117db924cf7c 3587 encContentOctetSz = SetImplicit(ASN_OCTET_STRING, 0, encryptedOutSz,
wolfSSL 15:117db924cf7c 3588 encContentOctet);
wolfSSL 15:117db924cf7c 3589
wolfSSL 15:117db924cf7c 3590 encContentSeqSz = SetSequence(contentTypeSz + contentEncAlgoSz +
wolfSSL 15:117db924cf7c 3591 ivOctetStringSz + blockSz +
wolfSSL 15:117db924cf7c 3592 encContentOctetSz + encryptedOutSz,
wolfSSL 15:117db924cf7c 3593 encContentSeq);
wolfSSL 15:117db924cf7c 3594
wolfSSL 15:117db924cf7c 3595 /* keep track of sizes for outer wrapper layering */
wolfSSL 15:117db924cf7c 3596 totalSz = verSz + recipSetSz + recipSz + encContentSeqSz + contentTypeSz +
wolfSSL 15:117db924cf7c 3597 contentEncAlgoSz + ivOctetStringSz + blockSz +
wolfSSL 15:117db924cf7c 3598 encContentOctetSz + encryptedOutSz;
wolfSSL 15:117db924cf7c 3599
wolfSSL 15:117db924cf7c 3600 /* EnvelopedData */
wolfSSL 15:117db924cf7c 3601 envDataSeqSz = SetSequence(totalSz, envDataSeq);
wolfSSL 15:117db924cf7c 3602 totalSz += envDataSeqSz;
wolfSSL 15:117db924cf7c 3603
wolfSSL 15:117db924cf7c 3604 /* outer content */
wolfSSL 15:117db924cf7c 3605 outerContentSz = SetExplicit(0, totalSz, outerContent);
wolfSSL 15:117db924cf7c 3606 totalSz += outerContentTypeSz;
wolfSSL 15:117db924cf7c 3607 totalSz += outerContentSz;
wolfSSL 15:117db924cf7c 3608
wolfSSL 15:117db924cf7c 3609 /* ContentInfo */
wolfSSL 15:117db924cf7c 3610 contentInfoSeqSz = SetSequence(totalSz, contentInfoSeq);
wolfSSL 15:117db924cf7c 3611 totalSz += contentInfoSeqSz;
wolfSSL 15:117db924cf7c 3612
wolfSSL 15:117db924cf7c 3613 if (totalSz > (int)outputSz) {
wolfSSL 15:117db924cf7c 3614 WOLFSSL_MSG("Pkcs7_encrypt output buffer too small");
wolfSSL 15:117db924cf7c 3615 XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 3616 XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3617 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 3618 XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3619 #endif
wolfSSL 15:117db924cf7c 3620 return BUFFER_E;
wolfSSL 15:117db924cf7c 3621 }
wolfSSL 15:117db924cf7c 3622
wolfSSL 15:117db924cf7c 3623 XMEMCPY(output + idx, contentInfoSeq, contentInfoSeqSz);
wolfSSL 15:117db924cf7c 3624 idx += contentInfoSeqSz;
wolfSSL 15:117db924cf7c 3625 XMEMCPY(output + idx, outerContentType, outerContentTypeSz);
wolfSSL 15:117db924cf7c 3626 idx += outerContentTypeSz;
wolfSSL 15:117db924cf7c 3627 XMEMCPY(output + idx, outerContent, outerContentSz);
wolfSSL 15:117db924cf7c 3628 idx += outerContentSz;
wolfSSL 15:117db924cf7c 3629 XMEMCPY(output + idx, envDataSeq, envDataSeqSz);
wolfSSL 15:117db924cf7c 3630 idx += envDataSeqSz;
wolfSSL 15:117db924cf7c 3631 XMEMCPY(output + idx, ver, verSz);
wolfSSL 15:117db924cf7c 3632 idx += verSz;
wolfSSL 15:117db924cf7c 3633 XMEMCPY(output + idx, recipSet, recipSetSz);
wolfSSL 15:117db924cf7c 3634 idx += recipSetSz;
wolfSSL 15:117db924cf7c 3635 XMEMCPY(output + idx, recip, recipSz);
wolfSSL 15:117db924cf7c 3636 idx += recipSz;
wolfSSL 15:117db924cf7c 3637 XMEMCPY(output + idx, encContentSeq, encContentSeqSz);
wolfSSL 15:117db924cf7c 3638 idx += encContentSeqSz;
wolfSSL 15:117db924cf7c 3639 XMEMCPY(output + idx, contentType, contentTypeSz);
wolfSSL 15:117db924cf7c 3640 idx += contentTypeSz;
wolfSSL 15:117db924cf7c 3641 XMEMCPY(output + idx, contentEncAlgo, contentEncAlgoSz);
wolfSSL 15:117db924cf7c 3642 idx += contentEncAlgoSz;
wolfSSL 15:117db924cf7c 3643 XMEMCPY(output + idx, ivOctetString, ivOctetStringSz);
wolfSSL 15:117db924cf7c 3644 idx += ivOctetStringSz;
wolfSSL 15:117db924cf7c 3645 XMEMCPY(output + idx, tmpIv, blockSz);
wolfSSL 15:117db924cf7c 3646 idx += blockSz;
wolfSSL 15:117db924cf7c 3647 XMEMCPY(output + idx, encContentOctet, encContentOctetSz);
wolfSSL 15:117db924cf7c 3648 idx += encContentOctetSz;
wolfSSL 15:117db924cf7c 3649 XMEMCPY(output + idx, encryptedContent, encryptedOutSz);
wolfSSL 15:117db924cf7c 3650 idx += encryptedOutSz;
wolfSSL 15:117db924cf7c 3651
wolfSSL 15:117db924cf7c 3652 ForceZero(contentKeyPlain, MAX_CONTENT_KEY_LEN);
wolfSSL 15:117db924cf7c 3653
wolfSSL 15:117db924cf7c 3654 XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 3655 XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 3656
wolfSSL 15:117db924cf7c 3657 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 3658 XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3659 #endif
wolfSSL 15:117db924cf7c 3660
wolfSSL 15:117db924cf7c 3661 return idx;
wolfSSL 15:117db924cf7c 3662 }
wolfSSL 15:117db924cf7c 3663
wolfSSL 15:117db924cf7c 3664 #ifndef NO_RSA
wolfSSL 15:117db924cf7c 3665 /* decode KeyTransRecipientInfo (ktri), return 0 on success, <0 on error */
wolfSSL 15:117db924cf7c 3666 static int wc_PKCS7_DecodeKtri(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz,
wolfSSL 15:117db924cf7c 3667 word32* idx, byte* decryptedKey,
wolfSSL 15:117db924cf7c 3668 word32* decryptedKeySz, int* recipFound)
wolfSSL 15:117db924cf7c 3669 {
wolfSSL 15:117db924cf7c 3670 int length, encryptedKeySz, ret;
wolfSSL 15:117db924cf7c 3671 int keySz;
wolfSSL 15:117db924cf7c 3672 word32 encOID;
wolfSSL 15:117db924cf7c 3673 word32 keyIdx;
wolfSSL 15:117db924cf7c 3674 byte issuerHash[KEYID_SIZE];
wolfSSL 15:117db924cf7c 3675 byte* outKey = NULL;
wolfSSL 15:117db924cf7c 3676
wolfSSL 15:117db924cf7c 3677 #ifdef WC_RSA_BLINDING
wolfSSL 15:117db924cf7c 3678 WC_RNG rng;
wolfSSL 15:117db924cf7c 3679 #endif
wolfSSL 15:117db924cf7c 3680
wolfSSL 15:117db924cf7c 3681 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 3682 mp_int* serialNum;
wolfSSL 15:117db924cf7c 3683 byte* encryptedKey;
wolfSSL 15:117db924cf7c 3684 RsaKey* privKey;
wolfSSL 15:117db924cf7c 3685 #else
wolfSSL 15:117db924cf7c 3686 mp_int stack_serialNum;
wolfSSL 15:117db924cf7c 3687 mp_int* serialNum = &stack_serialNum;
wolfSSL 15:117db924cf7c 3688 byte encryptedKey[MAX_ENCRYPTED_KEY_SZ];
wolfSSL 15:117db924cf7c 3689
wolfSSL 15:117db924cf7c 3690 RsaKey stack_privKey;
wolfSSL 15:117db924cf7c 3691 RsaKey* privKey = &stack_privKey;
wolfSSL 15:117db924cf7c 3692 #endif
wolfSSL 15:117db924cf7c 3693
wolfSSL 15:117db924cf7c 3694 /* remove IssuerAndSerialNumber */
wolfSSL 15:117db924cf7c 3695 if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 3696 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 3697
wolfSSL 15:117db924cf7c 3698 if (GetNameHash(pkiMsg, idx, issuerHash, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 3699 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 3700
wolfSSL 15:117db924cf7c 3701 /* if we found correct recipient, issuer hashes will match */
wolfSSL 15:117db924cf7c 3702 if (XMEMCMP(issuerHash, pkcs7->issuerHash, KEYID_SIZE) == 0) {
wolfSSL 15:117db924cf7c 3703 *recipFound = 1;
wolfSSL 15:117db924cf7c 3704 }
wolfSSL 15:117db924cf7c 3705
wolfSSL 15:117db924cf7c 3706 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 3707 serialNum = (mp_int*)XMALLOC(sizeof(mp_int), pkcs7->heap,
wolfSSL 15:117db924cf7c 3708 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3709 if (serialNum == NULL)
wolfSSL 15:117db924cf7c 3710 return MEMORY_E;
wolfSSL 15:117db924cf7c 3711 #endif
wolfSSL 15:117db924cf7c 3712
wolfSSL 15:117db924cf7c 3713 if (GetInt(serialNum, pkiMsg, idx, pkiMsgSz) < 0) {
wolfSSL 15:117db924cf7c 3714 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 3715 XFREE(serialNum, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3716 #endif
wolfSSL 15:117db924cf7c 3717 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 3718 }
wolfSSL 15:117db924cf7c 3719
wolfSSL 15:117db924cf7c 3720 mp_clear(serialNum);
wolfSSL 15:117db924cf7c 3721
wolfSSL 15:117db924cf7c 3722 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 3723 XFREE(serialNum, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3724 #endif
wolfSSL 15:117db924cf7c 3725
wolfSSL 15:117db924cf7c 3726 if (GetAlgoId(pkiMsg, idx, &encOID, oidKeyType, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 3727 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 3728
wolfSSL 15:117db924cf7c 3729 /* key encryption algorithm must be RSA for now */
wolfSSL 15:117db924cf7c 3730 if (encOID != RSAk)
wolfSSL 15:117db924cf7c 3731 return ALGO_ID_E;
wolfSSL 15:117db924cf7c 3732
wolfSSL 15:117db924cf7c 3733 /* read encryptedKey */
wolfSSL 15:117db924cf7c 3734 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 3735 encryptedKey = (byte*)XMALLOC(MAX_ENCRYPTED_KEY_SZ, pkcs7->heap,
wolfSSL 15:117db924cf7c 3736 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3737 if (encryptedKey == NULL)
wolfSSL 15:117db924cf7c 3738 return MEMORY_E;
wolfSSL 15:117db924cf7c 3739 #endif
wolfSSL 15:117db924cf7c 3740
wolfSSL 15:117db924cf7c 3741 if (pkiMsg[(*idx)++] != ASN_OCTET_STRING) {
wolfSSL 15:117db924cf7c 3742 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 3743 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3744 #endif
wolfSSL 15:117db924cf7c 3745 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 3746 }
wolfSSL 15:117db924cf7c 3747
wolfSSL 15:117db924cf7c 3748 if (GetLength(pkiMsg, idx, &encryptedKeySz, pkiMsgSz) < 0) {
wolfSSL 15:117db924cf7c 3749 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 3750 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3751 #endif
wolfSSL 15:117db924cf7c 3752 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 3753 }
wolfSSL 15:117db924cf7c 3754
wolfSSL 15:117db924cf7c 3755 if (*recipFound == 1)
wolfSSL 15:117db924cf7c 3756 XMEMCPY(encryptedKey, &pkiMsg[*idx], encryptedKeySz);
wolfSSL 15:117db924cf7c 3757 *idx += encryptedKeySz;
wolfSSL 15:117db924cf7c 3758
wolfSSL 15:117db924cf7c 3759 /* load private key */
wolfSSL 15:117db924cf7c 3760 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 3761 privKey = (RsaKey*)XMALLOC(sizeof(RsaKey), pkcs7->heap,
wolfSSL 15:117db924cf7c 3762 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3763 if (privKey == NULL) {
wolfSSL 15:117db924cf7c 3764 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3765 return MEMORY_E;
wolfSSL 15:117db924cf7c 3766 }
wolfSSL 15:117db924cf7c 3767 #endif
wolfSSL 15:117db924cf7c 3768
wolfSSL 15:117db924cf7c 3769 ret = wc_InitRsaKey_ex(privKey, pkcs7->heap, INVALID_DEVID);
wolfSSL 15:117db924cf7c 3770 if (ret != 0) {
wolfSSL 15:117db924cf7c 3771 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 3772 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3773 XFREE(privKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3774 #endif
wolfSSL 15:117db924cf7c 3775 return ret;
wolfSSL 15:117db924cf7c 3776 }
wolfSSL 15:117db924cf7c 3777
wolfSSL 15:117db924cf7c 3778 if (pkcs7->privateKey != NULL && pkcs7->privateKeySz > 0) {
wolfSSL 15:117db924cf7c 3779 keyIdx = 0;
wolfSSL 15:117db924cf7c 3780 ret = wc_RsaPrivateKeyDecode(pkcs7->privateKey, &keyIdx, privKey,
wolfSSL 15:117db924cf7c 3781 pkcs7->privateKeySz);
wolfSSL 15:117db924cf7c 3782 }
wolfSSL 15:117db924cf7c 3783 else if (pkcs7->devId == INVALID_DEVID) {
wolfSSL 15:117db924cf7c 3784 ret = BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 3785 }
wolfSSL 15:117db924cf7c 3786 if (ret != 0) {
wolfSSL 15:117db924cf7c 3787 WOLFSSL_MSG("Failed to decode RSA private key");
wolfSSL 15:117db924cf7c 3788 wc_FreeRsaKey(privKey);
wolfSSL 15:117db924cf7c 3789 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 3790 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3791 XFREE(privKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3792 #endif
wolfSSL 15:117db924cf7c 3793 return ret;
wolfSSL 15:117db924cf7c 3794 }
wolfSSL 15:117db924cf7c 3795
wolfSSL 15:117db924cf7c 3796 /* decrypt encryptedKey */
wolfSSL 15:117db924cf7c 3797 #ifdef WC_RSA_BLINDING
wolfSSL 15:117db924cf7c 3798 ret = wc_InitRng_ex(&rng, pkcs7->heap, pkcs7->devId);
wolfSSL 15:117db924cf7c 3799 if (ret == 0) {
wolfSSL 15:117db924cf7c 3800 ret = wc_RsaSetRNG(privKey, &rng);
wolfSSL 15:117db924cf7c 3801 }
wolfSSL 15:117db924cf7c 3802 #endif
wolfSSL 15:117db924cf7c 3803 if (ret == 0) {
wolfSSL 15:117db924cf7c 3804 keySz = wc_RsaPrivateDecryptInline(encryptedKey, encryptedKeySz,
wolfSSL 15:117db924cf7c 3805 &outKey, privKey);
wolfSSL 15:117db924cf7c 3806 #ifdef WC_RSA_BLINDING
wolfSSL 15:117db924cf7c 3807 wc_FreeRng(&rng);
wolfSSL 15:117db924cf7c 3808 #endif
wolfSSL 15:117db924cf7c 3809 } else {
wolfSSL 15:117db924cf7c 3810 keySz = ret;
wolfSSL 15:117db924cf7c 3811 }
wolfSSL 15:117db924cf7c 3812 wc_FreeRsaKey(privKey);
wolfSSL 15:117db924cf7c 3813
wolfSSL 15:117db924cf7c 3814 if (keySz <= 0 || outKey == NULL) {
wolfSSL 15:117db924cf7c 3815 ForceZero(encryptedKey, MAX_ENCRYPTED_KEY_SZ);
wolfSSL 15:117db924cf7c 3816 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 3817 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3818 XFREE(privKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3819 #endif
wolfSSL 15:117db924cf7c 3820 return keySz;
wolfSSL 15:117db924cf7c 3821 } else {
wolfSSL 15:117db924cf7c 3822 *decryptedKeySz = keySz;
wolfSSL 15:117db924cf7c 3823 XMEMCPY(decryptedKey, outKey, keySz);
wolfSSL 15:117db924cf7c 3824 ForceZero(encryptedKey, MAX_ENCRYPTED_KEY_SZ);
wolfSSL 15:117db924cf7c 3825 }
wolfSSL 15:117db924cf7c 3826
wolfSSL 15:117db924cf7c 3827 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 3828 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3829 XFREE(privKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3830 #endif
wolfSSL 15:117db924cf7c 3831
wolfSSL 15:117db924cf7c 3832 return 0;
wolfSSL 15:117db924cf7c 3833 }
wolfSSL 15:117db924cf7c 3834 #endif /* !NO_RSA */
wolfSSL 15:117db924cf7c 3835
wolfSSL 15:117db924cf7c 3836 #ifdef HAVE_ECC
wolfSSL 15:117db924cf7c 3837
wolfSSL 15:117db924cf7c 3838 /* remove ASN.1 OriginatorIdentifierOrKey, return 0 on success, <0 on error */
wolfSSL 15:117db924cf7c 3839 static int wc_PKCS7_KariGetOriginatorIdentifierOrKey(WC_PKCS7_KARI* kari,
wolfSSL 15:117db924cf7c 3840 byte* pkiMsg, word32 pkiMsgSz, word32* idx)
wolfSSL 15:117db924cf7c 3841 {
wolfSSL 15:117db924cf7c 3842 int ret, length;
wolfSSL 15:117db924cf7c 3843 word32 keyOID;
wolfSSL 15:117db924cf7c 3844
wolfSSL 15:117db924cf7c 3845 if (kari == NULL || pkiMsg == NULL || idx == NULL)
wolfSSL 15:117db924cf7c 3846 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 3847
wolfSSL 15:117db924cf7c 3848 /* remove OriginatorIdentifierOrKey */
wolfSSL 15:117db924cf7c 3849 if (pkiMsg[*idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) {
wolfSSL 15:117db924cf7c 3850 (*idx)++;
wolfSSL 15:117db924cf7c 3851 if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 3852 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 3853
wolfSSL 15:117db924cf7c 3854 } else {
wolfSSL 15:117db924cf7c 3855 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 3856 }
wolfSSL 15:117db924cf7c 3857
wolfSSL 15:117db924cf7c 3858 /* remove OriginatorPublicKey */
wolfSSL 15:117db924cf7c 3859 if (pkiMsg[*idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) {
wolfSSL 15:117db924cf7c 3860 (*idx)++;
wolfSSL 15:117db924cf7c 3861 if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 3862 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 3863
wolfSSL 15:117db924cf7c 3864 } else {
wolfSSL 15:117db924cf7c 3865 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 3866 }
wolfSSL 15:117db924cf7c 3867
wolfSSL 15:117db924cf7c 3868 /* remove AlgorithmIdentifier */
wolfSSL 15:117db924cf7c 3869 if (GetAlgoId(pkiMsg, idx, &keyOID, oidKeyType, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 3870 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 3871
wolfSSL 15:117db924cf7c 3872 if (keyOID != ECDSAk)
wolfSSL 15:117db924cf7c 3873 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 3874
wolfSSL 15:117db924cf7c 3875 /* remove ECPoint BIT STRING */
wolfSSL 15:117db924cf7c 3876 if ((pkiMsgSz > (*idx + 1)) && (pkiMsg[(*idx)++] != ASN_BIT_STRING))
wolfSSL 15:117db924cf7c 3877 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 3878
wolfSSL 15:117db924cf7c 3879 if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 3880 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 3881
wolfSSL 15:117db924cf7c 3882 if ((pkiMsgSz < (*idx + 1)) || (pkiMsg[(*idx)++] != 0x00))
wolfSSL 15:117db924cf7c 3883 return ASN_EXPECT_0_E;
wolfSSL 15:117db924cf7c 3884
wolfSSL 15:117db924cf7c 3885 /* get sender ephemeral public ECDSA key */
wolfSSL 15:117db924cf7c 3886 ret = wc_ecc_init_ex(kari->senderKey, kari->heap, kari->devId);
wolfSSL 15:117db924cf7c 3887 if (ret != 0)
wolfSSL 15:117db924cf7c 3888 return ret;
wolfSSL 15:117db924cf7c 3889
wolfSSL 15:117db924cf7c 3890 kari->senderKeyInit = 1;
wolfSSL 15:117db924cf7c 3891
wolfSSL 15:117db924cf7c 3892 /* length-1 for unused bits counter */
wolfSSL 15:117db924cf7c 3893 ret = wc_ecc_import_x963(pkiMsg + (*idx), length - 1, kari->senderKey);
wolfSSL 15:117db924cf7c 3894 if (ret != 0)
wolfSSL 15:117db924cf7c 3895 return ret;
wolfSSL 15:117db924cf7c 3896
wolfSSL 15:117db924cf7c 3897 (*idx) += length - 1;
wolfSSL 15:117db924cf7c 3898
wolfSSL 15:117db924cf7c 3899 return 0;
wolfSSL 15:117db924cf7c 3900 }
wolfSSL 15:117db924cf7c 3901
wolfSSL 15:117db924cf7c 3902
wolfSSL 15:117db924cf7c 3903 /* remove optional UserKeyingMaterial if available, return 0 on success,
wolfSSL 15:117db924cf7c 3904 * < 0 on error */
wolfSSL 15:117db924cf7c 3905 static int wc_PKCS7_KariGetUserKeyingMaterial(WC_PKCS7_KARI* kari,
wolfSSL 15:117db924cf7c 3906 byte* pkiMsg, word32 pkiMsgSz, word32* idx)
wolfSSL 15:117db924cf7c 3907 {
wolfSSL 15:117db924cf7c 3908 int length;
wolfSSL 15:117db924cf7c 3909 word32 savedIdx;
wolfSSL 15:117db924cf7c 3910
wolfSSL 15:117db924cf7c 3911 if (kari == NULL || pkiMsg == NULL || idx == NULL)
wolfSSL 15:117db924cf7c 3912 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 3913
wolfSSL 15:117db924cf7c 3914 savedIdx = *idx;
wolfSSL 15:117db924cf7c 3915
wolfSSL 15:117db924cf7c 3916 /* starts with EXPLICIT [1] */
wolfSSL 15:117db924cf7c 3917 if (pkiMsg[(*idx)++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) {
wolfSSL 15:117db924cf7c 3918 *idx = savedIdx;
wolfSSL 15:117db924cf7c 3919 return 0;
wolfSSL 15:117db924cf7c 3920 }
wolfSSL 15:117db924cf7c 3921
wolfSSL 15:117db924cf7c 3922 if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0) {
wolfSSL 15:117db924cf7c 3923 *idx = savedIdx;
wolfSSL 15:117db924cf7c 3924 return 0;
wolfSSL 15:117db924cf7c 3925 }
wolfSSL 15:117db924cf7c 3926
wolfSSL 15:117db924cf7c 3927 /* get OCTET STRING */
wolfSSL 15:117db924cf7c 3928 if ( (pkiMsgSz > ((*idx) + 1)) &&
wolfSSL 15:117db924cf7c 3929 (pkiMsg[(*idx)++] != ASN_OCTET_STRING) ) {
wolfSSL 15:117db924cf7c 3930 *idx = savedIdx;
wolfSSL 15:117db924cf7c 3931 return 0;
wolfSSL 15:117db924cf7c 3932 }
wolfSSL 15:117db924cf7c 3933
wolfSSL 15:117db924cf7c 3934 if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0) {
wolfSSL 15:117db924cf7c 3935 *idx = savedIdx;
wolfSSL 15:117db924cf7c 3936 return 0;
wolfSSL 15:117db924cf7c 3937 }
wolfSSL 15:117db924cf7c 3938
wolfSSL 15:117db924cf7c 3939 kari->ukm = NULL;
wolfSSL 15:117db924cf7c 3940 if (length > 0) {
wolfSSL 15:117db924cf7c 3941 kari->ukm = (byte*)XMALLOC(length, kari->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 3942 if (kari->ukm == NULL)
wolfSSL 15:117db924cf7c 3943 return MEMORY_E;
wolfSSL 15:117db924cf7c 3944
wolfSSL 15:117db924cf7c 3945 XMEMCPY(kari->ukm, pkiMsg + (*idx), length);
wolfSSL 15:117db924cf7c 3946 kari->ukmOwner = 1;
wolfSSL 15:117db924cf7c 3947 }
wolfSSL 15:117db924cf7c 3948
wolfSSL 15:117db924cf7c 3949 (*idx) += length;
wolfSSL 15:117db924cf7c 3950 kari->ukmSz = length;
wolfSSL 15:117db924cf7c 3951
wolfSSL 15:117db924cf7c 3952 return 0;
wolfSSL 15:117db924cf7c 3953 }
wolfSSL 15:117db924cf7c 3954
wolfSSL 15:117db924cf7c 3955
wolfSSL 15:117db924cf7c 3956 /* remove ASN.1 KeyEncryptionAlgorithmIdentifier, return 0 on success,
wolfSSL 15:117db924cf7c 3957 * < 0 on error */
wolfSSL 15:117db924cf7c 3958 static int wc_PKCS7_KariGetKeyEncryptionAlgorithmId(WC_PKCS7_KARI* kari,
wolfSSL 15:117db924cf7c 3959 byte* pkiMsg, word32 pkiMsgSz, word32* idx,
wolfSSL 15:117db924cf7c 3960 word32* keyAgreeOID, word32* keyWrapOID)
wolfSSL 15:117db924cf7c 3961 {
wolfSSL 15:117db924cf7c 3962 if (kari == NULL || pkiMsg == NULL || idx == NULL ||
wolfSSL 15:117db924cf7c 3963 keyAgreeOID == NULL || keyWrapOID == NULL)
wolfSSL 15:117db924cf7c 3964 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 3965
wolfSSL 15:117db924cf7c 3966 /* remove KeyEncryptionAlgorithmIdentifier */
wolfSSL 15:117db924cf7c 3967 if (GetAlgoId(pkiMsg, idx, keyAgreeOID, oidCmsKeyAgreeType,
wolfSSL 15:117db924cf7c 3968 pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 3969 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 3970
wolfSSL 15:117db924cf7c 3971 /* remove KeyWrapAlgorithm, stored in parameter of KeyEncAlgoId */
wolfSSL 15:117db924cf7c 3972 if (GetAlgoId(pkiMsg, idx, keyWrapOID, oidKeyWrapType, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 3973 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 3974
wolfSSL 15:117db924cf7c 3975 return 0;
wolfSSL 15:117db924cf7c 3976 }
wolfSSL 15:117db924cf7c 3977
wolfSSL 15:117db924cf7c 3978
wolfSSL 15:117db924cf7c 3979 /* remove ASN.1 SubjectKeyIdentifier, return 0 on success, < 0 on error
wolfSSL 15:117db924cf7c 3980 * if subject key ID matches, recipFound is set to 1 */
wolfSSL 15:117db924cf7c 3981 static int wc_PKCS7_KariGetSubjectKeyIdentifier(WC_PKCS7_KARI* kari,
wolfSSL 15:117db924cf7c 3982 byte* pkiMsg, word32 pkiMsgSz, word32* idx,
wolfSSL 15:117db924cf7c 3983 int* recipFound)
wolfSSL 15:117db924cf7c 3984 {
wolfSSL 15:117db924cf7c 3985 int length;
wolfSSL 15:117db924cf7c 3986 byte subjKeyId[KEYID_SIZE];
wolfSSL 15:117db924cf7c 3987
wolfSSL 15:117db924cf7c 3988 if (kari == NULL || pkiMsg == NULL || idx == NULL || recipFound == NULL)
wolfSSL 15:117db924cf7c 3989 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 3990
wolfSSL 15:117db924cf7c 3991 /* remove RecipientKeyIdentifier IMPLICIT [0] */
wolfSSL 15:117db924cf7c 3992 if ( (pkiMsgSz > (*idx + 1)) &&
wolfSSL 15:117db924cf7c 3993 (pkiMsg[(*idx)++] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) ) {
wolfSSL 15:117db924cf7c 3994
wolfSSL 15:117db924cf7c 3995 if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 3996 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 3997
wolfSSL 15:117db924cf7c 3998 } else {
wolfSSL 15:117db924cf7c 3999 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 4000 }
wolfSSL 15:117db924cf7c 4001
wolfSSL 15:117db924cf7c 4002 /* remove SubjectKeyIdentifier */
wolfSSL 15:117db924cf7c 4003 if ( (pkiMsgSz > (*idx + 1)) &&
wolfSSL 15:117db924cf7c 4004 (pkiMsg[(*idx)++] != ASN_OCTET_STRING) )
wolfSSL 15:117db924cf7c 4005 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 4006
wolfSSL 15:117db924cf7c 4007 if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 4008 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 4009
wolfSSL 15:117db924cf7c 4010 if (length != KEYID_SIZE)
wolfSSL 15:117db924cf7c 4011 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 4012
wolfSSL 15:117db924cf7c 4013 XMEMCPY(subjKeyId, pkiMsg + (*idx), KEYID_SIZE);
wolfSSL 15:117db924cf7c 4014 (*idx) += length;
wolfSSL 15:117db924cf7c 4015
wolfSSL 15:117db924cf7c 4016 /* subject key id should match if recipient found */
wolfSSL 15:117db924cf7c 4017 if (XMEMCMP(subjKeyId, kari->decoded->extSubjKeyId, KEYID_SIZE) == 0) {
wolfSSL 15:117db924cf7c 4018 *recipFound = 1;
wolfSSL 15:117db924cf7c 4019 }
wolfSSL 15:117db924cf7c 4020
wolfSSL 15:117db924cf7c 4021 return 0;
wolfSSL 15:117db924cf7c 4022 }
wolfSSL 15:117db924cf7c 4023
wolfSSL 15:117db924cf7c 4024
wolfSSL 15:117db924cf7c 4025 /* remove ASN.1 IssuerAndSerialNumber, return 0 on success, < 0 on error
wolfSSL 15:117db924cf7c 4026 * if issuer and serial number match, recipFound is set to 1 */
wolfSSL 15:117db924cf7c 4027 static int wc_PKCS7_KariGetIssuerAndSerialNumber(WC_PKCS7_KARI* kari,
wolfSSL 15:117db924cf7c 4028 byte* pkiMsg, word32 pkiMsgSz, word32* idx,
wolfSSL 15:117db924cf7c 4029 int* recipFound)
wolfSSL 15:117db924cf7c 4030 {
wolfSSL 15:117db924cf7c 4031 int length, ret;
wolfSSL 15:117db924cf7c 4032 byte issuerHash[KEYID_SIZE];
wolfSSL 15:117db924cf7c 4033 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 4034 mp_int* serial;
wolfSSL 15:117db924cf7c 4035 mp_int* recipSerial;
wolfSSL 15:117db924cf7c 4036 #else
wolfSSL 15:117db924cf7c 4037 mp_int stack_serial;
wolfSSL 15:117db924cf7c 4038 mp_int* serial = &stack_serial;
wolfSSL 15:117db924cf7c 4039
wolfSSL 15:117db924cf7c 4040 mp_int stack_recipSerial;
wolfSSL 15:117db924cf7c 4041 mp_int* recipSerial = &stack_recipSerial;
wolfSSL 15:117db924cf7c 4042 #endif
wolfSSL 15:117db924cf7c 4043
wolfSSL 15:117db924cf7c 4044 /* remove IssuerAndSerialNumber */
wolfSSL 15:117db924cf7c 4045 if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 4046 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 4047
wolfSSL 15:117db924cf7c 4048 if (GetNameHash(pkiMsg, idx, issuerHash, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 4049 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 4050
wolfSSL 15:117db924cf7c 4051 /* if we found correct recipient, issuer hashes will match */
wolfSSL 15:117db924cf7c 4052 if (XMEMCMP(issuerHash, kari->decoded->issuerHash, KEYID_SIZE) == 0) {
wolfSSL 15:117db924cf7c 4053 *recipFound = 1;
wolfSSL 15:117db924cf7c 4054 }
wolfSSL 15:117db924cf7c 4055
wolfSSL 15:117db924cf7c 4056 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 4057 serial = (mp_int*)XMALLOC(sizeof(mp_int), kari->heap,
wolfSSL 15:117db924cf7c 4058 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 4059 if (serial == NULL)
wolfSSL 15:117db924cf7c 4060 return MEMORY_E;
wolfSSL 15:117db924cf7c 4061
wolfSSL 15:117db924cf7c 4062 recipSerial = (mp_int*)XMALLOC(sizeof(mp_int), kari->heap,
wolfSSL 15:117db924cf7c 4063 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 4064 if (recipSerial == NULL) {
wolfSSL 15:117db924cf7c 4065 XFREE(serial, kari->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 4066 return MEMORY_E;
wolfSSL 15:117db924cf7c 4067 }
wolfSSL 15:117db924cf7c 4068 #endif
wolfSSL 15:117db924cf7c 4069
wolfSSL 15:117db924cf7c 4070 if (GetInt(serial, pkiMsg, idx, pkiMsgSz) < 0) {
wolfSSL 15:117db924cf7c 4071 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 4072 XFREE(serial, kari->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 4073 XFREE(recipSerial, kari->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 4074 #endif
wolfSSL 15:117db924cf7c 4075 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 4076 }
wolfSSL 15:117db924cf7c 4077
wolfSSL 15:117db924cf7c 4078 ret = mp_read_unsigned_bin(recipSerial, kari->decoded->serial,
wolfSSL 15:117db924cf7c 4079 kari->decoded->serialSz);
wolfSSL 15:117db924cf7c 4080 if (ret != MP_OKAY) {
wolfSSL 15:117db924cf7c 4081 mp_clear(serial);
wolfSSL 15:117db924cf7c 4082 WOLFSSL_MSG("Failed to parse CMS recipient serial number");
wolfSSL 15:117db924cf7c 4083 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 4084 XFREE(serial, kari->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 4085 XFREE(recipSerial, kari->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 4086 #endif
wolfSSL 15:117db924cf7c 4087 return ret;
wolfSSL 15:117db924cf7c 4088 }
wolfSSL 15:117db924cf7c 4089
wolfSSL 15:117db924cf7c 4090 if (mp_cmp(recipSerial, serial) != MP_EQ) {
wolfSSL 15:117db924cf7c 4091 mp_clear(serial);
wolfSSL 15:117db924cf7c 4092 mp_clear(recipSerial);
wolfSSL 15:117db924cf7c 4093 WOLFSSL_MSG("CMS serial number does not match recipient");
wolfSSL 15:117db924cf7c 4094 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 4095 XFREE(serial, kari->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 4096 XFREE(recipSerial, kari->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 4097 #endif
wolfSSL 15:117db924cf7c 4098 return PKCS7_RECIP_E;
wolfSSL 15:117db924cf7c 4099 }
wolfSSL 15:117db924cf7c 4100
wolfSSL 15:117db924cf7c 4101 mp_clear(serial);
wolfSSL 15:117db924cf7c 4102 mp_clear(recipSerial);
wolfSSL 15:117db924cf7c 4103
wolfSSL 15:117db924cf7c 4104 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 4105 XFREE(serial, kari->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 4106 XFREE(recipSerial, kari->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 4107 #endif
wolfSSL 15:117db924cf7c 4108
wolfSSL 15:117db924cf7c 4109 return 0;
wolfSSL 15:117db924cf7c 4110 }
wolfSSL 15:117db924cf7c 4111
wolfSSL 15:117db924cf7c 4112
wolfSSL 15:117db924cf7c 4113 /* remove ASN.1 RecipientEncryptedKeys, return 0 on success, < 0 on error */
wolfSSL 15:117db924cf7c 4114 static int wc_PKCS7_KariGetRecipientEncryptedKeys(WC_PKCS7_KARI* kari,
wolfSSL 15:117db924cf7c 4115 byte* pkiMsg, word32 pkiMsgSz, word32* idx,
wolfSSL 15:117db924cf7c 4116 int* recipFound, byte* encryptedKey,
wolfSSL 15:117db924cf7c 4117 int* encryptedKeySz)
wolfSSL 15:117db924cf7c 4118 {
wolfSSL 15:117db924cf7c 4119 int length;
wolfSSL 15:117db924cf7c 4120 int ret = 0;
wolfSSL 15:117db924cf7c 4121
wolfSSL 15:117db924cf7c 4122 if (kari == NULL || pkiMsg == NULL || idx == NULL ||
wolfSSL 15:117db924cf7c 4123 recipFound == NULL || encryptedKey == NULL)
wolfSSL 15:117db924cf7c 4124 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 4125
wolfSSL 15:117db924cf7c 4126 /* remove RecipientEncryptedKeys */
wolfSSL 15:117db924cf7c 4127 if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 4128 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 4129
wolfSSL 15:117db924cf7c 4130 /* remove RecipientEncryptedKeys */
wolfSSL 15:117db924cf7c 4131 if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 4132 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 4133
wolfSSL 15:117db924cf7c 4134 /* KeyAgreeRecipientIdentifier is CHOICE of IssuerAndSerialNumber
wolfSSL 15:117db924cf7c 4135 * or [0] IMMPLICIT RecipientKeyIdentifier */
wolfSSL 15:117db924cf7c 4136 if ( (pkiMsgSz > (*idx + 1)) &&
wolfSSL 15:117db924cf7c 4137 (pkiMsg[*idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) ) {
wolfSSL 15:117db924cf7c 4138
wolfSSL 15:117db924cf7c 4139 /* try to get RecipientKeyIdentifier */
wolfSSL 15:117db924cf7c 4140 ret = wc_PKCS7_KariGetSubjectKeyIdentifier(kari, pkiMsg, pkiMsgSz,
wolfSSL 15:117db924cf7c 4141 idx, recipFound);
wolfSSL 15:117db924cf7c 4142 } else {
wolfSSL 15:117db924cf7c 4143 /* try to get IssuerAndSerialNumber */
wolfSSL 15:117db924cf7c 4144 ret = wc_PKCS7_KariGetIssuerAndSerialNumber(kari, pkiMsg, pkiMsgSz,
wolfSSL 15:117db924cf7c 4145 idx, recipFound);
wolfSSL 15:117db924cf7c 4146 }
wolfSSL 15:117db924cf7c 4147
wolfSSL 15:117db924cf7c 4148 /* if we don't have either option, malformed CMS */
wolfSSL 15:117db924cf7c 4149 if (ret != 0)
wolfSSL 15:117db924cf7c 4150 return ret;
wolfSSL 15:117db924cf7c 4151
wolfSSL 15:117db924cf7c 4152 /* remove EncryptedKey */
wolfSSL 15:117db924cf7c 4153 if ( (pkiMsgSz > (*idx + 1)) &&
wolfSSL 15:117db924cf7c 4154 (pkiMsg[(*idx)++] != ASN_OCTET_STRING) )
wolfSSL 15:117db924cf7c 4155 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 4156
wolfSSL 15:117db924cf7c 4157 if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 4158 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 4159
wolfSSL 15:117db924cf7c 4160 /* put encrypted CEK in decryptedKey buffer for now, decrypt later */
wolfSSL 15:117db924cf7c 4161 if (length > *encryptedKeySz)
wolfSSL 15:117db924cf7c 4162 return BUFFER_E;
wolfSSL 15:117db924cf7c 4163
wolfSSL 15:117db924cf7c 4164 XMEMCPY(encryptedKey, pkiMsg + (*idx), length);
wolfSSL 15:117db924cf7c 4165 *encryptedKeySz = length;
wolfSSL 15:117db924cf7c 4166 (*idx) += length;
wolfSSL 15:117db924cf7c 4167
wolfSSL 15:117db924cf7c 4168 return 0;
wolfSSL 15:117db924cf7c 4169 }
wolfSSL 15:117db924cf7c 4170
wolfSSL 15:117db924cf7c 4171 #endif /* HAVE_ECC */
wolfSSL 15:117db924cf7c 4172
wolfSSL 15:117db924cf7c 4173
wolfSSL 15:117db924cf7c 4174 /* decode ASN.1 KeyAgreeRecipientInfo (kari), return 0 on success,
wolfSSL 15:117db924cf7c 4175 * < 0 on error */
wolfSSL 15:117db924cf7c 4176 static int wc_PKCS7_DecodeKari(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz,
wolfSSL 15:117db924cf7c 4177 word32* idx, byte* decryptedKey,
wolfSSL 15:117db924cf7c 4178 word32* decryptedKeySz, int* recipFound)
wolfSSL 15:117db924cf7c 4179 {
wolfSSL 15:117db924cf7c 4180 #ifdef HAVE_ECC
wolfSSL 15:117db924cf7c 4181 int ret, keySz;
wolfSSL 15:117db924cf7c 4182 int encryptedKeySz;
wolfSSL 15:117db924cf7c 4183 int direction = 0;
wolfSSL 15:117db924cf7c 4184 word32 keyAgreeOID, keyWrapOID;
wolfSSL 15:117db924cf7c 4185
wolfSSL 15:117db924cf7c 4186 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 4187 byte* encryptedKey;
wolfSSL 15:117db924cf7c 4188 #else
wolfSSL 15:117db924cf7c 4189 byte encryptedKey[MAX_ENCRYPTED_KEY_SZ];
wolfSSL 15:117db924cf7c 4190 #endif
wolfSSL 15:117db924cf7c 4191
wolfSSL 15:117db924cf7c 4192 WC_PKCS7_KARI* kari;
wolfSSL 15:117db924cf7c 4193
wolfSSL 15:117db924cf7c 4194 if (pkcs7 == NULL || pkcs7->singleCert == NULL ||
wolfSSL 15:117db924cf7c 4195 pkcs7->singleCertSz == 0 || pkiMsg == NULL ||
wolfSSL 15:117db924cf7c 4196 idx == NULL || decryptedKey == NULL || decryptedKeySz == NULL) {
wolfSSL 15:117db924cf7c 4197 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 4198 }
wolfSSL 15:117db924cf7c 4199
wolfSSL 15:117db924cf7c 4200 kari = wc_PKCS7_KariNew(pkcs7, WC_PKCS7_DECODE);
wolfSSL 15:117db924cf7c 4201 if (kari == NULL)
wolfSSL 15:117db924cf7c 4202 return MEMORY_E;
wolfSSL 15:117db924cf7c 4203
wolfSSL 15:117db924cf7c 4204 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 4205 encryptedKey = (byte*)XMALLOC(MAX_ENCRYPTED_KEY_SZ, pkcs7->heap,
wolfSSL 15:117db924cf7c 4206 DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 4207 if (encryptedKey == NULL) {
wolfSSL 15:117db924cf7c 4208 wc_PKCS7_KariFree(kari);
wolfSSL 15:117db924cf7c 4209 return MEMORY_E;
wolfSSL 15:117db924cf7c 4210 }
wolfSSL 15:117db924cf7c 4211 #endif
wolfSSL 15:117db924cf7c 4212 encryptedKeySz = MAX_ENCRYPTED_KEY_SZ;
wolfSSL 15:117db924cf7c 4213
wolfSSL 15:117db924cf7c 4214 /* parse cert and key */
wolfSSL 15:117db924cf7c 4215 ret = wc_PKCS7_KariParseRecipCert(kari, (byte*)pkcs7->singleCert,
wolfSSL 15:117db924cf7c 4216 pkcs7->singleCertSz, pkcs7->privateKey,
wolfSSL 15:117db924cf7c 4217 pkcs7->privateKeySz);
wolfSSL 15:117db924cf7c 4218 if (ret != 0) {
wolfSSL 15:117db924cf7c 4219 wc_PKCS7_KariFree(kari);
wolfSSL 15:117db924cf7c 4220 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 4221 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 4222 #endif
wolfSSL 15:117db924cf7c 4223 return ret;
wolfSSL 15:117db924cf7c 4224 }
wolfSSL 15:117db924cf7c 4225
wolfSSL 15:117db924cf7c 4226 /* remove OriginatorIdentifierOrKey */
wolfSSL 15:117db924cf7c 4227 ret = wc_PKCS7_KariGetOriginatorIdentifierOrKey(kari, pkiMsg,
wolfSSL 15:117db924cf7c 4228 pkiMsgSz, idx);
wolfSSL 15:117db924cf7c 4229 if (ret != 0) {
wolfSSL 15:117db924cf7c 4230 wc_PKCS7_KariFree(kari);
wolfSSL 15:117db924cf7c 4231 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 4232 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 4233 #endif
wolfSSL 15:117db924cf7c 4234 return ret;
wolfSSL 15:117db924cf7c 4235 }
wolfSSL 15:117db924cf7c 4236
wolfSSL 15:117db924cf7c 4237 /* try and remove optional UserKeyingMaterial */
wolfSSL 15:117db924cf7c 4238 ret = wc_PKCS7_KariGetUserKeyingMaterial(kari, pkiMsg, pkiMsgSz, idx);
wolfSSL 15:117db924cf7c 4239 if (ret != 0) {
wolfSSL 15:117db924cf7c 4240 wc_PKCS7_KariFree(kari);
wolfSSL 15:117db924cf7c 4241 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 4242 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 4243 #endif
wolfSSL 15:117db924cf7c 4244 return ret;
wolfSSL 15:117db924cf7c 4245 }
wolfSSL 15:117db924cf7c 4246
wolfSSL 15:117db924cf7c 4247 /* remove KeyEncryptionAlgorithmIdentifier */
wolfSSL 15:117db924cf7c 4248 ret = wc_PKCS7_KariGetKeyEncryptionAlgorithmId(kari, pkiMsg, pkiMsgSz,
wolfSSL 15:117db924cf7c 4249 idx, &keyAgreeOID,
wolfSSL 15:117db924cf7c 4250 &keyWrapOID);
wolfSSL 15:117db924cf7c 4251 if (ret != 0) {
wolfSSL 15:117db924cf7c 4252 wc_PKCS7_KariFree(kari);
wolfSSL 15:117db924cf7c 4253 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 4254 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 4255 #endif
wolfSSL 15:117db924cf7c 4256 return ret;
wolfSSL 15:117db924cf7c 4257 }
wolfSSL 15:117db924cf7c 4258
wolfSSL 15:117db924cf7c 4259 /* if user has not explicitly set keyAgreeOID, set from one in bundle */
wolfSSL 15:117db924cf7c 4260 if (pkcs7->keyAgreeOID == 0)
wolfSSL 15:117db924cf7c 4261 pkcs7->keyAgreeOID = keyAgreeOID;
wolfSSL 15:117db924cf7c 4262
wolfSSL 15:117db924cf7c 4263 /* set direction based on key wrap algorithm */
wolfSSL 15:117db924cf7c 4264 switch (keyWrapOID) {
wolfSSL 15:117db924cf7c 4265 #ifndef NO_AES
wolfSSL 15:117db924cf7c 4266 #ifdef WOLFSSL_AES_128
wolfSSL 15:117db924cf7c 4267 case AES128_WRAP:
wolfSSL 15:117db924cf7c 4268 #endif
wolfSSL 15:117db924cf7c 4269 #ifdef WOLFSSL_AES_192
wolfSSL 15:117db924cf7c 4270 case AES192_WRAP:
wolfSSL 15:117db924cf7c 4271 #endif
wolfSSL 15:117db924cf7c 4272 #ifdef WOLFSSL_AES_256
wolfSSL 15:117db924cf7c 4273 case AES256_WRAP:
wolfSSL 15:117db924cf7c 4274 #endif
wolfSSL 15:117db924cf7c 4275 direction = AES_DECRYPTION;
wolfSSL 15:117db924cf7c 4276 break;
wolfSSL 15:117db924cf7c 4277 #endif
wolfSSL 15:117db924cf7c 4278 default:
wolfSSL 15:117db924cf7c 4279 wc_PKCS7_KariFree(kari);
wolfSSL 15:117db924cf7c 4280 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 4281 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 4282 #endif
wolfSSL 15:117db924cf7c 4283 WOLFSSL_MSG("AES key wrap algorithm unsupported");
wolfSSL 15:117db924cf7c 4284 return BAD_KEYWRAP_ALG_E;
wolfSSL 15:117db924cf7c 4285 }
wolfSSL 15:117db924cf7c 4286
wolfSSL 15:117db924cf7c 4287 /* remove RecipientEncryptedKeys */
wolfSSL 15:117db924cf7c 4288 ret = wc_PKCS7_KariGetRecipientEncryptedKeys(kari, pkiMsg, pkiMsgSz,
wolfSSL 15:117db924cf7c 4289 idx, recipFound, encryptedKey, &encryptedKeySz);
wolfSSL 15:117db924cf7c 4290 if (ret != 0) {
wolfSSL 15:117db924cf7c 4291 wc_PKCS7_KariFree(kari);
wolfSSL 15:117db924cf7c 4292 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 4293 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 4294 #endif
wolfSSL 15:117db924cf7c 4295 return ret;
wolfSSL 15:117db924cf7c 4296 }
wolfSSL 15:117db924cf7c 4297
wolfSSL 15:117db924cf7c 4298 /* create KEK */
wolfSSL 15:117db924cf7c 4299 ret = wc_PKCS7_KariGenerateKEK(kari, keyWrapOID, pkcs7->keyAgreeOID);
wolfSSL 15:117db924cf7c 4300 if (ret != 0) {
wolfSSL 15:117db924cf7c 4301 wc_PKCS7_KariFree(kari);
wolfSSL 15:117db924cf7c 4302 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 4303 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 4304 #endif
wolfSSL 15:117db924cf7c 4305 return ret;
wolfSSL 15:117db924cf7c 4306 }
wolfSSL 15:117db924cf7c 4307
wolfSSL 15:117db924cf7c 4308 /* decrypt CEK with KEK */
wolfSSL 15:117db924cf7c 4309 keySz = wc_PKCS7_KariKeyWrap(encryptedKey, encryptedKeySz, kari->kek,
wolfSSL 15:117db924cf7c 4310 kari->kekSz, decryptedKey, *decryptedKeySz,
wolfSSL 15:117db924cf7c 4311 keyWrapOID, direction);
wolfSSL 15:117db924cf7c 4312 if (keySz <= 0) {
wolfSSL 15:117db924cf7c 4313 wc_PKCS7_KariFree(kari);
wolfSSL 15:117db924cf7c 4314 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 4315 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 4316 #endif
wolfSSL 15:117db924cf7c 4317 return keySz;
wolfSSL 15:117db924cf7c 4318 }
wolfSSL 15:117db924cf7c 4319 *decryptedKeySz = (word32)keySz;
wolfSSL 15:117db924cf7c 4320
wolfSSL 15:117db924cf7c 4321 wc_PKCS7_KariFree(kari);
wolfSSL 15:117db924cf7c 4322 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 4323 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 4324 #endif
wolfSSL 15:117db924cf7c 4325
wolfSSL 15:117db924cf7c 4326 return 0;
wolfSSL 15:117db924cf7c 4327 #else
wolfSSL 15:117db924cf7c 4328 (void)pkcs7;
wolfSSL 15:117db924cf7c 4329 (void)pkiMsg;
wolfSSL 15:117db924cf7c 4330 (void)pkiMsgSz;
wolfSSL 15:117db924cf7c 4331 (void)idx;
wolfSSL 15:117db924cf7c 4332 (void)decryptedKey;
wolfSSL 15:117db924cf7c 4333 (void)decryptedKeySz;
wolfSSL 15:117db924cf7c 4334 (void)recipFound;
wolfSSL 15:117db924cf7c 4335
wolfSSL 15:117db924cf7c 4336 return NOT_COMPILED_IN;
wolfSSL 15:117db924cf7c 4337 #endif /* HAVE_ECC */
wolfSSL 15:117db924cf7c 4338 }
wolfSSL 15:117db924cf7c 4339
wolfSSL 15:117db924cf7c 4340
wolfSSL 15:117db924cf7c 4341 /* decode ASN.1 RecipientInfos SET, return 0 on success, < 0 on error */
wolfSSL 15:117db924cf7c 4342 static int wc_PKCS7_DecodeRecipientInfos(PKCS7* pkcs7, byte* pkiMsg,
wolfSSL 15:117db924cf7c 4343 word32 pkiMsgSz, word32* idx, byte* decryptedKey,
wolfSSL 15:117db924cf7c 4344 word32* decryptedKeySz, int* recipFound)
wolfSSL 15:117db924cf7c 4345 {
wolfSSL 15:117db924cf7c 4346 word32 savedIdx;
wolfSSL 15:117db924cf7c 4347 int version, ret, length;
wolfSSL 15:117db924cf7c 4348
wolfSSL 15:117db924cf7c 4349 if (pkcs7 == NULL || pkiMsg == NULL || idx == NULL ||
wolfSSL 15:117db924cf7c 4350 decryptedKey == NULL || decryptedKeySz == NULL ||
wolfSSL 15:117db924cf7c 4351 recipFound == NULL) {
wolfSSL 15:117db924cf7c 4352 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 4353 }
wolfSSL 15:117db924cf7c 4354
wolfSSL 15:117db924cf7c 4355 savedIdx = *idx;
wolfSSL 15:117db924cf7c 4356
wolfSSL 15:117db924cf7c 4357 /* when looking for next recipient, use first sequence and version to
wolfSSL 15:117db924cf7c 4358 * indicate there is another, if not, move on */
wolfSSL 15:117db924cf7c 4359 while(*recipFound == 0) {
wolfSSL 15:117db924cf7c 4360
wolfSSL 15:117db924cf7c 4361 /* remove RecipientInfo, if we don't have a SEQUENCE, back up idx to
wolfSSL 15:117db924cf7c 4362 * last good saved one */
wolfSSL 15:117db924cf7c 4363 if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) > 0) {
wolfSSL 15:117db924cf7c 4364
wolfSSL 15:117db924cf7c 4365 if (GetMyVersion(pkiMsg, idx, &version, pkiMsgSz) < 0) {
wolfSSL 15:117db924cf7c 4366 *idx = savedIdx;
wolfSSL 15:117db924cf7c 4367 break;
wolfSSL 15:117db924cf7c 4368 }
wolfSSL 15:117db924cf7c 4369
wolfSSL 15:117db924cf7c 4370 if (version != 0)
wolfSSL 15:117db924cf7c 4371 return ASN_VERSION_E;
wolfSSL 15:117db924cf7c 4372
wolfSSL 15:117db924cf7c 4373 #ifndef NO_RSA
wolfSSL 15:117db924cf7c 4374 /* found ktri */
wolfSSL 15:117db924cf7c 4375 ret = wc_PKCS7_DecodeKtri(pkcs7, pkiMsg, pkiMsgSz, idx,
wolfSSL 15:117db924cf7c 4376 decryptedKey, decryptedKeySz,
wolfSSL 15:117db924cf7c 4377 recipFound);
wolfSSL 15:117db924cf7c 4378 if (ret != 0)
wolfSSL 15:117db924cf7c 4379 return ret;
wolfSSL 15:117db924cf7c 4380 #else
wolfSSL 15:117db924cf7c 4381 return NOT_COMPILED_IN;
wolfSSL 15:117db924cf7c 4382 #endif
wolfSSL 15:117db924cf7c 4383 }
wolfSSL 15:117db924cf7c 4384 else {
wolfSSL 15:117db924cf7c 4385 /* kari is IMPLICIT[1] */
wolfSSL 15:117db924cf7c 4386 *idx = savedIdx;
wolfSSL 15:117db924cf7c 4387 if (pkiMsg[*idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) {
wolfSSL 15:117db924cf7c 4388 (*idx)++;
wolfSSL 15:117db924cf7c 4389
wolfSSL 15:117db924cf7c 4390 if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 4391 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 4392
wolfSSL 15:117db924cf7c 4393 if (GetMyVersion(pkiMsg, idx, &version, pkiMsgSz) < 0) {
wolfSSL 15:117db924cf7c 4394 *idx = savedIdx;
wolfSSL 15:117db924cf7c 4395 break;
wolfSSL 15:117db924cf7c 4396 }
wolfSSL 15:117db924cf7c 4397
wolfSSL 15:117db924cf7c 4398 if (version != 3)
wolfSSL 15:117db924cf7c 4399 return ASN_VERSION_E;
wolfSSL 15:117db924cf7c 4400
wolfSSL 15:117db924cf7c 4401 /* found kari */
wolfSSL 15:117db924cf7c 4402 ret = wc_PKCS7_DecodeKari(pkcs7, pkiMsg, pkiMsgSz, idx,
wolfSSL 15:117db924cf7c 4403 decryptedKey, decryptedKeySz,
wolfSSL 15:117db924cf7c 4404 recipFound);
wolfSSL 15:117db924cf7c 4405 if (ret != 0)
wolfSSL 15:117db924cf7c 4406 return ret;
wolfSSL 15:117db924cf7c 4407 }
wolfSSL 15:117db924cf7c 4408 else {
wolfSSL 15:117db924cf7c 4409 /* failed to find RecipientInfo, restore idx and continue */
wolfSSL 15:117db924cf7c 4410 *idx = savedIdx;
wolfSSL 15:117db924cf7c 4411 break;
wolfSSL 15:117db924cf7c 4412 }
wolfSSL 15:117db924cf7c 4413 }
wolfSSL 15:117db924cf7c 4414
wolfSSL 15:117db924cf7c 4415 /* update good idx */
wolfSSL 15:117db924cf7c 4416 savedIdx = *idx;
wolfSSL 15:117db924cf7c 4417 }
wolfSSL 15:117db924cf7c 4418
wolfSSL 15:117db924cf7c 4419 return 0;
wolfSSL 15:117db924cf7c 4420 }
wolfSSL 15:117db924cf7c 4421
wolfSSL 15:117db924cf7c 4422
wolfSSL 15:117db924cf7c 4423 /* unwrap and decrypt PKCS#7 envelopedData object, return decoded size */
wolfSSL 15:117db924cf7c 4424 WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg,
wolfSSL 15:117db924cf7c 4425 word32 pkiMsgSz, byte* output,
wolfSSL 15:117db924cf7c 4426 word32 outputSz)
wolfSSL 15:117db924cf7c 4427 {
wolfSSL 15:117db924cf7c 4428 int recipFound = 0;
wolfSSL 15:117db924cf7c 4429 int ret, version, length;
wolfSSL 15:117db924cf7c 4430 word32 idx = 0;
wolfSSL 15:117db924cf7c 4431 word32 contentType, encOID;
wolfSSL 15:117db924cf7c 4432 word32 decryptedKeySz;
wolfSSL 15:117db924cf7c 4433
wolfSSL 15:117db924cf7c 4434 int expBlockSz, blockKeySz;
wolfSSL 15:117db924cf7c 4435 byte tmpIv[MAX_CONTENT_IV_SIZE];
wolfSSL 15:117db924cf7c 4436
wolfSSL 15:117db924cf7c 4437 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 4438 byte* decryptedKey;
wolfSSL 15:117db924cf7c 4439 #else
wolfSSL 15:117db924cf7c 4440 byte decryptedKey[MAX_ENCRYPTED_KEY_SZ];
wolfSSL 15:117db924cf7c 4441 #endif
wolfSSL 15:117db924cf7c 4442 int encryptedContentSz;
wolfSSL 15:117db924cf7c 4443 byte padLen;
wolfSSL 15:117db924cf7c 4444 byte* encryptedContent = NULL;
wolfSSL 15:117db924cf7c 4445 int explicitOctet;
wolfSSL 15:117db924cf7c 4446
wolfSSL 15:117db924cf7c 4447 if (pkcs7 == NULL || pkcs7->singleCert == NULL ||
wolfSSL 15:117db924cf7c 4448 pkcs7->singleCertSz == 0)
wolfSSL 15:117db924cf7c 4449 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 4450
wolfSSL 15:117db924cf7c 4451 if (pkiMsg == NULL || pkiMsgSz == 0 ||
wolfSSL 15:117db924cf7c 4452 output == NULL || outputSz == 0)
wolfSSL 15:117db924cf7c 4453 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 4454
wolfSSL 15:117db924cf7c 4455 /* read past ContentInfo, verify type is envelopedData */
wolfSSL 15:117db924cf7c 4456 if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 4457 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 4458
wolfSSL 15:117db924cf7c 4459 if (length == 0 && pkiMsg[idx-1] == 0x80) {
wolfSSL 15:117db924cf7c 4460 #ifdef ASN_BER_TO_DER
wolfSSL 15:117db924cf7c 4461 word32 len = 0;
wolfSSL 15:117db924cf7c 4462
wolfSSL 15:117db924cf7c 4463 ret = wc_BerToDer(pkiMsg, pkiMsgSz, NULL, &len);
wolfSSL 15:117db924cf7c 4464 if (ret != LENGTH_ONLY_E)
wolfSSL 15:117db924cf7c 4465 return ret;
wolfSSL 15:117db924cf7c 4466 pkcs7->der = (byte*)XMALLOC(len, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 4467 if (pkcs7->der == NULL)
wolfSSL 15:117db924cf7c 4468 return MEMORY_E;
wolfSSL 15:117db924cf7c 4469 ret = wc_BerToDer(pkiMsg, pkiMsgSz, pkcs7->der, &len);
wolfSSL 15:117db924cf7c 4470 if (ret < 0)
wolfSSL 15:117db924cf7c 4471 return ret;
wolfSSL 15:117db924cf7c 4472
wolfSSL 15:117db924cf7c 4473 pkiMsg = pkcs7->der;
wolfSSL 15:117db924cf7c 4474 pkiMsgSz = len;
wolfSSL 15:117db924cf7c 4475 idx = 0;
wolfSSL 15:117db924cf7c 4476 if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 4477 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 4478 #else
wolfSSL 15:117db924cf7c 4479 return BER_INDEF_E;
wolfSSL 15:117db924cf7c 4480 #endif
wolfSSL 15:117db924cf7c 4481 }
wolfSSL 15:117db924cf7c 4482
wolfSSL 15:117db924cf7c 4483 if (wc_GetContentType(pkiMsg, &idx, &contentType, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 4484 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 4485
wolfSSL 15:117db924cf7c 4486 if (contentType != ENVELOPED_DATA) {
wolfSSL 15:117db924cf7c 4487 WOLFSSL_MSG("PKCS#7 input not of type EnvelopedData");
wolfSSL 15:117db924cf7c 4488 return PKCS7_OID_E;
wolfSSL 15:117db924cf7c 4489 }
wolfSSL 15:117db924cf7c 4490
wolfSSL 15:117db924cf7c 4491 if (pkiMsg[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
wolfSSL 15:117db924cf7c 4492 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 4493
wolfSSL 15:117db924cf7c 4494 if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 4495 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 4496
wolfSSL 15:117db924cf7c 4497 /* remove EnvelopedData and version */
wolfSSL 15:117db924cf7c 4498 if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 4499 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 4500
wolfSSL 15:117db924cf7c 4501 if (GetMyVersion(pkiMsg, &idx, &version, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 4502 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 4503
wolfSSL 15:117db924cf7c 4504 /* TODO :: make this more accurate */
wolfSSL 15:117db924cf7c 4505 if ((pkcs7->publicKeyOID == RSAk && version != 0)
wolfSSL 15:117db924cf7c 4506 #ifdef HAVE_ECC
wolfSSL 15:117db924cf7c 4507 || (pkcs7->publicKeyOID == ECDSAk && version != 2)
wolfSSL 15:117db924cf7c 4508 #endif
wolfSSL 15:117db924cf7c 4509 ) {
wolfSSL 15:117db924cf7c 4510 WOLFSSL_MSG("PKCS#7 envelopedData needs to be of version 0");
wolfSSL 15:117db924cf7c 4511 return ASN_VERSION_E;
wolfSSL 15:117db924cf7c 4512 }
wolfSSL 15:117db924cf7c 4513
wolfSSL 15:117db924cf7c 4514 /* walk through RecipientInfo set, find correct recipient */
wolfSSL 15:117db924cf7c 4515 if (GetSet(pkiMsg, &idx, &length, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 4516 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 4517
wolfSSL 15:117db924cf7c 4518 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 4519 decryptedKey = (byte*)XMALLOC(MAX_ENCRYPTED_KEY_SZ, pkcs7->heap,
wolfSSL 15:117db924cf7c 4520 DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 4521 if (decryptedKey == NULL)
wolfSSL 15:117db924cf7c 4522 return MEMORY_E;
wolfSSL 15:117db924cf7c 4523 #endif
wolfSSL 15:117db924cf7c 4524 decryptedKeySz = MAX_ENCRYPTED_KEY_SZ;
wolfSSL 15:117db924cf7c 4525
wolfSSL 15:117db924cf7c 4526 ret = wc_PKCS7_DecodeRecipientInfos(pkcs7, pkiMsg, pkiMsgSz, &idx,
wolfSSL 15:117db924cf7c 4527 decryptedKey, &decryptedKeySz,
wolfSSL 15:117db924cf7c 4528 &recipFound);
wolfSSL 15:117db924cf7c 4529 if (ret != 0) {
wolfSSL 15:117db924cf7c 4530 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 4531 XFREE(decryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 4532 #endif
wolfSSL 15:117db924cf7c 4533 return ret;
wolfSSL 15:117db924cf7c 4534 }
wolfSSL 15:117db924cf7c 4535
wolfSSL 15:117db924cf7c 4536 if (recipFound == 0) {
wolfSSL 15:117db924cf7c 4537 WOLFSSL_MSG("No recipient found in envelopedData that matches input");
wolfSSL 15:117db924cf7c 4538 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 4539 XFREE(decryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 4540 #endif
wolfSSL 15:117db924cf7c 4541 return PKCS7_RECIP_E;
wolfSSL 15:117db924cf7c 4542 }
wolfSSL 15:117db924cf7c 4543
wolfSSL 15:117db924cf7c 4544 /* remove EncryptedContentInfo */
wolfSSL 15:117db924cf7c 4545 if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0) {
wolfSSL 15:117db924cf7c 4546 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 4547 XFREE(decryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 4548 #endif
wolfSSL 15:117db924cf7c 4549 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 4550 }
wolfSSL 15:117db924cf7c 4551
wolfSSL 15:117db924cf7c 4552 if (wc_GetContentType(pkiMsg, &idx, &contentType, pkiMsgSz) < 0) {
wolfSSL 15:117db924cf7c 4553 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 4554 XFREE(decryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 4555 #endif
wolfSSL 15:117db924cf7c 4556 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 4557 }
wolfSSL 15:117db924cf7c 4558
wolfSSL 15:117db924cf7c 4559 if (GetAlgoId(pkiMsg, &idx, &encOID, oidBlkType, pkiMsgSz) < 0) {
wolfSSL 15:117db924cf7c 4560 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 4561 XFREE(decryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 4562 #endif
wolfSSL 15:117db924cf7c 4563 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 4564 }
wolfSSL 15:117db924cf7c 4565
wolfSSL 15:117db924cf7c 4566 blockKeySz = wc_PKCS7_GetOIDKeySize(encOID);
wolfSSL 15:117db924cf7c 4567 if (blockKeySz < 0) {
wolfSSL 15:117db924cf7c 4568 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 4569 XFREE(decryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 4570 #endif
wolfSSL 15:117db924cf7c 4571 return blockKeySz;
wolfSSL 15:117db924cf7c 4572 }
wolfSSL 15:117db924cf7c 4573
wolfSSL 15:117db924cf7c 4574 expBlockSz = wc_PKCS7_GetOIDBlockSize(encOID);
wolfSSL 15:117db924cf7c 4575 if (expBlockSz < 0) {
wolfSSL 15:117db924cf7c 4576 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 4577 XFREE(decryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 4578 #endif
wolfSSL 15:117db924cf7c 4579 return expBlockSz;
wolfSSL 15:117db924cf7c 4580 }
wolfSSL 15:117db924cf7c 4581
wolfSSL 15:117db924cf7c 4582 /* get block cipher IV, stored in OPTIONAL parameter of AlgoID */
wolfSSL 15:117db924cf7c 4583 if (pkiMsg[idx++] != ASN_OCTET_STRING) {
wolfSSL 15:117db924cf7c 4584 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 4585 XFREE(decryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 4586 #endif
wolfSSL 15:117db924cf7c 4587 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 4588 }
wolfSSL 15:117db924cf7c 4589
wolfSSL 15:117db924cf7c 4590 if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0) {
wolfSSL 15:117db924cf7c 4591 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 4592 XFREE(decryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 4593 #endif
wolfSSL 15:117db924cf7c 4594 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 4595 }
wolfSSL 15:117db924cf7c 4596
wolfSSL 15:117db924cf7c 4597 if (length != expBlockSz) {
wolfSSL 15:117db924cf7c 4598 WOLFSSL_MSG("Incorrect IV length, must be of content alg block size");
wolfSSL 15:117db924cf7c 4599 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 4600 XFREE(decryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 4601 #endif
wolfSSL 15:117db924cf7c 4602 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 4603 }
wolfSSL 15:117db924cf7c 4604
wolfSSL 15:117db924cf7c 4605 XMEMCPY(tmpIv, &pkiMsg[idx], length);
wolfSSL 15:117db924cf7c 4606 idx += length;
wolfSSL 15:117db924cf7c 4607
wolfSSL 15:117db924cf7c 4608 explicitOctet = pkiMsg[idx] == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0);
wolfSSL 15:117db924cf7c 4609
wolfSSL 15:117db924cf7c 4610 /* read encryptedContent, cont[0] */
wolfSSL 15:117db924cf7c 4611 if (pkiMsg[idx] != (ASN_CONTEXT_SPECIFIC | 0) &&
wolfSSL 15:117db924cf7c 4612 pkiMsg[idx] != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0)) {
wolfSSL 15:117db924cf7c 4613 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 4614 XFREE(decryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 4615 #endif
wolfSSL 15:117db924cf7c 4616 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 4617 }
wolfSSL 15:117db924cf7c 4618 idx++;
wolfSSL 15:117db924cf7c 4619
wolfSSL 15:117db924cf7c 4620 if (GetLength(pkiMsg, &idx, &encryptedContentSz, pkiMsgSz) <= 0) {
wolfSSL 15:117db924cf7c 4621 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 4622 XFREE(decryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 4623 #endif
wolfSSL 15:117db924cf7c 4624 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 4625 }
wolfSSL 15:117db924cf7c 4626
wolfSSL 15:117db924cf7c 4627 if (explicitOctet) {
wolfSSL 15:117db924cf7c 4628 if (pkiMsg[idx++] != ASN_OCTET_STRING) {
wolfSSL 15:117db924cf7c 4629 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 4630 XFREE(decryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 4631 #endif
wolfSSL 15:117db924cf7c 4632 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 4633 }
wolfSSL 15:117db924cf7c 4634
wolfSSL 15:117db924cf7c 4635 if (GetLength(pkiMsg, &idx, &encryptedContentSz, pkiMsgSz) <= 0) {
wolfSSL 15:117db924cf7c 4636 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 4637 XFREE(decryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 4638 #endif
wolfSSL 15:117db924cf7c 4639 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 4640 }
wolfSSL 15:117db924cf7c 4641 }
wolfSSL 15:117db924cf7c 4642
wolfSSL 15:117db924cf7c 4643 encryptedContent = (byte*)XMALLOC(encryptedContentSz, pkcs7->heap,
wolfSSL 15:117db924cf7c 4644 DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 4645 if (encryptedContent == NULL) {
wolfSSL 15:117db924cf7c 4646 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 4647 XFREE(decryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 4648 #endif
wolfSSL 15:117db924cf7c 4649 return MEMORY_E;
wolfSSL 15:117db924cf7c 4650 }
wolfSSL 15:117db924cf7c 4651
wolfSSL 15:117db924cf7c 4652 XMEMCPY(encryptedContent, &pkiMsg[idx], encryptedContentSz);
wolfSSL 15:117db924cf7c 4653
wolfSSL 15:117db924cf7c 4654 /* decrypt encryptedContent */
wolfSSL 15:117db924cf7c 4655 ret = wc_PKCS7_DecryptContent(encOID, decryptedKey, blockKeySz,
wolfSSL 15:117db924cf7c 4656 tmpIv, expBlockSz, encryptedContent,
wolfSSL 15:117db924cf7c 4657 encryptedContentSz, encryptedContent);
wolfSSL 15:117db924cf7c 4658 if (ret != 0) {
wolfSSL 15:117db924cf7c 4659 XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 4660 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 4661 XFREE(decryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 4662 #endif
wolfSSL 15:117db924cf7c 4663 return ret;
wolfSSL 15:117db924cf7c 4664 }
wolfSSL 15:117db924cf7c 4665
wolfSSL 15:117db924cf7c 4666 padLen = encryptedContent[encryptedContentSz-1];
wolfSSL 15:117db924cf7c 4667
wolfSSL 15:117db924cf7c 4668 /* copy plaintext to output */
wolfSSL 15:117db924cf7c 4669 XMEMCPY(output, encryptedContent, encryptedContentSz - padLen);
wolfSSL 15:117db924cf7c 4670
wolfSSL 15:117db924cf7c 4671 /* free memory, zero out keys */
wolfSSL 15:117db924cf7c 4672 ForceZero(decryptedKey, MAX_ENCRYPTED_KEY_SZ);
wolfSSL 15:117db924cf7c 4673 ForceZero(encryptedContent, encryptedContentSz);
wolfSSL 15:117db924cf7c 4674 XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 4675 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 4676 XFREE(decryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 4677 #endif
wolfSSL 15:117db924cf7c 4678
wolfSSL 15:117db924cf7c 4679 return encryptedContentSz - padLen;
wolfSSL 15:117db924cf7c 4680 }
wolfSSL 15:117db924cf7c 4681
wolfSSL 15:117db924cf7c 4682
wolfSSL 15:117db924cf7c 4683 #ifndef NO_PKCS7_ENCRYPTED_DATA
wolfSSL 15:117db924cf7c 4684
wolfSSL 15:117db924cf7c 4685 /* build PKCS#7 encryptedData content type, return encrypted size */
wolfSSL 15:117db924cf7c 4686 int wc_PKCS7_EncodeEncryptedData(PKCS7* pkcs7, byte* output, word32 outputSz)
wolfSSL 15:117db924cf7c 4687 {
wolfSSL 15:117db924cf7c 4688 int ret, idx = 0;
wolfSSL 15:117db924cf7c 4689 int totalSz, padSz, encryptedOutSz;
wolfSSL 15:117db924cf7c 4690
wolfSSL 15:117db924cf7c 4691 int contentInfoSeqSz, outerContentTypeSz, outerContentSz;
wolfSSL 15:117db924cf7c 4692 byte contentInfoSeq[MAX_SEQ_SZ];
wolfSSL 15:117db924cf7c 4693 byte outerContentType[MAX_ALGO_SZ];
wolfSSL 15:117db924cf7c 4694 byte outerContent[MAX_SEQ_SZ];
wolfSSL 15:117db924cf7c 4695
wolfSSL 15:117db924cf7c 4696 int encDataSeqSz, verSz, blockSz;
wolfSSL 15:117db924cf7c 4697 byte encDataSeq[MAX_SEQ_SZ];
wolfSSL 15:117db924cf7c 4698 byte ver[MAX_VERSION_SZ];
wolfSSL 15:117db924cf7c 4699
wolfSSL 15:117db924cf7c 4700 byte* plain = NULL;
wolfSSL 15:117db924cf7c 4701 byte* encryptedContent = NULL;
wolfSSL 15:117db924cf7c 4702
wolfSSL 15:117db924cf7c 4703 int encContentOctetSz, encContentSeqSz, contentTypeSz;
wolfSSL 15:117db924cf7c 4704 int contentEncAlgoSz, ivOctetStringSz;
wolfSSL 15:117db924cf7c 4705 byte encContentSeq[MAX_SEQ_SZ];
wolfSSL 15:117db924cf7c 4706 byte contentType[MAX_ALGO_SZ];
wolfSSL 15:117db924cf7c 4707 byte contentEncAlgo[MAX_ALGO_SZ];
wolfSSL 15:117db924cf7c 4708 byte tmpIv[MAX_CONTENT_IV_SIZE];
wolfSSL 15:117db924cf7c 4709 byte ivOctetString[MAX_OCTET_STR_SZ];
wolfSSL 15:117db924cf7c 4710 byte encContentOctet[MAX_OCTET_STR_SZ];
wolfSSL 15:117db924cf7c 4711
wolfSSL 15:117db924cf7c 4712 byte attribSet[MAX_SET_SZ];
wolfSSL 15:117db924cf7c 4713 EncodedAttrib* attribs = NULL;
wolfSSL 15:117db924cf7c 4714 word32 attribsSz;
wolfSSL 15:117db924cf7c 4715 word32 attribsCount;
wolfSSL 15:117db924cf7c 4716 word32 attribsSetSz;
wolfSSL 15:117db924cf7c 4717
wolfSSL 15:117db924cf7c 4718 byte* flatAttribs = NULL;
wolfSSL 15:117db924cf7c 4719
wolfSSL 15:117db924cf7c 4720 if (pkcs7 == NULL || pkcs7->content == NULL || pkcs7->contentSz == 0 ||
wolfSSL 15:117db924cf7c 4721 pkcs7->encryptOID == 0 || pkcs7->encryptionKey == NULL ||
wolfSSL 15:117db924cf7c 4722 pkcs7->encryptionKeySz == 0)
wolfSSL 15:117db924cf7c 4723 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 4724
wolfSSL 15:117db924cf7c 4725 if (output == NULL || outputSz == 0)
wolfSSL 15:117db924cf7c 4726 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 4727
wolfSSL 15:117db924cf7c 4728 /* outer content type */
wolfSSL 15:117db924cf7c 4729 outerContentTypeSz = wc_SetContentType(ENCRYPTED_DATA, outerContentType);
wolfSSL 15:117db924cf7c 4730
wolfSSL 15:117db924cf7c 4731 /* version, 2 if unprotectedAttrs present, 0 if absent */
wolfSSL 15:117db924cf7c 4732 if (pkcs7->unprotectedAttribsSz > 0) {
wolfSSL 15:117db924cf7c 4733 verSz = SetMyVersion(2, ver, 0);
wolfSSL 15:117db924cf7c 4734 } else {
wolfSSL 15:117db924cf7c 4735 verSz = SetMyVersion(0, ver, 0);
wolfSSL 15:117db924cf7c 4736 }
wolfSSL 15:117db924cf7c 4737
wolfSSL 15:117db924cf7c 4738 /* EncryptedContentInfo */
wolfSSL 15:117db924cf7c 4739 contentTypeSz = wc_SetContentType(pkcs7->contentOID, contentType);
wolfSSL 15:117db924cf7c 4740 if (contentTypeSz == 0)
wolfSSL 15:117db924cf7c 4741 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 4742
wolfSSL 15:117db924cf7c 4743 /* allocate encrypted content buffer, do PKCS#7 padding */
wolfSSL 15:117db924cf7c 4744 blockSz = wc_PKCS7_GetOIDBlockSize(pkcs7->encryptOID);
wolfSSL 15:117db924cf7c 4745 if (blockSz < 0)
wolfSSL 15:117db924cf7c 4746 return blockSz;
wolfSSL 15:117db924cf7c 4747
wolfSSL 15:117db924cf7c 4748 padSz = wc_PKCS7_GetPadSize(pkcs7->contentSz, blockSz);
wolfSSL 15:117db924cf7c 4749 if (padSz < 0)
wolfSSL 15:117db924cf7c 4750 return padSz;
wolfSSL 15:117db924cf7c 4751
wolfSSL 15:117db924cf7c 4752 encryptedOutSz = pkcs7->contentSz + padSz;
wolfSSL 15:117db924cf7c 4753
wolfSSL 15:117db924cf7c 4754 plain = (byte*)XMALLOC(encryptedOutSz, pkcs7->heap,
wolfSSL 15:117db924cf7c 4755 DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 4756 if (plain == NULL)
wolfSSL 15:117db924cf7c 4757 return MEMORY_E;
wolfSSL 15:117db924cf7c 4758
wolfSSL 15:117db924cf7c 4759 ret = wc_PKCS7_PadData(pkcs7->content, pkcs7->contentSz, plain,
wolfSSL 15:117db924cf7c 4760 encryptedOutSz, blockSz);
wolfSSL 15:117db924cf7c 4761 if (ret < 0) {
wolfSSL 15:117db924cf7c 4762 XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 4763 return ret;
wolfSSL 15:117db924cf7c 4764 }
wolfSSL 15:117db924cf7c 4765
wolfSSL 15:117db924cf7c 4766 encryptedContent = (byte*)XMALLOC(encryptedOutSz, pkcs7->heap,
wolfSSL 15:117db924cf7c 4767 DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 4768 if (encryptedContent == NULL) {
wolfSSL 15:117db924cf7c 4769 XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 4770 return MEMORY_E;
wolfSSL 15:117db924cf7c 4771 }
wolfSSL 15:117db924cf7c 4772
wolfSSL 15:117db924cf7c 4773 /* put together IV OCTET STRING */
wolfSSL 15:117db924cf7c 4774 ivOctetStringSz = SetOctetString(blockSz, ivOctetString);
wolfSSL 15:117db924cf7c 4775
wolfSSL 15:117db924cf7c 4776 /* build up ContentEncryptionAlgorithmIdentifier sequence,
wolfSSL 15:117db924cf7c 4777 adding (ivOctetStringSz + blockSz) for IV OCTET STRING */
wolfSSL 15:117db924cf7c 4778 contentEncAlgoSz = SetAlgoID(pkcs7->encryptOID, contentEncAlgo,
wolfSSL 15:117db924cf7c 4779 oidBlkType, ivOctetStringSz + blockSz);
wolfSSL 15:117db924cf7c 4780 if (contentEncAlgoSz == 0) {
wolfSSL 15:117db924cf7c 4781 XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 4782 XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 4783 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 4784 }
wolfSSL 15:117db924cf7c 4785
wolfSSL 15:117db924cf7c 4786 /* encrypt content */
wolfSSL 15:117db924cf7c 4787 ret = wc_PKCS7_GenerateIV(pkcs7, NULL, tmpIv, blockSz);
wolfSSL 15:117db924cf7c 4788 if (ret != 0) {
wolfSSL 15:117db924cf7c 4789 XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 4790 XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 4791 return ret;
wolfSSL 15:117db924cf7c 4792 }
wolfSSL 15:117db924cf7c 4793
wolfSSL 15:117db924cf7c 4794 ret = wc_PKCS7_EncryptContent(pkcs7->encryptOID, pkcs7->encryptionKey,
wolfSSL 15:117db924cf7c 4795 pkcs7->encryptionKeySz, tmpIv, blockSz, plain, encryptedOutSz,
wolfSSL 15:117db924cf7c 4796 encryptedContent);
wolfSSL 15:117db924cf7c 4797 if (ret != 0) {
wolfSSL 15:117db924cf7c 4798 XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 4799 XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 4800 return ret;
wolfSSL 15:117db924cf7c 4801 }
wolfSSL 15:117db924cf7c 4802
wolfSSL 15:117db924cf7c 4803 encContentOctetSz = SetImplicit(ASN_OCTET_STRING, 0,
wolfSSL 15:117db924cf7c 4804 encryptedOutSz, encContentOctet);
wolfSSL 15:117db924cf7c 4805
wolfSSL 15:117db924cf7c 4806 encContentSeqSz = SetSequence(contentTypeSz + contentEncAlgoSz +
wolfSSL 15:117db924cf7c 4807 ivOctetStringSz + blockSz +
wolfSSL 15:117db924cf7c 4808 encContentOctetSz + encryptedOutSz,
wolfSSL 15:117db924cf7c 4809 encContentSeq);
wolfSSL 15:117db924cf7c 4810
wolfSSL 15:117db924cf7c 4811 /* optional UnprotectedAttributes */
wolfSSL 15:117db924cf7c 4812 if (pkcs7->unprotectedAttribsSz != 0) {
wolfSSL 15:117db924cf7c 4813
wolfSSL 15:117db924cf7c 4814 if (pkcs7->unprotectedAttribs == NULL) {
wolfSSL 15:117db924cf7c 4815 XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 4816 XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 4817 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 4818 }
wolfSSL 15:117db924cf7c 4819
wolfSSL 15:117db924cf7c 4820 attribs = (EncodedAttrib*)XMALLOC(
wolfSSL 15:117db924cf7c 4821 sizeof(EncodedAttrib) * pkcs7->unprotectedAttribsSz,
wolfSSL 15:117db924cf7c 4822 pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 4823 if (attribs == NULL) {
wolfSSL 15:117db924cf7c 4824 XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 4825 XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 4826 return MEMORY_E;
wolfSSL 15:117db924cf7c 4827 }
wolfSSL 15:117db924cf7c 4828
wolfSSL 15:117db924cf7c 4829 attribsCount = pkcs7->unprotectedAttribsSz;
wolfSSL 15:117db924cf7c 4830 attribsSz = EncodeAttributes(attribs, pkcs7->unprotectedAttribsSz,
wolfSSL 15:117db924cf7c 4831 pkcs7->unprotectedAttribs,
wolfSSL 15:117db924cf7c 4832 pkcs7->unprotectedAttribsSz);
wolfSSL 15:117db924cf7c 4833
wolfSSL 15:117db924cf7c 4834 flatAttribs = (byte*)XMALLOC(attribsSz, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 4835 if (flatAttribs == NULL) {
wolfSSL 15:117db924cf7c 4836 XFREE(attribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 4837 XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 4838 XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 4839 return MEMORY_E;
wolfSSL 15:117db924cf7c 4840 }
wolfSSL 15:117db924cf7c 4841
wolfSSL 15:117db924cf7c 4842 FlattenAttributes(flatAttribs, attribs, attribsCount);
wolfSSL 15:117db924cf7c 4843 attribsSetSz = SetImplicit(ASN_SET, 1, attribsSz, attribSet);
wolfSSL 15:117db924cf7c 4844
wolfSSL 15:117db924cf7c 4845 } else {
wolfSSL 15:117db924cf7c 4846 attribsSz = 0;
wolfSSL 15:117db924cf7c 4847 attribsSetSz = 0;
wolfSSL 15:117db924cf7c 4848 }
wolfSSL 15:117db924cf7c 4849
wolfSSL 15:117db924cf7c 4850 /* keep track of sizes for outer wrapper layering */
wolfSSL 15:117db924cf7c 4851 totalSz = verSz + encContentSeqSz + contentTypeSz + contentEncAlgoSz +
wolfSSL 15:117db924cf7c 4852 ivOctetStringSz + blockSz + encContentOctetSz + encryptedOutSz +
wolfSSL 15:117db924cf7c 4853 attribsSz + attribsSetSz;;
wolfSSL 15:117db924cf7c 4854
wolfSSL 15:117db924cf7c 4855 /* EncryptedData */
wolfSSL 15:117db924cf7c 4856 encDataSeqSz = SetSequence(totalSz, encDataSeq);
wolfSSL 15:117db924cf7c 4857 totalSz += encDataSeqSz;
wolfSSL 15:117db924cf7c 4858
wolfSSL 15:117db924cf7c 4859 /* outer content */
wolfSSL 15:117db924cf7c 4860 outerContentSz = SetExplicit(0, totalSz, outerContent);
wolfSSL 15:117db924cf7c 4861 totalSz += outerContentTypeSz;
wolfSSL 15:117db924cf7c 4862 totalSz += outerContentSz;
wolfSSL 15:117db924cf7c 4863
wolfSSL 15:117db924cf7c 4864 /* ContentInfo */
wolfSSL 15:117db924cf7c 4865 contentInfoSeqSz = SetSequence(totalSz, contentInfoSeq);
wolfSSL 15:117db924cf7c 4866 totalSz += contentInfoSeqSz;
wolfSSL 15:117db924cf7c 4867
wolfSSL 15:117db924cf7c 4868 if (totalSz > (int)outputSz) {
wolfSSL 15:117db924cf7c 4869 WOLFSSL_MSG("PKCS#7 output buffer too small");
wolfSSL 15:117db924cf7c 4870 if (pkcs7->unprotectedAttribsSz != 0) {
wolfSSL 15:117db924cf7c 4871 XFREE(attribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 4872 XFREE(flatAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 4873 }
wolfSSL 15:117db924cf7c 4874 XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 4875 XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 4876 return BUFFER_E;
wolfSSL 15:117db924cf7c 4877 }
wolfSSL 15:117db924cf7c 4878
wolfSSL 15:117db924cf7c 4879 XMEMCPY(output + idx, contentInfoSeq, contentInfoSeqSz);
wolfSSL 15:117db924cf7c 4880 idx += contentInfoSeqSz;
wolfSSL 15:117db924cf7c 4881 XMEMCPY(output + idx, outerContentType, outerContentTypeSz);
wolfSSL 15:117db924cf7c 4882 idx += outerContentTypeSz;
wolfSSL 15:117db924cf7c 4883 XMEMCPY(output + idx, outerContent, outerContentSz);
wolfSSL 15:117db924cf7c 4884 idx += outerContentSz;
wolfSSL 15:117db924cf7c 4885 XMEMCPY(output + idx, encDataSeq, encDataSeqSz);
wolfSSL 15:117db924cf7c 4886 idx += encDataSeqSz;
wolfSSL 15:117db924cf7c 4887 XMEMCPY(output + idx, ver, verSz);
wolfSSL 15:117db924cf7c 4888 idx += verSz;
wolfSSL 15:117db924cf7c 4889 XMEMCPY(output + idx, encContentSeq, encContentSeqSz);
wolfSSL 15:117db924cf7c 4890 idx += encContentSeqSz;
wolfSSL 15:117db924cf7c 4891 XMEMCPY(output + idx, contentType, contentTypeSz);
wolfSSL 15:117db924cf7c 4892 idx += contentTypeSz;
wolfSSL 15:117db924cf7c 4893 XMEMCPY(output + idx, contentEncAlgo, contentEncAlgoSz);
wolfSSL 15:117db924cf7c 4894 idx += contentEncAlgoSz;
wolfSSL 15:117db924cf7c 4895 XMEMCPY(output + idx, ivOctetString, ivOctetStringSz);
wolfSSL 15:117db924cf7c 4896 idx += ivOctetStringSz;
wolfSSL 15:117db924cf7c 4897 XMEMCPY(output + idx, tmpIv, blockSz);
wolfSSL 15:117db924cf7c 4898 idx += blockSz;
wolfSSL 15:117db924cf7c 4899 XMEMCPY(output + idx, encContentOctet, encContentOctetSz);
wolfSSL 15:117db924cf7c 4900 idx += encContentOctetSz;
wolfSSL 15:117db924cf7c 4901 XMEMCPY(output + idx, encryptedContent, encryptedOutSz);
wolfSSL 15:117db924cf7c 4902 idx += encryptedOutSz;
wolfSSL 15:117db924cf7c 4903
wolfSSL 15:117db924cf7c 4904 if (pkcs7->unprotectedAttribsSz != 0) {
wolfSSL 15:117db924cf7c 4905 XMEMCPY(output + idx, attribSet, attribsSetSz);
wolfSSL 15:117db924cf7c 4906 idx += attribsSetSz;
wolfSSL 15:117db924cf7c 4907 XMEMCPY(output + idx, flatAttribs, attribsSz);
wolfSSL 15:117db924cf7c 4908 idx += attribsSz;
wolfSSL 15:117db924cf7c 4909 XFREE(attribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 4910 XFREE(flatAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 4911 }
wolfSSL 15:117db924cf7c 4912
wolfSSL 15:117db924cf7c 4913 XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 4914 XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 4915
wolfSSL 15:117db924cf7c 4916 return idx;
wolfSSL 15:117db924cf7c 4917 }
wolfSSL 15:117db924cf7c 4918
wolfSSL 15:117db924cf7c 4919
wolfSSL 15:117db924cf7c 4920 /* decode and store unprotected attributes in PKCS7->decodedAttrib. Return
wolfSSL 15:117db924cf7c 4921 * 0 on success, negative on error. User must call wc_PKCS7_Free(). */
wolfSSL 15:117db924cf7c 4922 static int wc_PKCS7_DecodeUnprotectedAttributes(PKCS7* pkcs7, byte* pkiMsg,
wolfSSL 15:117db924cf7c 4923 word32 pkiMsgSz, word32* inOutIdx)
wolfSSL 15:117db924cf7c 4924 {
wolfSSL 15:117db924cf7c 4925 int ret, attribLen;
wolfSSL 15:117db924cf7c 4926 word32 idx;
wolfSSL 15:117db924cf7c 4927
wolfSSL 15:117db924cf7c 4928 if (pkcs7 == NULL || pkiMsg == NULL ||
wolfSSL 15:117db924cf7c 4929 pkiMsgSz == 0 || inOutIdx == NULL)
wolfSSL 15:117db924cf7c 4930 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 4931
wolfSSL 15:117db924cf7c 4932 idx = *inOutIdx;
wolfSSL 15:117db924cf7c 4933
wolfSSL 15:117db924cf7c 4934 if (pkiMsg[idx] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1))
wolfSSL 15:117db924cf7c 4935 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 4936 idx++;
wolfSSL 15:117db924cf7c 4937
wolfSSL 15:117db924cf7c 4938 if (GetLength(pkiMsg, &idx, &attribLen, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 4939 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 4940
wolfSSL 15:117db924cf7c 4941 /* loop through attributes */
wolfSSL 15:117db924cf7c 4942 if ((ret = wc_PKCS7_ParseAttribs(pkcs7, pkiMsg + idx, attribLen)) < 0) {
wolfSSL 15:117db924cf7c 4943 return ret;
wolfSSL 15:117db924cf7c 4944 }
wolfSSL 15:117db924cf7c 4945
wolfSSL 15:117db924cf7c 4946 *inOutIdx = idx;
wolfSSL 15:117db924cf7c 4947
wolfSSL 15:117db924cf7c 4948 return 0;
wolfSSL 15:117db924cf7c 4949 }
wolfSSL 15:117db924cf7c 4950
wolfSSL 15:117db924cf7c 4951
wolfSSL 15:117db924cf7c 4952 /* unwrap and decrypt PKCS#7/CMS encrypted-data object, returned decoded size */
wolfSSL 15:117db924cf7c 4953 int wc_PKCS7_DecodeEncryptedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz,
wolfSSL 15:117db924cf7c 4954 byte* output, word32 outputSz)
wolfSSL 15:117db924cf7c 4955 {
wolfSSL 15:117db924cf7c 4956 int ret, version, length, haveAttribs;
wolfSSL 15:117db924cf7c 4957 word32 idx = 0;
wolfSSL 15:117db924cf7c 4958 word32 contentType, encOID;
wolfSSL 15:117db924cf7c 4959
wolfSSL 15:117db924cf7c 4960 int expBlockSz;
wolfSSL 15:117db924cf7c 4961 byte tmpIv[MAX_CONTENT_IV_SIZE];
wolfSSL 15:117db924cf7c 4962
wolfSSL 15:117db924cf7c 4963 int encryptedContentSz;
wolfSSL 15:117db924cf7c 4964 byte padLen;
wolfSSL 15:117db924cf7c 4965 byte* encryptedContent = NULL;
wolfSSL 15:117db924cf7c 4966
wolfSSL 15:117db924cf7c 4967 if (pkcs7 == NULL || pkcs7->encryptionKey == NULL ||
wolfSSL 15:117db924cf7c 4968 pkcs7->encryptionKeySz == 0)
wolfSSL 15:117db924cf7c 4969 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 4970
wolfSSL 15:117db924cf7c 4971 if (pkiMsg == NULL || pkiMsgSz == 0 ||
wolfSSL 15:117db924cf7c 4972 output == NULL || outputSz == 0)
wolfSSL 15:117db924cf7c 4973 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 4974 /* read past ContentInfo, verify type is encrypted-data */
wolfSSL 15:117db924cf7c 4975 if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 4976 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 4977
wolfSSL 15:117db924cf7c 4978 if (wc_GetContentType(pkiMsg, &idx, &contentType, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 4979 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 4980
wolfSSL 15:117db924cf7c 4981 if (contentType != ENCRYPTED_DATA) {
wolfSSL 15:117db924cf7c 4982 WOLFSSL_MSG("PKCS#7 input not of type EncryptedData");
wolfSSL 15:117db924cf7c 4983 return PKCS7_OID_E;
wolfSSL 15:117db924cf7c 4984 }
wolfSSL 15:117db924cf7c 4985
wolfSSL 15:117db924cf7c 4986 if (pkiMsg[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
wolfSSL 15:117db924cf7c 4987 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 4988
wolfSSL 15:117db924cf7c 4989 if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 4990 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 4991
wolfSSL 15:117db924cf7c 4992 /* remove EncryptedData and version */
wolfSSL 15:117db924cf7c 4993 if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 4994 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 4995
wolfSSL 15:117db924cf7c 4996 /* get version, check later */
wolfSSL 15:117db924cf7c 4997 haveAttribs = 0;
wolfSSL 15:117db924cf7c 4998 if (GetMyVersion(pkiMsg, &idx, &version, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 4999 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 5000
wolfSSL 15:117db924cf7c 5001 /* remove EncryptedContentInfo */
wolfSSL 15:117db924cf7c 5002 if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 5003 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 5004
wolfSSL 15:117db924cf7c 5005 if (wc_GetContentType(pkiMsg, &idx, &contentType, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 5006 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 5007
wolfSSL 15:117db924cf7c 5008 if (GetAlgoId(pkiMsg, &idx, &encOID, oidBlkType, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 5009 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 5010
wolfSSL 15:117db924cf7c 5011 expBlockSz = wc_PKCS7_GetOIDBlockSize(encOID);
wolfSSL 15:117db924cf7c 5012 if (expBlockSz < 0)
wolfSSL 15:117db924cf7c 5013 return expBlockSz;
wolfSSL 15:117db924cf7c 5014
wolfSSL 15:117db924cf7c 5015 /* get block cipher IV, stored in OPTIONAL parameter of AlgoID */
wolfSSL 15:117db924cf7c 5016 if (pkiMsg[idx++] != ASN_OCTET_STRING)
wolfSSL 15:117db924cf7c 5017 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 5018
wolfSSL 15:117db924cf7c 5019 if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 5020 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 5021
wolfSSL 15:117db924cf7c 5022 if (length != expBlockSz) {
wolfSSL 15:117db924cf7c 5023 WOLFSSL_MSG("Incorrect IV length, must be of content alg block size");
wolfSSL 15:117db924cf7c 5024 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 5025 }
wolfSSL 15:117db924cf7c 5026
wolfSSL 15:117db924cf7c 5027 XMEMCPY(tmpIv, &pkiMsg[idx], length);
wolfSSL 15:117db924cf7c 5028 idx += length;
wolfSSL 15:117db924cf7c 5029
wolfSSL 15:117db924cf7c 5030 /* read encryptedContent, cont[0] */
wolfSSL 15:117db924cf7c 5031 if (pkiMsg[idx++] != (ASN_CONTEXT_SPECIFIC | 0))
wolfSSL 15:117db924cf7c 5032 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 5033
wolfSSL 15:117db924cf7c 5034 if (GetLength(pkiMsg, &idx, &encryptedContentSz, pkiMsgSz) <= 0)
wolfSSL 15:117db924cf7c 5035 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 5036
wolfSSL 15:117db924cf7c 5037 encryptedContent = (byte*)XMALLOC(encryptedContentSz, pkcs7->heap,
wolfSSL 15:117db924cf7c 5038 DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 5039 if (encryptedContent == NULL)
wolfSSL 15:117db924cf7c 5040 return MEMORY_E;
wolfSSL 15:117db924cf7c 5041
wolfSSL 15:117db924cf7c 5042 XMEMCPY(encryptedContent, &pkiMsg[idx], encryptedContentSz);
wolfSSL 15:117db924cf7c 5043 idx += encryptedContentSz;
wolfSSL 15:117db924cf7c 5044
wolfSSL 15:117db924cf7c 5045 /* decrypt encryptedContent */
wolfSSL 15:117db924cf7c 5046 ret = wc_PKCS7_DecryptContent(encOID, pkcs7->encryptionKey,
wolfSSL 15:117db924cf7c 5047 pkcs7->encryptionKeySz, tmpIv, expBlockSz,
wolfSSL 15:117db924cf7c 5048 encryptedContent, encryptedContentSz,
wolfSSL 15:117db924cf7c 5049 encryptedContent);
wolfSSL 15:117db924cf7c 5050 if (ret != 0) {
wolfSSL 15:117db924cf7c 5051 XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 5052 return ret;
wolfSSL 15:117db924cf7c 5053 }
wolfSSL 15:117db924cf7c 5054
wolfSSL 15:117db924cf7c 5055 padLen = encryptedContent[encryptedContentSz-1];
wolfSSL 15:117db924cf7c 5056
wolfSSL 15:117db924cf7c 5057 /* copy plaintext to output */
wolfSSL 15:117db924cf7c 5058 XMEMCPY(output, encryptedContent, encryptedContentSz - padLen);
wolfSSL 15:117db924cf7c 5059
wolfSSL 15:117db924cf7c 5060 /* get implicit[1] unprotected attributes, optional */
wolfSSL 15:117db924cf7c 5061 pkcs7->decodedAttrib = NULL;
wolfSSL 15:117db924cf7c 5062 if (idx < pkiMsgSz) {
wolfSSL 15:117db924cf7c 5063
wolfSSL 15:117db924cf7c 5064 haveAttribs = 1;
wolfSSL 15:117db924cf7c 5065
wolfSSL 15:117db924cf7c 5066 ret = wc_PKCS7_DecodeUnprotectedAttributes(pkcs7, pkiMsg,
wolfSSL 15:117db924cf7c 5067 pkiMsgSz, &idx);
wolfSSL 15:117db924cf7c 5068 if (ret != 0) {
wolfSSL 15:117db924cf7c 5069 ForceZero(encryptedContent, encryptedContentSz);
wolfSSL 15:117db924cf7c 5070 XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 5071 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 5072 }
wolfSSL 15:117db924cf7c 5073 }
wolfSSL 15:117db924cf7c 5074
wolfSSL 15:117db924cf7c 5075 /* go back and check the version now that attribs have been processed */
wolfSSL 15:117db924cf7c 5076 if ((haveAttribs == 0 && version != 0) ||
wolfSSL 15:117db924cf7c 5077 (haveAttribs == 1 && version != 2) ) {
wolfSSL 15:117db924cf7c 5078 XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 5079 WOLFSSL_MSG("Wrong PKCS#7 EncryptedData version");
wolfSSL 15:117db924cf7c 5080 return ASN_VERSION_E;
wolfSSL 15:117db924cf7c 5081 }
wolfSSL 15:117db924cf7c 5082
wolfSSL 15:117db924cf7c 5083 ForceZero(encryptedContent, encryptedContentSz);
wolfSSL 15:117db924cf7c 5084 XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 5085
wolfSSL 15:117db924cf7c 5086 return encryptedContentSz - padLen;
wolfSSL 15:117db924cf7c 5087 }
wolfSSL 15:117db924cf7c 5088
wolfSSL 15:117db924cf7c 5089 #endif /* NO_PKCS7_ENCRYPTED_DATA */
wolfSSL 15:117db924cf7c 5090
wolfSSL 15:117db924cf7c 5091 #else /* HAVE_PKCS7 */
wolfSSL 15:117db924cf7c 5092
wolfSSL 15:117db924cf7c 5093
wolfSSL 15:117db924cf7c 5094 #ifdef _MSC_VER
wolfSSL 15:117db924cf7c 5095 /* 4206 warning for blank file */
wolfSSL 15:117db924cf7c 5096 #pragma warning(disable: 4206)
wolfSSL 15:117db924cf7c 5097 #endif
wolfSSL 15:117db924cf7c 5098
wolfSSL 15:117db924cf7c 5099
wolfSSL 15:117db924cf7c 5100 #endif /* HAVE_PKCS7 */
wolfSSL 15:117db924cf7c 5101
wolfSSL 15:117db924cf7c 5102