wolfSSL SSL/TLS library, support up to TLS1.3

Dependents:   CyaSSL-Twitter-OAuth4Tw Example-client-tls-cert TwitterReader TweetTest ... more

Committer:
wolfSSL
Date:
Tue Aug 22 10:48:22 2017 +0000
Revision:
13:f67a6c6013ca
wolfSSL3.12.0 with TLS1.3

Who changed what in which revision?

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