Xuyi Wang / wolfSSL

Dependents:   OS

Committer:
wolfSSL
Date:
Fri Jun 26 00:39:20 2015 +0000
Revision:
0:d92f9d21154c
wolfSSL 3.6.0

Who changed what in which revision?

UserRevisionLine numberNew contents of line
wolfSSL 0:d92f9d21154c 1 /* pkcs7.c
wolfSSL 0:d92f9d21154c 2 *
wolfSSL 0:d92f9d21154c 3 * Copyright (C) 2006-2015 wolfSSL Inc.
wolfSSL 0:d92f9d21154c 4 *
wolfSSL 0:d92f9d21154c 5 * This file is part of wolfSSL. (formerly known as CyaSSL)
wolfSSL 0:d92f9d21154c 6 *
wolfSSL 0:d92f9d21154c 7 * wolfSSL is free software; you can redistribute it and/or modify
wolfSSL 0:d92f9d21154c 8 * it under the terms of the GNU General Public License as published by
wolfSSL 0:d92f9d21154c 9 * the Free Software Foundation; either version 2 of the License, or
wolfSSL 0:d92f9d21154c 10 * (at your option) any later version.
wolfSSL 0:d92f9d21154c 11 *
wolfSSL 0:d92f9d21154c 12 * wolfSSL is distributed in the hope that it will be useful,
wolfSSL 0:d92f9d21154c 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
wolfSSL 0:d92f9d21154c 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
wolfSSL 0:d92f9d21154c 15 * GNU General Public License for more details.
wolfSSL 0:d92f9d21154c 16 *
wolfSSL 0:d92f9d21154c 17 * You should have received a copy of the GNU General Public License
wolfSSL 0:d92f9d21154c 18 * along with this program; if not, write to the Free Software
wolfSSL 0:d92f9d21154c 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
wolfSSL 0:d92f9d21154c 20 */
wolfSSL 0:d92f9d21154c 21
wolfSSL 0:d92f9d21154c 22 #ifdef HAVE_CONFIG_H
wolfSSL 0:d92f9d21154c 23 #include <config.h>
wolfSSL 0:d92f9d21154c 24 #endif
wolfSSL 0:d92f9d21154c 25
wolfSSL 0:d92f9d21154c 26 #include <wolfssl/wolfcrypt/settings.h>
wolfSSL 0:d92f9d21154c 27
wolfSSL 0:d92f9d21154c 28 #ifdef HAVE_PKCS7
wolfSSL 0:d92f9d21154c 29
wolfSSL 0:d92f9d21154c 30 #include <wolfssl/wolfcrypt/pkcs7.h>
wolfSSL 0:d92f9d21154c 31 #include <wolfssl/wolfcrypt/error-crypt.h>
wolfSSL 0:d92f9d21154c 32 #include <wolfssl/wolfcrypt/logging.h>
wolfSSL 0:d92f9d21154c 33 #ifdef NO_INLINE
wolfSSL 0:d92f9d21154c 34 #include <wolfssl/wolfcrypt/misc.h>
wolfSSL 0:d92f9d21154c 35 #else
wolfSSL 0:d92f9d21154c 36 #include <wolfcrypt/src/misc.c>
wolfSSL 0:d92f9d21154c 37 #endif
wolfSSL 0:d92f9d21154c 38
wolfSSL 0:d92f9d21154c 39 #ifndef WOLFSSL_HAVE_MIN
wolfSSL 0:d92f9d21154c 40 #define WOLFSSL_HAVE_MIN
wolfSSL 0:d92f9d21154c 41
wolfSSL 0:d92f9d21154c 42 static INLINE word32 min(word32 a, word32 b)
wolfSSL 0:d92f9d21154c 43 {
wolfSSL 0:d92f9d21154c 44 return a > b ? b : a;
wolfSSL 0:d92f9d21154c 45 }
wolfSSL 0:d92f9d21154c 46
wolfSSL 0:d92f9d21154c 47 #endif /* WOLFSSL_HAVE_MIN */
wolfSSL 0:d92f9d21154c 48
wolfSSL 0:d92f9d21154c 49
wolfSSL 0:d92f9d21154c 50 /* placed ASN.1 contentType OID into *output, return idx on success,
wolfSSL 0:d92f9d21154c 51 * 0 upon failure */
wolfSSL 0:d92f9d21154c 52 WOLFSSL_LOCAL int wc_SetContentType(int pkcs7TypeOID, byte* output)
wolfSSL 0:d92f9d21154c 53 {
wolfSSL 0:d92f9d21154c 54 /* PKCS#7 content types, RFC 2315, section 14 */
wolfSSL 0:d92f9d21154c 55 static const byte pkcs7[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7,
wolfSSL 0:d92f9d21154c 56 0x0D, 0x01, 0x07 };
wolfSSL 0:d92f9d21154c 57 static const byte data[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7,
wolfSSL 0:d92f9d21154c 58 0x0D, 0x01, 0x07, 0x01 };
wolfSSL 0:d92f9d21154c 59 static const byte signedData[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7,
wolfSSL 0:d92f9d21154c 60 0x0D, 0x01, 0x07, 0x02};
wolfSSL 0:d92f9d21154c 61 static const byte envelopedData[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7,
wolfSSL 0:d92f9d21154c 62 0x0D, 0x01, 0x07, 0x03 };
wolfSSL 0:d92f9d21154c 63 static const byte signedAndEnveloped[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7,
wolfSSL 0:d92f9d21154c 64 0x0D, 0x01, 0x07, 0x04 };
wolfSSL 0:d92f9d21154c 65 static const byte digestedData[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7,
wolfSSL 0:d92f9d21154c 66 0x0D, 0x01, 0x07, 0x05 };
wolfSSL 0:d92f9d21154c 67 static const byte encryptedData[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7,
wolfSSL 0:d92f9d21154c 68 0x0D, 0x01, 0x07, 0x06 };
wolfSSL 0:d92f9d21154c 69
wolfSSL 0:d92f9d21154c 70 int idSz;
wolfSSL 0:d92f9d21154c 71 int typeSz = 0, idx = 0;
wolfSSL 0:d92f9d21154c 72 const byte* typeName = 0;
wolfSSL 0:d92f9d21154c 73 byte ID_Length[MAX_LENGTH_SZ];
wolfSSL 0:d92f9d21154c 74
wolfSSL 0:d92f9d21154c 75 switch (pkcs7TypeOID) {
wolfSSL 0:d92f9d21154c 76 case PKCS7_MSG:
wolfSSL 0:d92f9d21154c 77 typeSz = sizeof(pkcs7);
wolfSSL 0:d92f9d21154c 78 typeName = pkcs7;
wolfSSL 0:d92f9d21154c 79 break;
wolfSSL 0:d92f9d21154c 80
wolfSSL 0:d92f9d21154c 81 case DATA:
wolfSSL 0:d92f9d21154c 82 typeSz = sizeof(data);
wolfSSL 0:d92f9d21154c 83 typeName = data;
wolfSSL 0:d92f9d21154c 84 break;
wolfSSL 0:d92f9d21154c 85
wolfSSL 0:d92f9d21154c 86 case SIGNED_DATA:
wolfSSL 0:d92f9d21154c 87 typeSz = sizeof(signedData);
wolfSSL 0:d92f9d21154c 88 typeName = signedData;
wolfSSL 0:d92f9d21154c 89 break;
wolfSSL 0:d92f9d21154c 90
wolfSSL 0:d92f9d21154c 91 case ENVELOPED_DATA:
wolfSSL 0:d92f9d21154c 92 typeSz = sizeof(envelopedData);
wolfSSL 0:d92f9d21154c 93 typeName = envelopedData;
wolfSSL 0:d92f9d21154c 94 break;
wolfSSL 0:d92f9d21154c 95
wolfSSL 0:d92f9d21154c 96 case SIGNED_AND_ENVELOPED_DATA:
wolfSSL 0:d92f9d21154c 97 typeSz = sizeof(signedAndEnveloped);
wolfSSL 0:d92f9d21154c 98 typeName = signedAndEnveloped;
wolfSSL 0:d92f9d21154c 99 break;
wolfSSL 0:d92f9d21154c 100
wolfSSL 0:d92f9d21154c 101 case DIGESTED_DATA:
wolfSSL 0:d92f9d21154c 102 typeSz = sizeof(digestedData);
wolfSSL 0:d92f9d21154c 103 typeName = digestedData;
wolfSSL 0:d92f9d21154c 104 break;
wolfSSL 0:d92f9d21154c 105
wolfSSL 0:d92f9d21154c 106 case ENCRYPTED_DATA:
wolfSSL 0:d92f9d21154c 107 typeSz = sizeof(encryptedData);
wolfSSL 0:d92f9d21154c 108 typeName = encryptedData;
wolfSSL 0:d92f9d21154c 109 break;
wolfSSL 0:d92f9d21154c 110
wolfSSL 0:d92f9d21154c 111 default:
wolfSSL 0:d92f9d21154c 112 WOLFSSL_MSG("Unknown PKCS#7 Type");
wolfSSL 0:d92f9d21154c 113 return 0;
wolfSSL 0:d92f9d21154c 114 };
wolfSSL 0:d92f9d21154c 115
wolfSSL 0:d92f9d21154c 116 idSz = SetLength(typeSz, ID_Length);
wolfSSL 0:d92f9d21154c 117 output[idx++] = ASN_OBJECT_ID;
wolfSSL 0:d92f9d21154c 118 XMEMCPY(output + idx, ID_Length, idSz);
wolfSSL 0:d92f9d21154c 119 idx += idSz;
wolfSSL 0:d92f9d21154c 120 XMEMCPY(output + idx, typeName, typeSz);
wolfSSL 0:d92f9d21154c 121 idx += typeSz;
wolfSSL 0:d92f9d21154c 122
wolfSSL 0:d92f9d21154c 123 return idx;
wolfSSL 0:d92f9d21154c 124
wolfSSL 0:d92f9d21154c 125 }
wolfSSL 0:d92f9d21154c 126
wolfSSL 0:d92f9d21154c 127
wolfSSL 0:d92f9d21154c 128 /* get ASN.1 contentType OID sum, return 0 on success, <0 on failure */
wolfSSL 0:d92f9d21154c 129 int wc_GetContentType(const byte* input, word32* inOutIdx, word32* oid,
wolfSSL 0:d92f9d21154c 130 word32 maxIdx)
wolfSSL 0:d92f9d21154c 131 {
wolfSSL 0:d92f9d21154c 132 int length;
wolfSSL 0:d92f9d21154c 133 word32 i = *inOutIdx;
wolfSSL 0:d92f9d21154c 134 byte b;
wolfSSL 0:d92f9d21154c 135 *oid = 0;
wolfSSL 0:d92f9d21154c 136
wolfSSL 0:d92f9d21154c 137 WOLFSSL_ENTER("wc_GetContentType");
wolfSSL 0:d92f9d21154c 138
wolfSSL 0:d92f9d21154c 139 b = input[i++];
wolfSSL 0:d92f9d21154c 140 if (b != ASN_OBJECT_ID)
wolfSSL 0:d92f9d21154c 141 return ASN_OBJECT_ID_E;
wolfSSL 0:d92f9d21154c 142
wolfSSL 0:d92f9d21154c 143 if (GetLength(input, &i, &length, maxIdx) < 0)
wolfSSL 0:d92f9d21154c 144 return ASN_PARSE_E;
wolfSSL 0:d92f9d21154c 145
wolfSSL 0:d92f9d21154c 146 while(length--) {
wolfSSL 0:d92f9d21154c 147 *oid += input[i];
wolfSSL 0:d92f9d21154c 148 i++;
wolfSSL 0:d92f9d21154c 149 }
wolfSSL 0:d92f9d21154c 150
wolfSSL 0:d92f9d21154c 151 *inOutIdx = i;
wolfSSL 0:d92f9d21154c 152
wolfSSL 0:d92f9d21154c 153 return 0;
wolfSSL 0:d92f9d21154c 154 }
wolfSSL 0:d92f9d21154c 155
wolfSSL 0:d92f9d21154c 156
wolfSSL 0:d92f9d21154c 157 /* init PKCS7 struct with recipient cert, decode into DecodedCert */
wolfSSL 0:d92f9d21154c 158 int wc_PKCS7_InitWithCert(PKCS7* pkcs7, byte* cert, word32 certSz)
wolfSSL 0:d92f9d21154c 159 {
wolfSSL 0:d92f9d21154c 160 int ret = 0;
wolfSSL 0:d92f9d21154c 161
wolfSSL 0:d92f9d21154c 162 XMEMSET(pkcs7, 0, sizeof(PKCS7));
wolfSSL 0:d92f9d21154c 163 if (cert != NULL && certSz > 0) {
wolfSSL 0:d92f9d21154c 164 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 165 DecodedCert* dCert;
wolfSSL 0:d92f9d21154c 166
wolfSSL 0:d92f9d21154c 167 dCert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
wolfSSL 0:d92f9d21154c 168 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 169 if (dCert == NULL)
wolfSSL 0:d92f9d21154c 170 return MEMORY_E;
wolfSSL 0:d92f9d21154c 171 #else
wolfSSL 0:d92f9d21154c 172 DecodedCert stack_dCert;
wolfSSL 0:d92f9d21154c 173 DecodedCert* dCert = &stack_dCert;
wolfSSL 0:d92f9d21154c 174 #endif
wolfSSL 0:d92f9d21154c 175
wolfSSL 0:d92f9d21154c 176 pkcs7->singleCert = cert;
wolfSSL 0:d92f9d21154c 177 pkcs7->singleCertSz = certSz;
wolfSSL 0:d92f9d21154c 178 InitDecodedCert(dCert, cert, certSz, 0);
wolfSSL 0:d92f9d21154c 179
wolfSSL 0:d92f9d21154c 180 ret = ParseCert(dCert, CA_TYPE, NO_VERIFY, 0);
wolfSSL 0:d92f9d21154c 181 if (ret < 0) {
wolfSSL 0:d92f9d21154c 182 FreeDecodedCert(dCert);
wolfSSL 0:d92f9d21154c 183 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 184 XFREE(dCert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 185 #endif
wolfSSL 0:d92f9d21154c 186 return ret;
wolfSSL 0:d92f9d21154c 187 }
wolfSSL 0:d92f9d21154c 188
wolfSSL 0:d92f9d21154c 189 XMEMCPY(pkcs7->publicKey, dCert->publicKey, dCert->pubKeySize);
wolfSSL 0:d92f9d21154c 190 pkcs7->publicKeySz = dCert->pubKeySize;
wolfSSL 0:d92f9d21154c 191 XMEMCPY(pkcs7->issuerHash, dCert->issuerHash, KEYID_SIZE);
wolfSSL 0:d92f9d21154c 192 pkcs7->issuer = dCert->issuerRaw;
wolfSSL 0:d92f9d21154c 193 pkcs7->issuerSz = dCert->issuerRawLen;
wolfSSL 0:d92f9d21154c 194 XMEMCPY(pkcs7->issuerSn, dCert->serial, dCert->serialSz);
wolfSSL 0:d92f9d21154c 195 pkcs7->issuerSnSz = dCert->serialSz;
wolfSSL 0:d92f9d21154c 196 FreeDecodedCert(dCert);
wolfSSL 0:d92f9d21154c 197
wolfSSL 0:d92f9d21154c 198 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 199 XFREE(dCert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 200 #endif
wolfSSL 0:d92f9d21154c 201 }
wolfSSL 0:d92f9d21154c 202
wolfSSL 0:d92f9d21154c 203 return ret;
wolfSSL 0:d92f9d21154c 204 }
wolfSSL 0:d92f9d21154c 205
wolfSSL 0:d92f9d21154c 206
wolfSSL 0:d92f9d21154c 207 /* releases any memory allocated by a PKCS7 initializer */
wolfSSL 0:d92f9d21154c 208 void wc_PKCS7_Free(PKCS7* pkcs7)
wolfSSL 0:d92f9d21154c 209 {
wolfSSL 0:d92f9d21154c 210 (void)pkcs7;
wolfSSL 0:d92f9d21154c 211 }
wolfSSL 0:d92f9d21154c 212
wolfSSL 0:d92f9d21154c 213
wolfSSL 0:d92f9d21154c 214 /* build PKCS#7 data content type */
wolfSSL 0:d92f9d21154c 215 int wc_PKCS7_EncodeData(PKCS7* pkcs7, byte* output, word32 outputSz)
wolfSSL 0:d92f9d21154c 216 {
wolfSSL 0:d92f9d21154c 217 static const byte oid[] =
wolfSSL 0:d92f9d21154c 218 { ASN_OBJECT_ID, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01,
wolfSSL 0:d92f9d21154c 219 0x07, 0x01 };
wolfSSL 0:d92f9d21154c 220 byte seq[MAX_SEQ_SZ];
wolfSSL 0:d92f9d21154c 221 byte octetStr[MAX_OCTET_STR_SZ];
wolfSSL 0:d92f9d21154c 222 word32 seqSz;
wolfSSL 0:d92f9d21154c 223 word32 octetStrSz;
wolfSSL 0:d92f9d21154c 224 word32 oidSz = (word32)sizeof(oid);
wolfSSL 0:d92f9d21154c 225 int idx = 0;
wolfSSL 0:d92f9d21154c 226
wolfSSL 0:d92f9d21154c 227 octetStrSz = SetOctetString(pkcs7->contentSz, octetStr);
wolfSSL 0:d92f9d21154c 228 seqSz = SetSequence(pkcs7->contentSz + octetStrSz + oidSz, seq);
wolfSSL 0:d92f9d21154c 229
wolfSSL 0:d92f9d21154c 230 if (outputSz < pkcs7->contentSz + octetStrSz + oidSz + seqSz)
wolfSSL 0:d92f9d21154c 231 return BUFFER_E;
wolfSSL 0:d92f9d21154c 232
wolfSSL 0:d92f9d21154c 233 XMEMCPY(output, seq, seqSz);
wolfSSL 0:d92f9d21154c 234 idx += seqSz;
wolfSSL 0:d92f9d21154c 235 XMEMCPY(output + idx, oid, oidSz);
wolfSSL 0:d92f9d21154c 236 idx += oidSz;
wolfSSL 0:d92f9d21154c 237 XMEMCPY(output + idx, octetStr, octetStrSz);
wolfSSL 0:d92f9d21154c 238 idx += octetStrSz;
wolfSSL 0:d92f9d21154c 239 XMEMCPY(output + idx, pkcs7->content, pkcs7->contentSz);
wolfSSL 0:d92f9d21154c 240 idx += pkcs7->contentSz;
wolfSSL 0:d92f9d21154c 241
wolfSSL 0:d92f9d21154c 242 return idx;
wolfSSL 0:d92f9d21154c 243 }
wolfSSL 0:d92f9d21154c 244
wolfSSL 0:d92f9d21154c 245
wolfSSL 0:d92f9d21154c 246 typedef struct EncodedAttrib {
wolfSSL 0:d92f9d21154c 247 byte valueSeq[MAX_SEQ_SZ];
wolfSSL 0:d92f9d21154c 248 const byte* oid;
wolfSSL 0:d92f9d21154c 249 byte valueSet[MAX_SET_SZ];
wolfSSL 0:d92f9d21154c 250 const byte* value;
wolfSSL 0:d92f9d21154c 251 word32 valueSeqSz, oidSz, idSz, valueSetSz, valueSz, totalSz;
wolfSSL 0:d92f9d21154c 252 } EncodedAttrib;
wolfSSL 0:d92f9d21154c 253
wolfSSL 0:d92f9d21154c 254
wolfSSL 0:d92f9d21154c 255 typedef struct ESD {
wolfSSL 0:d92f9d21154c 256 Sha sha;
wolfSSL 0:d92f9d21154c 257 byte contentDigest[SHA_DIGEST_SIZE + 2]; /* content only + ASN.1 heading */
wolfSSL 0:d92f9d21154c 258 byte contentAttribsDigest[SHA_DIGEST_SIZE];
wolfSSL 0:d92f9d21154c 259 byte encContentDigest[512];
wolfSSL 0:d92f9d21154c 260
wolfSSL 0:d92f9d21154c 261 byte outerSeq[MAX_SEQ_SZ];
wolfSSL 0:d92f9d21154c 262 byte outerContent[MAX_EXP_SZ];
wolfSSL 0:d92f9d21154c 263 byte innerSeq[MAX_SEQ_SZ];
wolfSSL 0:d92f9d21154c 264 byte version[MAX_VERSION_SZ];
wolfSSL 0:d92f9d21154c 265 byte digAlgoIdSet[MAX_SET_SZ];
wolfSSL 0:d92f9d21154c 266 byte singleDigAlgoId[MAX_ALGO_SZ];
wolfSSL 0:d92f9d21154c 267
wolfSSL 0:d92f9d21154c 268 byte contentInfoSeq[MAX_SEQ_SZ];
wolfSSL 0:d92f9d21154c 269 byte innerContSeq[MAX_EXP_SZ];
wolfSSL 0:d92f9d21154c 270 byte innerOctets[MAX_OCTET_STR_SZ];
wolfSSL 0:d92f9d21154c 271
wolfSSL 0:d92f9d21154c 272 byte certsSet[MAX_SET_SZ];
wolfSSL 0:d92f9d21154c 273
wolfSSL 0:d92f9d21154c 274 byte signerInfoSet[MAX_SET_SZ];
wolfSSL 0:d92f9d21154c 275 byte signerInfoSeq[MAX_SEQ_SZ];
wolfSSL 0:d92f9d21154c 276 byte signerVersion[MAX_VERSION_SZ];
wolfSSL 0:d92f9d21154c 277 byte issuerSnSeq[MAX_SEQ_SZ];
wolfSSL 0:d92f9d21154c 278 byte issuerName[MAX_SEQ_SZ];
wolfSSL 0:d92f9d21154c 279 byte issuerSn[MAX_SN_SZ];
wolfSSL 0:d92f9d21154c 280 byte signerDigAlgoId[MAX_ALGO_SZ];
wolfSSL 0:d92f9d21154c 281 byte digEncAlgoId[MAX_ALGO_SZ];
wolfSSL 0:d92f9d21154c 282 byte signedAttribSet[MAX_SET_SZ];
wolfSSL 0:d92f9d21154c 283 EncodedAttrib signedAttribs[6];
wolfSSL 0:d92f9d21154c 284 byte signerDigest[MAX_OCTET_STR_SZ];
wolfSSL 0:d92f9d21154c 285 word32 innerOctetsSz, innerContSeqSz, contentInfoSeqSz;
wolfSSL 0:d92f9d21154c 286 word32 outerSeqSz, outerContentSz, innerSeqSz, versionSz, digAlgoIdSetSz,
wolfSSL 0:d92f9d21154c 287 singleDigAlgoIdSz, certsSetSz;
wolfSSL 0:d92f9d21154c 288 word32 signerInfoSetSz, signerInfoSeqSz, signerVersionSz,
wolfSSL 0:d92f9d21154c 289 issuerSnSeqSz, issuerNameSz, issuerSnSz,
wolfSSL 0:d92f9d21154c 290 signerDigAlgoIdSz, digEncAlgoIdSz, signerDigestSz;
wolfSSL 0:d92f9d21154c 291 word32 encContentDigestSz, signedAttribsSz, signedAttribsCount,
wolfSSL 0:d92f9d21154c 292 signedAttribSetSz;
wolfSSL 0:d92f9d21154c 293 } ESD;
wolfSSL 0:d92f9d21154c 294
wolfSSL 0:d92f9d21154c 295
wolfSSL 0:d92f9d21154c 296 static int EncodeAttributes(EncodedAttrib* ea, int eaSz,
wolfSSL 0:d92f9d21154c 297 PKCS7Attrib* attribs, int attribsSz)
wolfSSL 0:d92f9d21154c 298 {
wolfSSL 0:d92f9d21154c 299 int i;
wolfSSL 0:d92f9d21154c 300 int maxSz = min(eaSz, attribsSz);
wolfSSL 0:d92f9d21154c 301 int allAttribsSz = 0;
wolfSSL 0:d92f9d21154c 302
wolfSSL 0:d92f9d21154c 303 for (i = 0; i < maxSz; i++)
wolfSSL 0:d92f9d21154c 304 {
wolfSSL 0:d92f9d21154c 305 int attribSz = 0;
wolfSSL 0:d92f9d21154c 306
wolfSSL 0:d92f9d21154c 307 ea[i].value = attribs[i].value;
wolfSSL 0:d92f9d21154c 308 ea[i].valueSz = attribs[i].valueSz;
wolfSSL 0:d92f9d21154c 309 attribSz += ea[i].valueSz;
wolfSSL 0:d92f9d21154c 310 ea[i].valueSetSz = SetSet(attribSz, ea[i].valueSet);
wolfSSL 0:d92f9d21154c 311 attribSz += ea[i].valueSetSz;
wolfSSL 0:d92f9d21154c 312 ea[i].oid = attribs[i].oid;
wolfSSL 0:d92f9d21154c 313 ea[i].oidSz = attribs[i].oidSz;
wolfSSL 0:d92f9d21154c 314 attribSz += ea[i].oidSz;
wolfSSL 0:d92f9d21154c 315 ea[i].valueSeqSz = SetSequence(attribSz, ea[i].valueSeq);
wolfSSL 0:d92f9d21154c 316 attribSz += ea[i].valueSeqSz;
wolfSSL 0:d92f9d21154c 317 ea[i].totalSz = attribSz;
wolfSSL 0:d92f9d21154c 318
wolfSSL 0:d92f9d21154c 319 allAttribsSz += attribSz;
wolfSSL 0:d92f9d21154c 320 }
wolfSSL 0:d92f9d21154c 321 return allAttribsSz;
wolfSSL 0:d92f9d21154c 322 }
wolfSSL 0:d92f9d21154c 323
wolfSSL 0:d92f9d21154c 324
wolfSSL 0:d92f9d21154c 325 static int FlattenAttributes(byte* output, EncodedAttrib* ea, int eaSz)
wolfSSL 0:d92f9d21154c 326 {
wolfSSL 0:d92f9d21154c 327 int i, idx;
wolfSSL 0:d92f9d21154c 328
wolfSSL 0:d92f9d21154c 329 idx = 0;
wolfSSL 0:d92f9d21154c 330 for (i = 0; i < eaSz; i++) {
wolfSSL 0:d92f9d21154c 331 XMEMCPY(output + idx, ea[i].valueSeq, ea[i].valueSeqSz);
wolfSSL 0:d92f9d21154c 332 idx += ea[i].valueSeqSz;
wolfSSL 0:d92f9d21154c 333 XMEMCPY(output + idx, ea[i].oid, ea[i].oidSz);
wolfSSL 0:d92f9d21154c 334 idx += ea[i].oidSz;
wolfSSL 0:d92f9d21154c 335 XMEMCPY(output + idx, ea[i].valueSet, ea[i].valueSetSz);
wolfSSL 0:d92f9d21154c 336 idx += ea[i].valueSetSz;
wolfSSL 0:d92f9d21154c 337 XMEMCPY(output + idx, ea[i].value, ea[i].valueSz);
wolfSSL 0:d92f9d21154c 338 idx += ea[i].valueSz;
wolfSSL 0:d92f9d21154c 339 }
wolfSSL 0:d92f9d21154c 340 return 0;
wolfSSL 0:d92f9d21154c 341 }
wolfSSL 0:d92f9d21154c 342
wolfSSL 0:d92f9d21154c 343
wolfSSL 0:d92f9d21154c 344 /* build PKCS#7 signedData content type */
wolfSSL 0:d92f9d21154c 345 int wc_PKCS7_EncodeSignedData(PKCS7* pkcs7, byte* output, word32 outputSz)
wolfSSL 0:d92f9d21154c 346 {
wolfSSL 0:d92f9d21154c 347 static const byte outerOid[] =
wolfSSL 0:d92f9d21154c 348 { ASN_OBJECT_ID, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01,
wolfSSL 0:d92f9d21154c 349 0x07, 0x02 };
wolfSSL 0:d92f9d21154c 350 static const byte innerOid[] =
wolfSSL 0:d92f9d21154c 351 { ASN_OBJECT_ID, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01,
wolfSSL 0:d92f9d21154c 352 0x07, 0x01 };
wolfSSL 0:d92f9d21154c 353
wolfSSL 0:d92f9d21154c 354 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 355 ESD* esd = NULL;
wolfSSL 0:d92f9d21154c 356 #else
wolfSSL 0:d92f9d21154c 357 ESD stack_esd;
wolfSSL 0:d92f9d21154c 358 ESD* esd = &stack_esd;
wolfSSL 0:d92f9d21154c 359 #endif
wolfSSL 0:d92f9d21154c 360
wolfSSL 0:d92f9d21154c 361 word32 signerInfoSz = 0;
wolfSSL 0:d92f9d21154c 362 word32 totalSz = 0;
wolfSSL 0:d92f9d21154c 363 int idx = 0, ret = 0;
wolfSSL 0:d92f9d21154c 364 byte* flatSignedAttribs = NULL;
wolfSSL 0:d92f9d21154c 365 word32 flatSignedAttribsSz = 0;
wolfSSL 0:d92f9d21154c 366 word32 innerOidSz = sizeof(innerOid);
wolfSSL 0:d92f9d21154c 367 word32 outerOidSz = sizeof(outerOid);
wolfSSL 0:d92f9d21154c 368
wolfSSL 0:d92f9d21154c 369 if (pkcs7 == NULL || pkcs7->content == NULL || pkcs7->contentSz == 0 ||
wolfSSL 0:d92f9d21154c 370 pkcs7->encryptOID == 0 || pkcs7->hashOID == 0 || pkcs7->rng == 0 ||
wolfSSL 0:d92f9d21154c 371 pkcs7->singleCert == NULL || pkcs7->singleCertSz == 0 ||
wolfSSL 0:d92f9d21154c 372 pkcs7->privateKey == NULL || pkcs7->privateKeySz == 0 ||
wolfSSL 0:d92f9d21154c 373 output == NULL || outputSz == 0)
wolfSSL 0:d92f9d21154c 374 return BAD_FUNC_ARG;
wolfSSL 0:d92f9d21154c 375
wolfSSL 0:d92f9d21154c 376 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 377 esd = (ESD*)XMALLOC(sizeof(ESD), NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 378 if (esd == NULL)
wolfSSL 0:d92f9d21154c 379 return MEMORY_E;
wolfSSL 0:d92f9d21154c 380 #endif
wolfSSL 0:d92f9d21154c 381
wolfSSL 0:d92f9d21154c 382 XMEMSET(esd, 0, sizeof(ESD));
wolfSSL 0:d92f9d21154c 383 ret = wc_InitSha(&esd->sha);
wolfSSL 0:d92f9d21154c 384 if (ret != 0) {
wolfSSL 0:d92f9d21154c 385 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 386 XFREE(esd, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 387 #endif
wolfSSL 0:d92f9d21154c 388 return ret;
wolfSSL 0:d92f9d21154c 389 }
wolfSSL 0:d92f9d21154c 390
wolfSSL 0:d92f9d21154c 391 if (pkcs7->contentSz != 0)
wolfSSL 0:d92f9d21154c 392 {
wolfSSL 0:d92f9d21154c 393 wc_ShaUpdate(&esd->sha, pkcs7->content, pkcs7->contentSz);
wolfSSL 0:d92f9d21154c 394 esd->contentDigest[0] = ASN_OCTET_STRING;
wolfSSL 0:d92f9d21154c 395 esd->contentDigest[1] = SHA_DIGEST_SIZE;
wolfSSL 0:d92f9d21154c 396 wc_ShaFinal(&esd->sha, &esd->contentDigest[2]);
wolfSSL 0:d92f9d21154c 397 }
wolfSSL 0:d92f9d21154c 398
wolfSSL 0:d92f9d21154c 399 esd->innerOctetsSz = SetOctetString(pkcs7->contentSz, esd->innerOctets);
wolfSSL 0:d92f9d21154c 400 esd->innerContSeqSz = SetExplicit(0, esd->innerOctetsSz + pkcs7->contentSz,
wolfSSL 0:d92f9d21154c 401 esd->innerContSeq);
wolfSSL 0:d92f9d21154c 402 esd->contentInfoSeqSz = SetSequence(pkcs7->contentSz + esd->innerOctetsSz +
wolfSSL 0:d92f9d21154c 403 innerOidSz + esd->innerContSeqSz,
wolfSSL 0:d92f9d21154c 404 esd->contentInfoSeq);
wolfSSL 0:d92f9d21154c 405
wolfSSL 0:d92f9d21154c 406 esd->issuerSnSz = SetSerialNumber(pkcs7->issuerSn, pkcs7->issuerSnSz,
wolfSSL 0:d92f9d21154c 407 esd->issuerSn);
wolfSSL 0:d92f9d21154c 408 signerInfoSz += esd->issuerSnSz;
wolfSSL 0:d92f9d21154c 409 esd->issuerNameSz = SetSequence(pkcs7->issuerSz, esd->issuerName);
wolfSSL 0:d92f9d21154c 410 signerInfoSz += esd->issuerNameSz + pkcs7->issuerSz;
wolfSSL 0:d92f9d21154c 411 esd->issuerSnSeqSz = SetSequence(signerInfoSz, esd->issuerSnSeq);
wolfSSL 0:d92f9d21154c 412 signerInfoSz += esd->issuerSnSeqSz;
wolfSSL 0:d92f9d21154c 413 esd->signerVersionSz = SetMyVersion(1, esd->signerVersion, 0);
wolfSSL 0:d92f9d21154c 414 signerInfoSz += esd->signerVersionSz;
wolfSSL 0:d92f9d21154c 415 esd->signerDigAlgoIdSz = SetAlgoID(pkcs7->hashOID, esd->signerDigAlgoId,
wolfSSL 0:d92f9d21154c 416 hashType, 0);
wolfSSL 0:d92f9d21154c 417 signerInfoSz += esd->signerDigAlgoIdSz;
wolfSSL 0:d92f9d21154c 418 esd->digEncAlgoIdSz = SetAlgoID(pkcs7->encryptOID, esd->digEncAlgoId,
wolfSSL 0:d92f9d21154c 419 keyType, 0);
wolfSSL 0:d92f9d21154c 420 signerInfoSz += esd->digEncAlgoIdSz;
wolfSSL 0:d92f9d21154c 421
wolfSSL 0:d92f9d21154c 422 if (pkcs7->signedAttribsSz != 0) {
wolfSSL 0:d92f9d21154c 423 byte contentTypeOid[] =
wolfSSL 0:d92f9d21154c 424 { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xF7, 0x0d, 0x01,
wolfSSL 0:d92f9d21154c 425 0x09, 0x03 };
wolfSSL 0:d92f9d21154c 426 byte contentType[] =
wolfSSL 0:d92f9d21154c 427 { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
wolfSSL 0:d92f9d21154c 428 0x07, 0x01 };
wolfSSL 0:d92f9d21154c 429 byte messageDigestOid[] =
wolfSSL 0:d92f9d21154c 430 { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
wolfSSL 0:d92f9d21154c 431 0x09, 0x04 };
wolfSSL 0:d92f9d21154c 432
wolfSSL 0:d92f9d21154c 433 PKCS7Attrib cannedAttribs[2] =
wolfSSL 0:d92f9d21154c 434 {
wolfSSL 0:d92f9d21154c 435 { contentTypeOid, sizeof(contentTypeOid),
wolfSSL 0:d92f9d21154c 436 contentType, sizeof(contentType) },
wolfSSL 0:d92f9d21154c 437 { messageDigestOid, sizeof(messageDigestOid),
wolfSSL 0:d92f9d21154c 438 esd->contentDigest, sizeof(esd->contentDigest) }
wolfSSL 0:d92f9d21154c 439 };
wolfSSL 0:d92f9d21154c 440 word32 cannedAttribsCount = sizeof(cannedAttribs)/sizeof(PKCS7Attrib);
wolfSSL 0:d92f9d21154c 441
wolfSSL 0:d92f9d21154c 442 esd->signedAttribsCount += cannedAttribsCount;
wolfSSL 0:d92f9d21154c 443 esd->signedAttribsSz += EncodeAttributes(&esd->signedAttribs[0], 2,
wolfSSL 0:d92f9d21154c 444 cannedAttribs, cannedAttribsCount);
wolfSSL 0:d92f9d21154c 445
wolfSSL 0:d92f9d21154c 446 esd->signedAttribsCount += pkcs7->signedAttribsSz;
wolfSSL 0:d92f9d21154c 447 esd->signedAttribsSz += EncodeAttributes(&esd->signedAttribs[2], 4,
wolfSSL 0:d92f9d21154c 448 pkcs7->signedAttribs, pkcs7->signedAttribsSz);
wolfSSL 0:d92f9d21154c 449
wolfSSL 0:d92f9d21154c 450 flatSignedAttribs = (byte*)XMALLOC(esd->signedAttribsSz, 0, NULL);
wolfSSL 0:d92f9d21154c 451 flatSignedAttribsSz = esd->signedAttribsSz;
wolfSSL 0:d92f9d21154c 452 if (flatSignedAttribs == NULL) {
wolfSSL 0:d92f9d21154c 453 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 454 XFREE(esd, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 455 #endif
wolfSSL 0:d92f9d21154c 456 return MEMORY_E;
wolfSSL 0:d92f9d21154c 457 }
wolfSSL 0:d92f9d21154c 458 FlattenAttributes(flatSignedAttribs,
wolfSSL 0:d92f9d21154c 459 esd->signedAttribs, esd->signedAttribsCount);
wolfSSL 0:d92f9d21154c 460 esd->signedAttribSetSz = SetImplicit(ASN_SET, 0, esd->signedAttribsSz,
wolfSSL 0:d92f9d21154c 461 esd->signedAttribSet);
wolfSSL 0:d92f9d21154c 462 }
wolfSSL 0:d92f9d21154c 463 /* Calculate the final hash and encrypt it. */
wolfSSL 0:d92f9d21154c 464 {
wolfSSL 0:d92f9d21154c 465 int result;
wolfSSL 0:d92f9d21154c 466 word32 scratch = 0;
wolfSSL 0:d92f9d21154c 467
wolfSSL 0:d92f9d21154c 468 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 469 byte* digestInfo;
wolfSSL 0:d92f9d21154c 470 RsaKey* privKey;
wolfSSL 0:d92f9d21154c 471 #else
wolfSSL 0:d92f9d21154c 472 RsaKey stack_privKey;
wolfSSL 0:d92f9d21154c 473 RsaKey* privKey = &stack_privKey;
wolfSSL 0:d92f9d21154c 474 byte digestInfo[MAX_SEQ_SZ + MAX_ALGO_SZ +
wolfSSL 0:d92f9d21154c 475 MAX_OCTET_STR_SZ + SHA_DIGEST_SIZE];
wolfSSL 0:d92f9d21154c 476 #endif
wolfSSL 0:d92f9d21154c 477 byte digestInfoSeq[MAX_SEQ_SZ];
wolfSSL 0:d92f9d21154c 478 byte digestStr[MAX_OCTET_STR_SZ];
wolfSSL 0:d92f9d21154c 479 word32 digestInfoSeqSz, digestStrSz;
wolfSSL 0:d92f9d21154c 480 int digIdx = 0;
wolfSSL 0:d92f9d21154c 481
wolfSSL 0:d92f9d21154c 482 if (pkcs7->signedAttribsSz != 0) {
wolfSSL 0:d92f9d21154c 483 byte attribSet[MAX_SET_SZ];
wolfSSL 0:d92f9d21154c 484 word32 attribSetSz;
wolfSSL 0:d92f9d21154c 485
wolfSSL 0:d92f9d21154c 486 attribSetSz = SetSet(flatSignedAttribsSz, attribSet);
wolfSSL 0:d92f9d21154c 487
wolfSSL 0:d92f9d21154c 488 ret = wc_InitSha(&esd->sha);
wolfSSL 0:d92f9d21154c 489 if (ret < 0) {
wolfSSL 0:d92f9d21154c 490 XFREE(flatSignedAttribs, 0, NULL);
wolfSSL 0:d92f9d21154c 491 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 492 XFREE(esd, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 493 #endif
wolfSSL 0:d92f9d21154c 494 return ret;
wolfSSL 0:d92f9d21154c 495 }
wolfSSL 0:d92f9d21154c 496 wc_ShaUpdate(&esd->sha, attribSet, attribSetSz);
wolfSSL 0:d92f9d21154c 497 wc_ShaUpdate(&esd->sha, flatSignedAttribs, flatSignedAttribsSz);
wolfSSL 0:d92f9d21154c 498 }
wolfSSL 0:d92f9d21154c 499 wc_ShaFinal(&esd->sha, esd->contentAttribsDigest);
wolfSSL 0:d92f9d21154c 500
wolfSSL 0:d92f9d21154c 501 digestStrSz = SetOctetString(SHA_DIGEST_SIZE, digestStr);
wolfSSL 0:d92f9d21154c 502 digestInfoSeqSz = SetSequence(esd->signerDigAlgoIdSz +
wolfSSL 0:d92f9d21154c 503 digestStrSz + SHA_DIGEST_SIZE,
wolfSSL 0:d92f9d21154c 504 digestInfoSeq);
wolfSSL 0:d92f9d21154c 505
wolfSSL 0:d92f9d21154c 506 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 507 digestInfo = (byte*)XMALLOC(MAX_SEQ_SZ + MAX_ALGO_SZ +
wolfSSL 0:d92f9d21154c 508 MAX_OCTET_STR_SZ + SHA_DIGEST_SIZE,
wolfSSL 0:d92f9d21154c 509 NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 510 if (digestInfo == NULL) {
wolfSSL 0:d92f9d21154c 511 if (pkcs7->signedAttribsSz != 0)
wolfSSL 0:d92f9d21154c 512 XFREE(flatSignedAttribs, 0, NULL);
wolfSSL 0:d92f9d21154c 513 XFREE(esd, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 514 return MEMORY_E;
wolfSSL 0:d92f9d21154c 515 }
wolfSSL 0:d92f9d21154c 516 #endif
wolfSSL 0:d92f9d21154c 517
wolfSSL 0:d92f9d21154c 518 XMEMCPY(digestInfo + digIdx, digestInfoSeq, digestInfoSeqSz);
wolfSSL 0:d92f9d21154c 519 digIdx += digestInfoSeqSz;
wolfSSL 0:d92f9d21154c 520 XMEMCPY(digestInfo + digIdx,
wolfSSL 0:d92f9d21154c 521 esd->signerDigAlgoId, esd->signerDigAlgoIdSz);
wolfSSL 0:d92f9d21154c 522 digIdx += esd->signerDigAlgoIdSz;
wolfSSL 0:d92f9d21154c 523 XMEMCPY(digestInfo + digIdx, digestStr, digestStrSz);
wolfSSL 0:d92f9d21154c 524 digIdx += digestStrSz;
wolfSSL 0:d92f9d21154c 525 XMEMCPY(digestInfo + digIdx, esd->contentAttribsDigest,
wolfSSL 0:d92f9d21154c 526 SHA_DIGEST_SIZE);
wolfSSL 0:d92f9d21154c 527 digIdx += SHA_DIGEST_SIZE;
wolfSSL 0:d92f9d21154c 528
wolfSSL 0:d92f9d21154c 529 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 530 privKey = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL,
wolfSSL 0:d92f9d21154c 531 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 532 if (privKey == NULL) {
wolfSSL 0:d92f9d21154c 533 if (pkcs7->signedAttribsSz != 0)
wolfSSL 0:d92f9d21154c 534 XFREE(flatSignedAttribs, 0, NULL);
wolfSSL 0:d92f9d21154c 535 XFREE(digestInfo, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 536 XFREE(esd, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 537 return MEMORY_E;
wolfSSL 0:d92f9d21154c 538 }
wolfSSL 0:d92f9d21154c 539 #endif
wolfSSL 0:d92f9d21154c 540
wolfSSL 0:d92f9d21154c 541 result = wc_InitRsaKey(privKey, NULL);
wolfSSL 0:d92f9d21154c 542 if (result == 0)
wolfSSL 0:d92f9d21154c 543 result = wc_RsaPrivateKeyDecode(pkcs7->privateKey, &scratch, privKey,
wolfSSL 0:d92f9d21154c 544 pkcs7->privateKeySz);
wolfSSL 0:d92f9d21154c 545 if (result < 0) {
wolfSSL 0:d92f9d21154c 546 if (pkcs7->signedAttribsSz != 0)
wolfSSL 0:d92f9d21154c 547 XFREE(flatSignedAttribs, 0, NULL);
wolfSSL 0:d92f9d21154c 548 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 549 XFREE(privKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 550 XFREE(digestInfo, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 551 XFREE(esd, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 552 #endif
wolfSSL 0:d92f9d21154c 553 return PUBLIC_KEY_E;
wolfSSL 0:d92f9d21154c 554 }
wolfSSL 0:d92f9d21154c 555
wolfSSL 0:d92f9d21154c 556 result = wc_RsaSSL_Sign(digestInfo, digIdx,
wolfSSL 0:d92f9d21154c 557 esd->encContentDigest,
wolfSSL 0:d92f9d21154c 558 sizeof(esd->encContentDigest),
wolfSSL 0:d92f9d21154c 559 privKey, pkcs7->rng);
wolfSSL 0:d92f9d21154c 560
wolfSSL 0:d92f9d21154c 561 wc_FreeRsaKey(privKey);
wolfSSL 0:d92f9d21154c 562
wolfSSL 0:d92f9d21154c 563 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 564 XFREE(privKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 565 XFREE(digestInfo, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 566 #endif
wolfSSL 0:d92f9d21154c 567
wolfSSL 0:d92f9d21154c 568 if (result < 0) {
wolfSSL 0:d92f9d21154c 569 if (pkcs7->signedAttribsSz != 0)
wolfSSL 0:d92f9d21154c 570 XFREE(flatSignedAttribs, 0, NULL);
wolfSSL 0:d92f9d21154c 571 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 572 XFREE(esd, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 573 #endif
wolfSSL 0:d92f9d21154c 574 return result;
wolfSSL 0:d92f9d21154c 575 }
wolfSSL 0:d92f9d21154c 576 esd->encContentDigestSz = (word32)result;
wolfSSL 0:d92f9d21154c 577 }
wolfSSL 0:d92f9d21154c 578 signerInfoSz += flatSignedAttribsSz + esd->signedAttribSetSz;
wolfSSL 0:d92f9d21154c 579
wolfSSL 0:d92f9d21154c 580 esd->signerDigestSz = SetOctetString(esd->encContentDigestSz,
wolfSSL 0:d92f9d21154c 581 esd->signerDigest);
wolfSSL 0:d92f9d21154c 582 signerInfoSz += esd->signerDigestSz + esd->encContentDigestSz;
wolfSSL 0:d92f9d21154c 583
wolfSSL 0:d92f9d21154c 584 esd->signerInfoSeqSz = SetSequence(signerInfoSz, esd->signerInfoSeq);
wolfSSL 0:d92f9d21154c 585 signerInfoSz += esd->signerInfoSeqSz;
wolfSSL 0:d92f9d21154c 586 esd->signerInfoSetSz = SetSet(signerInfoSz, esd->signerInfoSet);
wolfSSL 0:d92f9d21154c 587 signerInfoSz += esd->signerInfoSetSz;
wolfSSL 0:d92f9d21154c 588
wolfSSL 0:d92f9d21154c 589 esd->certsSetSz = SetImplicit(ASN_SET, 0, pkcs7->singleCertSz,
wolfSSL 0:d92f9d21154c 590 esd->certsSet);
wolfSSL 0:d92f9d21154c 591
wolfSSL 0:d92f9d21154c 592 esd->singleDigAlgoIdSz = SetAlgoID(pkcs7->hashOID, esd->singleDigAlgoId,
wolfSSL 0:d92f9d21154c 593 hashType, 0);
wolfSSL 0:d92f9d21154c 594 esd->digAlgoIdSetSz = SetSet(esd->singleDigAlgoIdSz, esd->digAlgoIdSet);
wolfSSL 0:d92f9d21154c 595
wolfSSL 0:d92f9d21154c 596
wolfSSL 0:d92f9d21154c 597 esd->versionSz = SetMyVersion(1, esd->version, 0);
wolfSSL 0:d92f9d21154c 598
wolfSSL 0:d92f9d21154c 599 totalSz = esd->versionSz + esd->singleDigAlgoIdSz + esd->digAlgoIdSetSz +
wolfSSL 0:d92f9d21154c 600 esd->contentInfoSeqSz + esd->certsSetSz + pkcs7->singleCertSz +
wolfSSL 0:d92f9d21154c 601 esd->innerOctetsSz + esd->innerContSeqSz +
wolfSSL 0:d92f9d21154c 602 innerOidSz + pkcs7->contentSz +
wolfSSL 0:d92f9d21154c 603 signerInfoSz;
wolfSSL 0:d92f9d21154c 604 esd->innerSeqSz = SetSequence(totalSz, esd->innerSeq);
wolfSSL 0:d92f9d21154c 605 totalSz += esd->innerSeqSz;
wolfSSL 0:d92f9d21154c 606 esd->outerContentSz = SetExplicit(0, totalSz, esd->outerContent);
wolfSSL 0:d92f9d21154c 607 totalSz += esd->outerContentSz + outerOidSz;
wolfSSL 0:d92f9d21154c 608 esd->outerSeqSz = SetSequence(totalSz, esd->outerSeq);
wolfSSL 0:d92f9d21154c 609 totalSz += esd->outerSeqSz;
wolfSSL 0:d92f9d21154c 610
wolfSSL 0:d92f9d21154c 611 if (outputSz < totalSz) {
wolfSSL 0:d92f9d21154c 612 if (pkcs7->signedAttribsSz != 0)
wolfSSL 0:d92f9d21154c 613 XFREE(flatSignedAttribs, 0, NULL);
wolfSSL 0:d92f9d21154c 614 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 615 XFREE(esd, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 616 #endif
wolfSSL 0:d92f9d21154c 617 return BUFFER_E;
wolfSSL 0:d92f9d21154c 618 }
wolfSSL 0:d92f9d21154c 619
wolfSSL 0:d92f9d21154c 620 idx = 0;
wolfSSL 0:d92f9d21154c 621 XMEMCPY(output + idx, esd->outerSeq, esd->outerSeqSz);
wolfSSL 0:d92f9d21154c 622 idx += esd->outerSeqSz;
wolfSSL 0:d92f9d21154c 623 XMEMCPY(output + idx, outerOid, outerOidSz);
wolfSSL 0:d92f9d21154c 624 idx += outerOidSz;
wolfSSL 0:d92f9d21154c 625 XMEMCPY(output + idx, esd->outerContent, esd->outerContentSz);
wolfSSL 0:d92f9d21154c 626 idx += esd->outerContentSz;
wolfSSL 0:d92f9d21154c 627 XMEMCPY(output + idx, esd->innerSeq, esd->innerSeqSz);
wolfSSL 0:d92f9d21154c 628 idx += esd->innerSeqSz;
wolfSSL 0:d92f9d21154c 629 XMEMCPY(output + idx, esd->version, esd->versionSz);
wolfSSL 0:d92f9d21154c 630 idx += esd->versionSz;
wolfSSL 0:d92f9d21154c 631 XMEMCPY(output + idx, esd->digAlgoIdSet, esd->digAlgoIdSetSz);
wolfSSL 0:d92f9d21154c 632 idx += esd->digAlgoIdSetSz;
wolfSSL 0:d92f9d21154c 633 XMEMCPY(output + idx, esd->singleDigAlgoId, esd->singleDigAlgoIdSz);
wolfSSL 0:d92f9d21154c 634 idx += esd->singleDigAlgoIdSz;
wolfSSL 0:d92f9d21154c 635 XMEMCPY(output + idx, esd->contentInfoSeq, esd->contentInfoSeqSz);
wolfSSL 0:d92f9d21154c 636 idx += esd->contentInfoSeqSz;
wolfSSL 0:d92f9d21154c 637 XMEMCPY(output + idx, innerOid, innerOidSz);
wolfSSL 0:d92f9d21154c 638 idx += innerOidSz;
wolfSSL 0:d92f9d21154c 639 XMEMCPY(output + idx, esd->innerContSeq, esd->innerContSeqSz);
wolfSSL 0:d92f9d21154c 640 idx += esd->innerContSeqSz;
wolfSSL 0:d92f9d21154c 641 XMEMCPY(output + idx, esd->innerOctets, esd->innerOctetsSz);
wolfSSL 0:d92f9d21154c 642 idx += esd->innerOctetsSz;
wolfSSL 0:d92f9d21154c 643 XMEMCPY(output + idx, pkcs7->content, pkcs7->contentSz);
wolfSSL 0:d92f9d21154c 644 idx += pkcs7->contentSz;
wolfSSL 0:d92f9d21154c 645 XMEMCPY(output + idx, esd->certsSet, esd->certsSetSz);
wolfSSL 0:d92f9d21154c 646 idx += esd->certsSetSz;
wolfSSL 0:d92f9d21154c 647 XMEMCPY(output + idx, pkcs7->singleCert, pkcs7->singleCertSz);
wolfSSL 0:d92f9d21154c 648 idx += pkcs7->singleCertSz;
wolfSSL 0:d92f9d21154c 649 XMEMCPY(output + idx, esd->signerInfoSet, esd->signerInfoSetSz);
wolfSSL 0:d92f9d21154c 650 idx += esd->signerInfoSetSz;
wolfSSL 0:d92f9d21154c 651 XMEMCPY(output + idx, esd->signerInfoSeq, esd->signerInfoSeqSz);
wolfSSL 0:d92f9d21154c 652 idx += esd->signerInfoSeqSz;
wolfSSL 0:d92f9d21154c 653 XMEMCPY(output + idx, esd->signerVersion, esd->signerVersionSz);
wolfSSL 0:d92f9d21154c 654 idx += esd->signerVersionSz;
wolfSSL 0:d92f9d21154c 655 XMEMCPY(output + idx, esd->issuerSnSeq, esd->issuerSnSeqSz);
wolfSSL 0:d92f9d21154c 656 idx += esd->issuerSnSeqSz;
wolfSSL 0:d92f9d21154c 657 XMEMCPY(output + idx, esd->issuerName, esd->issuerNameSz);
wolfSSL 0:d92f9d21154c 658 idx += esd->issuerNameSz;
wolfSSL 0:d92f9d21154c 659 XMEMCPY(output + idx, pkcs7->issuer, pkcs7->issuerSz);
wolfSSL 0:d92f9d21154c 660 idx += pkcs7->issuerSz;
wolfSSL 0:d92f9d21154c 661 XMEMCPY(output + idx, esd->issuerSn, esd->issuerSnSz);
wolfSSL 0:d92f9d21154c 662 idx += esd->issuerSnSz;
wolfSSL 0:d92f9d21154c 663 XMEMCPY(output + idx, esd->signerDigAlgoId, esd->signerDigAlgoIdSz);
wolfSSL 0:d92f9d21154c 664 idx += esd->signerDigAlgoIdSz;
wolfSSL 0:d92f9d21154c 665
wolfSSL 0:d92f9d21154c 666 /* SignerInfo:Attributes */
wolfSSL 0:d92f9d21154c 667 if (pkcs7->signedAttribsSz != 0) {
wolfSSL 0:d92f9d21154c 668 XMEMCPY(output + idx, esd->signedAttribSet, esd->signedAttribSetSz);
wolfSSL 0:d92f9d21154c 669 idx += esd->signedAttribSetSz;
wolfSSL 0:d92f9d21154c 670 XMEMCPY(output + idx, flatSignedAttribs, flatSignedAttribsSz);
wolfSSL 0:d92f9d21154c 671 idx += flatSignedAttribsSz;
wolfSSL 0:d92f9d21154c 672 XFREE(flatSignedAttribs, 0, NULL);
wolfSSL 0:d92f9d21154c 673 }
wolfSSL 0:d92f9d21154c 674
wolfSSL 0:d92f9d21154c 675 XMEMCPY(output + idx, esd->digEncAlgoId, esd->digEncAlgoIdSz);
wolfSSL 0:d92f9d21154c 676 idx += esd->digEncAlgoIdSz;
wolfSSL 0:d92f9d21154c 677 XMEMCPY(output + idx, esd->signerDigest, esd->signerDigestSz);
wolfSSL 0:d92f9d21154c 678 idx += esd->signerDigestSz;
wolfSSL 0:d92f9d21154c 679 XMEMCPY(output + idx, esd->encContentDigest, esd->encContentDigestSz);
wolfSSL 0:d92f9d21154c 680 idx += esd->encContentDigestSz;
wolfSSL 0:d92f9d21154c 681
wolfSSL 0:d92f9d21154c 682 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 683 XFREE(esd, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 684 #endif
wolfSSL 0:d92f9d21154c 685
wolfSSL 0:d92f9d21154c 686 return idx;
wolfSSL 0:d92f9d21154c 687 }
wolfSSL 0:d92f9d21154c 688
wolfSSL 0:d92f9d21154c 689
wolfSSL 0:d92f9d21154c 690 /* Finds the certificates in the message and saves it. */
wolfSSL 0:d92f9d21154c 691 int wc_PKCS7_VerifySignedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz)
wolfSSL 0:d92f9d21154c 692 {
wolfSSL 0:d92f9d21154c 693 word32 idx, contentType;
wolfSSL 0:d92f9d21154c 694 int length, version, ret;
wolfSSL 0:d92f9d21154c 695 byte* content = NULL;
wolfSSL 0:d92f9d21154c 696 byte* sig = NULL;
wolfSSL 0:d92f9d21154c 697 byte* cert = NULL;
wolfSSL 0:d92f9d21154c 698 int contentSz = 0, sigSz = 0, certSz = 0;
wolfSSL 0:d92f9d21154c 699
wolfSSL 0:d92f9d21154c 700 if (pkcs7 == NULL || pkiMsg == NULL || pkiMsgSz == 0)
wolfSSL 0:d92f9d21154c 701 return BAD_FUNC_ARG;
wolfSSL 0:d92f9d21154c 702
wolfSSL 0:d92f9d21154c 703 idx = 0;
wolfSSL 0:d92f9d21154c 704
wolfSSL 0:d92f9d21154c 705 /* Get the contentInfo sequence */
wolfSSL 0:d92f9d21154c 706 if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
wolfSSL 0:d92f9d21154c 707 return ASN_PARSE_E;
wolfSSL 0:d92f9d21154c 708
wolfSSL 0:d92f9d21154c 709 /* Get the contentInfo contentType */
wolfSSL 0:d92f9d21154c 710 if (wc_GetContentType(pkiMsg, &idx, &contentType, pkiMsgSz) < 0)
wolfSSL 0:d92f9d21154c 711 return ASN_PARSE_E;
wolfSSL 0:d92f9d21154c 712
wolfSSL 0:d92f9d21154c 713 if (contentType != SIGNED_DATA) {
wolfSSL 0:d92f9d21154c 714 WOLFSSL_MSG("PKCS#7 input not of type SignedData");
wolfSSL 0:d92f9d21154c 715 return PKCS7_OID_E;
wolfSSL 0:d92f9d21154c 716 }
wolfSSL 0:d92f9d21154c 717
wolfSSL 0:d92f9d21154c 718 /* get the ContentInfo content */
wolfSSL 0:d92f9d21154c 719 if (pkiMsg[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
wolfSSL 0:d92f9d21154c 720 return ASN_PARSE_E;
wolfSSL 0:d92f9d21154c 721
wolfSSL 0:d92f9d21154c 722 if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
wolfSSL 0:d92f9d21154c 723 return ASN_PARSE_E;
wolfSSL 0:d92f9d21154c 724
wolfSSL 0:d92f9d21154c 725 /* Get the signedData sequence */
wolfSSL 0:d92f9d21154c 726 if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
wolfSSL 0:d92f9d21154c 727 return ASN_PARSE_E;
wolfSSL 0:d92f9d21154c 728
wolfSSL 0:d92f9d21154c 729 /* Get the version */
wolfSSL 0:d92f9d21154c 730 if (GetMyVersion(pkiMsg, &idx, &version) < 0)
wolfSSL 0:d92f9d21154c 731 return ASN_PARSE_E;
wolfSSL 0:d92f9d21154c 732
wolfSSL 0:d92f9d21154c 733 if (version != 1) {
wolfSSL 0:d92f9d21154c 734 WOLFSSL_MSG("PKCS#7 signedData needs to be of version 1");
wolfSSL 0:d92f9d21154c 735 return ASN_VERSION_E;
wolfSSL 0:d92f9d21154c 736 }
wolfSSL 0:d92f9d21154c 737
wolfSSL 0:d92f9d21154c 738 /* Get the set of DigestAlgorithmIdentifiers */
wolfSSL 0:d92f9d21154c 739 if (GetSet(pkiMsg, &idx, &length, pkiMsgSz) < 0)
wolfSSL 0:d92f9d21154c 740 return ASN_PARSE_E;
wolfSSL 0:d92f9d21154c 741
wolfSSL 0:d92f9d21154c 742 /* Skip the set. */
wolfSSL 0:d92f9d21154c 743 idx += length;
wolfSSL 0:d92f9d21154c 744
wolfSSL 0:d92f9d21154c 745 /* Get the inner ContentInfo sequence */
wolfSSL 0:d92f9d21154c 746 if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
wolfSSL 0:d92f9d21154c 747 return ASN_PARSE_E;
wolfSSL 0:d92f9d21154c 748
wolfSSL 0:d92f9d21154c 749 /* Get the inner ContentInfo contentType */
wolfSSL 0:d92f9d21154c 750 if (wc_GetContentType(pkiMsg, &idx, &contentType, pkiMsgSz) < 0)
wolfSSL 0:d92f9d21154c 751 return ASN_PARSE_E;
wolfSSL 0:d92f9d21154c 752
wolfSSL 0:d92f9d21154c 753 if (contentType != DATA) {
wolfSSL 0:d92f9d21154c 754 WOLFSSL_MSG("PKCS#7 inner input not of type Data");
wolfSSL 0:d92f9d21154c 755 return PKCS7_OID_E;
wolfSSL 0:d92f9d21154c 756 }
wolfSSL 0:d92f9d21154c 757
wolfSSL 0:d92f9d21154c 758 if (pkiMsg[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
wolfSSL 0:d92f9d21154c 759 return ASN_PARSE_E;
wolfSSL 0:d92f9d21154c 760
wolfSSL 0:d92f9d21154c 761 if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
wolfSSL 0:d92f9d21154c 762 return ASN_PARSE_E;
wolfSSL 0:d92f9d21154c 763
wolfSSL 0:d92f9d21154c 764 if (pkiMsg[idx++] != ASN_OCTET_STRING)
wolfSSL 0:d92f9d21154c 765 return ASN_PARSE_E;
wolfSSL 0:d92f9d21154c 766
wolfSSL 0:d92f9d21154c 767 if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
wolfSSL 0:d92f9d21154c 768 return ASN_PARSE_E;
wolfSSL 0:d92f9d21154c 769
wolfSSL 0:d92f9d21154c 770 /* Save the inner data as the content. */
wolfSSL 0:d92f9d21154c 771 if (length > 0) {
wolfSSL 0:d92f9d21154c 772 /* Local pointer for calculating hashes later */
wolfSSL 0:d92f9d21154c 773 pkcs7->content = content = &pkiMsg[idx];
wolfSSL 0:d92f9d21154c 774 pkcs7->contentSz = contentSz = length;
wolfSSL 0:d92f9d21154c 775 idx += length;
wolfSSL 0:d92f9d21154c 776 }
wolfSSL 0:d92f9d21154c 777
wolfSSL 0:d92f9d21154c 778 /* Get the implicit[0] set of certificates */
wolfSSL 0:d92f9d21154c 779 if (pkiMsg[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) {
wolfSSL 0:d92f9d21154c 780 idx++;
wolfSSL 0:d92f9d21154c 781 if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
wolfSSL 0:d92f9d21154c 782 return ASN_PARSE_E;
wolfSSL 0:d92f9d21154c 783
wolfSSL 0:d92f9d21154c 784 if (length > 0) {
wolfSSL 0:d92f9d21154c 785 /* At this point, idx is at the first certificate in
wolfSSL 0:d92f9d21154c 786 * a set of certificates. There may be more than one,
wolfSSL 0:d92f9d21154c 787 * or none, or they may be a PKCS 6 extended
wolfSSL 0:d92f9d21154c 788 * certificate. We want to save the first cert if it
wolfSSL 0:d92f9d21154c 789 * is X.509. */
wolfSSL 0:d92f9d21154c 790
wolfSSL 0:d92f9d21154c 791 word32 certIdx = idx;
wolfSSL 0:d92f9d21154c 792
wolfSSL 0:d92f9d21154c 793 if (pkiMsg[certIdx++] == (ASN_CONSTRUCTED | ASN_SEQUENCE)) {
wolfSSL 0:d92f9d21154c 794 if (GetLength(pkiMsg, &certIdx, &certSz, pkiMsgSz) < 0)
wolfSSL 0:d92f9d21154c 795 return ASN_PARSE_E;
wolfSSL 0:d92f9d21154c 796
wolfSSL 0:d92f9d21154c 797 cert = &pkiMsg[idx];
wolfSSL 0:d92f9d21154c 798 certSz += (certIdx - idx);
wolfSSL 0:d92f9d21154c 799 }
wolfSSL 0:d92f9d21154c 800 wc_PKCS7_InitWithCert(pkcs7, cert, certSz);
wolfSSL 0:d92f9d21154c 801 }
wolfSSL 0:d92f9d21154c 802 idx += length;
wolfSSL 0:d92f9d21154c 803 }
wolfSSL 0:d92f9d21154c 804
wolfSSL 0:d92f9d21154c 805 /* Get the implicit[1] set of crls */
wolfSSL 0:d92f9d21154c 806 if (pkiMsg[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) {
wolfSSL 0:d92f9d21154c 807 idx++;
wolfSSL 0:d92f9d21154c 808 if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
wolfSSL 0:d92f9d21154c 809 return ASN_PARSE_E;
wolfSSL 0:d92f9d21154c 810
wolfSSL 0:d92f9d21154c 811 /* Skip the set */
wolfSSL 0:d92f9d21154c 812 idx += length;
wolfSSL 0:d92f9d21154c 813 }
wolfSSL 0:d92f9d21154c 814
wolfSSL 0:d92f9d21154c 815 /* Get the set of signerInfos */
wolfSSL 0:d92f9d21154c 816 if (GetSet(pkiMsg, &idx, &length, pkiMsgSz) < 0)
wolfSSL 0:d92f9d21154c 817 return ASN_PARSE_E;
wolfSSL 0:d92f9d21154c 818
wolfSSL 0:d92f9d21154c 819 if (length > 0) {
wolfSSL 0:d92f9d21154c 820 /* Get the sequence of the first signerInfo */
wolfSSL 0:d92f9d21154c 821 if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
wolfSSL 0:d92f9d21154c 822 return ASN_PARSE_E;
wolfSSL 0:d92f9d21154c 823
wolfSSL 0:d92f9d21154c 824 /* Get the version */
wolfSSL 0:d92f9d21154c 825 if (GetMyVersion(pkiMsg, &idx, &version) < 0)
wolfSSL 0:d92f9d21154c 826 return ASN_PARSE_E;
wolfSSL 0:d92f9d21154c 827
wolfSSL 0:d92f9d21154c 828 if (version != 1) {
wolfSSL 0:d92f9d21154c 829 WOLFSSL_MSG("PKCS#7 signerInfo needs to be of version 1");
wolfSSL 0:d92f9d21154c 830 return ASN_VERSION_E;
wolfSSL 0:d92f9d21154c 831 }
wolfSSL 0:d92f9d21154c 832
wolfSSL 0:d92f9d21154c 833 /* Get the sequence of IssuerAndSerialNumber */
wolfSSL 0:d92f9d21154c 834 if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
wolfSSL 0:d92f9d21154c 835 return ASN_PARSE_E;
wolfSSL 0:d92f9d21154c 836
wolfSSL 0:d92f9d21154c 837 /* Skip it */
wolfSSL 0:d92f9d21154c 838 idx += length;
wolfSSL 0:d92f9d21154c 839
wolfSSL 0:d92f9d21154c 840 /* Get the sequence of digestAlgorithm */
wolfSSL 0:d92f9d21154c 841 if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
wolfSSL 0:d92f9d21154c 842 return ASN_PARSE_E;
wolfSSL 0:d92f9d21154c 843
wolfSSL 0:d92f9d21154c 844 /* Skip it */
wolfSSL 0:d92f9d21154c 845 idx += length;
wolfSSL 0:d92f9d21154c 846
wolfSSL 0:d92f9d21154c 847 /* Get the IMPLICIT[0] SET OF signedAttributes */
wolfSSL 0:d92f9d21154c 848 if (pkiMsg[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) {
wolfSSL 0:d92f9d21154c 849 idx++;
wolfSSL 0:d92f9d21154c 850
wolfSSL 0:d92f9d21154c 851 if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
wolfSSL 0:d92f9d21154c 852 return ASN_PARSE_E;
wolfSSL 0:d92f9d21154c 853
wolfSSL 0:d92f9d21154c 854 idx += length;
wolfSSL 0:d92f9d21154c 855 }
wolfSSL 0:d92f9d21154c 856
wolfSSL 0:d92f9d21154c 857 /* Get the sequence of digestEncryptionAlgorithm */
wolfSSL 0:d92f9d21154c 858 if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
wolfSSL 0:d92f9d21154c 859 return ASN_PARSE_E;
wolfSSL 0:d92f9d21154c 860
wolfSSL 0:d92f9d21154c 861 /* Skip it */
wolfSSL 0:d92f9d21154c 862 idx += length;
wolfSSL 0:d92f9d21154c 863
wolfSSL 0:d92f9d21154c 864 /* Get the signature */
wolfSSL 0:d92f9d21154c 865 if (pkiMsg[idx] == ASN_OCTET_STRING) {
wolfSSL 0:d92f9d21154c 866 idx++;
wolfSSL 0:d92f9d21154c 867
wolfSSL 0:d92f9d21154c 868 if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
wolfSSL 0:d92f9d21154c 869 return ASN_PARSE_E;
wolfSSL 0:d92f9d21154c 870
wolfSSL 0:d92f9d21154c 871 /* save pointer and length */
wolfSSL 0:d92f9d21154c 872 sig = &pkiMsg[idx];
wolfSSL 0:d92f9d21154c 873 sigSz = length;
wolfSSL 0:d92f9d21154c 874
wolfSSL 0:d92f9d21154c 875 idx += length;
wolfSSL 0:d92f9d21154c 876 }
wolfSSL 0:d92f9d21154c 877
wolfSSL 0:d92f9d21154c 878 pkcs7->content = content;
wolfSSL 0:d92f9d21154c 879 pkcs7->contentSz = contentSz;
wolfSSL 0:d92f9d21154c 880
wolfSSL 0:d92f9d21154c 881 {
wolfSSL 0:d92f9d21154c 882 word32 scratch = 0;
wolfSSL 0:d92f9d21154c 883 int plainSz = 0;
wolfSSL 0:d92f9d21154c 884 int digestSz = MAX_SEQ_SZ + MAX_ALGO_SZ +
wolfSSL 0:d92f9d21154c 885 MAX_OCTET_STR_SZ + SHA_DIGEST_SIZE;
wolfSSL 0:d92f9d21154c 886
wolfSSL 0:d92f9d21154c 887 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 888 byte* digest;
wolfSSL 0:d92f9d21154c 889 RsaKey* key;
wolfSSL 0:d92f9d21154c 890
wolfSSL 0:d92f9d21154c 891 digest = (byte*)XMALLOC(digestSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 892
wolfSSL 0:d92f9d21154c 893 if (digest == NULL)
wolfSSL 0:d92f9d21154c 894 return MEMORY_E;
wolfSSL 0:d92f9d21154c 895
wolfSSL 0:d92f9d21154c 896 key = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL,
wolfSSL 0:d92f9d21154c 897 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 898 if (key == NULL) {
wolfSSL 0:d92f9d21154c 899 XFREE(digest, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 900 return MEMORY_E;
wolfSSL 0:d92f9d21154c 901 }
wolfSSL 0:d92f9d21154c 902 #else
wolfSSL 0:d92f9d21154c 903 byte digest[digestSz];
wolfSSL 0:d92f9d21154c 904 RsaKey stack_key;
wolfSSL 0:d92f9d21154c 905 RsaKey* key = &stack_key;
wolfSSL 0:d92f9d21154c 906 #endif
wolfSSL 0:d92f9d21154c 907
wolfSSL 0:d92f9d21154c 908 XMEMSET(digest, 0, digestSz);
wolfSSL 0:d92f9d21154c 909
wolfSSL 0:d92f9d21154c 910 ret = wc_InitRsaKey(key, NULL);
wolfSSL 0:d92f9d21154c 911 if (ret != 0) {
wolfSSL 0:d92f9d21154c 912 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 913 XFREE(digest, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 914 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 915 #endif
wolfSSL 0:d92f9d21154c 916 return ret;
wolfSSL 0:d92f9d21154c 917 }
wolfSSL 0:d92f9d21154c 918 if (wc_RsaPublicKeyDecode(pkcs7->publicKey, &scratch, key,
wolfSSL 0:d92f9d21154c 919 pkcs7->publicKeySz) < 0) {
wolfSSL 0:d92f9d21154c 920 WOLFSSL_MSG("ASN RSA key decode error");
wolfSSL 0:d92f9d21154c 921 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 922 XFREE(digest, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 923 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 924 #endif
wolfSSL 0:d92f9d21154c 925 return PUBLIC_KEY_E;
wolfSSL 0:d92f9d21154c 926 }
wolfSSL 0:d92f9d21154c 927
wolfSSL 0:d92f9d21154c 928 plainSz = wc_RsaSSL_Verify(sig, sigSz, digest, digestSz, key);
wolfSSL 0:d92f9d21154c 929 wc_FreeRsaKey(key);
wolfSSL 0:d92f9d21154c 930
wolfSSL 0:d92f9d21154c 931 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 932 XFREE(digest, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 933 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 934 #endif
wolfSSL 0:d92f9d21154c 935
wolfSSL 0:d92f9d21154c 936 if (plainSz < 0)
wolfSSL 0:d92f9d21154c 937 return plainSz;
wolfSSL 0:d92f9d21154c 938 }
wolfSSL 0:d92f9d21154c 939 }
wolfSSL 0:d92f9d21154c 940
wolfSSL 0:d92f9d21154c 941 return 0;
wolfSSL 0:d92f9d21154c 942 }
wolfSSL 0:d92f9d21154c 943
wolfSSL 0:d92f9d21154c 944
wolfSSL 0:d92f9d21154c 945 /* create ASN.1 fomatted RecipientInfo structure, returns sequence size */
wolfSSL 0:d92f9d21154c 946 WOLFSSL_LOCAL int wc_CreateRecipientInfo(const byte* cert, word32 certSz,
wolfSSL 0:d92f9d21154c 947 int keyEncAlgo, int blockKeySz,
wolfSSL 0:d92f9d21154c 948 RNG* rng, byte* contentKeyPlain,
wolfSSL 0:d92f9d21154c 949 byte* contentKeyEnc,
wolfSSL 0:d92f9d21154c 950 int* keyEncSz, byte* out, word32 outSz)
wolfSSL 0:d92f9d21154c 951 {
wolfSSL 0:d92f9d21154c 952 word32 idx = 0;
wolfSSL 0:d92f9d21154c 953 int ret = 0, totalSz = 0;
wolfSSL 0:d92f9d21154c 954 int verSz, issuerSz, snSz, keyEncAlgSz;
wolfSSL 0:d92f9d21154c 955 int issuerSeqSz, recipSeqSz, issuerSerialSeqSz;
wolfSSL 0:d92f9d21154c 956 int encKeyOctetStrSz;
wolfSSL 0:d92f9d21154c 957
wolfSSL 0:d92f9d21154c 958 byte ver[MAX_VERSION_SZ];
wolfSSL 0:d92f9d21154c 959 byte issuerSerialSeq[MAX_SEQ_SZ];
wolfSSL 0:d92f9d21154c 960 byte recipSeq[MAX_SEQ_SZ];
wolfSSL 0:d92f9d21154c 961 byte issuerSeq[MAX_SEQ_SZ];
wolfSSL 0:d92f9d21154c 962 byte encKeyOctetStr[MAX_OCTET_STR_SZ];
wolfSSL 0:d92f9d21154c 963
wolfSSL 0:d92f9d21154c 964 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 965 byte *serial;
wolfSSL 0:d92f9d21154c 966 byte *keyAlgArray;
wolfSSL 0:d92f9d21154c 967
wolfSSL 0:d92f9d21154c 968 RsaKey* pubKey;
wolfSSL 0:d92f9d21154c 969 DecodedCert* decoded;
wolfSSL 0:d92f9d21154c 970
wolfSSL 0:d92f9d21154c 971 serial = (byte*)XMALLOC(MAX_SN_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 972 keyAlgArray = (byte*)XMALLOC(MAX_SN_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 973 decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
wolfSSL 0:d92f9d21154c 974 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 975
wolfSSL 0:d92f9d21154c 976 if (decoded == NULL || serial == NULL || keyAlgArray == NULL) {
wolfSSL 0:d92f9d21154c 977 if (serial) XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 978 if (keyAlgArray) XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 979 if (decoded) XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 980 return MEMORY_E;
wolfSSL 0:d92f9d21154c 981 }
wolfSSL 0:d92f9d21154c 982
wolfSSL 0:d92f9d21154c 983 #else
wolfSSL 0:d92f9d21154c 984 byte serial[MAX_SN_SZ];
wolfSSL 0:d92f9d21154c 985 byte keyAlgArray[MAX_ALGO_SZ];
wolfSSL 0:d92f9d21154c 986
wolfSSL 0:d92f9d21154c 987 RsaKey stack_pubKey;
wolfSSL 0:d92f9d21154c 988 RsaKey* pubKey = &stack_pubKey;
wolfSSL 0:d92f9d21154c 989 DecodedCert stack_decoded;
wolfSSL 0:d92f9d21154c 990 DecodedCert* decoded = &stack_decoded;
wolfSSL 0:d92f9d21154c 991 #endif
wolfSSL 0:d92f9d21154c 992
wolfSSL 0:d92f9d21154c 993 InitDecodedCert(decoded, (byte*)cert, certSz, 0);
wolfSSL 0:d92f9d21154c 994 ret = ParseCert(decoded, CA_TYPE, NO_VERIFY, 0);
wolfSSL 0:d92f9d21154c 995 if (ret < 0) {
wolfSSL 0:d92f9d21154c 996 FreeDecodedCert(decoded);
wolfSSL 0:d92f9d21154c 997 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 998 XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 999 XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1000 XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1001 #endif
wolfSSL 0:d92f9d21154c 1002 return ret;
wolfSSL 0:d92f9d21154c 1003 }
wolfSSL 0:d92f9d21154c 1004
wolfSSL 0:d92f9d21154c 1005 /* version */
wolfSSL 0:d92f9d21154c 1006 verSz = SetMyVersion(0, ver, 0);
wolfSSL 0:d92f9d21154c 1007
wolfSSL 0:d92f9d21154c 1008 /* IssuerAndSerialNumber */
wolfSSL 0:d92f9d21154c 1009 if (decoded->issuerRaw == NULL || decoded->issuerRawLen == 0) {
wolfSSL 0:d92f9d21154c 1010 WOLFSSL_MSG("DecodedCert lacks raw issuer pointer and length");
wolfSSL 0:d92f9d21154c 1011 FreeDecodedCert(decoded);
wolfSSL 0:d92f9d21154c 1012 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 1013 XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1014 XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1015 XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1016 #endif
wolfSSL 0:d92f9d21154c 1017 return -1;
wolfSSL 0:d92f9d21154c 1018 }
wolfSSL 0:d92f9d21154c 1019 issuerSz = decoded->issuerRawLen;
wolfSSL 0:d92f9d21154c 1020 issuerSeqSz = SetSequence(issuerSz, issuerSeq);
wolfSSL 0:d92f9d21154c 1021
wolfSSL 0:d92f9d21154c 1022 if (decoded->serialSz == 0) {
wolfSSL 0:d92f9d21154c 1023 WOLFSSL_MSG("DecodedCert missing serial number");
wolfSSL 0:d92f9d21154c 1024 FreeDecodedCert(decoded);
wolfSSL 0:d92f9d21154c 1025 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 1026 XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1027 XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1028 XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1029 #endif
wolfSSL 0:d92f9d21154c 1030 return -1;
wolfSSL 0:d92f9d21154c 1031 }
wolfSSL 0:d92f9d21154c 1032 snSz = SetSerialNumber(decoded->serial, decoded->serialSz, serial);
wolfSSL 0:d92f9d21154c 1033
wolfSSL 0:d92f9d21154c 1034 issuerSerialSeqSz = SetSequence(issuerSeqSz + issuerSz + snSz,
wolfSSL 0:d92f9d21154c 1035 issuerSerialSeq);
wolfSSL 0:d92f9d21154c 1036
wolfSSL 0:d92f9d21154c 1037 /* KeyEncryptionAlgorithmIdentifier, only support RSA now */
wolfSSL 0:d92f9d21154c 1038 if (keyEncAlgo != RSAk) {
wolfSSL 0:d92f9d21154c 1039 FreeDecodedCert(decoded);
wolfSSL 0:d92f9d21154c 1040 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 1041 XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1042 XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1043 XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1044 #endif
wolfSSL 0:d92f9d21154c 1045 return ALGO_ID_E;
wolfSSL 0:d92f9d21154c 1046 }
wolfSSL 0:d92f9d21154c 1047
wolfSSL 0:d92f9d21154c 1048 keyEncAlgSz = SetAlgoID(keyEncAlgo, keyAlgArray, keyType, 0);
wolfSSL 0:d92f9d21154c 1049 if (keyEncAlgSz == 0) {
wolfSSL 0:d92f9d21154c 1050 FreeDecodedCert(decoded);
wolfSSL 0:d92f9d21154c 1051 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 1052 XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1053 XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1054 XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1055 #endif
wolfSSL 0:d92f9d21154c 1056 return BAD_FUNC_ARG;
wolfSSL 0:d92f9d21154c 1057 }
wolfSSL 0:d92f9d21154c 1058
wolfSSL 0:d92f9d21154c 1059 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 1060 pubKey = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1061 if (pubKey == NULL) {
wolfSSL 0:d92f9d21154c 1062 FreeDecodedCert(decoded);
wolfSSL 0:d92f9d21154c 1063 XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1064 XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1065 XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1066 return MEMORY_E;
wolfSSL 0:d92f9d21154c 1067 }
wolfSSL 0:d92f9d21154c 1068 #endif
wolfSSL 0:d92f9d21154c 1069
wolfSSL 0:d92f9d21154c 1070 /* EncryptedKey */
wolfSSL 0:d92f9d21154c 1071 ret = wc_InitRsaKey(pubKey, 0);
wolfSSL 0:d92f9d21154c 1072 if (ret != 0) {
wolfSSL 0:d92f9d21154c 1073 FreeDecodedCert(decoded);
wolfSSL 0:d92f9d21154c 1074 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 1075 XFREE(pubKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1076 XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1077 XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1078 XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1079 #endif
wolfSSL 0:d92f9d21154c 1080 return ret;
wolfSSL 0:d92f9d21154c 1081 }
wolfSSL 0:d92f9d21154c 1082
wolfSSL 0:d92f9d21154c 1083 if (wc_RsaPublicKeyDecode(decoded->publicKey, &idx, pubKey,
wolfSSL 0:d92f9d21154c 1084 decoded->pubKeySize) < 0) {
wolfSSL 0:d92f9d21154c 1085 WOLFSSL_MSG("ASN RSA key decode error");
wolfSSL 0:d92f9d21154c 1086 wc_FreeRsaKey(pubKey);
wolfSSL 0:d92f9d21154c 1087 FreeDecodedCert(decoded);
wolfSSL 0:d92f9d21154c 1088 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 1089 XFREE(pubKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1090 XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1091 XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1092 XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1093 #endif
wolfSSL 0:d92f9d21154c 1094 return PUBLIC_KEY_E;
wolfSSL 0:d92f9d21154c 1095 }
wolfSSL 0:d92f9d21154c 1096
wolfSSL 0:d92f9d21154c 1097 *keyEncSz = wc_RsaPublicEncrypt(contentKeyPlain, blockKeySz, contentKeyEnc,
wolfSSL 0:d92f9d21154c 1098 MAX_ENCRYPTED_KEY_SZ, pubKey, rng);
wolfSSL 0:d92f9d21154c 1099 wc_FreeRsaKey(pubKey);
wolfSSL 0:d92f9d21154c 1100
wolfSSL 0:d92f9d21154c 1101 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 1102 XFREE(pubKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1103 #endif
wolfSSL 0:d92f9d21154c 1104
wolfSSL 0:d92f9d21154c 1105 if (*keyEncSz < 0) {
wolfSSL 0:d92f9d21154c 1106 WOLFSSL_MSG("RSA Public Encrypt failed");
wolfSSL 0:d92f9d21154c 1107 FreeDecodedCert(decoded);
wolfSSL 0:d92f9d21154c 1108 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 1109 XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1110 XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1111 XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1112 #endif
wolfSSL 0:d92f9d21154c 1113 return *keyEncSz;
wolfSSL 0:d92f9d21154c 1114 }
wolfSSL 0:d92f9d21154c 1115
wolfSSL 0:d92f9d21154c 1116 encKeyOctetStrSz = SetOctetString(*keyEncSz, encKeyOctetStr);
wolfSSL 0:d92f9d21154c 1117
wolfSSL 0:d92f9d21154c 1118 /* RecipientInfo */
wolfSSL 0:d92f9d21154c 1119 recipSeqSz = SetSequence(verSz + issuerSerialSeqSz + issuerSeqSz +
wolfSSL 0:d92f9d21154c 1120 issuerSz + snSz + keyEncAlgSz + encKeyOctetStrSz +
wolfSSL 0:d92f9d21154c 1121 *keyEncSz, recipSeq);
wolfSSL 0:d92f9d21154c 1122
wolfSSL 0:d92f9d21154c 1123 if (recipSeqSz + verSz + issuerSerialSeqSz + issuerSeqSz + snSz +
wolfSSL 0:d92f9d21154c 1124 keyEncAlgSz + encKeyOctetStrSz + *keyEncSz > (int)outSz) {
wolfSSL 0:d92f9d21154c 1125 WOLFSSL_MSG("RecipientInfo output buffer too small");
wolfSSL 0:d92f9d21154c 1126 FreeDecodedCert(decoded);
wolfSSL 0:d92f9d21154c 1127 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 1128 XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1129 XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1130 XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1131 #endif
wolfSSL 0:d92f9d21154c 1132 return BUFFER_E;
wolfSSL 0:d92f9d21154c 1133 }
wolfSSL 0:d92f9d21154c 1134
wolfSSL 0:d92f9d21154c 1135 XMEMCPY(out + totalSz, recipSeq, recipSeqSz);
wolfSSL 0:d92f9d21154c 1136 totalSz += recipSeqSz;
wolfSSL 0:d92f9d21154c 1137 XMEMCPY(out + totalSz, ver, verSz);
wolfSSL 0:d92f9d21154c 1138 totalSz += verSz;
wolfSSL 0:d92f9d21154c 1139 XMEMCPY(out + totalSz, issuerSerialSeq, issuerSerialSeqSz);
wolfSSL 0:d92f9d21154c 1140 totalSz += issuerSerialSeqSz;
wolfSSL 0:d92f9d21154c 1141 XMEMCPY(out + totalSz, issuerSeq, issuerSeqSz);
wolfSSL 0:d92f9d21154c 1142 totalSz += issuerSeqSz;
wolfSSL 0:d92f9d21154c 1143 XMEMCPY(out + totalSz, decoded->issuerRaw, issuerSz);
wolfSSL 0:d92f9d21154c 1144 totalSz += issuerSz;
wolfSSL 0:d92f9d21154c 1145 XMEMCPY(out + totalSz, serial, snSz);
wolfSSL 0:d92f9d21154c 1146 totalSz += snSz;
wolfSSL 0:d92f9d21154c 1147 XMEMCPY(out + totalSz, keyAlgArray, keyEncAlgSz);
wolfSSL 0:d92f9d21154c 1148 totalSz += keyEncAlgSz;
wolfSSL 0:d92f9d21154c 1149 XMEMCPY(out + totalSz, encKeyOctetStr, encKeyOctetStrSz);
wolfSSL 0:d92f9d21154c 1150 totalSz += encKeyOctetStrSz;
wolfSSL 0:d92f9d21154c 1151 XMEMCPY(out + totalSz, contentKeyEnc, *keyEncSz);
wolfSSL 0:d92f9d21154c 1152 totalSz += *keyEncSz;
wolfSSL 0:d92f9d21154c 1153
wolfSSL 0:d92f9d21154c 1154 FreeDecodedCert(decoded);
wolfSSL 0:d92f9d21154c 1155
wolfSSL 0:d92f9d21154c 1156 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 1157 XFREE(serial, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1158 XFREE(keyAlgArray, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1159 XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1160 #endif
wolfSSL 0:d92f9d21154c 1161
wolfSSL 0:d92f9d21154c 1162 return totalSz;
wolfSSL 0:d92f9d21154c 1163 }
wolfSSL 0:d92f9d21154c 1164
wolfSSL 0:d92f9d21154c 1165
wolfSSL 0:d92f9d21154c 1166 /* build PKCS#7 envelopedData content type, return enveloped size */
wolfSSL 0:d92f9d21154c 1167 int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz)
wolfSSL 0:d92f9d21154c 1168 {
wolfSSL 0:d92f9d21154c 1169 int i, ret = 0, idx = 0;
wolfSSL 0:d92f9d21154c 1170 int totalSz = 0, padSz = 0, desOutSz = 0;
wolfSSL 0:d92f9d21154c 1171
wolfSSL 0:d92f9d21154c 1172 int contentInfoSeqSz, outerContentTypeSz, outerContentSz;
wolfSSL 0:d92f9d21154c 1173 byte contentInfoSeq[MAX_SEQ_SZ];
wolfSSL 0:d92f9d21154c 1174 byte outerContentType[MAX_ALGO_SZ];
wolfSSL 0:d92f9d21154c 1175 byte outerContent[MAX_SEQ_SZ];
wolfSSL 0:d92f9d21154c 1176
wolfSSL 0:d92f9d21154c 1177 int envDataSeqSz, verSz;
wolfSSL 0:d92f9d21154c 1178 byte envDataSeq[MAX_SEQ_SZ];
wolfSSL 0:d92f9d21154c 1179 byte ver[MAX_VERSION_SZ];
wolfSSL 0:d92f9d21154c 1180
wolfSSL 0:d92f9d21154c 1181 RNG rng;
wolfSSL 0:d92f9d21154c 1182 int contentKeyEncSz, blockKeySz;
wolfSSL 0:d92f9d21154c 1183 int dynamicFlag = 0;
wolfSSL 0:d92f9d21154c 1184 byte contentKeyPlain[MAX_CONTENT_KEY_LEN];
wolfSSL 0:d92f9d21154c 1185 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 1186 byte* contentKeyEnc;
wolfSSL 0:d92f9d21154c 1187 #else
wolfSSL 0:d92f9d21154c 1188 byte contentKeyEnc[MAX_ENCRYPTED_KEY_SZ];
wolfSSL 0:d92f9d21154c 1189 #endif
wolfSSL 0:d92f9d21154c 1190 byte* plain;
wolfSSL 0:d92f9d21154c 1191 byte* encryptedContent;
wolfSSL 0:d92f9d21154c 1192
wolfSSL 0:d92f9d21154c 1193 int recipSz, recipSetSz;
wolfSSL 0:d92f9d21154c 1194 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 1195 byte* recip;
wolfSSL 0:d92f9d21154c 1196 #else
wolfSSL 0:d92f9d21154c 1197 byte recip[MAX_RECIP_SZ];
wolfSSL 0:d92f9d21154c 1198 #endif
wolfSSL 0:d92f9d21154c 1199 byte recipSet[MAX_SET_SZ];
wolfSSL 0:d92f9d21154c 1200
wolfSSL 0:d92f9d21154c 1201 int encContentOctetSz, encContentSeqSz, contentTypeSz;
wolfSSL 0:d92f9d21154c 1202 int contentEncAlgoSz, ivOctetStringSz;
wolfSSL 0:d92f9d21154c 1203 byte encContentSeq[MAX_SEQ_SZ];
wolfSSL 0:d92f9d21154c 1204 byte contentType[MAX_ALGO_SZ];
wolfSSL 0:d92f9d21154c 1205 byte contentEncAlgo[MAX_ALGO_SZ];
wolfSSL 0:d92f9d21154c 1206 byte tmpIv[DES_BLOCK_SIZE];
wolfSSL 0:d92f9d21154c 1207 byte ivOctetString[MAX_OCTET_STR_SZ];
wolfSSL 0:d92f9d21154c 1208 byte encContentOctet[MAX_OCTET_STR_SZ];
wolfSSL 0:d92f9d21154c 1209
wolfSSL 0:d92f9d21154c 1210 if (pkcs7 == NULL || pkcs7->content == NULL || pkcs7->contentSz == 0 ||
wolfSSL 0:d92f9d21154c 1211 pkcs7->encryptOID == 0 || pkcs7->singleCert == NULL)
wolfSSL 0:d92f9d21154c 1212 return BAD_FUNC_ARG;
wolfSSL 0:d92f9d21154c 1213
wolfSSL 0:d92f9d21154c 1214 if (output == NULL || outputSz == 0)
wolfSSL 0:d92f9d21154c 1215 return BAD_FUNC_ARG;
wolfSSL 0:d92f9d21154c 1216
wolfSSL 0:d92f9d21154c 1217 /* PKCS#7 only supports DES, 3DES for now */
wolfSSL 0:d92f9d21154c 1218 switch (pkcs7->encryptOID) {
wolfSSL 0:d92f9d21154c 1219 case DESb:
wolfSSL 0:d92f9d21154c 1220 blockKeySz = DES_KEYLEN;
wolfSSL 0:d92f9d21154c 1221 break;
wolfSSL 0:d92f9d21154c 1222
wolfSSL 0:d92f9d21154c 1223 case DES3b:
wolfSSL 0:d92f9d21154c 1224 blockKeySz = DES3_KEYLEN;
wolfSSL 0:d92f9d21154c 1225 break;
wolfSSL 0:d92f9d21154c 1226
wolfSSL 0:d92f9d21154c 1227 default:
wolfSSL 0:d92f9d21154c 1228 WOLFSSL_MSG("Unsupported content cipher type");
wolfSSL 0:d92f9d21154c 1229 return ALGO_ID_E;
wolfSSL 0:d92f9d21154c 1230 };
wolfSSL 0:d92f9d21154c 1231
wolfSSL 0:d92f9d21154c 1232 /* outer content type */
wolfSSL 0:d92f9d21154c 1233 outerContentTypeSz = wc_SetContentType(ENVELOPED_DATA, outerContentType);
wolfSSL 0:d92f9d21154c 1234
wolfSSL 0:d92f9d21154c 1235 /* version, defined as 0 in RFC 2315 */
wolfSSL 0:d92f9d21154c 1236 verSz = SetMyVersion(0, ver, 0);
wolfSSL 0:d92f9d21154c 1237
wolfSSL 0:d92f9d21154c 1238 /* generate random content encryption key */
wolfSSL 0:d92f9d21154c 1239 ret = wc_InitRng(&rng);
wolfSSL 0:d92f9d21154c 1240 if (ret != 0)
wolfSSL 0:d92f9d21154c 1241 return ret;
wolfSSL 0:d92f9d21154c 1242
wolfSSL 0:d92f9d21154c 1243 ret = wc_RNG_GenerateBlock(&rng, contentKeyPlain, blockKeySz);
wolfSSL 0:d92f9d21154c 1244 if (ret != 0) {
wolfSSL 0:d92f9d21154c 1245 wc_FreeRng(&rng);
wolfSSL 0:d92f9d21154c 1246 return ret;
wolfSSL 0:d92f9d21154c 1247 }
wolfSSL 0:d92f9d21154c 1248
wolfSSL 0:d92f9d21154c 1249 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 1250 recip = (byte*)XMALLOC(MAX_RECIP_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1251 contentKeyEnc = (byte*)XMALLOC(MAX_ENCRYPTED_KEY_SZ, NULL,
wolfSSL 0:d92f9d21154c 1252 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1253 if (contentKeyEnc == NULL || recip == NULL) {
wolfSSL 0:d92f9d21154c 1254 if (recip) XFREE(recip, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1255 if (contentKeyEnc) XFREE(contentKeyEnc, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1256 wc_FreeRng(&rng);
wolfSSL 0:d92f9d21154c 1257 return MEMORY_E;
wolfSSL 0:d92f9d21154c 1258 }
wolfSSL 0:d92f9d21154c 1259
wolfSSL 0:d92f9d21154c 1260 #endif
wolfSSL 0:d92f9d21154c 1261
wolfSSL 0:d92f9d21154c 1262 /* build RecipientInfo, only handle 1 for now */
wolfSSL 0:d92f9d21154c 1263 recipSz = wc_CreateRecipientInfo(pkcs7->singleCert, pkcs7->singleCertSz, RSAk,
wolfSSL 0:d92f9d21154c 1264 blockKeySz, &rng, contentKeyPlain,
wolfSSL 0:d92f9d21154c 1265 contentKeyEnc, &contentKeyEncSz, recip,
wolfSSL 0:d92f9d21154c 1266 MAX_RECIP_SZ);
wolfSSL 0:d92f9d21154c 1267
wolfSSL 0:d92f9d21154c 1268 ForceZero(contentKeyEnc, MAX_ENCRYPTED_KEY_SZ);
wolfSSL 0:d92f9d21154c 1269
wolfSSL 0:d92f9d21154c 1270 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 1271 XFREE(contentKeyEnc, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1272 #endif
wolfSSL 0:d92f9d21154c 1273
wolfSSL 0:d92f9d21154c 1274 if (recipSz < 0) {
wolfSSL 0:d92f9d21154c 1275 WOLFSSL_MSG("Failed to create RecipientInfo");
wolfSSL 0:d92f9d21154c 1276 wc_FreeRng(&rng);
wolfSSL 0:d92f9d21154c 1277 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 1278 XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1279 #endif
wolfSSL 0:d92f9d21154c 1280 return recipSz;
wolfSSL 0:d92f9d21154c 1281 }
wolfSSL 0:d92f9d21154c 1282 recipSetSz = SetSet(recipSz, recipSet);
wolfSSL 0:d92f9d21154c 1283
wolfSSL 0:d92f9d21154c 1284 /* generate IV for block cipher */
wolfSSL 0:d92f9d21154c 1285 ret = wc_RNG_GenerateBlock(&rng, tmpIv, DES_BLOCK_SIZE);
wolfSSL 0:d92f9d21154c 1286 wc_FreeRng(&rng);
wolfSSL 0:d92f9d21154c 1287 if (ret != 0) {
wolfSSL 0:d92f9d21154c 1288 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 1289 XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1290 #endif
wolfSSL 0:d92f9d21154c 1291 return ret;
wolfSSL 0:d92f9d21154c 1292 }
wolfSSL 0:d92f9d21154c 1293
wolfSSL 0:d92f9d21154c 1294 /* EncryptedContentInfo */
wolfSSL 0:d92f9d21154c 1295 contentTypeSz = wc_SetContentType(pkcs7->contentOID, contentType);
wolfSSL 0:d92f9d21154c 1296 if (contentTypeSz == 0) {
wolfSSL 0:d92f9d21154c 1297 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 1298 XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1299 #endif
wolfSSL 0:d92f9d21154c 1300 return BAD_FUNC_ARG;
wolfSSL 0:d92f9d21154c 1301 }
wolfSSL 0:d92f9d21154c 1302
wolfSSL 0:d92f9d21154c 1303 /* allocate encrypted content buffer, pad if necessary, PKCS#7 padding */
wolfSSL 0:d92f9d21154c 1304 padSz = DES_BLOCK_SIZE - (pkcs7->contentSz % DES_BLOCK_SIZE);
wolfSSL 0:d92f9d21154c 1305 desOutSz = pkcs7->contentSz + padSz;
wolfSSL 0:d92f9d21154c 1306
wolfSSL 0:d92f9d21154c 1307 if (padSz != 0) {
wolfSSL 0:d92f9d21154c 1308 plain = (byte*)XMALLOC(desOutSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1309 if (plain == NULL) {
wolfSSL 0:d92f9d21154c 1310 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 1311 XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1312 #endif
wolfSSL 0:d92f9d21154c 1313 return MEMORY_E;
wolfSSL 0:d92f9d21154c 1314 }
wolfSSL 0:d92f9d21154c 1315 XMEMCPY(plain, pkcs7->content, pkcs7->contentSz);
wolfSSL 0:d92f9d21154c 1316 dynamicFlag = 1;
wolfSSL 0:d92f9d21154c 1317
wolfSSL 0:d92f9d21154c 1318 for (i = 0; i < padSz; i++) {
wolfSSL 0:d92f9d21154c 1319 plain[pkcs7->contentSz + i] = padSz;
wolfSSL 0:d92f9d21154c 1320 }
wolfSSL 0:d92f9d21154c 1321
wolfSSL 0:d92f9d21154c 1322 } else {
wolfSSL 0:d92f9d21154c 1323 plain = pkcs7->content;
wolfSSL 0:d92f9d21154c 1324 desOutSz = pkcs7->contentSz;
wolfSSL 0:d92f9d21154c 1325 }
wolfSSL 0:d92f9d21154c 1326
wolfSSL 0:d92f9d21154c 1327 encryptedContent = (byte*)XMALLOC(desOutSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1328 if (encryptedContent == NULL) {
wolfSSL 0:d92f9d21154c 1329 if (dynamicFlag)
wolfSSL 0:d92f9d21154c 1330 XFREE(plain, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1331 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 1332 XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1333 #endif
wolfSSL 0:d92f9d21154c 1334 return MEMORY_E;
wolfSSL 0:d92f9d21154c 1335 }
wolfSSL 0:d92f9d21154c 1336
wolfSSL 0:d92f9d21154c 1337 /* put together IV OCTET STRING */
wolfSSL 0:d92f9d21154c 1338 ivOctetStringSz = SetOctetString(DES_BLOCK_SIZE, ivOctetString);
wolfSSL 0:d92f9d21154c 1339
wolfSSL 0:d92f9d21154c 1340 /* build up our ContentEncryptionAlgorithmIdentifier sequence,
wolfSSL 0:d92f9d21154c 1341 * adding (ivOctetStringSz + DES_BLOCK_SIZE) for IV OCTET STRING */
wolfSSL 0:d92f9d21154c 1342 contentEncAlgoSz = SetAlgoID(pkcs7->encryptOID, contentEncAlgo,
wolfSSL 0:d92f9d21154c 1343 blkType, ivOctetStringSz + DES_BLOCK_SIZE);
wolfSSL 0:d92f9d21154c 1344
wolfSSL 0:d92f9d21154c 1345 if (contentEncAlgoSz == 0) {
wolfSSL 0:d92f9d21154c 1346 XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1347 if (dynamicFlag)
wolfSSL 0:d92f9d21154c 1348 XFREE(plain, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1349 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 1350 XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1351 #endif
wolfSSL 0:d92f9d21154c 1352 return BAD_FUNC_ARG;
wolfSSL 0:d92f9d21154c 1353 }
wolfSSL 0:d92f9d21154c 1354
wolfSSL 0:d92f9d21154c 1355 /* encrypt content */
wolfSSL 0:d92f9d21154c 1356 if (pkcs7->encryptOID == DESb) {
wolfSSL 0:d92f9d21154c 1357 Des des;
wolfSSL 0:d92f9d21154c 1358
wolfSSL 0:d92f9d21154c 1359 ret = wc_Des_SetKey(&des, contentKeyPlain, tmpIv, DES_ENCRYPTION);
wolfSSL 0:d92f9d21154c 1360
wolfSSL 0:d92f9d21154c 1361 if (ret == 0)
wolfSSL 0:d92f9d21154c 1362 wc_Des_CbcEncrypt(&des, encryptedContent, plain, desOutSz);
wolfSSL 0:d92f9d21154c 1363
wolfSSL 0:d92f9d21154c 1364 if (ret != 0) {
wolfSSL 0:d92f9d21154c 1365 XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1366 if (dynamicFlag)
wolfSSL 0:d92f9d21154c 1367 XFREE(plain, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1368 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 1369 XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1370 #endif
wolfSSL 0:d92f9d21154c 1371 return ret;
wolfSSL 0:d92f9d21154c 1372 }
wolfSSL 0:d92f9d21154c 1373 }
wolfSSL 0:d92f9d21154c 1374 else if (pkcs7->encryptOID == DES3b) {
wolfSSL 0:d92f9d21154c 1375 Des3 des3;
wolfSSL 0:d92f9d21154c 1376
wolfSSL 0:d92f9d21154c 1377 ret = wc_Des3_SetKey(&des3, contentKeyPlain, tmpIv, DES_ENCRYPTION);
wolfSSL 0:d92f9d21154c 1378
wolfSSL 0:d92f9d21154c 1379 if (ret == 0)
wolfSSL 0:d92f9d21154c 1380 ret = wc_Des3_CbcEncrypt(&des3, encryptedContent, plain, desOutSz);
wolfSSL 0:d92f9d21154c 1381
wolfSSL 0:d92f9d21154c 1382 if (ret != 0) {
wolfSSL 0:d92f9d21154c 1383 XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1384 if (dynamicFlag)
wolfSSL 0:d92f9d21154c 1385 XFREE(plain, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1386 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 1387 XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1388 #endif
wolfSSL 0:d92f9d21154c 1389 return ret;
wolfSSL 0:d92f9d21154c 1390 }
wolfSSL 0:d92f9d21154c 1391 }
wolfSSL 0:d92f9d21154c 1392
wolfSSL 0:d92f9d21154c 1393 encContentOctetSz = SetImplicit(ASN_OCTET_STRING, 0,
wolfSSL 0:d92f9d21154c 1394 desOutSz, encContentOctet);
wolfSSL 0:d92f9d21154c 1395
wolfSSL 0:d92f9d21154c 1396 encContentSeqSz = SetSequence(contentTypeSz + contentEncAlgoSz +
wolfSSL 0:d92f9d21154c 1397 ivOctetStringSz + DES_BLOCK_SIZE +
wolfSSL 0:d92f9d21154c 1398 encContentOctetSz + desOutSz, encContentSeq);
wolfSSL 0:d92f9d21154c 1399
wolfSSL 0:d92f9d21154c 1400 /* keep track of sizes for outer wrapper layering */
wolfSSL 0:d92f9d21154c 1401 totalSz = verSz + recipSetSz + recipSz + encContentSeqSz + contentTypeSz +
wolfSSL 0:d92f9d21154c 1402 contentEncAlgoSz + ivOctetStringSz + DES_BLOCK_SIZE +
wolfSSL 0:d92f9d21154c 1403 encContentOctetSz + desOutSz;
wolfSSL 0:d92f9d21154c 1404
wolfSSL 0:d92f9d21154c 1405 /* EnvelopedData */
wolfSSL 0:d92f9d21154c 1406 envDataSeqSz = SetSequence(totalSz, envDataSeq);
wolfSSL 0:d92f9d21154c 1407 totalSz += envDataSeqSz;
wolfSSL 0:d92f9d21154c 1408
wolfSSL 0:d92f9d21154c 1409 /* outer content */
wolfSSL 0:d92f9d21154c 1410 outerContentSz = SetExplicit(0, totalSz, outerContent);
wolfSSL 0:d92f9d21154c 1411 totalSz += outerContentTypeSz;
wolfSSL 0:d92f9d21154c 1412 totalSz += outerContentSz;
wolfSSL 0:d92f9d21154c 1413
wolfSSL 0:d92f9d21154c 1414 /* ContentInfo */
wolfSSL 0:d92f9d21154c 1415 contentInfoSeqSz = SetSequence(totalSz, contentInfoSeq);
wolfSSL 0:d92f9d21154c 1416 totalSz += contentInfoSeqSz;
wolfSSL 0:d92f9d21154c 1417
wolfSSL 0:d92f9d21154c 1418 if (totalSz > (int)outputSz) {
wolfSSL 0:d92f9d21154c 1419 WOLFSSL_MSG("Pkcs7_encrypt output buffer too small");
wolfSSL 0:d92f9d21154c 1420 XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1421 if (dynamicFlag)
wolfSSL 0:d92f9d21154c 1422 XFREE(plain, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1423 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 1424 XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1425 #endif
wolfSSL 0:d92f9d21154c 1426 return BUFFER_E;
wolfSSL 0:d92f9d21154c 1427 }
wolfSSL 0:d92f9d21154c 1428
wolfSSL 0:d92f9d21154c 1429 XMEMCPY(output + idx, contentInfoSeq, contentInfoSeqSz);
wolfSSL 0:d92f9d21154c 1430 idx += contentInfoSeqSz;
wolfSSL 0:d92f9d21154c 1431 XMEMCPY(output + idx, outerContentType, outerContentTypeSz);
wolfSSL 0:d92f9d21154c 1432 idx += outerContentTypeSz;
wolfSSL 0:d92f9d21154c 1433 XMEMCPY(output + idx, outerContent, outerContentSz);
wolfSSL 0:d92f9d21154c 1434 idx += outerContentSz;
wolfSSL 0:d92f9d21154c 1435 XMEMCPY(output + idx, envDataSeq, envDataSeqSz);
wolfSSL 0:d92f9d21154c 1436 idx += envDataSeqSz;
wolfSSL 0:d92f9d21154c 1437 XMEMCPY(output + idx, ver, verSz);
wolfSSL 0:d92f9d21154c 1438 idx += verSz;
wolfSSL 0:d92f9d21154c 1439 XMEMCPY(output + idx, recipSet, recipSetSz);
wolfSSL 0:d92f9d21154c 1440 idx += recipSetSz;
wolfSSL 0:d92f9d21154c 1441 XMEMCPY(output + idx, recip, recipSz);
wolfSSL 0:d92f9d21154c 1442 idx += recipSz;
wolfSSL 0:d92f9d21154c 1443 XMEMCPY(output + idx, encContentSeq, encContentSeqSz);
wolfSSL 0:d92f9d21154c 1444 idx += encContentSeqSz;
wolfSSL 0:d92f9d21154c 1445 XMEMCPY(output + idx, contentType, contentTypeSz);
wolfSSL 0:d92f9d21154c 1446 idx += contentTypeSz;
wolfSSL 0:d92f9d21154c 1447 XMEMCPY(output + idx, contentEncAlgo, contentEncAlgoSz);
wolfSSL 0:d92f9d21154c 1448 idx += contentEncAlgoSz;
wolfSSL 0:d92f9d21154c 1449 XMEMCPY(output + idx, ivOctetString, ivOctetStringSz);
wolfSSL 0:d92f9d21154c 1450 idx += ivOctetStringSz;
wolfSSL 0:d92f9d21154c 1451 XMEMCPY(output + idx, tmpIv, DES_BLOCK_SIZE);
wolfSSL 0:d92f9d21154c 1452 idx += DES_BLOCK_SIZE;
wolfSSL 0:d92f9d21154c 1453 XMEMCPY(output + idx, encContentOctet, encContentOctetSz);
wolfSSL 0:d92f9d21154c 1454 idx += encContentOctetSz;
wolfSSL 0:d92f9d21154c 1455 XMEMCPY(output + idx, encryptedContent, desOutSz);
wolfSSL 0:d92f9d21154c 1456 idx += desOutSz;
wolfSSL 0:d92f9d21154c 1457
wolfSSL 0:d92f9d21154c 1458 ForceZero(contentKeyPlain, MAX_CONTENT_KEY_LEN);
wolfSSL 0:d92f9d21154c 1459
wolfSSL 0:d92f9d21154c 1460 if (dynamicFlag)
wolfSSL 0:d92f9d21154c 1461 XFREE(plain, NULL, DYNAMMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1462 XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1463
wolfSSL 0:d92f9d21154c 1464 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 1465 XFREE(recip, NULL, DYNAMMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1466 #endif
wolfSSL 0:d92f9d21154c 1467
wolfSSL 0:d92f9d21154c 1468 return idx;
wolfSSL 0:d92f9d21154c 1469 }
wolfSSL 0:d92f9d21154c 1470
wolfSSL 0:d92f9d21154c 1471 /* unwrap and decrypt PKCS#7 envelopedData object, return decoded size */
wolfSSL 0:d92f9d21154c 1472 WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg,
wolfSSL 0:d92f9d21154c 1473 word32 pkiMsgSz, byte* output,
wolfSSL 0:d92f9d21154c 1474 word32 outputSz)
wolfSSL 0:d92f9d21154c 1475 {
wolfSSL 0:d92f9d21154c 1476 int recipFound = 0;
wolfSSL 0:d92f9d21154c 1477 int ret, version, length;
wolfSSL 0:d92f9d21154c 1478 word32 savedIdx = 0, idx = 0;
wolfSSL 0:d92f9d21154c 1479 word32 contentType, encOID;
wolfSSL 0:d92f9d21154c 1480 byte issuerHash[SHA_DIGEST_SIZE];
wolfSSL 0:d92f9d21154c 1481
wolfSSL 0:d92f9d21154c 1482 int encryptedKeySz, keySz;
wolfSSL 0:d92f9d21154c 1483 byte tmpIv[DES_BLOCK_SIZE];
wolfSSL 0:d92f9d21154c 1484 byte* decryptedKey = NULL;
wolfSSL 0:d92f9d21154c 1485
wolfSSL 0:d92f9d21154c 1486 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 1487 mp_int* serialNum;
wolfSSL 0:d92f9d21154c 1488 byte* encryptedKey;
wolfSSL 0:d92f9d21154c 1489 RsaKey* privKey;
wolfSSL 0:d92f9d21154c 1490 #else
wolfSSL 0:d92f9d21154c 1491 mp_int stack_serialNum;
wolfSSL 0:d92f9d21154c 1492 mp_int* serialNum = &stack_serialNum;
wolfSSL 0:d92f9d21154c 1493 byte encryptedKey[MAX_ENCRYPTED_KEY_SZ];
wolfSSL 0:d92f9d21154c 1494
wolfSSL 0:d92f9d21154c 1495 RsaKey stack_privKey;
wolfSSL 0:d92f9d21154c 1496 RsaKey* privKey = &stack_privKey;
wolfSSL 0:d92f9d21154c 1497 #endif
wolfSSL 0:d92f9d21154c 1498 int encryptedContentSz;
wolfSSL 0:d92f9d21154c 1499 byte padLen;
wolfSSL 0:d92f9d21154c 1500 byte* encryptedContent = NULL;
wolfSSL 0:d92f9d21154c 1501
wolfSSL 0:d92f9d21154c 1502 if (pkcs7 == NULL || pkcs7->singleCert == NULL ||
wolfSSL 0:d92f9d21154c 1503 pkcs7->singleCertSz == 0 || pkcs7->privateKey == NULL ||
wolfSSL 0:d92f9d21154c 1504 pkcs7->privateKeySz == 0)
wolfSSL 0:d92f9d21154c 1505 return BAD_FUNC_ARG;
wolfSSL 0:d92f9d21154c 1506
wolfSSL 0:d92f9d21154c 1507 if (pkiMsg == NULL || pkiMsgSz == 0 ||
wolfSSL 0:d92f9d21154c 1508 output == NULL || outputSz == 0)
wolfSSL 0:d92f9d21154c 1509 return BAD_FUNC_ARG;
wolfSSL 0:d92f9d21154c 1510
wolfSSL 0:d92f9d21154c 1511 /* read past ContentInfo, verify type is envelopedData */
wolfSSL 0:d92f9d21154c 1512 if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
wolfSSL 0:d92f9d21154c 1513 return ASN_PARSE_E;
wolfSSL 0:d92f9d21154c 1514
wolfSSL 0:d92f9d21154c 1515 if (wc_GetContentType(pkiMsg, &idx, &contentType, pkiMsgSz) < 0)
wolfSSL 0:d92f9d21154c 1516 return ASN_PARSE_E;
wolfSSL 0:d92f9d21154c 1517
wolfSSL 0:d92f9d21154c 1518 if (contentType != ENVELOPED_DATA) {
wolfSSL 0:d92f9d21154c 1519 WOLFSSL_MSG("PKCS#7 input not of type EnvelopedData");
wolfSSL 0:d92f9d21154c 1520 return PKCS7_OID_E;
wolfSSL 0:d92f9d21154c 1521 }
wolfSSL 0:d92f9d21154c 1522
wolfSSL 0:d92f9d21154c 1523 if (pkiMsg[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
wolfSSL 0:d92f9d21154c 1524 return ASN_PARSE_E;
wolfSSL 0:d92f9d21154c 1525
wolfSSL 0:d92f9d21154c 1526 if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
wolfSSL 0:d92f9d21154c 1527 return ASN_PARSE_E;
wolfSSL 0:d92f9d21154c 1528
wolfSSL 0:d92f9d21154c 1529 /* remove EnvelopedData and version */
wolfSSL 0:d92f9d21154c 1530 if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
wolfSSL 0:d92f9d21154c 1531 return ASN_PARSE_E;
wolfSSL 0:d92f9d21154c 1532
wolfSSL 0:d92f9d21154c 1533 if (GetMyVersion(pkiMsg, &idx, &version) < 0)
wolfSSL 0:d92f9d21154c 1534 return ASN_PARSE_E;
wolfSSL 0:d92f9d21154c 1535
wolfSSL 0:d92f9d21154c 1536 if (version != 0) {
wolfSSL 0:d92f9d21154c 1537 WOLFSSL_MSG("PKCS#7 envelopedData needs to be of version 0");
wolfSSL 0:d92f9d21154c 1538 return ASN_VERSION_E;
wolfSSL 0:d92f9d21154c 1539 }
wolfSSL 0:d92f9d21154c 1540
wolfSSL 0:d92f9d21154c 1541 /* walk through RecipientInfo set, find correct recipient */
wolfSSL 0:d92f9d21154c 1542 if (GetSet(pkiMsg, &idx, &length, pkiMsgSz) < 0)
wolfSSL 0:d92f9d21154c 1543 return ASN_PARSE_E;
wolfSSL 0:d92f9d21154c 1544
wolfSSL 0:d92f9d21154c 1545 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 1546 encryptedKey = (byte*)XMALLOC(MAX_ENCRYPTED_KEY_SZ, NULL,
wolfSSL 0:d92f9d21154c 1547 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1548 if (encryptedKey == NULL)
wolfSSL 0:d92f9d21154c 1549 return MEMORY_E;
wolfSSL 0:d92f9d21154c 1550 #endif
wolfSSL 0:d92f9d21154c 1551
wolfSSL 0:d92f9d21154c 1552 savedIdx = idx;
wolfSSL 0:d92f9d21154c 1553 recipFound = 0;
wolfSSL 0:d92f9d21154c 1554
wolfSSL 0:d92f9d21154c 1555 /* when looking for next recipient, use first sequence and version to
wolfSSL 0:d92f9d21154c 1556 * indicate there is another, if not, move on */
wolfSSL 0:d92f9d21154c 1557 while(recipFound == 0) {
wolfSSL 0:d92f9d21154c 1558
wolfSSL 0:d92f9d21154c 1559 /* remove RecipientInfo, if we don't have a SEQUENCE, back up idx to
wolfSSL 0:d92f9d21154c 1560 * last good saved one */
wolfSSL 0:d92f9d21154c 1561 if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0) {
wolfSSL 0:d92f9d21154c 1562 idx = savedIdx;
wolfSSL 0:d92f9d21154c 1563 break;
wolfSSL 0:d92f9d21154c 1564 }
wolfSSL 0:d92f9d21154c 1565
wolfSSL 0:d92f9d21154c 1566 if (GetMyVersion(pkiMsg, &idx, &version) < 0) {
wolfSSL 0:d92f9d21154c 1567 idx = savedIdx;
wolfSSL 0:d92f9d21154c 1568 break;
wolfSSL 0:d92f9d21154c 1569 }
wolfSSL 0:d92f9d21154c 1570
wolfSSL 0:d92f9d21154c 1571 if (version != 0) {
wolfSSL 0:d92f9d21154c 1572 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 1573 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1574 #endif
wolfSSL 0:d92f9d21154c 1575 return ASN_VERSION_E;
wolfSSL 0:d92f9d21154c 1576 }
wolfSSL 0:d92f9d21154c 1577
wolfSSL 0:d92f9d21154c 1578 /* remove IssuerAndSerialNumber */
wolfSSL 0:d92f9d21154c 1579 if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0) {
wolfSSL 0:d92f9d21154c 1580 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 1581 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1582 #endif
wolfSSL 0:d92f9d21154c 1583 return ASN_PARSE_E;
wolfSSL 0:d92f9d21154c 1584 }
wolfSSL 0:d92f9d21154c 1585
wolfSSL 0:d92f9d21154c 1586 if (GetNameHash(pkiMsg, &idx, issuerHash, pkiMsgSz) < 0) {
wolfSSL 0:d92f9d21154c 1587 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 1588 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1589 #endif
wolfSSL 0:d92f9d21154c 1590 return ASN_PARSE_E;
wolfSSL 0:d92f9d21154c 1591 }
wolfSSL 0:d92f9d21154c 1592
wolfSSL 0:d92f9d21154c 1593 /* if we found correct recipient, issuer hashes will match */
wolfSSL 0:d92f9d21154c 1594 if (XMEMCMP(issuerHash, pkcs7->issuerHash, SHA_DIGEST_SIZE) == 0) {
wolfSSL 0:d92f9d21154c 1595 recipFound = 1;
wolfSSL 0:d92f9d21154c 1596 }
wolfSSL 0:d92f9d21154c 1597
wolfSSL 0:d92f9d21154c 1598 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 1599 serialNum = (mp_int*)XMALLOC(sizeof(mp_int), NULL,
wolfSSL 0:d92f9d21154c 1600 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1601 if (serialNum == NULL) {
wolfSSL 0:d92f9d21154c 1602 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1603 return MEMORY_E;
wolfSSL 0:d92f9d21154c 1604 }
wolfSSL 0:d92f9d21154c 1605 #endif
wolfSSL 0:d92f9d21154c 1606
wolfSSL 0:d92f9d21154c 1607 if (GetInt(serialNum, pkiMsg, &idx, pkiMsgSz) < 0) {
wolfSSL 0:d92f9d21154c 1608 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 1609 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1610 XFREE(serialNum, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1611 #endif
wolfSSL 0:d92f9d21154c 1612 return ASN_PARSE_E;
wolfSSL 0:d92f9d21154c 1613 }
wolfSSL 0:d92f9d21154c 1614
wolfSSL 0:d92f9d21154c 1615 mp_clear(serialNum);
wolfSSL 0:d92f9d21154c 1616
wolfSSL 0:d92f9d21154c 1617 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 1618 XFREE(serialNum, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1619 #endif
wolfSSL 0:d92f9d21154c 1620
wolfSSL 0:d92f9d21154c 1621 if (GetAlgoId(pkiMsg, &idx, &encOID, pkiMsgSz) < 0) {
wolfSSL 0:d92f9d21154c 1622 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 1623 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1624 #endif
wolfSSL 0:d92f9d21154c 1625 return ASN_PARSE_E;
wolfSSL 0:d92f9d21154c 1626 }
wolfSSL 0:d92f9d21154c 1627
wolfSSL 0:d92f9d21154c 1628 /* key encryption algorithm must be RSA for now */
wolfSSL 0:d92f9d21154c 1629 if (encOID != RSAk) {
wolfSSL 0:d92f9d21154c 1630 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 1631 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1632 #endif
wolfSSL 0:d92f9d21154c 1633 return ALGO_ID_E;
wolfSSL 0:d92f9d21154c 1634 }
wolfSSL 0:d92f9d21154c 1635
wolfSSL 0:d92f9d21154c 1636 /* read encryptedKey */
wolfSSL 0:d92f9d21154c 1637 if (pkiMsg[idx++] != ASN_OCTET_STRING) {
wolfSSL 0:d92f9d21154c 1638 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 1639 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1640 #endif
wolfSSL 0:d92f9d21154c 1641 return ASN_PARSE_E;
wolfSSL 0:d92f9d21154c 1642 }
wolfSSL 0:d92f9d21154c 1643
wolfSSL 0:d92f9d21154c 1644 if (GetLength(pkiMsg, &idx, &encryptedKeySz, pkiMsgSz) < 0) {
wolfSSL 0:d92f9d21154c 1645 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 1646 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1647 #endif
wolfSSL 0:d92f9d21154c 1648 return ASN_PARSE_E;
wolfSSL 0:d92f9d21154c 1649 }
wolfSSL 0:d92f9d21154c 1650
wolfSSL 0:d92f9d21154c 1651 if (recipFound == 1)
wolfSSL 0:d92f9d21154c 1652 XMEMCPY(encryptedKey, &pkiMsg[idx], encryptedKeySz);
wolfSSL 0:d92f9d21154c 1653 idx += encryptedKeySz;
wolfSSL 0:d92f9d21154c 1654
wolfSSL 0:d92f9d21154c 1655 /* update good idx */
wolfSSL 0:d92f9d21154c 1656 savedIdx = idx;
wolfSSL 0:d92f9d21154c 1657 }
wolfSSL 0:d92f9d21154c 1658
wolfSSL 0:d92f9d21154c 1659 if (recipFound == 0) {
wolfSSL 0:d92f9d21154c 1660 WOLFSSL_MSG("No recipient found in envelopedData that matches input");
wolfSSL 0:d92f9d21154c 1661 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 1662 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1663 #endif
wolfSSL 0:d92f9d21154c 1664 return PKCS7_RECIP_E;
wolfSSL 0:d92f9d21154c 1665 }
wolfSSL 0:d92f9d21154c 1666
wolfSSL 0:d92f9d21154c 1667 /* remove EncryptedContentInfo */
wolfSSL 0:d92f9d21154c 1668 if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0) {
wolfSSL 0:d92f9d21154c 1669 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 1670 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1671 #endif
wolfSSL 0:d92f9d21154c 1672 return ASN_PARSE_E;
wolfSSL 0:d92f9d21154c 1673 }
wolfSSL 0:d92f9d21154c 1674
wolfSSL 0:d92f9d21154c 1675 if (wc_GetContentType(pkiMsg, &idx, &contentType, pkiMsgSz) < 0) {
wolfSSL 0:d92f9d21154c 1676 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 1677 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1678 #endif
wolfSSL 0:d92f9d21154c 1679 return ASN_PARSE_E;
wolfSSL 0:d92f9d21154c 1680 }
wolfSSL 0:d92f9d21154c 1681
wolfSSL 0:d92f9d21154c 1682 if (GetAlgoId(pkiMsg, &idx, &encOID, pkiMsgSz) < 0) {
wolfSSL 0:d92f9d21154c 1683 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 1684 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1685 #endif
wolfSSL 0:d92f9d21154c 1686 return ASN_PARSE_E;
wolfSSL 0:d92f9d21154c 1687 }
wolfSSL 0:d92f9d21154c 1688
wolfSSL 0:d92f9d21154c 1689 /* get block cipher IV, stored in OPTIONAL parameter of AlgoID */
wolfSSL 0:d92f9d21154c 1690 if (pkiMsg[idx++] != ASN_OCTET_STRING) {
wolfSSL 0:d92f9d21154c 1691 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 1692 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1693 #endif
wolfSSL 0:d92f9d21154c 1694 return ASN_PARSE_E;
wolfSSL 0:d92f9d21154c 1695 }
wolfSSL 0:d92f9d21154c 1696
wolfSSL 0:d92f9d21154c 1697 if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0) {
wolfSSL 0:d92f9d21154c 1698 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 1699 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1700 #endif
wolfSSL 0:d92f9d21154c 1701 return ASN_PARSE_E;
wolfSSL 0:d92f9d21154c 1702 }
wolfSSL 0:d92f9d21154c 1703
wolfSSL 0:d92f9d21154c 1704 if (length != DES_BLOCK_SIZE) {
wolfSSL 0:d92f9d21154c 1705 WOLFSSL_MSG("Incorrect IV length, must be of DES_BLOCK_SIZE");
wolfSSL 0:d92f9d21154c 1706 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 1707 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1708 #endif
wolfSSL 0:d92f9d21154c 1709 return ASN_PARSE_E;
wolfSSL 0:d92f9d21154c 1710 }
wolfSSL 0:d92f9d21154c 1711
wolfSSL 0:d92f9d21154c 1712 XMEMCPY(tmpIv, &pkiMsg[idx], length);
wolfSSL 0:d92f9d21154c 1713 idx += length;
wolfSSL 0:d92f9d21154c 1714
wolfSSL 0:d92f9d21154c 1715 /* read encryptedContent, cont[0] */
wolfSSL 0:d92f9d21154c 1716 if (pkiMsg[idx++] != (ASN_CONTEXT_SPECIFIC | 0)) {
wolfSSL 0:d92f9d21154c 1717 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 1718 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1719 #endif
wolfSSL 0:d92f9d21154c 1720 return ASN_PARSE_E;
wolfSSL 0:d92f9d21154c 1721 }
wolfSSL 0:d92f9d21154c 1722
wolfSSL 0:d92f9d21154c 1723 if (GetLength(pkiMsg, &idx, &encryptedContentSz, pkiMsgSz) < 0) {
wolfSSL 0:d92f9d21154c 1724 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 1725 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1726 #endif
wolfSSL 0:d92f9d21154c 1727 return ASN_PARSE_E;
wolfSSL 0:d92f9d21154c 1728 }
wolfSSL 0:d92f9d21154c 1729
wolfSSL 0:d92f9d21154c 1730 encryptedContent = (byte*)XMALLOC(encryptedContentSz, NULL,
wolfSSL 0:d92f9d21154c 1731 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1732 if (encryptedContent == NULL) {
wolfSSL 0:d92f9d21154c 1733 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 1734 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1735 #endif
wolfSSL 0:d92f9d21154c 1736 return MEMORY_E;
wolfSSL 0:d92f9d21154c 1737 }
wolfSSL 0:d92f9d21154c 1738
wolfSSL 0:d92f9d21154c 1739 XMEMCPY(encryptedContent, &pkiMsg[idx], encryptedContentSz);
wolfSSL 0:d92f9d21154c 1740
wolfSSL 0:d92f9d21154c 1741 /* load private key */
wolfSSL 0:d92f9d21154c 1742 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 1743 privKey = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1744 if (privKey == NULL) {
wolfSSL 0:d92f9d21154c 1745 XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1746 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); return MEMORY_E;
wolfSSL 0:d92f9d21154c 1747 }
wolfSSL 0:d92f9d21154c 1748 #endif
wolfSSL 0:d92f9d21154c 1749
wolfSSL 0:d92f9d21154c 1750 ret = wc_InitRsaKey(privKey, 0);
wolfSSL 0:d92f9d21154c 1751 if (ret != 0) {
wolfSSL 0:d92f9d21154c 1752 XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1753 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 1754 XFREE(privKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1755 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1756 #endif
wolfSSL 0:d92f9d21154c 1757 return ret;
wolfSSL 0:d92f9d21154c 1758 }
wolfSSL 0:d92f9d21154c 1759
wolfSSL 0:d92f9d21154c 1760 idx = 0;
wolfSSL 0:d92f9d21154c 1761
wolfSSL 0:d92f9d21154c 1762 ret = wc_RsaPrivateKeyDecode(pkcs7->privateKey, &idx, privKey,
wolfSSL 0:d92f9d21154c 1763 pkcs7->privateKeySz);
wolfSSL 0:d92f9d21154c 1764 if (ret != 0) {
wolfSSL 0:d92f9d21154c 1765 WOLFSSL_MSG("Failed to decode RSA private key");
wolfSSL 0:d92f9d21154c 1766 XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1767 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 1768 XFREE(privKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1769 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1770 #endif
wolfSSL 0:d92f9d21154c 1771 return ret;
wolfSSL 0:d92f9d21154c 1772 }
wolfSSL 0:d92f9d21154c 1773
wolfSSL 0:d92f9d21154c 1774 /* decrypt encryptedKey */
wolfSSL 0:d92f9d21154c 1775 keySz = wc_RsaPrivateDecryptInline(encryptedKey, encryptedKeySz,
wolfSSL 0:d92f9d21154c 1776 &decryptedKey, privKey);
wolfSSL 0:d92f9d21154c 1777 wc_FreeRsaKey(privKey);
wolfSSL 0:d92f9d21154c 1778
wolfSSL 0:d92f9d21154c 1779 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 1780 XFREE(privKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1781 #endif
wolfSSL 0:d92f9d21154c 1782
wolfSSL 0:d92f9d21154c 1783 if (keySz <= 0) {
wolfSSL 0:d92f9d21154c 1784 XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1785 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 1786 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1787 #endif
wolfSSL 0:d92f9d21154c 1788 return keySz;
wolfSSL 0:d92f9d21154c 1789 }
wolfSSL 0:d92f9d21154c 1790
wolfSSL 0:d92f9d21154c 1791 /* decrypt encryptedContent */
wolfSSL 0:d92f9d21154c 1792 if (encOID == DESb) {
wolfSSL 0:d92f9d21154c 1793 Des des;
wolfSSL 0:d92f9d21154c 1794 ret = wc_Des_SetKey(&des, decryptedKey, tmpIv, DES_DECRYPTION);
wolfSSL 0:d92f9d21154c 1795
wolfSSL 0:d92f9d21154c 1796 if (ret == 0)
wolfSSL 0:d92f9d21154c 1797 wc_Des_CbcDecrypt(&des, encryptedContent, encryptedContent,
wolfSSL 0:d92f9d21154c 1798 encryptedContentSz);
wolfSSL 0:d92f9d21154c 1799
wolfSSL 0:d92f9d21154c 1800 if (ret != 0) {
wolfSSL 0:d92f9d21154c 1801 XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1802 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 1803 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1804 #endif
wolfSSL 0:d92f9d21154c 1805 return ret;
wolfSSL 0:d92f9d21154c 1806 }
wolfSSL 0:d92f9d21154c 1807 }
wolfSSL 0:d92f9d21154c 1808 else if (encOID == DES3b) {
wolfSSL 0:d92f9d21154c 1809 Des3 des;
wolfSSL 0:d92f9d21154c 1810 ret = wc_Des3_SetKey(&des, decryptedKey, tmpIv, DES_DECRYPTION);
wolfSSL 0:d92f9d21154c 1811 if (ret == 0)
wolfSSL 0:d92f9d21154c 1812 ret = wc_Des3_CbcDecrypt(&des, encryptedContent, encryptedContent,
wolfSSL 0:d92f9d21154c 1813 encryptedContentSz);
wolfSSL 0:d92f9d21154c 1814
wolfSSL 0:d92f9d21154c 1815 if (ret != 0) {
wolfSSL 0:d92f9d21154c 1816 XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1817 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 1818 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1819 #endif
wolfSSL 0:d92f9d21154c 1820 return ret;
wolfSSL 0:d92f9d21154c 1821 }
wolfSSL 0:d92f9d21154c 1822 } else {
wolfSSL 0:d92f9d21154c 1823 WOLFSSL_MSG("Unsupported content encryption OID type");
wolfSSL 0:d92f9d21154c 1824 XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1825 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 1826 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1827 #endif
wolfSSL 0:d92f9d21154c 1828 return ALGO_ID_E;
wolfSSL 0:d92f9d21154c 1829 }
wolfSSL 0:d92f9d21154c 1830
wolfSSL 0:d92f9d21154c 1831 padLen = encryptedContent[encryptedContentSz-1];
wolfSSL 0:d92f9d21154c 1832
wolfSSL 0:d92f9d21154c 1833 /* copy plaintext to output */
wolfSSL 0:d92f9d21154c 1834 XMEMCPY(output, encryptedContent, encryptedContentSz - padLen);
wolfSSL 0:d92f9d21154c 1835
wolfSSL 0:d92f9d21154c 1836 /* free memory, zero out keys */
wolfSSL 0:d92f9d21154c 1837 ForceZero(encryptedKey, MAX_ENCRYPTED_KEY_SZ);
wolfSSL 0:d92f9d21154c 1838 ForceZero(encryptedContent, encryptedContentSz);
wolfSSL 0:d92f9d21154c 1839 XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1840 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 0:d92f9d21154c 1841 XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:d92f9d21154c 1842 #endif
wolfSSL 0:d92f9d21154c 1843
wolfSSL 0:d92f9d21154c 1844 return encryptedContentSz - padLen;
wolfSSL 0:d92f9d21154c 1845 }
wolfSSL 0:d92f9d21154c 1846
wolfSSL 0:d92f9d21154c 1847
wolfSSL 0:d92f9d21154c 1848 #else /* HAVE_PKCS7 */
wolfSSL 0:d92f9d21154c 1849
wolfSSL 0:d92f9d21154c 1850
wolfSSL 0:d92f9d21154c 1851 #ifdef _MSC_VER
wolfSSL 0:d92f9d21154c 1852 /* 4206 warning for blank file */
wolfSSL 0:d92f9d21154c 1853 #pragma warning(disable: 4206)
wolfSSL 0:d92f9d21154c 1854 #endif
wolfSSL 0:d92f9d21154c 1855
wolfSSL 0:d92f9d21154c 1856
wolfSSL 0:d92f9d21154c 1857 #endif /* HAVE_PKCS7 */
wolfSSL 0:d92f9d21154c 1858
wolfSSL 0:d92f9d21154c 1859