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

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

Committer:
wolfSSL
Date:
Fri Jun 05 00:11:07 2020 +0000
Revision:
17:a5f916481144
Parent:
16:8e0d178b1d1e
wolfSSL 4.4.0

Who changed what in which revision?

UserRevisionLine numberNew contents of line
wolfSSL 15:117db924cf7c 1 /* pkcs7.c
wolfSSL 15:117db924cf7c 2 *
wolfSSL 16:8e0d178b1d1e 3 * Copyright (C) 2006-2020 wolfSSL Inc.
wolfSSL 15:117db924cf7c 4 *
wolfSSL 15:117db924cf7c 5 * This file is part of wolfSSL.
wolfSSL 15:117db924cf7c 6 *
wolfSSL 15:117db924cf7c 7 * wolfSSL is free software; you can redistribute it and/or modify
wolfSSL 15:117db924cf7c 8 * it under the terms of the GNU General Public License as published by
wolfSSL 15:117db924cf7c 9 * the Free Software Foundation; either version 2 of the License, or
wolfSSL 15:117db924cf7c 10 * (at your option) any later version.
wolfSSL 15:117db924cf7c 11 *
wolfSSL 15:117db924cf7c 12 * wolfSSL is distributed in the hope that it will be useful,
wolfSSL 15:117db924cf7c 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
wolfSSL 15:117db924cf7c 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
wolfSSL 15:117db924cf7c 15 * GNU General Public License for more details.
wolfSSL 15:117db924cf7c 16 *
wolfSSL 15:117db924cf7c 17 * You should have received a copy of the GNU General Public License
wolfSSL 15:117db924cf7c 18 * along with this program; if not, write to the Free Software
wolfSSL 15:117db924cf7c 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
wolfSSL 15:117db924cf7c 20 */
wolfSSL 15:117db924cf7c 21
wolfSSL 15:117db924cf7c 22
wolfSSL 15:117db924cf7c 23 #ifdef HAVE_CONFIG_H
wolfSSL 15:117db924cf7c 24 #include <config.h>
wolfSSL 15:117db924cf7c 25 #endif
wolfSSL 15:117db924cf7c 26
wolfSSL 15:117db924cf7c 27 #include <wolfssl/wolfcrypt/settings.h>
wolfSSL 15:117db924cf7c 28
wolfSSL 15:117db924cf7c 29 #ifdef HAVE_PKCS7
wolfSSL 15:117db924cf7c 30
wolfSSL 15:117db924cf7c 31 #include <wolfssl/wolfcrypt/pkcs7.h>
wolfSSL 15:117db924cf7c 32 #include <wolfssl/wolfcrypt/error-crypt.h>
wolfSSL 15:117db924cf7c 33 #include <wolfssl/wolfcrypt/logging.h>
wolfSSL 15:117db924cf7c 34 #include <wolfssl/wolfcrypt/hash.h>
wolfSSL 15:117db924cf7c 35 #ifndef NO_RSA
wolfSSL 15:117db924cf7c 36 #include <wolfssl/wolfcrypt/rsa.h>
wolfSSL 15:117db924cf7c 37 #endif
wolfSSL 15:117db924cf7c 38 #ifdef HAVE_ECC
wolfSSL 15:117db924cf7c 39 #include <wolfssl/wolfcrypt/ecc.h>
wolfSSL 15:117db924cf7c 40 #endif
wolfSSL 16:8e0d178b1d1e 41 #ifdef HAVE_LIBZ
wolfSSL 16:8e0d178b1d1e 42 #include <wolfssl/wolfcrypt/compress.h>
wolfSSL 16:8e0d178b1d1e 43 #endif
wolfSSL 16:8e0d178b1d1e 44 #ifndef NO_PWDBASED
wolfSSL 16:8e0d178b1d1e 45 #include <wolfssl/wolfcrypt/pwdbased.h>
wolfSSL 16:8e0d178b1d1e 46 #endif
wolfSSL 15:117db924cf7c 47 #ifdef NO_INLINE
wolfSSL 15:117db924cf7c 48 #include <wolfssl/wolfcrypt/misc.h>
wolfSSL 15:117db924cf7c 49 #else
wolfSSL 15:117db924cf7c 50 #define WOLFSSL_MISC_INCLUDED
wolfSSL 15:117db924cf7c 51 #include <wolfcrypt/src/misc.c>
wolfSSL 15:117db924cf7c 52 #endif
wolfSSL 15:117db924cf7c 53
wolfSSL 15:117db924cf7c 54 /* direction for processing, encoding or decoding */
wolfSSL 15:117db924cf7c 55 typedef enum {
wolfSSL 15:117db924cf7c 56 WC_PKCS7_ENCODE,
wolfSSL 15:117db924cf7c 57 WC_PKCS7_DECODE
wolfSSL 15:117db924cf7c 58 } pkcs7Direction;
wolfSSL 15:117db924cf7c 59
wolfSSL 16:8e0d178b1d1e 60 #define NO_USER_CHECK 0
wolfSSL 16:8e0d178b1d1e 61
wolfSSL 16:8e0d178b1d1e 62 /* holds information about the signers */
wolfSSL 16:8e0d178b1d1e 63 struct PKCS7SignerInfo {
wolfSSL 16:8e0d178b1d1e 64 int version;
wolfSSL 16:8e0d178b1d1e 65 byte *sid;
wolfSSL 16:8e0d178b1d1e 66 word32 sidSz;
wolfSSL 16:8e0d178b1d1e 67 };
wolfSSL 16:8e0d178b1d1e 68
wolfSSL 16:8e0d178b1d1e 69
wolfSSL 16:8e0d178b1d1e 70 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 71
wolfSSL 16:8e0d178b1d1e 72 #define MAX_PKCS7_STREAM_BUFFER 256
wolfSSL 16:8e0d178b1d1e 73 struct PKCS7State {
wolfSSL 16:8e0d178b1d1e 74 byte* tmpCert;
wolfSSL 16:8e0d178b1d1e 75 byte* bufferPt;
wolfSSL 16:8e0d178b1d1e 76 byte* key;
wolfSSL 16:8e0d178b1d1e 77 byte* nonce; /* stored nonce */
wolfSSL 16:8e0d178b1d1e 78 byte* aad; /* additional data for AEAD algos */
wolfSSL 16:8e0d178b1d1e 79 byte* tag; /* tag data for AEAD algos */
wolfSSL 16:8e0d178b1d1e 80 byte* content;
wolfSSL 16:8e0d178b1d1e 81 byte* buffer; /* main internal read buffer */
wolfSSL 16:8e0d178b1d1e 82
wolfSSL 16:8e0d178b1d1e 83 /* stack variables to store for when returning */
wolfSSL 16:8e0d178b1d1e 84 word32 varOne;
wolfSSL 16:8e0d178b1d1e 85 int varTwo;
wolfSSL 16:8e0d178b1d1e 86 int varThree;
wolfSSL 16:8e0d178b1d1e 87
wolfSSL 16:8e0d178b1d1e 88 word32 vers;
wolfSSL 16:8e0d178b1d1e 89 word32 idx; /* index read into current input buffer */
wolfSSL 16:8e0d178b1d1e 90 word32 maxLen; /* sanity cap on maximum amount of data to allow
wolfSSL 16:8e0d178b1d1e 91 * needed for GetSequence and other calls */
wolfSSL 16:8e0d178b1d1e 92 word32 length; /* amount of data stored */
wolfSSL 16:8e0d178b1d1e 93 word32 bufferSz; /* size of internal buffer */
wolfSSL 16:8e0d178b1d1e 94 word32 expected; /* next amount of data expected, if needed */
wolfSSL 16:8e0d178b1d1e 95 word32 totalRd; /* total amount of bytes read */
wolfSSL 16:8e0d178b1d1e 96 word32 nonceSz; /* size of nonce stored */
wolfSSL 16:8e0d178b1d1e 97 word32 aadSz; /* size of additional AEAD data */
wolfSSL 16:8e0d178b1d1e 98 word32 tagSz; /* size of tag for AEAD */
wolfSSL 16:8e0d178b1d1e 99 word32 contentSz;
wolfSSL 16:8e0d178b1d1e 100 byte tmpIv[MAX_CONTENT_IV_SIZE]; /* store IV if needed */
wolfSSL 16:8e0d178b1d1e 101 #ifdef WC_PKCS7_STREAM_DEBUG
wolfSSL 16:8e0d178b1d1e 102 word32 peakUsed; /* most bytes used for struct at any one time */
wolfSSL 16:8e0d178b1d1e 103 word32 peakRead; /* most bytes used by read buffer */
wolfSSL 16:8e0d178b1d1e 104 #endif
wolfSSL 16:8e0d178b1d1e 105 byte multi:1; /* flag for if content is in multiple parts */
wolfSSL 16:8e0d178b1d1e 106 byte flagOne:1;
wolfSSL 16:8e0d178b1d1e 107 byte detached:1; /* flag to indicate detached signature is present */
wolfSSL 16:8e0d178b1d1e 108 };
wolfSSL 16:8e0d178b1d1e 109
wolfSSL 16:8e0d178b1d1e 110
wolfSSL 16:8e0d178b1d1e 111 enum PKCS7_MaxLen {
wolfSSL 16:8e0d178b1d1e 112 PKCS7_DEFAULT_PEEK = 0,
wolfSSL 16:8e0d178b1d1e 113 PKCS7_SEQ_PEEK
wolfSSL 16:8e0d178b1d1e 114 };
wolfSSL 16:8e0d178b1d1e 115
wolfSSL 16:8e0d178b1d1e 116 /* creates a PKCS7State structure and returns 0 on success */
wolfSSL 16:8e0d178b1d1e 117 static int wc_PKCS7_CreateStream(PKCS7* pkcs7)
wolfSSL 16:8e0d178b1d1e 118 {
wolfSSL 16:8e0d178b1d1e 119 WOLFSSL_MSG("creating PKCS7 stream structure");
wolfSSL 16:8e0d178b1d1e 120 pkcs7->stream = (PKCS7State*)XMALLOC(sizeof(PKCS7State), pkcs7->heap,
wolfSSL 16:8e0d178b1d1e 121 DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 122 if (pkcs7->stream == NULL) {
wolfSSL 16:8e0d178b1d1e 123 return MEMORY_E;
wolfSSL 16:8e0d178b1d1e 124 }
wolfSSL 16:8e0d178b1d1e 125 XMEMSET(pkcs7->stream, 0, sizeof(PKCS7State));
wolfSSL 16:8e0d178b1d1e 126 #ifdef WC_PKCS7_STREAM_DEBUG
wolfSSL 16:8e0d178b1d1e 127 printf("\nCreating new PKCS#7 stream %p\n", pkcs7->stream);
wolfSSL 16:8e0d178b1d1e 128 #endif
wolfSSL 16:8e0d178b1d1e 129 return 0;
wolfSSL 16:8e0d178b1d1e 130 }
wolfSSL 16:8e0d178b1d1e 131
wolfSSL 16:8e0d178b1d1e 132
wolfSSL 16:8e0d178b1d1e 133 static void wc_PKCS7_ResetStream(PKCS7* pkcs7)
wolfSSL 16:8e0d178b1d1e 134 {
wolfSSL 16:8e0d178b1d1e 135 if (pkcs7 != NULL && pkcs7->stream != NULL) {
wolfSSL 16:8e0d178b1d1e 136 #ifdef WC_PKCS7_STREAM_DEBUG
wolfSSL 16:8e0d178b1d1e 137 /* collect final data point in case more was read right before reset */
wolfSSL 16:8e0d178b1d1e 138 if (pkcs7->stream->length > pkcs7->stream->peakRead) {
wolfSSL 16:8e0d178b1d1e 139 pkcs7->stream->peakRead = pkcs7->stream->length;
wolfSSL 16:8e0d178b1d1e 140 }
wolfSSL 16:8e0d178b1d1e 141 if (pkcs7->stream->bufferSz + pkcs7->stream->aadSz +
wolfSSL 16:8e0d178b1d1e 142 pkcs7->stream->nonceSz + pkcs7->stream->tagSz >
wolfSSL 16:8e0d178b1d1e 143 pkcs7->stream->peakUsed) {
wolfSSL 16:8e0d178b1d1e 144 pkcs7->stream->peakUsed = pkcs7->stream->bufferSz +
wolfSSL 16:8e0d178b1d1e 145 pkcs7->stream->aadSz + pkcs7->stream->nonceSz +
wolfSSL 16:8e0d178b1d1e 146 pkcs7->stream->tagSz;
wolfSSL 16:8e0d178b1d1e 147 }
wolfSSL 16:8e0d178b1d1e 148
wolfSSL 16:8e0d178b1d1e 149 /* print out debugging statistics */
wolfSSL 16:8e0d178b1d1e 150 if (pkcs7->stream->peakUsed > 0 || pkcs7->stream->peakRead > 0) {
wolfSSL 16:8e0d178b1d1e 151 printf("PKCS#7 STREAM:\n\tPeak heap used by struct = %d"
wolfSSL 16:8e0d178b1d1e 152 "\n\tPeak read buffer bytes = %d"
wolfSSL 16:8e0d178b1d1e 153 "\n\tTotal bytes read = %d"
wolfSSL 16:8e0d178b1d1e 154 "\n",
wolfSSL 16:8e0d178b1d1e 155 pkcs7->stream->peakUsed, pkcs7->stream->peakRead,
wolfSSL 16:8e0d178b1d1e 156 pkcs7->stream->totalRd);
wolfSSL 16:8e0d178b1d1e 157 }
wolfSSL 16:8e0d178b1d1e 158 printf("PKCS#7 stream reset : Address [%p]\n", pkcs7->stream);
wolfSSL 16:8e0d178b1d1e 159 #endif
wolfSSL 16:8e0d178b1d1e 160
wolfSSL 16:8e0d178b1d1e 161 /* free any buffers that may be allocated */
wolfSSL 16:8e0d178b1d1e 162 XFREE(pkcs7->stream->aad, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 163 XFREE(pkcs7->stream->tag, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 164 XFREE(pkcs7->stream->nonce, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 165 XFREE(pkcs7->stream->buffer, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 166 XFREE(pkcs7->stream->key, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 167 pkcs7->stream->aad = NULL;
wolfSSL 16:8e0d178b1d1e 168 pkcs7->stream->tag = NULL;
wolfSSL 16:8e0d178b1d1e 169 pkcs7->stream->nonce = NULL;
wolfSSL 16:8e0d178b1d1e 170 pkcs7->stream->buffer = NULL;
wolfSSL 16:8e0d178b1d1e 171 pkcs7->stream->key = NULL;
wolfSSL 16:8e0d178b1d1e 172
wolfSSL 16:8e0d178b1d1e 173 /* reset values, note that content and tmpCert are saved */
wolfSSL 16:8e0d178b1d1e 174 pkcs7->stream->maxLen = 0;
wolfSSL 16:8e0d178b1d1e 175 pkcs7->stream->length = 0;
wolfSSL 16:8e0d178b1d1e 176 pkcs7->stream->idx = 0;
wolfSSL 16:8e0d178b1d1e 177 pkcs7->stream->expected = 0;
wolfSSL 16:8e0d178b1d1e 178 pkcs7->stream->totalRd = 0;
wolfSSL 16:8e0d178b1d1e 179 pkcs7->stream->bufferSz = 0;
wolfSSL 16:8e0d178b1d1e 180
wolfSSL 16:8e0d178b1d1e 181 pkcs7->stream->multi = 0;
wolfSSL 16:8e0d178b1d1e 182 pkcs7->stream->flagOne = 0;
wolfSSL 16:8e0d178b1d1e 183 pkcs7->stream->detached = 0;
wolfSSL 16:8e0d178b1d1e 184 pkcs7->stream->varOne = 0;
wolfSSL 16:8e0d178b1d1e 185 pkcs7->stream->varTwo = 0;
wolfSSL 16:8e0d178b1d1e 186 pkcs7->stream->varThree = 0;
wolfSSL 16:8e0d178b1d1e 187 }
wolfSSL 16:8e0d178b1d1e 188 }
wolfSSL 16:8e0d178b1d1e 189
wolfSSL 16:8e0d178b1d1e 190
wolfSSL 16:8e0d178b1d1e 191 static void wc_PKCS7_FreeStream(PKCS7* pkcs7)
wolfSSL 16:8e0d178b1d1e 192 {
wolfSSL 16:8e0d178b1d1e 193 if (pkcs7 != NULL && pkcs7->stream != NULL) {
wolfSSL 16:8e0d178b1d1e 194 wc_PKCS7_ResetStream(pkcs7);
wolfSSL 16:8e0d178b1d1e 195
wolfSSL 16:8e0d178b1d1e 196 XFREE(pkcs7->stream->content, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 197 XFREE(pkcs7->stream->tmpCert, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 198 pkcs7->stream->content = NULL;
wolfSSL 16:8e0d178b1d1e 199 pkcs7->stream->tmpCert = NULL;
wolfSSL 16:8e0d178b1d1e 200
wolfSSL 16:8e0d178b1d1e 201 XFREE(pkcs7->stream, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 202 pkcs7->stream = NULL;
wolfSSL 16:8e0d178b1d1e 203 }
wolfSSL 16:8e0d178b1d1e 204 }
wolfSSL 16:8e0d178b1d1e 205
wolfSSL 16:8e0d178b1d1e 206
wolfSSL 16:8e0d178b1d1e 207 /* used to increase the max size for internal buffer
wolfSSL 16:8e0d178b1d1e 208 * returns 0 on success */
wolfSSL 16:8e0d178b1d1e 209 static int wc_PKCS7_GrowStream(PKCS7* pkcs7, word32 newSz)
wolfSSL 16:8e0d178b1d1e 210 {
wolfSSL 16:8e0d178b1d1e 211 byte* pt;
wolfSSL 16:8e0d178b1d1e 212
wolfSSL 16:8e0d178b1d1e 213 pt = (byte*)XMALLOC(newSz, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 214 if (pt == NULL) {
wolfSSL 16:8e0d178b1d1e 215 return MEMORY_E;
wolfSSL 16:8e0d178b1d1e 216 }
wolfSSL 16:8e0d178b1d1e 217 XMEMCPY(pt, pkcs7->stream->buffer, pkcs7->stream->bufferSz);
wolfSSL 16:8e0d178b1d1e 218
wolfSSL 16:8e0d178b1d1e 219 #ifdef WC_PKCS7_STREAM_DEBUG
wolfSSL 16:8e0d178b1d1e 220 printf("PKCS7 increasing internal stream buffer %d -> %d\n",
wolfSSL 16:8e0d178b1d1e 221 pkcs7->stream->bufferSz, newSz);
wolfSSL 16:8e0d178b1d1e 222 #endif
wolfSSL 16:8e0d178b1d1e 223 pkcs7->stream->bufferSz = newSz;
wolfSSL 16:8e0d178b1d1e 224 XFREE(pkcs7->stream->buffer, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 225 pkcs7->stream->buffer = pt;
wolfSSL 16:8e0d178b1d1e 226 return 0;
wolfSSL 16:8e0d178b1d1e 227 }
wolfSSL 16:8e0d178b1d1e 228
wolfSSL 16:8e0d178b1d1e 229
wolfSSL 16:8e0d178b1d1e 230 /* pt gets set to the buffer that is holding data in the case that stream struct
wolfSSL 16:8e0d178b1d1e 231 * is used.
wolfSSL 16:8e0d178b1d1e 232 *
wolfSSL 16:8e0d178b1d1e 233 * Sets idx to be the current offset into "pt" buffer
wolfSSL 16:8e0d178b1d1e 234 * returns 0 on success
wolfSSL 16:8e0d178b1d1e 235 */
wolfSSL 16:8e0d178b1d1e 236 static int wc_PKCS7_AddDataToStream(PKCS7* pkcs7, byte* in, word32 inSz,
wolfSSL 16:8e0d178b1d1e 237 word32 expected, byte** pt, word32* idx)
wolfSSL 16:8e0d178b1d1e 238 {
wolfSSL 16:8e0d178b1d1e 239 word32 rdSz = pkcs7->stream->idx;
wolfSSL 16:8e0d178b1d1e 240
wolfSSL 16:8e0d178b1d1e 241 /* If the input size minus current index into input buffer is greater than
wolfSSL 16:8e0d178b1d1e 242 * the expected size then use the input buffer. If data is already stored
wolfSSL 16:8e0d178b1d1e 243 * in stream buffer or if there is not enough input data available then use
wolfSSL 16:8e0d178b1d1e 244 * the stream buffer. */
wolfSSL 16:8e0d178b1d1e 245 if (inSz - rdSz >= expected && pkcs7->stream->length == 0) {
wolfSSL 16:8e0d178b1d1e 246 /* storing input buffer is not needed */
wolfSSL 16:8e0d178b1d1e 247 *pt = in; /* reset in case previously used internal buffer */
wolfSSL 16:8e0d178b1d1e 248 *idx = rdSz;
wolfSSL 16:8e0d178b1d1e 249 return 0;
wolfSSL 16:8e0d178b1d1e 250 }
wolfSSL 16:8e0d178b1d1e 251
wolfSSL 16:8e0d178b1d1e 252 /* is there enough stored in buffer already? */
wolfSSL 16:8e0d178b1d1e 253 if (pkcs7->stream->length >= expected) {
wolfSSL 16:8e0d178b1d1e 254 *idx = 0; /* start reading from beginning of stream buffer */
wolfSSL 16:8e0d178b1d1e 255 *pt = pkcs7->stream->buffer;
wolfSSL 16:8e0d178b1d1e 256 return 0;
wolfSSL 16:8e0d178b1d1e 257 }
wolfSSL 16:8e0d178b1d1e 258
wolfSSL 16:8e0d178b1d1e 259 /* check if all data has been read from input */
wolfSSL 16:8e0d178b1d1e 260 if (rdSz >= inSz) {
wolfSSL 16:8e0d178b1d1e 261 /* no more input to read, reset input index and request more data */
wolfSSL 16:8e0d178b1d1e 262 pkcs7->stream->idx = 0;
wolfSSL 16:8e0d178b1d1e 263 return WC_PKCS7_WANT_READ_E;
wolfSSL 16:8e0d178b1d1e 264 }
wolfSSL 16:8e0d178b1d1e 265
wolfSSL 16:8e0d178b1d1e 266 /* try to store input data into stream buffer */
wolfSSL 16:8e0d178b1d1e 267 if (inSz - rdSz > 0 && pkcs7->stream->length < expected) {
wolfSSL 16:8e0d178b1d1e 268 int len = min(inSz - rdSz, expected - pkcs7->stream->length);
wolfSSL 16:8e0d178b1d1e 269
wolfSSL 16:8e0d178b1d1e 270 /* sanity check that the input buffer is not internal buffer */
wolfSSL 16:8e0d178b1d1e 271 if (in == pkcs7->stream->buffer) {
wolfSSL 16:8e0d178b1d1e 272 return WC_PKCS7_WANT_READ_E;
wolfSSL 16:8e0d178b1d1e 273 }
wolfSSL 16:8e0d178b1d1e 274
wolfSSL 16:8e0d178b1d1e 275 /* check if internal buffer size needs to be increased */
wolfSSL 16:8e0d178b1d1e 276 if (len + pkcs7->stream->length > pkcs7->stream->bufferSz) {
wolfSSL 16:8e0d178b1d1e 277 int ret = wc_PKCS7_GrowStream(pkcs7, expected);
wolfSSL 16:8e0d178b1d1e 278 if (ret < 0) {
wolfSSL 16:8e0d178b1d1e 279 return ret;
wolfSSL 16:8e0d178b1d1e 280 }
wolfSSL 16:8e0d178b1d1e 281 }
wolfSSL 16:8e0d178b1d1e 282 XMEMCPY(pkcs7->stream->buffer + pkcs7->stream->length, in + rdSz, len);
wolfSSL 16:8e0d178b1d1e 283 pkcs7->stream->length += len;
wolfSSL 16:8e0d178b1d1e 284 pkcs7->stream->idx += len;
wolfSSL 16:8e0d178b1d1e 285 pkcs7->stream->totalRd += len;
wolfSSL 16:8e0d178b1d1e 286 }
wolfSSL 16:8e0d178b1d1e 287
wolfSSL 16:8e0d178b1d1e 288 #ifdef WC_PKCS7_STREAM_DEBUG
wolfSSL 16:8e0d178b1d1e 289 /* collects memory usage for debugging */
wolfSSL 16:8e0d178b1d1e 290 if (pkcs7->stream->length > pkcs7->stream->peakRead) {
wolfSSL 16:8e0d178b1d1e 291 pkcs7->stream->peakRead = pkcs7->stream->length;
wolfSSL 16:8e0d178b1d1e 292 }
wolfSSL 16:8e0d178b1d1e 293 if (pkcs7->stream->bufferSz + pkcs7->stream->aadSz + pkcs7->stream->nonceSz +
wolfSSL 16:8e0d178b1d1e 294 pkcs7->stream->tagSz > pkcs7->stream->peakUsed) {
wolfSSL 16:8e0d178b1d1e 295 pkcs7->stream->peakUsed = pkcs7->stream->bufferSz +
wolfSSL 16:8e0d178b1d1e 296 pkcs7->stream->aadSz + pkcs7->stream->nonceSz + pkcs7->stream->tagSz;
wolfSSL 16:8e0d178b1d1e 297 }
wolfSSL 16:8e0d178b1d1e 298 #endif
wolfSSL 16:8e0d178b1d1e 299
wolfSSL 16:8e0d178b1d1e 300 /* if not enough data was read in then request more */
wolfSSL 16:8e0d178b1d1e 301 if (pkcs7->stream->length < expected) {
wolfSSL 16:8e0d178b1d1e 302 pkcs7->stream->idx = 0;
wolfSSL 16:8e0d178b1d1e 303 return WC_PKCS7_WANT_READ_E;
wolfSSL 16:8e0d178b1d1e 304 }
wolfSSL 16:8e0d178b1d1e 305
wolfSSL 16:8e0d178b1d1e 306 /* adjust pointer to read from stored buffer */
wolfSSL 16:8e0d178b1d1e 307 *idx = 0;
wolfSSL 16:8e0d178b1d1e 308 *pt = pkcs7->stream->buffer;
wolfSSL 16:8e0d178b1d1e 309 return 0;
wolfSSL 16:8e0d178b1d1e 310 }
wolfSSL 16:8e0d178b1d1e 311
wolfSSL 16:8e0d178b1d1e 312
wolfSSL 16:8e0d178b1d1e 313 /* Does two things
wolfSSL 16:8e0d178b1d1e 314 * 1) Tries to get the length from current buffer and set it as max length
wolfSSL 16:8e0d178b1d1e 315 * 2) Retrieves the set max length
wolfSSL 16:8e0d178b1d1e 316 *
wolfSSL 16:8e0d178b1d1e 317 * if no flag value is set then the stored max length is returned.
wolfSSL 16:8e0d178b1d1e 318 * returns length found on success and defSz if no stored data is found
wolfSSL 16:8e0d178b1d1e 319 */
wolfSSL 16:8e0d178b1d1e 320 static long wc_PKCS7_GetMaxStream(PKCS7* pkcs7, byte flag, byte* in,
wolfSSL 16:8e0d178b1d1e 321 word32 defSz)
wolfSSL 16:8e0d178b1d1e 322 {
wolfSSL 16:8e0d178b1d1e 323 /* check there is a buffer to read from */
wolfSSL 16:8e0d178b1d1e 324 if (pkcs7) {
wolfSSL 16:8e0d178b1d1e 325 int length = 0, ret;
wolfSSL 16:8e0d178b1d1e 326 word32 idx = 0, maxIdx;
wolfSSL 16:8e0d178b1d1e 327 byte* pt;
wolfSSL 16:8e0d178b1d1e 328
wolfSSL 16:8e0d178b1d1e 329 if (flag != PKCS7_DEFAULT_PEEK) {
wolfSSL 16:8e0d178b1d1e 330 if (pkcs7->stream->length > 0) {
wolfSSL 16:8e0d178b1d1e 331 length = pkcs7->stream->length;
wolfSSL 16:8e0d178b1d1e 332 pt = pkcs7->stream->buffer;
wolfSSL 16:8e0d178b1d1e 333 }
wolfSSL 16:8e0d178b1d1e 334 else {
wolfSSL 16:8e0d178b1d1e 335 length = defSz;
wolfSSL 16:8e0d178b1d1e 336 pt = in;
wolfSSL 16:8e0d178b1d1e 337 }
wolfSSL 16:8e0d178b1d1e 338 maxIdx = (word32)length;
wolfSSL 16:8e0d178b1d1e 339
wolfSSL 16:8e0d178b1d1e 340 if (length < MAX_SEQ_SZ) {
wolfSSL 16:8e0d178b1d1e 341 WOLFSSL_MSG("PKCS7 Error not enough data for SEQ peek\n");
wolfSSL 16:8e0d178b1d1e 342 return 0;
wolfSSL 16:8e0d178b1d1e 343 }
wolfSSL 16:8e0d178b1d1e 344 if (flag == PKCS7_SEQ_PEEK) {
wolfSSL 16:8e0d178b1d1e 345 if ((ret = GetSequence_ex(pt, &idx, &length, maxIdx,
wolfSSL 16:8e0d178b1d1e 346 NO_USER_CHECK)) < 0) {
wolfSSL 16:8e0d178b1d1e 347 return ret;
wolfSSL 16:8e0d178b1d1e 348 }
wolfSSL 16:8e0d178b1d1e 349
wolfSSL 16:8e0d178b1d1e 350 #ifdef ASN_BER_TO_DER
wolfSSL 16:8e0d178b1d1e 351 if (length == 0 && ret == 0) {
wolfSSL 16:8e0d178b1d1e 352 idx = 0;
wolfSSL 16:8e0d178b1d1e 353 if ((ret = wc_BerToDer(pt, defSz, NULL,
wolfSSL 16:8e0d178b1d1e 354 (word32*)&length)) != LENGTH_ONLY_E) {
wolfSSL 16:8e0d178b1d1e 355 return ret;
wolfSSL 16:8e0d178b1d1e 356 }
wolfSSL 16:8e0d178b1d1e 357 }
wolfSSL 16:8e0d178b1d1e 358 #endif /* ASN_BER_TO_DER */
wolfSSL 16:8e0d178b1d1e 359 pkcs7->stream->maxLen = length + idx;
wolfSSL 16:8e0d178b1d1e 360 }
wolfSSL 16:8e0d178b1d1e 361 }
wolfSSL 16:8e0d178b1d1e 362
wolfSSL 16:8e0d178b1d1e 363 if (pkcs7->stream->maxLen == 0) {
wolfSSL 16:8e0d178b1d1e 364 pkcs7->stream->maxLen = defSz;
wolfSSL 16:8e0d178b1d1e 365 }
wolfSSL 16:8e0d178b1d1e 366
wolfSSL 16:8e0d178b1d1e 367 return pkcs7->stream->maxLen;
wolfSSL 16:8e0d178b1d1e 368 }
wolfSSL 16:8e0d178b1d1e 369
wolfSSL 16:8e0d178b1d1e 370 return defSz;
wolfSSL 16:8e0d178b1d1e 371 }
wolfSSL 16:8e0d178b1d1e 372
wolfSSL 16:8e0d178b1d1e 373
wolfSSL 16:8e0d178b1d1e 374 /* setter function for stored variables */
wolfSSL 16:8e0d178b1d1e 375 static void wc_PKCS7_StreamStoreVar(PKCS7* pkcs7, word32 var1, int var2,
wolfSSL 16:8e0d178b1d1e 376 int var3)
wolfSSL 16:8e0d178b1d1e 377 {
wolfSSL 16:8e0d178b1d1e 378 if (pkcs7 != NULL && pkcs7->stream != NULL) {
wolfSSL 16:8e0d178b1d1e 379 pkcs7->stream->varOne = var1;
wolfSSL 16:8e0d178b1d1e 380 pkcs7->stream->varTwo = var2;
wolfSSL 16:8e0d178b1d1e 381 pkcs7->stream->varThree = var3;
wolfSSL 16:8e0d178b1d1e 382 }
wolfSSL 16:8e0d178b1d1e 383 }
wolfSSL 16:8e0d178b1d1e 384
wolfSSL 16:8e0d178b1d1e 385 /* getter function for stored variables */
wolfSSL 16:8e0d178b1d1e 386 static void wc_PKCS7_StreamGetVar(PKCS7* pkcs7, word32* var1, int* var2,
wolfSSL 16:8e0d178b1d1e 387 int* var3)
wolfSSL 16:8e0d178b1d1e 388 {
wolfSSL 16:8e0d178b1d1e 389 if (pkcs7 != NULL && pkcs7->stream != NULL) {
wolfSSL 16:8e0d178b1d1e 390 if (var1 != NULL) *var1 = pkcs7->stream->varOne;
wolfSSL 16:8e0d178b1d1e 391 if (var2 != NULL) *var2 = pkcs7->stream->varTwo;
wolfSSL 16:8e0d178b1d1e 392 if (var3 != NULL) *var3 = pkcs7->stream->varThree;
wolfSSL 16:8e0d178b1d1e 393 }
wolfSSL 16:8e0d178b1d1e 394 }
wolfSSL 16:8e0d178b1d1e 395
wolfSSL 16:8e0d178b1d1e 396
wolfSSL 16:8e0d178b1d1e 397 /* common update of index and total read after section complete
wolfSSL 16:8e0d178b1d1e 398 * returns 0 on success */
wolfSSL 16:8e0d178b1d1e 399 static int wc_PKCS7_StreamEndCase(PKCS7* pkcs7, word32* tmpIdx, word32* idx)
wolfSSL 16:8e0d178b1d1e 400 {
wolfSSL 16:8e0d178b1d1e 401 int ret = 0;
wolfSSL 16:8e0d178b1d1e 402
wolfSSL 16:8e0d178b1d1e 403 if (pkcs7->stream->length > 0) {
wolfSSL 16:8e0d178b1d1e 404 if (pkcs7->stream->length < *idx) {
wolfSSL 16:8e0d178b1d1e 405 WOLFSSL_MSG("PKCS7 read too much data from internal buffer");
wolfSSL 16:8e0d178b1d1e 406 ret = BUFFER_E;
wolfSSL 16:8e0d178b1d1e 407 }
wolfSSL 16:8e0d178b1d1e 408 else {
wolfSSL 16:8e0d178b1d1e 409 XMEMMOVE(pkcs7->stream->buffer, pkcs7->stream->buffer + *idx,
wolfSSL 16:8e0d178b1d1e 410 pkcs7->stream->length - *idx);
wolfSSL 16:8e0d178b1d1e 411 pkcs7->stream->length -= *idx;
wolfSSL 16:8e0d178b1d1e 412 }
wolfSSL 16:8e0d178b1d1e 413 }
wolfSSL 16:8e0d178b1d1e 414 else {
wolfSSL 16:8e0d178b1d1e 415 pkcs7->stream->totalRd += *idx - *tmpIdx;
wolfSSL 16:8e0d178b1d1e 416 pkcs7->stream->idx = *idx; /* adjust index into input buffer */
wolfSSL 16:8e0d178b1d1e 417 *tmpIdx = *idx;
wolfSSL 16:8e0d178b1d1e 418 }
wolfSSL 16:8e0d178b1d1e 419
wolfSSL 16:8e0d178b1d1e 420 return ret;
wolfSSL 16:8e0d178b1d1e 421 }
wolfSSL 16:8e0d178b1d1e 422 #endif /* NO_PKCS7_STREAM */
wolfSSL 16:8e0d178b1d1e 423
wolfSSL 16:8e0d178b1d1e 424 #ifdef WC_PKCS7_STREAM_DEBUG
wolfSSL 16:8e0d178b1d1e 425 /* used to print out human readable state for debugging */
wolfSSL 16:8e0d178b1d1e 426 static const char* wc_PKCS7_GetStateName(int in)
wolfSSL 16:8e0d178b1d1e 427 {
wolfSSL 16:8e0d178b1d1e 428 switch (in) {
wolfSSL 16:8e0d178b1d1e 429 case WC_PKCS7_START: return "WC_PKCS7_START";
wolfSSL 16:8e0d178b1d1e 430
wolfSSL 16:8e0d178b1d1e 431 case WC_PKCS7_STAGE2: return "WC_PKCS7_STAGE2";
wolfSSL 16:8e0d178b1d1e 432 case WC_PKCS7_STAGE3: return "WC_PKCS7_STAGE3";
wolfSSL 16:8e0d178b1d1e 433 case WC_PKCS7_STAGE4: return "WC_PKCS7_STAGE4";
wolfSSL 16:8e0d178b1d1e 434 case WC_PKCS7_STAGE5: return "WC_PKCS7_STAGE5";
wolfSSL 16:8e0d178b1d1e 435 case WC_PKCS7_STAGE6: return "WC_PKCS7_STAGE6";
wolfSSL 16:8e0d178b1d1e 436
wolfSSL 16:8e0d178b1d1e 437 /* parse info set */
wolfSSL 16:8e0d178b1d1e 438 case WC_PKCS7_INFOSET_START: return "WC_PKCS7_INFOSET_START";
wolfSSL 16:8e0d178b1d1e 439 case WC_PKCS7_INFOSET_BER: return "WC_PKCS7_INFOSET_BER";
wolfSSL 16:8e0d178b1d1e 440 case WC_PKCS7_INFOSET_STAGE1: return "WC_PKCS7_INFOSET_STAGE1";
wolfSSL 16:8e0d178b1d1e 441 case WC_PKCS7_INFOSET_STAGE2: return "WC_PKCS7_INFOSET_STAGE2";
wolfSSL 16:8e0d178b1d1e 442 case WC_PKCS7_INFOSET_END: return "WC_PKCS7_INFOSET_END";
wolfSSL 16:8e0d178b1d1e 443
wolfSSL 16:8e0d178b1d1e 444 /* decode enveloped data */
wolfSSL 16:8e0d178b1d1e 445 case WC_PKCS7_ENV_2: return "WC_PKCS7_ENV_2";
wolfSSL 16:8e0d178b1d1e 446 case WC_PKCS7_ENV_3: return "WC_PKCS7_ENV_3";
wolfSSL 16:8e0d178b1d1e 447 case WC_PKCS7_ENV_4: return "WC_PKCS7_ENV_4";
wolfSSL 16:8e0d178b1d1e 448 case WC_PKCS7_ENV_5: return "WC_PKCS7_ENV_5";
wolfSSL 16:8e0d178b1d1e 449
wolfSSL 16:8e0d178b1d1e 450 /* decode auth enveloped */
wolfSSL 16:8e0d178b1d1e 451 case WC_PKCS7_AUTHENV_2: return "WC_PKCS7_AUTHENV_2";
wolfSSL 16:8e0d178b1d1e 452 case WC_PKCS7_AUTHENV_3: return "WC_PKCS7_AUTHENV_3";
wolfSSL 16:8e0d178b1d1e 453 case WC_PKCS7_AUTHENV_4: return "WC_PKCS7_AUTHENV_4";
wolfSSL 16:8e0d178b1d1e 454 case WC_PKCS7_AUTHENV_5: return "WC_PKCS7_AUTHENV_5";
wolfSSL 16:8e0d178b1d1e 455 case WC_PKCS7_AUTHENV_6: return "WC_PKCS7_AUTHENV_6";
wolfSSL 16:8e0d178b1d1e 456 case WC_PKCS7_AUTHENV_ATRB: return "WC_PKCS7_AUTHENV_ATRB";
wolfSSL 16:8e0d178b1d1e 457 case WC_PKCS7_AUTHENV_ATRBEND: return "WC_PKCS7_AUTHENV_ATRBEND";
wolfSSL 16:8e0d178b1d1e 458 case WC_PKCS7_AUTHENV_7: return "WC_PKCS7_AUTHENV_7";
wolfSSL 16:8e0d178b1d1e 459
wolfSSL 16:8e0d178b1d1e 460 /* decryption state types */
wolfSSL 16:8e0d178b1d1e 461 case WC_PKCS7_DECRYPT_KTRI: return "WC_PKCS7_DECRYPT_KTRI";
wolfSSL 16:8e0d178b1d1e 462 case WC_PKCS7_DECRYPT_KTRI_2: return "WC_PKCS7_DECRYPT_KTRI_2";
wolfSSL 16:8e0d178b1d1e 463 case WC_PKCS7_DECRYPT_KTRI_3: return "WC_PKCS7_DECRYPT_KTRI_3";
wolfSSL 16:8e0d178b1d1e 464
wolfSSL 16:8e0d178b1d1e 465 case WC_PKCS7_DECRYPT_KARI: return "WC_PKCS7_DECRYPT_KARI";
wolfSSL 16:8e0d178b1d1e 466 case WC_PKCS7_DECRYPT_KEKRI: return "WC_PKCS7_DECRYPT_KEKRI";
wolfSSL 16:8e0d178b1d1e 467 case WC_PKCS7_DECRYPT_PWRI: return "WC_PKCS7_DECRYPT_PWRI";
wolfSSL 16:8e0d178b1d1e 468 case WC_PKCS7_DECRYPT_ORI: return "WC_PKCS7_DECRYPT_ORI";
wolfSSL 16:8e0d178b1d1e 469 case WC_PKCS7_DECRYPT_DONE: return "WC_PKCS7_DECRYPT_DONE";
wolfSSL 16:8e0d178b1d1e 470
wolfSSL 16:8e0d178b1d1e 471 case WC_PKCS7_VERIFY_STAGE2: return "WC_PKCS7_VERIFY_STAGE2";
wolfSSL 16:8e0d178b1d1e 472 case WC_PKCS7_VERIFY_STAGE3: return "WC_PKCS7_VERIFY_STAGE3";
wolfSSL 16:8e0d178b1d1e 473 case WC_PKCS7_VERIFY_STAGE4: return "WC_PKCS7_VERIFY_STAGE4";
wolfSSL 16:8e0d178b1d1e 474 case WC_PKCS7_VERIFY_STAGE5: return "WC_PKCS7_VERIFY_STAGE5";
wolfSSL 16:8e0d178b1d1e 475 case WC_PKCS7_VERIFY_STAGE6: return "WC_PKCS7_VERIFY_STAGE6";
wolfSSL 16:8e0d178b1d1e 476
wolfSSL 16:8e0d178b1d1e 477 default:
wolfSSL 16:8e0d178b1d1e 478 return "Unknown state";
wolfSSL 16:8e0d178b1d1e 479 }
wolfSSL 16:8e0d178b1d1e 480 }
wolfSSL 16:8e0d178b1d1e 481 #endif
wolfSSL 16:8e0d178b1d1e 482
wolfSSL 16:8e0d178b1d1e 483 /* Used to change the PKCS7 state. Having state change as a function allows
wolfSSL 16:8e0d178b1d1e 484 * for easier debugging */
wolfSSL 16:8e0d178b1d1e 485 static void wc_PKCS7_ChangeState(PKCS7* pkcs7, int newState)
wolfSSL 16:8e0d178b1d1e 486 {
wolfSSL 16:8e0d178b1d1e 487 #ifdef WC_PKCS7_STREAM_DEBUG
wolfSSL 16:8e0d178b1d1e 488 printf("\tChanging from state [%02d] %s to [%02d] %s\n",
wolfSSL 16:8e0d178b1d1e 489 pkcs7->state, wc_PKCS7_GetStateName(pkcs7->state),
wolfSSL 16:8e0d178b1d1e 490 newState, wc_PKCS7_GetStateName(newState));
wolfSSL 16:8e0d178b1d1e 491 #endif
wolfSSL 16:8e0d178b1d1e 492 pkcs7->state = newState;
wolfSSL 16:8e0d178b1d1e 493 }
wolfSSL 16:8e0d178b1d1e 494
wolfSSL 15:117db924cf7c 495 #define MAX_PKCS7_DIGEST_SZ (MAX_SEQ_SZ + MAX_ALGO_SZ + \
wolfSSL 15:117db924cf7c 496 MAX_OCTET_STR_SZ + WC_MAX_DIGEST_SIZE)
wolfSSL 15:117db924cf7c 497
wolfSSL 15:117db924cf7c 498
wolfSSL 15:117db924cf7c 499 /* placed ASN.1 contentType OID into *output, return idx on success,
wolfSSL 15:117db924cf7c 500 * 0 upon failure */
wolfSSL 16:8e0d178b1d1e 501 static int wc_SetContentType(int pkcs7TypeOID, byte* output, word32 outputSz)
wolfSSL 15:117db924cf7c 502 {
wolfSSL 15:117db924cf7c 503 /* PKCS#7 content types, RFC 2315, section 14 */
wolfSSL 15:117db924cf7c 504 const byte pkcs7[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7,
wolfSSL 15:117db924cf7c 505 0x0D, 0x01, 0x07 };
wolfSSL 15:117db924cf7c 506 const byte data[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7,
wolfSSL 15:117db924cf7c 507 0x0D, 0x01, 0x07, 0x01 };
wolfSSL 15:117db924cf7c 508 const byte signedData[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7,
wolfSSL 15:117db924cf7c 509 0x0D, 0x01, 0x07, 0x02};
wolfSSL 15:117db924cf7c 510 const byte envelopedData[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7,
wolfSSL 15:117db924cf7c 511 0x0D, 0x01, 0x07, 0x03 };
wolfSSL 16:8e0d178b1d1e 512 const byte authEnvelopedData[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7,
wolfSSL 16:8e0d178b1d1e 513 0x0D, 0x01, 0x09, 0x10, 0x01, 0x17};
wolfSSL 15:117db924cf7c 514 const byte signedAndEnveloped[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7,
wolfSSL 15:117db924cf7c 515 0x0D, 0x01, 0x07, 0x04 };
wolfSSL 15:117db924cf7c 516 const byte digestedData[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7,
wolfSSL 15:117db924cf7c 517 0x0D, 0x01, 0x07, 0x05 };
wolfSSL 15:117db924cf7c 518 #ifndef NO_PKCS7_ENCRYPTED_DATA
wolfSSL 15:117db924cf7c 519 const byte encryptedData[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7,
wolfSSL 15:117db924cf7c 520 0x0D, 0x01, 0x07, 0x06 };
wolfSSL 15:117db924cf7c 521 #endif
wolfSSL 16:8e0d178b1d1e 522 /* FirmwarePkgData (1.2.840.113549.1.9.16.1.16), RFC 4108 */
wolfSSL 16:8e0d178b1d1e 523 const byte firmwarePkgData[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D,
wolfSSL 16:8e0d178b1d1e 524 0x01, 0x09, 0x10, 0x01, 0x10 };
wolfSSL 16:8e0d178b1d1e 525 #if defined(HAVE_LIBZ) && !defined(NO_PKCS7_COMPRESSED_DATA)
wolfSSL 16:8e0d178b1d1e 526 /* id-ct-compressedData (1.2.840.113549.1.9.16.1.9), RFC 3274 */
wolfSSL 16:8e0d178b1d1e 527 const byte compressedData[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D,
wolfSSL 16:8e0d178b1d1e 528 0x01, 0x09, 0x10, 0x01, 0x09 };
wolfSSL 16:8e0d178b1d1e 529 #endif
wolfSSL 16:8e0d178b1d1e 530
wolfSSL 16:8e0d178b1d1e 531 #if !defined(NO_PWDBASED) && !defined(NO_SHA)
wolfSSL 16:8e0d178b1d1e 532 const byte pwriKek[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D,
wolfSSL 16:8e0d178b1d1e 533 0x01, 0x09, 0x10, 0x03, 0x09 };
wolfSSL 16:8e0d178b1d1e 534 const byte pbkdf2[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D,
wolfSSL 16:8e0d178b1d1e 535 0x01, 0x05, 0x0C };
wolfSSL 16:8e0d178b1d1e 536 #endif
wolfSSL 16:8e0d178b1d1e 537
wolfSSL 16:8e0d178b1d1e 538 int idSz, idx = 0;
wolfSSL 16:8e0d178b1d1e 539 word32 typeSz = 0;
wolfSSL 15:117db924cf7c 540 const byte* typeName = 0;
wolfSSL 15:117db924cf7c 541 byte ID_Length[MAX_LENGTH_SZ];
wolfSSL 15:117db924cf7c 542
wolfSSL 15:117db924cf7c 543 switch (pkcs7TypeOID) {
wolfSSL 15:117db924cf7c 544 case PKCS7_MSG:
wolfSSL 15:117db924cf7c 545 typeSz = sizeof(pkcs7);
wolfSSL 15:117db924cf7c 546 typeName = pkcs7;
wolfSSL 15:117db924cf7c 547 break;
wolfSSL 15:117db924cf7c 548
wolfSSL 15:117db924cf7c 549 case DATA:
wolfSSL 15:117db924cf7c 550 typeSz = sizeof(data);
wolfSSL 15:117db924cf7c 551 typeName = data;
wolfSSL 15:117db924cf7c 552 break;
wolfSSL 15:117db924cf7c 553
wolfSSL 15:117db924cf7c 554 case SIGNED_DATA:
wolfSSL 15:117db924cf7c 555 typeSz = sizeof(signedData);
wolfSSL 15:117db924cf7c 556 typeName = signedData;
wolfSSL 15:117db924cf7c 557 break;
wolfSSL 15:117db924cf7c 558
wolfSSL 15:117db924cf7c 559 case ENVELOPED_DATA:
wolfSSL 15:117db924cf7c 560 typeSz = sizeof(envelopedData);
wolfSSL 15:117db924cf7c 561 typeName = envelopedData;
wolfSSL 15:117db924cf7c 562 break;
wolfSSL 15:117db924cf7c 563
wolfSSL 16:8e0d178b1d1e 564 case AUTH_ENVELOPED_DATA:
wolfSSL 16:8e0d178b1d1e 565 typeSz = sizeof(authEnvelopedData);
wolfSSL 16:8e0d178b1d1e 566 typeName = authEnvelopedData;
wolfSSL 16:8e0d178b1d1e 567 break;
wolfSSL 16:8e0d178b1d1e 568
wolfSSL 15:117db924cf7c 569 case SIGNED_AND_ENVELOPED_DATA:
wolfSSL 15:117db924cf7c 570 typeSz = sizeof(signedAndEnveloped);
wolfSSL 15:117db924cf7c 571 typeName = signedAndEnveloped;
wolfSSL 15:117db924cf7c 572 break;
wolfSSL 15:117db924cf7c 573
wolfSSL 15:117db924cf7c 574 case DIGESTED_DATA:
wolfSSL 15:117db924cf7c 575 typeSz = sizeof(digestedData);
wolfSSL 15:117db924cf7c 576 typeName = digestedData;
wolfSSL 15:117db924cf7c 577 break;
wolfSSL 15:117db924cf7c 578
wolfSSL 15:117db924cf7c 579 #ifndef NO_PKCS7_ENCRYPTED_DATA
wolfSSL 15:117db924cf7c 580 case ENCRYPTED_DATA:
wolfSSL 15:117db924cf7c 581 typeSz = sizeof(encryptedData);
wolfSSL 15:117db924cf7c 582 typeName = encryptedData;
wolfSSL 15:117db924cf7c 583 break;
wolfSSL 15:117db924cf7c 584 #endif
wolfSSL 16:8e0d178b1d1e 585 #if defined(HAVE_LIBZ) && !defined(NO_PKCS7_COMPRESSED_DATA)
wolfSSL 16:8e0d178b1d1e 586 case COMPRESSED_DATA:
wolfSSL 16:8e0d178b1d1e 587 typeSz = sizeof(compressedData);
wolfSSL 16:8e0d178b1d1e 588 typeName = compressedData;
wolfSSL 16:8e0d178b1d1e 589 break;
wolfSSL 16:8e0d178b1d1e 590 #endif
wolfSSL 16:8e0d178b1d1e 591 case FIRMWARE_PKG_DATA:
wolfSSL 16:8e0d178b1d1e 592 typeSz = sizeof(firmwarePkgData);
wolfSSL 16:8e0d178b1d1e 593 typeName = firmwarePkgData;
wolfSSL 16:8e0d178b1d1e 594 break;
wolfSSL 16:8e0d178b1d1e 595
wolfSSL 16:8e0d178b1d1e 596 #if !defined(NO_PWDBASED) && !defined(NO_SHA)
wolfSSL 16:8e0d178b1d1e 597 case PWRI_KEK_WRAP:
wolfSSL 16:8e0d178b1d1e 598 typeSz = sizeof(pwriKek);
wolfSSL 16:8e0d178b1d1e 599 typeName = pwriKek;
wolfSSL 16:8e0d178b1d1e 600 break;
wolfSSL 16:8e0d178b1d1e 601
wolfSSL 16:8e0d178b1d1e 602 case PBKDF2_OID:
wolfSSL 16:8e0d178b1d1e 603 typeSz = sizeof(pbkdf2);
wolfSSL 16:8e0d178b1d1e 604 typeName = pbkdf2;
wolfSSL 16:8e0d178b1d1e 605 break;
wolfSSL 16:8e0d178b1d1e 606 #endif
wolfSSL 15:117db924cf7c 607
wolfSSL 15:117db924cf7c 608 default:
wolfSSL 15:117db924cf7c 609 WOLFSSL_MSG("Unknown PKCS#7 Type");
wolfSSL 15:117db924cf7c 610 return 0;
wolfSSL 15:117db924cf7c 611 };
wolfSSL 15:117db924cf7c 612
wolfSSL 16:8e0d178b1d1e 613 if (outputSz < (MAX_LENGTH_SZ + 1 + typeSz)) {
wolfSSL 16:8e0d178b1d1e 614 WOLFSSL_MSG("CMS content type buffer too small");
wolfSSL 16:8e0d178b1d1e 615 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 616 }
wolfSSL 16:8e0d178b1d1e 617
wolfSSL 15:117db924cf7c 618 idSz = SetLength(typeSz, ID_Length);
wolfSSL 15:117db924cf7c 619 output[idx++] = ASN_OBJECT_ID;
wolfSSL 15:117db924cf7c 620 XMEMCPY(output + idx, ID_Length, idSz);
wolfSSL 15:117db924cf7c 621 idx += idSz;
wolfSSL 15:117db924cf7c 622 XMEMCPY(output + idx, typeName, typeSz);
wolfSSL 15:117db924cf7c 623 idx += typeSz;
wolfSSL 15:117db924cf7c 624
wolfSSL 15:117db924cf7c 625 return idx;
wolfSSL 15:117db924cf7c 626 }
wolfSSL 15:117db924cf7c 627
wolfSSL 15:117db924cf7c 628
wolfSSL 15:117db924cf7c 629 /* get ASN.1 contentType OID sum, return 0 on success, <0 on failure */
wolfSSL 15:117db924cf7c 630 static int wc_GetContentType(const byte* input, word32* inOutIdx, word32* oid,
wolfSSL 15:117db924cf7c 631 word32 maxIdx)
wolfSSL 15:117db924cf7c 632 {
wolfSSL 15:117db924cf7c 633 WOLFSSL_ENTER("wc_GetContentType");
wolfSSL 15:117db924cf7c 634 if (GetObjectId(input, inOutIdx, oid, oidIgnoreType, maxIdx) < 0)
wolfSSL 15:117db924cf7c 635 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 636
wolfSSL 15:117db924cf7c 637 return 0;
wolfSSL 15:117db924cf7c 638 }
wolfSSL 15:117db924cf7c 639
wolfSSL 15:117db924cf7c 640
wolfSSL 15:117db924cf7c 641 /* return block size for algorithm represented by oid, or <0 on error */
wolfSSL 15:117db924cf7c 642 static int wc_PKCS7_GetOIDBlockSize(int oid)
wolfSSL 15:117db924cf7c 643 {
wolfSSL 15:117db924cf7c 644 int blockSz;
wolfSSL 15:117db924cf7c 645
wolfSSL 15:117db924cf7c 646 switch (oid) {
wolfSSL 15:117db924cf7c 647 #ifndef NO_AES
wolfSSL 15:117db924cf7c 648 #ifdef WOLFSSL_AES_128
wolfSSL 15:117db924cf7c 649 case AES128CBCb:
wolfSSL 16:8e0d178b1d1e 650 case AES128GCMb:
wolfSSL 16:8e0d178b1d1e 651 case AES128CCMb:
wolfSSL 15:117db924cf7c 652 #endif
wolfSSL 15:117db924cf7c 653 #ifdef WOLFSSL_AES_192
wolfSSL 15:117db924cf7c 654 case AES192CBCb:
wolfSSL 16:8e0d178b1d1e 655 case AES192GCMb:
wolfSSL 16:8e0d178b1d1e 656 case AES192CCMb:
wolfSSL 15:117db924cf7c 657 #endif
wolfSSL 15:117db924cf7c 658 #ifdef WOLFSSL_AES_256
wolfSSL 15:117db924cf7c 659 case AES256CBCb:
wolfSSL 16:8e0d178b1d1e 660 case AES256GCMb:
wolfSSL 16:8e0d178b1d1e 661 case AES256CCMb:
wolfSSL 15:117db924cf7c 662 #endif
wolfSSL 15:117db924cf7c 663 blockSz = AES_BLOCK_SIZE;
wolfSSL 15:117db924cf7c 664 break;
wolfSSL 15:117db924cf7c 665 #endif
wolfSSL 15:117db924cf7c 666 #ifndef NO_DES3
wolfSSL 15:117db924cf7c 667 case DESb:
wolfSSL 15:117db924cf7c 668 case DES3b:
wolfSSL 15:117db924cf7c 669 blockSz = DES_BLOCK_SIZE;
wolfSSL 15:117db924cf7c 670 break;
wolfSSL 15:117db924cf7c 671 #endif
wolfSSL 15:117db924cf7c 672 default:
wolfSSL 15:117db924cf7c 673 WOLFSSL_MSG("Unsupported content cipher type");
wolfSSL 15:117db924cf7c 674 return ALGO_ID_E;
wolfSSL 15:117db924cf7c 675 };
wolfSSL 15:117db924cf7c 676
wolfSSL 15:117db924cf7c 677 return blockSz;
wolfSSL 15:117db924cf7c 678 }
wolfSSL 15:117db924cf7c 679
wolfSSL 15:117db924cf7c 680
wolfSSL 15:117db924cf7c 681 /* get key size for algorithm represented by oid, or <0 on error */
wolfSSL 15:117db924cf7c 682 static int wc_PKCS7_GetOIDKeySize(int oid)
wolfSSL 15:117db924cf7c 683 {
wolfSSL 15:117db924cf7c 684 int blockKeySz;
wolfSSL 15:117db924cf7c 685
wolfSSL 15:117db924cf7c 686 switch (oid) {
wolfSSL 15:117db924cf7c 687 #ifndef NO_AES
wolfSSL 15:117db924cf7c 688 #ifdef WOLFSSL_AES_128
wolfSSL 15:117db924cf7c 689 case AES128CBCb:
wolfSSL 16:8e0d178b1d1e 690 case AES128GCMb:
wolfSSL 16:8e0d178b1d1e 691 case AES128CCMb:
wolfSSL 15:117db924cf7c 692 case AES128_WRAP:
wolfSSL 15:117db924cf7c 693 blockKeySz = 16;
wolfSSL 15:117db924cf7c 694 break;
wolfSSL 15:117db924cf7c 695 #endif
wolfSSL 15:117db924cf7c 696 #ifdef WOLFSSL_AES_192
wolfSSL 15:117db924cf7c 697 case AES192CBCb:
wolfSSL 16:8e0d178b1d1e 698 case AES192GCMb:
wolfSSL 16:8e0d178b1d1e 699 case AES192CCMb:
wolfSSL 15:117db924cf7c 700 case AES192_WRAP:
wolfSSL 15:117db924cf7c 701 blockKeySz = 24;
wolfSSL 15:117db924cf7c 702 break;
wolfSSL 15:117db924cf7c 703 #endif
wolfSSL 15:117db924cf7c 704 #ifdef WOLFSSL_AES_256
wolfSSL 15:117db924cf7c 705 case AES256CBCb:
wolfSSL 16:8e0d178b1d1e 706 case AES256GCMb:
wolfSSL 16:8e0d178b1d1e 707 case AES256CCMb:
wolfSSL 15:117db924cf7c 708 case AES256_WRAP:
wolfSSL 15:117db924cf7c 709 blockKeySz = 32;
wolfSSL 15:117db924cf7c 710 break;
wolfSSL 15:117db924cf7c 711 #endif
wolfSSL 15:117db924cf7c 712 #endif
wolfSSL 15:117db924cf7c 713 #ifndef NO_DES3
wolfSSL 15:117db924cf7c 714 case DESb:
wolfSSL 15:117db924cf7c 715 blockKeySz = DES_KEYLEN;
wolfSSL 15:117db924cf7c 716 break;
wolfSSL 15:117db924cf7c 717
wolfSSL 15:117db924cf7c 718 case DES3b:
wolfSSL 15:117db924cf7c 719 blockKeySz = DES3_KEYLEN;
wolfSSL 15:117db924cf7c 720 break;
wolfSSL 15:117db924cf7c 721 #endif
wolfSSL 15:117db924cf7c 722 default:
wolfSSL 15:117db924cf7c 723 WOLFSSL_MSG("Unsupported content cipher type");
wolfSSL 15:117db924cf7c 724 return ALGO_ID_E;
wolfSSL 15:117db924cf7c 725 };
wolfSSL 15:117db924cf7c 726
wolfSSL 15:117db924cf7c 727 return blockKeySz;
wolfSSL 15:117db924cf7c 728 }
wolfSSL 15:117db924cf7c 729
wolfSSL 15:117db924cf7c 730
wolfSSL 15:117db924cf7c 731 PKCS7* wc_PKCS7_New(void* heap, int devId)
wolfSSL 15:117db924cf7c 732 {
wolfSSL 15:117db924cf7c 733 PKCS7* pkcs7 = (PKCS7*)XMALLOC(sizeof(PKCS7), heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 734 if (pkcs7) {
wolfSSL 15:117db924cf7c 735 XMEMSET(pkcs7, 0, sizeof(PKCS7));
wolfSSL 15:117db924cf7c 736 if (wc_PKCS7_Init(pkcs7, heap, devId) == 0) {
wolfSSL 15:117db924cf7c 737 pkcs7->isDynamic = 1;
wolfSSL 15:117db924cf7c 738 }
wolfSSL 15:117db924cf7c 739 else {
wolfSSL 15:117db924cf7c 740 XFREE(pkcs7, heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 741 pkcs7 = NULL;
wolfSSL 15:117db924cf7c 742 }
wolfSSL 15:117db924cf7c 743 }
wolfSSL 15:117db924cf7c 744 return pkcs7;
wolfSSL 15:117db924cf7c 745 }
wolfSSL 15:117db924cf7c 746
wolfSSL 15:117db924cf7c 747 /* This is to initialize a PKCS7 structure. It sets all values to 0 and can be
wolfSSL 15:117db924cf7c 748 * used to set the heap hint.
wolfSSL 15:117db924cf7c 749 *
wolfSSL 15:117db924cf7c 750 * pkcs7 PKCS7 structure to initialize
wolfSSL 15:117db924cf7c 751 * heap memory heap hint for PKCS7 structure to use
wolfSSL 15:117db924cf7c 752 * devId currently not used but a place holder for async operations
wolfSSL 15:117db924cf7c 753 *
wolfSSL 15:117db924cf7c 754 * returns 0 on success or a negative value for failure
wolfSSL 15:117db924cf7c 755 */
wolfSSL 15:117db924cf7c 756 int wc_PKCS7_Init(PKCS7* pkcs7, void* heap, int devId)
wolfSSL 15:117db924cf7c 757 {
wolfSSL 16:8e0d178b1d1e 758 word16 isDynamic;
wolfSSL 16:8e0d178b1d1e 759
wolfSSL 15:117db924cf7c 760 WOLFSSL_ENTER("wc_PKCS7_Init");
wolfSSL 15:117db924cf7c 761
wolfSSL 15:117db924cf7c 762 if (pkcs7 == NULL) {
wolfSSL 15:117db924cf7c 763 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 764 }
wolfSSL 15:117db924cf7c 765
wolfSSL 16:8e0d178b1d1e 766 isDynamic = pkcs7->isDynamic;
wolfSSL 15:117db924cf7c 767 XMEMSET(pkcs7, 0, sizeof(PKCS7));
wolfSSL 16:8e0d178b1d1e 768 pkcs7->isDynamic = isDynamic;
wolfSSL 15:117db924cf7c 769 #ifdef WOLFSSL_HEAP_TEST
wolfSSL 15:117db924cf7c 770 pkcs7->heap = (void*)WOLFSSL_HEAP_TEST;
wolfSSL 15:117db924cf7c 771 #else
wolfSSL 15:117db924cf7c 772 pkcs7->heap = heap;
wolfSSL 15:117db924cf7c 773 #endif
wolfSSL 15:117db924cf7c 774 pkcs7->devId = devId;
wolfSSL 15:117db924cf7c 775
wolfSSL 15:117db924cf7c 776 return 0;
wolfSSL 15:117db924cf7c 777 }
wolfSSL 15:117db924cf7c 778
wolfSSL 15:117db924cf7c 779
wolfSSL 16:8e0d178b1d1e 780 /* Certificate structure holding der pointer, size, and pointer to next
wolfSSL 16:8e0d178b1d1e 781 * Pkcs7Cert struct. Used when creating SignedData types with multiple
wolfSSL 16:8e0d178b1d1e 782 * certificates. */
wolfSSL 16:8e0d178b1d1e 783 struct Pkcs7Cert {
wolfSSL 16:8e0d178b1d1e 784 byte* der;
wolfSSL 16:8e0d178b1d1e 785 word32 derSz;
wolfSSL 16:8e0d178b1d1e 786 Pkcs7Cert* next;
wolfSSL 16:8e0d178b1d1e 787 };
wolfSSL 16:8e0d178b1d1e 788
wolfSSL 16:8e0d178b1d1e 789
wolfSSL 16:8e0d178b1d1e 790 /* Linked list of ASN.1 encoded RecipientInfos */
wolfSSL 16:8e0d178b1d1e 791 struct Pkcs7EncodedRecip {
wolfSSL 16:8e0d178b1d1e 792 byte recip[MAX_RECIP_SZ];
wolfSSL 16:8e0d178b1d1e 793 word32 recipSz;
wolfSSL 16:8e0d178b1d1e 794 int recipType;
wolfSSL 16:8e0d178b1d1e 795 int recipVersion;
wolfSSL 16:8e0d178b1d1e 796 Pkcs7EncodedRecip* next;
wolfSSL 16:8e0d178b1d1e 797 };
wolfSSL 16:8e0d178b1d1e 798
wolfSSL 16:8e0d178b1d1e 799
wolfSSL 16:8e0d178b1d1e 800 /* free all members of Pkcs7Cert linked list */
wolfSSL 16:8e0d178b1d1e 801 static void wc_PKCS7_FreeCertSet(PKCS7* pkcs7)
wolfSSL 16:8e0d178b1d1e 802 {
wolfSSL 16:8e0d178b1d1e 803 Pkcs7Cert* curr = NULL;
wolfSSL 16:8e0d178b1d1e 804 Pkcs7Cert* next = NULL;
wolfSSL 16:8e0d178b1d1e 805
wolfSSL 16:8e0d178b1d1e 806 if (pkcs7 == NULL)
wolfSSL 16:8e0d178b1d1e 807 return;
wolfSSL 16:8e0d178b1d1e 808
wolfSSL 16:8e0d178b1d1e 809 curr = pkcs7->certList;
wolfSSL 16:8e0d178b1d1e 810 pkcs7->certList = NULL;
wolfSSL 16:8e0d178b1d1e 811
wolfSSL 16:8e0d178b1d1e 812 while (curr != NULL) {
wolfSSL 16:8e0d178b1d1e 813 next = curr->next;
wolfSSL 16:8e0d178b1d1e 814 curr->next = NULL;
wolfSSL 16:8e0d178b1d1e 815 XFREE(curr, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 816 curr = next;
wolfSSL 16:8e0d178b1d1e 817 }
wolfSSL 16:8e0d178b1d1e 818
wolfSSL 16:8e0d178b1d1e 819 return;
wolfSSL 16:8e0d178b1d1e 820 }
wolfSSL 16:8e0d178b1d1e 821
wolfSSL 16:8e0d178b1d1e 822
wolfSSL 16:8e0d178b1d1e 823 /* Get total size of all recipients in recipient list.
wolfSSL 16:8e0d178b1d1e 824 *
wolfSSL 16:8e0d178b1d1e 825 * Returns total size of recipients, or negative upon error */
wolfSSL 16:8e0d178b1d1e 826 static int wc_PKCS7_GetRecipientListSize(PKCS7* pkcs7)
wolfSSL 16:8e0d178b1d1e 827 {
wolfSSL 16:8e0d178b1d1e 828 int totalSz = 0;
wolfSSL 16:8e0d178b1d1e 829 Pkcs7EncodedRecip* tmp = NULL;
wolfSSL 16:8e0d178b1d1e 830
wolfSSL 16:8e0d178b1d1e 831 if (pkcs7 == NULL)
wolfSSL 16:8e0d178b1d1e 832 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 833
wolfSSL 16:8e0d178b1d1e 834 tmp = pkcs7->recipList;
wolfSSL 16:8e0d178b1d1e 835
wolfSSL 16:8e0d178b1d1e 836 while (tmp != NULL) {
wolfSSL 16:8e0d178b1d1e 837 totalSz += tmp->recipSz;
wolfSSL 16:8e0d178b1d1e 838 tmp = tmp->next;
wolfSSL 16:8e0d178b1d1e 839 }
wolfSSL 16:8e0d178b1d1e 840
wolfSSL 16:8e0d178b1d1e 841 return totalSz;
wolfSSL 16:8e0d178b1d1e 842 }
wolfSSL 16:8e0d178b1d1e 843
wolfSSL 16:8e0d178b1d1e 844
wolfSSL 16:8e0d178b1d1e 845 /* free all members of Pkcs7EncodedRecip linked list */
wolfSSL 16:8e0d178b1d1e 846 static void wc_PKCS7_FreeEncodedRecipientSet(PKCS7* pkcs7)
wolfSSL 16:8e0d178b1d1e 847 {
wolfSSL 16:8e0d178b1d1e 848 Pkcs7EncodedRecip* curr = NULL;
wolfSSL 16:8e0d178b1d1e 849 Pkcs7EncodedRecip* next = NULL;
wolfSSL 16:8e0d178b1d1e 850
wolfSSL 16:8e0d178b1d1e 851 if (pkcs7 == NULL)
wolfSSL 16:8e0d178b1d1e 852 return;
wolfSSL 16:8e0d178b1d1e 853
wolfSSL 16:8e0d178b1d1e 854 curr = pkcs7->recipList;
wolfSSL 16:8e0d178b1d1e 855 pkcs7->recipList = NULL;
wolfSSL 16:8e0d178b1d1e 856
wolfSSL 16:8e0d178b1d1e 857 while (curr != NULL) {
wolfSSL 16:8e0d178b1d1e 858 next = curr->next;
wolfSSL 16:8e0d178b1d1e 859 curr->next = NULL;
wolfSSL 16:8e0d178b1d1e 860 XFREE(curr, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 861 curr = next;
wolfSSL 16:8e0d178b1d1e 862 }
wolfSSL 16:8e0d178b1d1e 863
wolfSSL 16:8e0d178b1d1e 864 return;
wolfSSL 16:8e0d178b1d1e 865 }
wolfSSL 16:8e0d178b1d1e 866
wolfSSL 16:8e0d178b1d1e 867
wolfSSL 16:8e0d178b1d1e 868 /* search through RecipientInfo list for specific type.
wolfSSL 16:8e0d178b1d1e 869 * return 1 if ANY recipient of type specified is present, otherwise
wolfSSL 16:8e0d178b1d1e 870 * return 0 */
wolfSSL 16:8e0d178b1d1e 871 static int wc_PKCS7_RecipientListIncludesType(PKCS7* pkcs7, int type)
wolfSSL 16:8e0d178b1d1e 872 {
wolfSSL 16:8e0d178b1d1e 873 Pkcs7EncodedRecip* tmp = NULL;
wolfSSL 16:8e0d178b1d1e 874
wolfSSL 16:8e0d178b1d1e 875 if (pkcs7 == NULL)
wolfSSL 16:8e0d178b1d1e 876 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 877
wolfSSL 16:8e0d178b1d1e 878 tmp = pkcs7->recipList;
wolfSSL 16:8e0d178b1d1e 879
wolfSSL 16:8e0d178b1d1e 880 while (tmp != NULL) {
wolfSSL 16:8e0d178b1d1e 881 if (tmp->recipType == type)
wolfSSL 16:8e0d178b1d1e 882 return 1;
wolfSSL 16:8e0d178b1d1e 883
wolfSSL 16:8e0d178b1d1e 884 tmp = tmp->next;
wolfSSL 16:8e0d178b1d1e 885 }
wolfSSL 16:8e0d178b1d1e 886
wolfSSL 16:8e0d178b1d1e 887 return 0;
wolfSSL 16:8e0d178b1d1e 888 }
wolfSSL 16:8e0d178b1d1e 889
wolfSSL 16:8e0d178b1d1e 890
wolfSSL 16:8e0d178b1d1e 891 /* searches through RecipientInfo list, returns 1 if all structure
wolfSSL 16:8e0d178b1d1e 892 * versions are set to 0, otherwise returns 0 */
wolfSSL 16:8e0d178b1d1e 893 static int wc_PKCS7_RecipientListVersionsAllZero(PKCS7* pkcs7)
wolfSSL 16:8e0d178b1d1e 894 {
wolfSSL 16:8e0d178b1d1e 895 Pkcs7EncodedRecip* tmp = NULL;
wolfSSL 16:8e0d178b1d1e 896
wolfSSL 16:8e0d178b1d1e 897 if (pkcs7 == NULL)
wolfSSL 16:8e0d178b1d1e 898 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 899
wolfSSL 16:8e0d178b1d1e 900 tmp = pkcs7->recipList;
wolfSSL 16:8e0d178b1d1e 901
wolfSSL 16:8e0d178b1d1e 902 while (tmp != NULL) {
wolfSSL 16:8e0d178b1d1e 903 if (tmp->recipVersion != 0)
wolfSSL 16:8e0d178b1d1e 904 return 0;
wolfSSL 16:8e0d178b1d1e 905
wolfSSL 16:8e0d178b1d1e 906 tmp = tmp->next;
wolfSSL 16:8e0d178b1d1e 907 }
wolfSSL 16:8e0d178b1d1e 908
wolfSSL 16:8e0d178b1d1e 909 return 1;
wolfSSL 16:8e0d178b1d1e 910 }
wolfSSL 16:8e0d178b1d1e 911
wolfSSL 16:8e0d178b1d1e 912
wolfSSL 16:8e0d178b1d1e 913 /* Init PKCS7 struct with recipient cert, decode into DecodedCert
wolfSSL 15:117db924cf7c 914 * NOTE: keeps previously set pkcs7 heap hint, devId and isDynamic */
wolfSSL 16:8e0d178b1d1e 915 int wc_PKCS7_InitWithCert(PKCS7* pkcs7, byte* derCert, word32 derCertSz)
wolfSSL 15:117db924cf7c 916 {
wolfSSL 15:117db924cf7c 917 int ret = 0;
wolfSSL 15:117db924cf7c 918 void* heap;
wolfSSL 15:117db924cf7c 919 int devId;
wolfSSL 16:8e0d178b1d1e 920 Pkcs7Cert* cert;
wolfSSL 16:8e0d178b1d1e 921 Pkcs7Cert* lastCert;
wolfSSL 16:8e0d178b1d1e 922
wolfSSL 16:8e0d178b1d1e 923 if (pkcs7 == NULL || (derCert == NULL && derCertSz != 0)) {
wolfSSL 15:117db924cf7c 924 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 925 }
wolfSSL 15:117db924cf7c 926
wolfSSL 15:117db924cf7c 927 heap = pkcs7->heap;
wolfSSL 15:117db924cf7c 928 devId = pkcs7->devId;
wolfSSL 16:8e0d178b1d1e 929 cert = pkcs7->certList;
wolfSSL 15:117db924cf7c 930 ret = wc_PKCS7_Init(pkcs7, heap, devId);
wolfSSL 15:117db924cf7c 931 if (ret != 0)
wolfSSL 15:117db924cf7c 932 return ret;
wolfSSL 16:8e0d178b1d1e 933 pkcs7->certList = cert;
wolfSSL 16:8e0d178b1d1e 934
wolfSSL 16:8e0d178b1d1e 935 if (derCert != NULL && derCertSz > 0) {
wolfSSL 15:117db924cf7c 936 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 937 DecodedCert* dCert;
wolfSSL 15:117db924cf7c 938
wolfSSL 15:117db924cf7c 939 dCert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), pkcs7->heap,
wolfSSL 15:117db924cf7c 940 DYNAMIC_TYPE_DCERT);
wolfSSL 15:117db924cf7c 941 if (dCert == NULL)
wolfSSL 15:117db924cf7c 942 return MEMORY_E;
wolfSSL 15:117db924cf7c 943 #else
wolfSSL 16:8e0d178b1d1e 944 DecodedCert dCert[1];
wolfSSL 16:8e0d178b1d1e 945 #endif
wolfSSL 16:8e0d178b1d1e 946
wolfSSL 16:8e0d178b1d1e 947 pkcs7->singleCert = derCert;
wolfSSL 16:8e0d178b1d1e 948 pkcs7->singleCertSz = derCertSz;
wolfSSL 16:8e0d178b1d1e 949 pkcs7->cert[0] = derCert;
wolfSSL 16:8e0d178b1d1e 950 pkcs7->certSz[0] = derCertSz;
wolfSSL 16:8e0d178b1d1e 951
wolfSSL 16:8e0d178b1d1e 952 /* create new Pkcs7Cert for recipient, freed during cleanup */
wolfSSL 16:8e0d178b1d1e 953 cert = (Pkcs7Cert*)XMALLOC(sizeof(Pkcs7Cert), pkcs7->heap,
wolfSSL 16:8e0d178b1d1e 954 DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 955 XMEMSET(cert, 0, sizeof(Pkcs7Cert));
wolfSSL 16:8e0d178b1d1e 956 cert->der = derCert;
wolfSSL 16:8e0d178b1d1e 957 cert->derSz = derCertSz;
wolfSSL 16:8e0d178b1d1e 958 cert->next = NULL;
wolfSSL 16:8e0d178b1d1e 959
wolfSSL 16:8e0d178b1d1e 960 /* free existing cert list if existing */
wolfSSL 16:8e0d178b1d1e 961 wc_PKCS7_FreeCertSet(pkcs7);
wolfSSL 16:8e0d178b1d1e 962
wolfSSL 16:8e0d178b1d1e 963 /* add cert to list */
wolfSSL 16:8e0d178b1d1e 964 if (pkcs7->certList == NULL) {
wolfSSL 16:8e0d178b1d1e 965 pkcs7->certList = cert;
wolfSSL 16:8e0d178b1d1e 966 } else {
wolfSSL 16:8e0d178b1d1e 967 lastCert = pkcs7->certList;
wolfSSL 16:8e0d178b1d1e 968 while (lastCert->next != NULL) {
wolfSSL 16:8e0d178b1d1e 969 lastCert = lastCert->next;
wolfSSL 16:8e0d178b1d1e 970 }
wolfSSL 16:8e0d178b1d1e 971 lastCert->next = cert;
wolfSSL 16:8e0d178b1d1e 972 }
wolfSSL 16:8e0d178b1d1e 973
wolfSSL 16:8e0d178b1d1e 974 InitDecodedCert(dCert, derCert, derCertSz, pkcs7->heap);
wolfSSL 15:117db924cf7c 975 ret = ParseCert(dCert, CA_TYPE, NO_VERIFY, 0);
wolfSSL 15:117db924cf7c 976 if (ret < 0) {
wolfSSL 15:117db924cf7c 977 FreeDecodedCert(dCert);
wolfSSL 15:117db924cf7c 978 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 979 XFREE(dCert, pkcs7->heap, DYNAMIC_TYPE_DCERT);
wolfSSL 15:117db924cf7c 980 #endif
wolfSSL 15:117db924cf7c 981 return ret;
wolfSSL 15:117db924cf7c 982 }
wolfSSL 15:117db924cf7c 983
wolfSSL 15:117db924cf7c 984 XMEMCPY(pkcs7->publicKey, dCert->publicKey, dCert->pubKeySize);
wolfSSL 15:117db924cf7c 985 pkcs7->publicKeySz = dCert->pubKeySize;
wolfSSL 15:117db924cf7c 986 pkcs7->publicKeyOID = dCert->keyOID;
wolfSSL 15:117db924cf7c 987 XMEMCPY(pkcs7->issuerHash, dCert->issuerHash, KEYID_SIZE);
wolfSSL 15:117db924cf7c 988 pkcs7->issuer = dCert->issuerRaw;
wolfSSL 15:117db924cf7c 989 pkcs7->issuerSz = dCert->issuerRawLen;
wolfSSL 15:117db924cf7c 990 XMEMCPY(pkcs7->issuerSn, dCert->serial, dCert->serialSz);
wolfSSL 15:117db924cf7c 991 pkcs7->issuerSnSz = dCert->serialSz;
wolfSSL 16:8e0d178b1d1e 992 XMEMCPY(pkcs7->issuerSubjKeyId, dCert->extSubjKeyId, KEYID_SIZE);
wolfSSL 16:8e0d178b1d1e 993
wolfSSL 16:8e0d178b1d1e 994 /* default to IssuerAndSerialNumber for SignerIdentifier */
wolfSSL 16:8e0d178b1d1e 995 pkcs7->sidType = CMS_ISSUER_AND_SERIAL_NUMBER;
wolfSSL 16:8e0d178b1d1e 996
wolfSSL 16:8e0d178b1d1e 997 /* free existing recipient list if existing */
wolfSSL 16:8e0d178b1d1e 998 wc_PKCS7_FreeEncodedRecipientSet(pkcs7);
wolfSSL 16:8e0d178b1d1e 999
wolfSSL 15:117db924cf7c 1000 FreeDecodedCert(dCert);
wolfSSL 15:117db924cf7c 1001
wolfSSL 15:117db924cf7c 1002 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 1003 XFREE(dCert, pkcs7->heap, DYNAMIC_TYPE_DCERT);
wolfSSL 15:117db924cf7c 1004 #endif
wolfSSL 15:117db924cf7c 1005 }
wolfSSL 15:117db924cf7c 1006
wolfSSL 15:117db924cf7c 1007 return ret;
wolfSSL 15:117db924cf7c 1008 }
wolfSSL 15:117db924cf7c 1009
wolfSSL 15:117db924cf7c 1010
wolfSSL 16:8e0d178b1d1e 1011 /* Adds one DER-formatted certificate to the internal PKCS7/CMS certificate
wolfSSL 16:8e0d178b1d1e 1012 * list, to be added as part of the certificates CertificateSet. Currently
wolfSSL 16:8e0d178b1d1e 1013 * used in SignedData content type.
wolfSSL 16:8e0d178b1d1e 1014 *
wolfSSL 16:8e0d178b1d1e 1015 * Must be called after wc_PKCS7_Init() or wc_PKCS7_InitWithCert().
wolfSSL 16:8e0d178b1d1e 1016 *
wolfSSL 16:8e0d178b1d1e 1017 * Does not represent the recipient/signer certificate, only certificates that
wolfSSL 16:8e0d178b1d1e 1018 * are part of the certificate chain used to build and verify signer
wolfSSL 16:8e0d178b1d1e 1019 * certificates.
wolfSSL 16:8e0d178b1d1e 1020 *
wolfSSL 16:8e0d178b1d1e 1021 * This API does not currently validate certificates.
wolfSSL 16:8e0d178b1d1e 1022 *
wolfSSL 16:8e0d178b1d1e 1023 * Returns 0 on success, negative upon error */
wolfSSL 16:8e0d178b1d1e 1024 int wc_PKCS7_AddCertificate(PKCS7* pkcs7, byte* derCert, word32 derCertSz)
wolfSSL 16:8e0d178b1d1e 1025 {
wolfSSL 16:8e0d178b1d1e 1026 Pkcs7Cert* cert;
wolfSSL 16:8e0d178b1d1e 1027
wolfSSL 16:8e0d178b1d1e 1028 if (pkcs7 == NULL || derCert == NULL || derCertSz == 0)
wolfSSL 16:8e0d178b1d1e 1029 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 1030
wolfSSL 16:8e0d178b1d1e 1031 cert = (Pkcs7Cert*)XMALLOC(sizeof(Pkcs7Cert), pkcs7->heap,
wolfSSL 16:8e0d178b1d1e 1032 DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 1033 if (cert == NULL)
wolfSSL 16:8e0d178b1d1e 1034 return MEMORY_E;
wolfSSL 16:8e0d178b1d1e 1035
wolfSSL 16:8e0d178b1d1e 1036 cert->der = derCert;
wolfSSL 16:8e0d178b1d1e 1037 cert->derSz = derCertSz;
wolfSSL 16:8e0d178b1d1e 1038
wolfSSL 16:8e0d178b1d1e 1039 if (pkcs7->certList == NULL) {
wolfSSL 16:8e0d178b1d1e 1040 pkcs7->certList = cert;
wolfSSL 16:8e0d178b1d1e 1041 } else {
wolfSSL 16:8e0d178b1d1e 1042 cert->next = pkcs7->certList;
wolfSSL 16:8e0d178b1d1e 1043 pkcs7->certList = cert;
wolfSSL 16:8e0d178b1d1e 1044 }
wolfSSL 16:8e0d178b1d1e 1045
wolfSSL 16:8e0d178b1d1e 1046 return 0;
wolfSSL 16:8e0d178b1d1e 1047 }
wolfSSL 16:8e0d178b1d1e 1048
wolfSSL 16:8e0d178b1d1e 1049
wolfSSL 15:117db924cf7c 1050 /* free linked list of PKCS7DecodedAttrib structs */
wolfSSL 15:117db924cf7c 1051 static void wc_PKCS7_FreeDecodedAttrib(PKCS7DecodedAttrib* attrib, void* heap)
wolfSSL 15:117db924cf7c 1052 {
wolfSSL 15:117db924cf7c 1053 PKCS7DecodedAttrib* current;
wolfSSL 15:117db924cf7c 1054
wolfSSL 15:117db924cf7c 1055 if (attrib == NULL) {
wolfSSL 15:117db924cf7c 1056 return;
wolfSSL 15:117db924cf7c 1057 }
wolfSSL 15:117db924cf7c 1058
wolfSSL 15:117db924cf7c 1059 current = attrib;
wolfSSL 15:117db924cf7c 1060 while (current != NULL) {
wolfSSL 15:117db924cf7c 1061 PKCS7DecodedAttrib* next = current->next;
wolfSSL 15:117db924cf7c 1062 if (current->oid != NULL) {
wolfSSL 15:117db924cf7c 1063 XFREE(current->oid, heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 1064 }
wolfSSL 15:117db924cf7c 1065 if (current->value != NULL) {
wolfSSL 15:117db924cf7c 1066 XFREE(current->value, heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 1067 }
wolfSSL 15:117db924cf7c 1068 XFREE(current, heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 1069 current = next;
wolfSSL 15:117db924cf7c 1070 }
wolfSSL 15:117db924cf7c 1071
wolfSSL 15:117db924cf7c 1072 (void)heap;
wolfSSL 15:117db924cf7c 1073 }
wolfSSL 15:117db924cf7c 1074
wolfSSL 15:117db924cf7c 1075
wolfSSL 16:8e0d178b1d1e 1076 /* return 0 on success */
wolfSSL 16:8e0d178b1d1e 1077 static int wc_PKCS7_SignerInfoNew(PKCS7* pkcs7)
wolfSSL 16:8e0d178b1d1e 1078 {
wolfSSL 16:8e0d178b1d1e 1079 if (pkcs7->signerInfo != NULL) {
wolfSSL 16:8e0d178b1d1e 1080 XFREE(pkcs7->signerInfo, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 1081 pkcs7->signerInfo = NULL;
wolfSSL 16:8e0d178b1d1e 1082 }
wolfSSL 16:8e0d178b1d1e 1083
wolfSSL 16:8e0d178b1d1e 1084 pkcs7->signerInfo = (PKCS7SignerInfo*)XMALLOC(sizeof(PKCS7SignerInfo),
wolfSSL 16:8e0d178b1d1e 1085 pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 1086 if (pkcs7->signerInfo == NULL) {
wolfSSL 16:8e0d178b1d1e 1087 WOLFSSL_MSG("Unable to malloc memory for signer info");
wolfSSL 16:8e0d178b1d1e 1088 return MEMORY_E;
wolfSSL 16:8e0d178b1d1e 1089 }
wolfSSL 16:8e0d178b1d1e 1090 XMEMSET(pkcs7->signerInfo, 0, sizeof(PKCS7SignerInfo));
wolfSSL 16:8e0d178b1d1e 1091 return 0;
wolfSSL 16:8e0d178b1d1e 1092 }
wolfSSL 16:8e0d178b1d1e 1093
wolfSSL 16:8e0d178b1d1e 1094
wolfSSL 16:8e0d178b1d1e 1095 static void wc_PKCS7_SignerInfoFree(PKCS7* pkcs7)
wolfSSL 16:8e0d178b1d1e 1096 {
wolfSSL 16:8e0d178b1d1e 1097 if (pkcs7->signerInfo != NULL) {
wolfSSL 16:8e0d178b1d1e 1098 if (pkcs7->signerInfo->sid != NULL) {
wolfSSL 16:8e0d178b1d1e 1099 XFREE(pkcs7->signerInfo->sid, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 1100 pkcs7->signerInfo->sid = NULL;
wolfSSL 16:8e0d178b1d1e 1101 }
wolfSSL 16:8e0d178b1d1e 1102 XFREE(pkcs7->signerInfo, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 1103 pkcs7->signerInfo = NULL;
wolfSSL 16:8e0d178b1d1e 1104 }
wolfSSL 16:8e0d178b1d1e 1105 }
wolfSSL 16:8e0d178b1d1e 1106
wolfSSL 16:8e0d178b1d1e 1107
wolfSSL 16:8e0d178b1d1e 1108 /* free's any current SID and sets it to "in"
wolfSSL 16:8e0d178b1d1e 1109 * returns 0 on success
wolfSSL 16:8e0d178b1d1e 1110 */
wolfSSL 16:8e0d178b1d1e 1111 static int wc_PKCS7_SignerInfoSetSID(PKCS7* pkcs7, byte* in, int inSz)
wolfSSL 16:8e0d178b1d1e 1112 {
wolfSSL 16:8e0d178b1d1e 1113 if (pkcs7 == NULL || in == NULL || inSz < 0) {
wolfSSL 16:8e0d178b1d1e 1114 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 1115 }
wolfSSL 16:8e0d178b1d1e 1116
wolfSSL 16:8e0d178b1d1e 1117 if (pkcs7->signerInfo->sid != NULL) {
wolfSSL 16:8e0d178b1d1e 1118 XFREE(pkcs7->signerInfo->sid, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 1119 pkcs7->signerInfo->sid = NULL;
wolfSSL 16:8e0d178b1d1e 1120 }
wolfSSL 16:8e0d178b1d1e 1121 pkcs7->signerInfo->sid = (byte*)XMALLOC(inSz, pkcs7->heap,
wolfSSL 16:8e0d178b1d1e 1122 DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 1123 if (pkcs7->signerInfo->sid == NULL) {
wolfSSL 16:8e0d178b1d1e 1124 return MEMORY_E;
wolfSSL 16:8e0d178b1d1e 1125 }
wolfSSL 16:8e0d178b1d1e 1126 XMEMCPY(pkcs7->signerInfo->sid, in, inSz);
wolfSSL 16:8e0d178b1d1e 1127 pkcs7->signerInfo->sidSz = inSz;
wolfSSL 16:8e0d178b1d1e 1128 return 0;
wolfSSL 16:8e0d178b1d1e 1129 }
wolfSSL 16:8e0d178b1d1e 1130
wolfSSL 16:8e0d178b1d1e 1131
wolfSSL 15:117db924cf7c 1132 /* releases any memory allocated by a PKCS7 initializer */
wolfSSL 15:117db924cf7c 1133 void wc_PKCS7_Free(PKCS7* pkcs7)
wolfSSL 15:117db924cf7c 1134 {
wolfSSL 15:117db924cf7c 1135 if (pkcs7 == NULL)
wolfSSL 15:117db924cf7c 1136 return;
wolfSSL 15:117db924cf7c 1137
wolfSSL 16:8e0d178b1d1e 1138 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 1139 wc_PKCS7_FreeStream(pkcs7);
wolfSSL 16:8e0d178b1d1e 1140 #endif
wolfSSL 16:8e0d178b1d1e 1141
wolfSSL 16:8e0d178b1d1e 1142 wc_PKCS7_SignerInfoFree(pkcs7);
wolfSSL 15:117db924cf7c 1143 wc_PKCS7_FreeDecodedAttrib(pkcs7->decodedAttrib, pkcs7->heap);
wolfSSL 16:8e0d178b1d1e 1144 wc_PKCS7_FreeCertSet(pkcs7);
wolfSSL 15:117db924cf7c 1145
wolfSSL 15:117db924cf7c 1146 #ifdef ASN_BER_TO_DER
wolfSSL 15:117db924cf7c 1147 if (pkcs7->der != NULL)
wolfSSL 15:117db924cf7c 1148 XFREE(pkcs7->der, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 1149 #endif
wolfSSL 16:8e0d178b1d1e 1150 if (pkcs7->contentDynamic != NULL)
wolfSSL 16:8e0d178b1d1e 1151 XFREE(pkcs7->contentDynamic, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 1152
wolfSSL 16:8e0d178b1d1e 1153 if (pkcs7->cek != NULL) {
wolfSSL 16:8e0d178b1d1e 1154 ForceZero(pkcs7->cek, pkcs7->cekSz);
wolfSSL 16:8e0d178b1d1e 1155 XFREE(pkcs7->cek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 1156 }
wolfSSL 16:8e0d178b1d1e 1157
wolfSSL 16:8e0d178b1d1e 1158 pkcs7->contentTypeSz = 0;
wolfSSL 16:8e0d178b1d1e 1159
wolfSSL 16:8e0d178b1d1e 1160 if (pkcs7->signature) {
wolfSSL 16:8e0d178b1d1e 1161 XFREE(pkcs7->signature, pkcs7->heap, DYNAMIC_TYPE_SIGNATURE);
wolfSSL 16:8e0d178b1d1e 1162 pkcs7->signature = NULL;
wolfSSL 16:8e0d178b1d1e 1163 pkcs7->signatureSz = 0;
wolfSSL 16:8e0d178b1d1e 1164 }
wolfSSL 16:8e0d178b1d1e 1165 if (pkcs7->plainDigest) {
wolfSSL 16:8e0d178b1d1e 1166 XFREE(pkcs7->plainDigest, pkcs7->heap, DYNAMIC_TYPE_DIGEST);
wolfSSL 16:8e0d178b1d1e 1167 pkcs7->plainDigest = NULL;
wolfSSL 16:8e0d178b1d1e 1168 pkcs7->plainDigestSz = 0;
wolfSSL 16:8e0d178b1d1e 1169 }
wolfSSL 16:8e0d178b1d1e 1170 if (pkcs7->pkcs7Digest) {
wolfSSL 16:8e0d178b1d1e 1171 XFREE(pkcs7->pkcs7Digest, pkcs7->heap, DYNAMIC_TYPE_DIGEST);
wolfSSL 16:8e0d178b1d1e 1172 pkcs7->pkcs7Digest = NULL;
wolfSSL 16:8e0d178b1d1e 1173 pkcs7->pkcs7DigestSz = 0;
wolfSSL 16:8e0d178b1d1e 1174 }
wolfSSL 16:8e0d178b1d1e 1175 if (pkcs7->cachedEncryptedContent != NULL) {
wolfSSL 16:8e0d178b1d1e 1176 XFREE(pkcs7->cachedEncryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 1177 pkcs7->cachedEncryptedContent = NULL;
wolfSSL 16:8e0d178b1d1e 1178 pkcs7->cachedEncryptedContentSz = 0;
wolfSSL 16:8e0d178b1d1e 1179 }
wolfSSL 15:117db924cf7c 1180
wolfSSL 15:117db924cf7c 1181 if (pkcs7->isDynamic) {
wolfSSL 15:117db924cf7c 1182 pkcs7->isDynamic = 0;
wolfSSL 15:117db924cf7c 1183 XFREE(pkcs7, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 1184 }
wolfSSL 15:117db924cf7c 1185 }
wolfSSL 15:117db924cf7c 1186
wolfSSL 15:117db924cf7c 1187
wolfSSL 15:117db924cf7c 1188 /* helper function for parsing through attributes and finding a specific one.
wolfSSL 15:117db924cf7c 1189 * returns PKCS7DecodedAttrib pointer on success */
wolfSSL 15:117db924cf7c 1190 static PKCS7DecodedAttrib* findAttrib(PKCS7* pkcs7, const byte* oid, word32 oidSz)
wolfSSL 15:117db924cf7c 1191 {
wolfSSL 15:117db924cf7c 1192 PKCS7DecodedAttrib* list;
wolfSSL 15:117db924cf7c 1193
wolfSSL 15:117db924cf7c 1194 if (pkcs7 == NULL || oid == NULL) {
wolfSSL 15:117db924cf7c 1195 return NULL;
wolfSSL 15:117db924cf7c 1196 }
wolfSSL 15:117db924cf7c 1197
wolfSSL 15:117db924cf7c 1198 /* search attributes for pkiStatus */
wolfSSL 15:117db924cf7c 1199 list = pkcs7->decodedAttrib;
wolfSSL 15:117db924cf7c 1200 while (list != NULL) {
wolfSSL 15:117db924cf7c 1201 word32 sz = oidSz;
wolfSSL 15:117db924cf7c 1202 word32 idx = 0;
wolfSSL 15:117db924cf7c 1203 int length = 0;
wolfSSL 16:8e0d178b1d1e 1204 byte tag;
wolfSSL 16:8e0d178b1d1e 1205
wolfSSL 16:8e0d178b1d1e 1206 if (GetASNTag(list->oid, &idx, &tag, list->oidSz) < 0) {
wolfSSL 16:8e0d178b1d1e 1207 return NULL;
wolfSSL 16:8e0d178b1d1e 1208 }
wolfSSL 16:8e0d178b1d1e 1209 if (tag != ASN_OBJECT_ID) {
wolfSSL 15:117db924cf7c 1210 WOLFSSL_MSG("Bad attribute ASN1 syntax");
wolfSSL 15:117db924cf7c 1211 return NULL;
wolfSSL 15:117db924cf7c 1212 }
wolfSSL 15:117db924cf7c 1213
wolfSSL 15:117db924cf7c 1214 if (GetLength(list->oid, &idx, &length, list->oidSz) < 0) {
wolfSSL 15:117db924cf7c 1215 WOLFSSL_MSG("Bad attribute length");
wolfSSL 15:117db924cf7c 1216 return NULL;
wolfSSL 15:117db924cf7c 1217 }
wolfSSL 15:117db924cf7c 1218
wolfSSL 15:117db924cf7c 1219 sz = (sz < (word32)length)? sz : (word32)length;
wolfSSL 15:117db924cf7c 1220 if (XMEMCMP(oid, list->oid + idx, sz) == 0) {
wolfSSL 15:117db924cf7c 1221 return list;
wolfSSL 15:117db924cf7c 1222 }
wolfSSL 15:117db924cf7c 1223 list = list->next;
wolfSSL 15:117db924cf7c 1224 }
wolfSSL 15:117db924cf7c 1225 return NULL;
wolfSSL 15:117db924cf7c 1226 }
wolfSSL 15:117db924cf7c 1227
wolfSSL 15:117db924cf7c 1228
wolfSSL 15:117db924cf7c 1229 /* Searches through decoded attributes and returns the value for the first one
wolfSSL 15:117db924cf7c 1230 * matching the oid passed in. Note that this value includes the leading ASN1
wolfSSL 15:117db924cf7c 1231 * syntax. So for a printable string of "3" this would be something like
wolfSSL 15:117db924cf7c 1232 *
wolfSSL 15:117db924cf7c 1233 * 0x13, 0x01, 0x33
wolfSSL 15:117db924cf7c 1234 * ID SIZE "3"
wolfSSL 15:117db924cf7c 1235 *
wolfSSL 15:117db924cf7c 1236 * pkcs7 structure to get value from
wolfSSL 15:117db924cf7c 1237 * oid OID value to search for with attributes
wolfSSL 15:117db924cf7c 1238 * oidSz size of oid buffer
wolfSSL 15:117db924cf7c 1239 * out buffer to hold result
wolfSSL 15:117db924cf7c 1240 * outSz size of out buffer (if out is NULL this is set to needed size and
wolfSSL 15:117db924cf7c 1241 LENGTH_ONLY_E is returned)
wolfSSL 15:117db924cf7c 1242 *
wolfSSL 15:117db924cf7c 1243 * returns size of value on success
wolfSSL 15:117db924cf7c 1244 */
wolfSSL 15:117db924cf7c 1245 int wc_PKCS7_GetAttributeValue(PKCS7* pkcs7, const byte* oid, word32 oidSz,
wolfSSL 15:117db924cf7c 1246 byte* out, word32* outSz)
wolfSSL 15:117db924cf7c 1247 {
wolfSSL 15:117db924cf7c 1248 PKCS7DecodedAttrib* attrib;
wolfSSL 15:117db924cf7c 1249
wolfSSL 15:117db924cf7c 1250 if (pkcs7 == NULL || oid == NULL || outSz == NULL) {
wolfSSL 15:117db924cf7c 1251 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 1252 }
wolfSSL 15:117db924cf7c 1253
wolfSSL 15:117db924cf7c 1254 attrib = findAttrib(pkcs7, oid, oidSz);
wolfSSL 15:117db924cf7c 1255 if (attrib == NULL) {
wolfSSL 15:117db924cf7c 1256 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 1257 }
wolfSSL 15:117db924cf7c 1258
wolfSSL 15:117db924cf7c 1259 if (out == NULL) {
wolfSSL 15:117db924cf7c 1260 *outSz = attrib->valueSz;
wolfSSL 15:117db924cf7c 1261 return LENGTH_ONLY_E;
wolfSSL 15:117db924cf7c 1262 }
wolfSSL 15:117db924cf7c 1263
wolfSSL 15:117db924cf7c 1264 if (*outSz < attrib->valueSz) {
wolfSSL 15:117db924cf7c 1265 return BUFFER_E;
wolfSSL 15:117db924cf7c 1266 }
wolfSSL 15:117db924cf7c 1267
wolfSSL 15:117db924cf7c 1268 XMEMCPY(out, attrib->value, attrib->valueSz);
wolfSSL 15:117db924cf7c 1269 return attrib->valueSz;
wolfSSL 15:117db924cf7c 1270 }
wolfSSL 15:117db924cf7c 1271
wolfSSL 15:117db924cf7c 1272
wolfSSL 15:117db924cf7c 1273 /* build PKCS#7 data content type */
wolfSSL 15:117db924cf7c 1274 int wc_PKCS7_EncodeData(PKCS7* pkcs7, byte* output, word32 outputSz)
wolfSSL 15:117db924cf7c 1275 {
wolfSSL 15:117db924cf7c 1276 static const byte oid[] =
wolfSSL 15:117db924cf7c 1277 { ASN_OBJECT_ID, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01,
wolfSSL 15:117db924cf7c 1278 0x07, 0x01 };
wolfSSL 15:117db924cf7c 1279 byte seq[MAX_SEQ_SZ];
wolfSSL 15:117db924cf7c 1280 byte octetStr[MAX_OCTET_STR_SZ];
wolfSSL 15:117db924cf7c 1281 word32 seqSz;
wolfSSL 15:117db924cf7c 1282 word32 octetStrSz;
wolfSSL 15:117db924cf7c 1283 word32 oidSz = (word32)sizeof(oid);
wolfSSL 15:117db924cf7c 1284 int idx = 0;
wolfSSL 15:117db924cf7c 1285
wolfSSL 15:117db924cf7c 1286 if (pkcs7 == NULL || output == NULL) {
wolfSSL 15:117db924cf7c 1287 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 1288 }
wolfSSL 15:117db924cf7c 1289
wolfSSL 15:117db924cf7c 1290 octetStrSz = SetOctetString(pkcs7->contentSz, octetStr);
wolfSSL 15:117db924cf7c 1291 seqSz = SetSequence(pkcs7->contentSz + octetStrSz + oidSz, seq);
wolfSSL 15:117db924cf7c 1292
wolfSSL 15:117db924cf7c 1293 if (outputSz < pkcs7->contentSz + octetStrSz + oidSz + seqSz)
wolfSSL 15:117db924cf7c 1294 return BUFFER_E;
wolfSSL 15:117db924cf7c 1295
wolfSSL 15:117db924cf7c 1296 XMEMCPY(output, seq, seqSz);
wolfSSL 15:117db924cf7c 1297 idx += seqSz;
wolfSSL 15:117db924cf7c 1298 XMEMCPY(output + idx, oid, oidSz);
wolfSSL 15:117db924cf7c 1299 idx += oidSz;
wolfSSL 15:117db924cf7c 1300 XMEMCPY(output + idx, octetStr, octetStrSz);
wolfSSL 15:117db924cf7c 1301 idx += octetStrSz;
wolfSSL 15:117db924cf7c 1302 XMEMCPY(output + idx, pkcs7->content, pkcs7->contentSz);
wolfSSL 15:117db924cf7c 1303 idx += pkcs7->contentSz;
wolfSSL 15:117db924cf7c 1304
wolfSSL 15:117db924cf7c 1305 return idx;
wolfSSL 15:117db924cf7c 1306 }
wolfSSL 15:117db924cf7c 1307
wolfSSL 15:117db924cf7c 1308
wolfSSL 15:117db924cf7c 1309 typedef struct EncodedAttrib {
wolfSSL 15:117db924cf7c 1310 byte valueSeq[MAX_SEQ_SZ];
wolfSSL 15:117db924cf7c 1311 const byte* oid;
wolfSSL 15:117db924cf7c 1312 byte valueSet[MAX_SET_SZ];
wolfSSL 15:117db924cf7c 1313 const byte* value;
wolfSSL 15:117db924cf7c 1314 word32 valueSeqSz, oidSz, idSz, valueSetSz, valueSz, totalSz;
wolfSSL 15:117db924cf7c 1315 } EncodedAttrib;
wolfSSL 15:117db924cf7c 1316
wolfSSL 15:117db924cf7c 1317
wolfSSL 15:117db924cf7c 1318 typedef struct ESD {
wolfSSL 15:117db924cf7c 1319 wc_HashAlg hash;
wolfSSL 15:117db924cf7c 1320 enum wc_HashType hashType;
wolfSSL 15:117db924cf7c 1321 byte contentDigest[WC_MAX_DIGEST_SIZE + 2]; /* content only + ASN.1 heading */
wolfSSL 15:117db924cf7c 1322 byte contentAttribsDigest[WC_MAX_DIGEST_SIZE];
wolfSSL 15:117db924cf7c 1323 byte encContentDigest[MAX_ENCRYPTED_KEY_SZ];
wolfSSL 15:117db924cf7c 1324
wolfSSL 15:117db924cf7c 1325 byte outerSeq[MAX_SEQ_SZ];
wolfSSL 15:117db924cf7c 1326 byte outerContent[MAX_EXP_SZ];
wolfSSL 15:117db924cf7c 1327 byte innerSeq[MAX_SEQ_SZ];
wolfSSL 15:117db924cf7c 1328 byte version[MAX_VERSION_SZ];
wolfSSL 15:117db924cf7c 1329 byte digAlgoIdSet[MAX_SET_SZ];
wolfSSL 15:117db924cf7c 1330 byte singleDigAlgoId[MAX_ALGO_SZ];
wolfSSL 15:117db924cf7c 1331
wolfSSL 15:117db924cf7c 1332 byte contentInfoSeq[MAX_SEQ_SZ];
wolfSSL 15:117db924cf7c 1333 byte innerContSeq[MAX_EXP_SZ];
wolfSSL 15:117db924cf7c 1334 byte innerOctets[MAX_OCTET_STR_SZ];
wolfSSL 15:117db924cf7c 1335
wolfSSL 15:117db924cf7c 1336 byte certsSet[MAX_SET_SZ];
wolfSSL 15:117db924cf7c 1337
wolfSSL 15:117db924cf7c 1338 byte signerInfoSet[MAX_SET_SZ];
wolfSSL 15:117db924cf7c 1339 byte signerInfoSeq[MAX_SEQ_SZ];
wolfSSL 15:117db924cf7c 1340 byte signerVersion[MAX_VERSION_SZ];
wolfSSL 16:8e0d178b1d1e 1341 /* issuerAndSerialNumber ...*/
wolfSSL 15:117db924cf7c 1342 byte issuerSnSeq[MAX_SEQ_SZ];
wolfSSL 15:117db924cf7c 1343 byte issuerName[MAX_SEQ_SZ];
wolfSSL 15:117db924cf7c 1344 byte issuerSn[MAX_SN_SZ];
wolfSSL 16:8e0d178b1d1e 1345 /* OR subjectKeyIdentifier */
wolfSSL 16:8e0d178b1d1e 1346 byte issuerSKIDSeq[MAX_SEQ_SZ];
wolfSSL 16:8e0d178b1d1e 1347 byte issuerSKID[MAX_OCTET_STR_SZ];
wolfSSL 15:117db924cf7c 1348 byte signerDigAlgoId[MAX_ALGO_SZ];
wolfSSL 15:117db924cf7c 1349 byte digEncAlgoId[MAX_ALGO_SZ];
wolfSSL 15:117db924cf7c 1350 byte signedAttribSet[MAX_SET_SZ];
wolfSSL 16:8e0d178b1d1e 1351 EncodedAttrib signedAttribs[7];
wolfSSL 15:117db924cf7c 1352 byte signerDigest[MAX_OCTET_STR_SZ];
wolfSSL 15:117db924cf7c 1353 word32 innerOctetsSz, innerContSeqSz, contentInfoSeqSz;
wolfSSL 15:117db924cf7c 1354 word32 outerSeqSz, outerContentSz, innerSeqSz, versionSz, digAlgoIdSetSz,
wolfSSL 15:117db924cf7c 1355 singleDigAlgoIdSz, certsSetSz;
wolfSSL 15:117db924cf7c 1356 word32 signerInfoSetSz, signerInfoSeqSz, signerVersionSz,
wolfSSL 16:8e0d178b1d1e 1357 issuerSnSeqSz, issuerNameSz, issuerSnSz, issuerSKIDSz,
wolfSSL 16:8e0d178b1d1e 1358 issuerSKIDSeqSz, signerDigAlgoIdSz, digEncAlgoIdSz, signerDigestSz;
wolfSSL 15:117db924cf7c 1359 word32 encContentDigestSz, signedAttribsSz, signedAttribsCount,
wolfSSL 15:117db924cf7c 1360 signedAttribSetSz;
wolfSSL 15:117db924cf7c 1361 } ESD;
wolfSSL 15:117db924cf7c 1362
wolfSSL 15:117db924cf7c 1363
wolfSSL 15:117db924cf7c 1364 static int EncodeAttributes(EncodedAttrib* ea, int eaSz,
wolfSSL 15:117db924cf7c 1365 PKCS7Attrib* attribs, int attribsSz)
wolfSSL 15:117db924cf7c 1366 {
wolfSSL 15:117db924cf7c 1367 int i;
wolfSSL 15:117db924cf7c 1368 int maxSz = min(eaSz, attribsSz);
wolfSSL 15:117db924cf7c 1369 int allAttribsSz = 0;
wolfSSL 15:117db924cf7c 1370
wolfSSL 15:117db924cf7c 1371 for (i = 0; i < maxSz; i++)
wolfSSL 15:117db924cf7c 1372 {
wolfSSL 15:117db924cf7c 1373 int attribSz = 0;
wolfSSL 15:117db924cf7c 1374
wolfSSL 15:117db924cf7c 1375 ea[i].value = attribs[i].value;
wolfSSL 15:117db924cf7c 1376 ea[i].valueSz = attribs[i].valueSz;
wolfSSL 15:117db924cf7c 1377 attribSz += ea[i].valueSz;
wolfSSL 15:117db924cf7c 1378 ea[i].valueSetSz = SetSet(attribSz, ea[i].valueSet);
wolfSSL 15:117db924cf7c 1379 attribSz += ea[i].valueSetSz;
wolfSSL 15:117db924cf7c 1380 ea[i].oid = attribs[i].oid;
wolfSSL 15:117db924cf7c 1381 ea[i].oidSz = attribs[i].oidSz;
wolfSSL 15:117db924cf7c 1382 attribSz += ea[i].oidSz;
wolfSSL 15:117db924cf7c 1383 ea[i].valueSeqSz = SetSequence(attribSz, ea[i].valueSeq);
wolfSSL 15:117db924cf7c 1384 attribSz += ea[i].valueSeqSz;
wolfSSL 15:117db924cf7c 1385 ea[i].totalSz = attribSz;
wolfSSL 15:117db924cf7c 1386
wolfSSL 15:117db924cf7c 1387 allAttribsSz += attribSz;
wolfSSL 15:117db924cf7c 1388 }
wolfSSL 15:117db924cf7c 1389 return allAttribsSz;
wolfSSL 15:117db924cf7c 1390 }
wolfSSL 15:117db924cf7c 1391
wolfSSL 15:117db924cf7c 1392
wolfSSL 16:8e0d178b1d1e 1393 typedef struct FlatAttrib {
wolfSSL 16:8e0d178b1d1e 1394 byte* data;
wolfSSL 16:8e0d178b1d1e 1395 word32 dataSz;
wolfSSL 16:8e0d178b1d1e 1396 } FlatAttrib;
wolfSSL 16:8e0d178b1d1e 1397
wolfSSL 16:8e0d178b1d1e 1398 /* Returns a pointer to FlatAttrib whose members are initialized to 0.
wolfSSL 16:8e0d178b1d1e 1399 * Caller is expected to free.
wolfSSL 16:8e0d178b1d1e 1400 */
wolfSSL 16:8e0d178b1d1e 1401 static FlatAttrib* NewAttrib(void* heap)
wolfSSL 16:8e0d178b1d1e 1402 {
wolfSSL 16:8e0d178b1d1e 1403 FlatAttrib* fb = (FlatAttrib*) XMALLOC(sizeof(FlatAttrib), heap,
wolfSSL 16:8e0d178b1d1e 1404 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 1405 if (fb != NULL) {
wolfSSL 16:8e0d178b1d1e 1406 ForceZero(fb, sizeof(FlatAttrib));
wolfSSL 16:8e0d178b1d1e 1407 }
wolfSSL 16:8e0d178b1d1e 1408 (void)heap;
wolfSSL 16:8e0d178b1d1e 1409 return fb;
wolfSSL 16:8e0d178b1d1e 1410 }
wolfSSL 16:8e0d178b1d1e 1411
wolfSSL 16:8e0d178b1d1e 1412 /* Free FlatAttrib array and memory allocated to internal struct members */
wolfSSL 16:8e0d178b1d1e 1413 static void FreeAttribArray(PKCS7* pkcs7, FlatAttrib** arr, int rows)
wolfSSL 16:8e0d178b1d1e 1414 {
wolfSSL 16:8e0d178b1d1e 1415 int i;
wolfSSL 16:8e0d178b1d1e 1416
wolfSSL 16:8e0d178b1d1e 1417 if (arr) {
wolfSSL 16:8e0d178b1d1e 1418 for (i = 0; i < rows; i++) {
wolfSSL 16:8e0d178b1d1e 1419 if (arr[i]) {
wolfSSL 16:8e0d178b1d1e 1420 if (arr[i]->data) {
wolfSSL 16:8e0d178b1d1e 1421 ForceZero(arr[i]->data, arr[i]->dataSz);
wolfSSL 16:8e0d178b1d1e 1422 XFREE(arr[i]->data, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 1423 }
wolfSSL 16:8e0d178b1d1e 1424 ForceZero(arr[i], sizeof(FlatAttrib));
wolfSSL 16:8e0d178b1d1e 1425 XFREE(arr[i], pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 1426 }
wolfSSL 16:8e0d178b1d1e 1427 }
wolfSSL 16:8e0d178b1d1e 1428 ForceZero(arr, rows);
wolfSSL 16:8e0d178b1d1e 1429 XFREE(arr, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 1430 }
wolfSSL 16:8e0d178b1d1e 1431 (void)pkcs7;
wolfSSL 16:8e0d178b1d1e 1432 }
wolfSSL 16:8e0d178b1d1e 1433
wolfSSL 16:8e0d178b1d1e 1434
wolfSSL 16:8e0d178b1d1e 1435 /* Sort FlatAttrib array in ascending order */
wolfSSL 16:8e0d178b1d1e 1436 static int SortAttribArray(FlatAttrib** arr, int rows)
wolfSSL 16:8e0d178b1d1e 1437 {
wolfSSL 16:8e0d178b1d1e 1438 int i, j;
wolfSSL 16:8e0d178b1d1e 1439 word32 minSz, minIdx;
wolfSSL 16:8e0d178b1d1e 1440 FlatAttrib* a = NULL;
wolfSSL 16:8e0d178b1d1e 1441 FlatAttrib* b = NULL;
wolfSSL 16:8e0d178b1d1e 1442 FlatAttrib* tmp = NULL;
wolfSSL 16:8e0d178b1d1e 1443
wolfSSL 16:8e0d178b1d1e 1444 if (arr == NULL) {
wolfSSL 16:8e0d178b1d1e 1445 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 1446 }
wolfSSL 16:8e0d178b1d1e 1447
wolfSSL 16:8e0d178b1d1e 1448 for (i = 0; i < rows; i++) {
wolfSSL 16:8e0d178b1d1e 1449 a = arr[i];
wolfSSL 16:8e0d178b1d1e 1450 minSz = a->dataSz;
wolfSSL 16:8e0d178b1d1e 1451 minIdx = i;
wolfSSL 16:8e0d178b1d1e 1452 for (j = i+1; j < rows; j++) {
wolfSSL 16:8e0d178b1d1e 1453 b = arr[j];
wolfSSL 16:8e0d178b1d1e 1454 if (b->dataSz < minSz) {
wolfSSL 16:8e0d178b1d1e 1455 minSz = b->dataSz;
wolfSSL 16:8e0d178b1d1e 1456 minIdx = j;
wolfSSL 16:8e0d178b1d1e 1457 }
wolfSSL 16:8e0d178b1d1e 1458 }
wolfSSL 16:8e0d178b1d1e 1459 if (minSz < a->dataSz) {
wolfSSL 16:8e0d178b1d1e 1460 /* swap array positions */
wolfSSL 16:8e0d178b1d1e 1461 tmp = arr[i];
wolfSSL 16:8e0d178b1d1e 1462 arr[i] = arr[minIdx];
wolfSSL 16:8e0d178b1d1e 1463 arr[minIdx] = tmp;
wolfSSL 16:8e0d178b1d1e 1464 }
wolfSSL 16:8e0d178b1d1e 1465 }
wolfSSL 16:8e0d178b1d1e 1466
wolfSSL 16:8e0d178b1d1e 1467 return 0;
wolfSSL 16:8e0d178b1d1e 1468 }
wolfSSL 16:8e0d178b1d1e 1469
wolfSSL 16:8e0d178b1d1e 1470
wolfSSL 16:8e0d178b1d1e 1471 /* Build up array of FlatAttrib structs from EncodedAttrib ones. FlatAttrib
wolfSSL 16:8e0d178b1d1e 1472 * holds flattened DER encoding of each attribute */
wolfSSL 16:8e0d178b1d1e 1473 static int FlattenEncodedAttribs(PKCS7* pkcs7, FlatAttrib** derArr, int rows,
wolfSSL 16:8e0d178b1d1e 1474 EncodedAttrib* ea, int eaSz)
wolfSSL 16:8e0d178b1d1e 1475 {
wolfSSL 16:8e0d178b1d1e 1476 int i, idx, sz;
wolfSSL 16:8e0d178b1d1e 1477 byte* output = NULL;
wolfSSL 16:8e0d178b1d1e 1478 FlatAttrib* fa = NULL;
wolfSSL 16:8e0d178b1d1e 1479
wolfSSL 16:8e0d178b1d1e 1480 if (pkcs7 == NULL || derArr == NULL || ea == NULL) {
wolfSSL 16:8e0d178b1d1e 1481 WOLFSSL_MSG("Invalid arguments to FlattenEncodedAttribs");
wolfSSL 16:8e0d178b1d1e 1482 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 1483 }
wolfSSL 16:8e0d178b1d1e 1484
wolfSSL 16:8e0d178b1d1e 1485 if (rows != eaSz) {
wolfSSL 16:8e0d178b1d1e 1486 WOLFSSL_MSG("DER array not large enough to hold attribute count");
wolfSSL 16:8e0d178b1d1e 1487 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 1488 }
wolfSSL 16:8e0d178b1d1e 1489
wolfSSL 15:117db924cf7c 1490 for (i = 0; i < eaSz; i++) {
wolfSSL 16:8e0d178b1d1e 1491 sz = ea[i].valueSeqSz + ea[i].oidSz + ea[i].valueSetSz + ea[i].valueSz;
wolfSSL 16:8e0d178b1d1e 1492
wolfSSL 16:8e0d178b1d1e 1493 output = (byte*)XMALLOC(sz, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 1494 if (output == NULL) {
wolfSSL 16:8e0d178b1d1e 1495 return MEMORY_E;
wolfSSL 16:8e0d178b1d1e 1496 }
wolfSSL 16:8e0d178b1d1e 1497
wolfSSL 16:8e0d178b1d1e 1498 idx = 0;
wolfSSL 15:117db924cf7c 1499 XMEMCPY(output + idx, ea[i].valueSeq, ea[i].valueSeqSz);
wolfSSL 15:117db924cf7c 1500 idx += ea[i].valueSeqSz;
wolfSSL 15:117db924cf7c 1501 XMEMCPY(output + idx, ea[i].oid, ea[i].oidSz);
wolfSSL 15:117db924cf7c 1502 idx += ea[i].oidSz;
wolfSSL 15:117db924cf7c 1503 XMEMCPY(output + idx, ea[i].valueSet, ea[i].valueSetSz);
wolfSSL 15:117db924cf7c 1504 idx += ea[i].valueSetSz;
wolfSSL 15:117db924cf7c 1505 XMEMCPY(output + idx, ea[i].value, ea[i].valueSz);
wolfSSL 16:8e0d178b1d1e 1506
wolfSSL 16:8e0d178b1d1e 1507 fa = derArr[i];
wolfSSL 16:8e0d178b1d1e 1508 fa->data = output;
wolfSSL 16:8e0d178b1d1e 1509 fa->dataSz = sz;
wolfSSL 16:8e0d178b1d1e 1510 }
wolfSSL 16:8e0d178b1d1e 1511
wolfSSL 16:8e0d178b1d1e 1512 return 0;
wolfSSL 16:8e0d178b1d1e 1513 }
wolfSSL 16:8e0d178b1d1e 1514
wolfSSL 16:8e0d178b1d1e 1515
wolfSSL 16:8e0d178b1d1e 1516 /* Sort and Flatten EncodedAttrib attributes into output buffer */
wolfSSL 16:8e0d178b1d1e 1517 static int FlattenAttributes(PKCS7* pkcs7, byte* output, EncodedAttrib* ea,
wolfSSL 16:8e0d178b1d1e 1518 int eaSz)
wolfSSL 16:8e0d178b1d1e 1519 {
wolfSSL 16:8e0d178b1d1e 1520 int i, idx, ret;
wolfSSL 16:8e0d178b1d1e 1521 FlatAttrib** derArr = NULL;
wolfSSL 16:8e0d178b1d1e 1522 FlatAttrib* fa = NULL;
wolfSSL 16:8e0d178b1d1e 1523
wolfSSL 16:8e0d178b1d1e 1524 if (pkcs7 == NULL || output == NULL || ea == NULL) {
wolfSSL 16:8e0d178b1d1e 1525 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 1526 }
wolfSSL 16:8e0d178b1d1e 1527
wolfSSL 16:8e0d178b1d1e 1528 /* create array of FlatAttrib struct pointers to hold DER attribs */
wolfSSL 16:8e0d178b1d1e 1529 derArr = (FlatAttrib**) XMALLOC(eaSz * sizeof(FlatAttrib*), pkcs7->heap,
wolfSSL 16:8e0d178b1d1e 1530 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 1531 if (derArr == NULL) {
wolfSSL 16:8e0d178b1d1e 1532 return MEMORY_E;
wolfSSL 16:8e0d178b1d1e 1533 }
wolfSSL 16:8e0d178b1d1e 1534 XMEMSET(derArr, 0, eaSz * sizeof(FlatAttrib*));
wolfSSL 16:8e0d178b1d1e 1535
wolfSSL 16:8e0d178b1d1e 1536 for (i = 0; i < eaSz; i++) {
wolfSSL 16:8e0d178b1d1e 1537 derArr[i] = NewAttrib(pkcs7->heap);
wolfSSL 16:8e0d178b1d1e 1538 if (derArr[i] == NULL) {
wolfSSL 16:8e0d178b1d1e 1539 FreeAttribArray(pkcs7, derArr, eaSz);
wolfSSL 16:8e0d178b1d1e 1540 return MEMORY_E;
wolfSSL 16:8e0d178b1d1e 1541 }
wolfSSL 16:8e0d178b1d1e 1542 ForceZero(derArr[i], sizeof(FlatAttrib));
wolfSSL 16:8e0d178b1d1e 1543 }
wolfSSL 16:8e0d178b1d1e 1544
wolfSSL 16:8e0d178b1d1e 1545 /* flatten EncodedAttrib into DER byte arrays */
wolfSSL 16:8e0d178b1d1e 1546 ret = FlattenEncodedAttribs(pkcs7, derArr, eaSz, ea, eaSz);
wolfSSL 16:8e0d178b1d1e 1547 if (ret != 0) {
wolfSSL 16:8e0d178b1d1e 1548 FreeAttribArray(pkcs7, derArr, eaSz);
wolfSSL 16:8e0d178b1d1e 1549 return ret;
wolfSSL 16:8e0d178b1d1e 1550 }
wolfSSL 16:8e0d178b1d1e 1551
wolfSSL 16:8e0d178b1d1e 1552 /* SET OF DER signed attributes must be sorted in ascending order */
wolfSSL 16:8e0d178b1d1e 1553 ret = SortAttribArray(derArr, eaSz);
wolfSSL 16:8e0d178b1d1e 1554 if (ret != 0) {
wolfSSL 16:8e0d178b1d1e 1555 FreeAttribArray(pkcs7, derArr, eaSz);
wolfSSL 16:8e0d178b1d1e 1556 return ret;
wolfSSL 16:8e0d178b1d1e 1557 }
wolfSSL 16:8e0d178b1d1e 1558
wolfSSL 16:8e0d178b1d1e 1559 /* copy sorted DER attribute arrays into output buffer */
wolfSSL 16:8e0d178b1d1e 1560 idx = 0;
wolfSSL 16:8e0d178b1d1e 1561 for (i = 0; i < eaSz; i++) {
wolfSSL 16:8e0d178b1d1e 1562 fa = derArr[i];
wolfSSL 16:8e0d178b1d1e 1563 XMEMCPY(output + idx, fa->data, fa->dataSz);
wolfSSL 16:8e0d178b1d1e 1564 idx += fa->dataSz;
wolfSSL 16:8e0d178b1d1e 1565 }
wolfSSL 16:8e0d178b1d1e 1566
wolfSSL 16:8e0d178b1d1e 1567 FreeAttribArray(pkcs7, derArr, eaSz);
wolfSSL 16:8e0d178b1d1e 1568
wolfSSL 15:117db924cf7c 1569 return 0;
wolfSSL 15:117db924cf7c 1570 }
wolfSSL 15:117db924cf7c 1571
wolfSSL 15:117db924cf7c 1572
wolfSSL 15:117db924cf7c 1573 #ifndef NO_RSA
wolfSSL 15:117db924cf7c 1574
wolfSSL 15:117db924cf7c 1575 /* returns size of signature put into out, negative on error */
wolfSSL 15:117db924cf7c 1576 static int wc_PKCS7_RsaSign(PKCS7* pkcs7, byte* in, word32 inSz, ESD* esd)
wolfSSL 15:117db924cf7c 1577 {
wolfSSL 15:117db924cf7c 1578 int ret;
wolfSSL 15:117db924cf7c 1579 word32 idx;
wolfSSL 15:117db924cf7c 1580 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 1581 RsaKey* privKey;
wolfSSL 15:117db924cf7c 1582 #else
wolfSSL 16:8e0d178b1d1e 1583 RsaKey privKey[1];
wolfSSL 15:117db924cf7c 1584 #endif
wolfSSL 15:117db924cf7c 1585
wolfSSL 15:117db924cf7c 1586 if (pkcs7 == NULL || pkcs7->rng == NULL || in == NULL || esd == NULL) {
wolfSSL 15:117db924cf7c 1587 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 1588 }
wolfSSL 15:117db924cf7c 1589
wolfSSL 15:117db924cf7c 1590 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 1591 privKey = (RsaKey*)XMALLOC(sizeof(RsaKey), pkcs7->heap,
wolfSSL 15:117db924cf7c 1592 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1593 if (privKey == NULL)
wolfSSL 15:117db924cf7c 1594 return MEMORY_E;
wolfSSL 15:117db924cf7c 1595 #endif
wolfSSL 15:117db924cf7c 1596
wolfSSL 15:117db924cf7c 1597 ret = wc_InitRsaKey_ex(privKey, pkcs7->heap, pkcs7->devId);
wolfSSL 15:117db924cf7c 1598 if (ret == 0) {
wolfSSL 15:117db924cf7c 1599 if (pkcs7->privateKey != NULL && pkcs7->privateKeySz > 0) {
wolfSSL 15:117db924cf7c 1600 idx = 0;
wolfSSL 15:117db924cf7c 1601 ret = wc_RsaPrivateKeyDecode(pkcs7->privateKey, &idx, privKey,
wolfSSL 15:117db924cf7c 1602 pkcs7->privateKeySz);
wolfSSL 15:117db924cf7c 1603 }
wolfSSL 15:117db924cf7c 1604 else if (pkcs7->devId == INVALID_DEVID) {
wolfSSL 15:117db924cf7c 1605 ret = BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 1606 }
wolfSSL 15:117db924cf7c 1607 }
wolfSSL 15:117db924cf7c 1608 if (ret == 0) {
wolfSSL 16:8e0d178b1d1e 1609 #ifdef WOLFSSL_ASYNC_CRYPT
wolfSSL 16:8e0d178b1d1e 1610 do {
wolfSSL 16:8e0d178b1d1e 1611 ret = wc_AsyncWait(ret, &privKey->asyncDev,
wolfSSL 16:8e0d178b1d1e 1612 WC_ASYNC_FLAG_CALL_AGAIN);
wolfSSL 16:8e0d178b1d1e 1613 if (ret >= 0)
wolfSSL 16:8e0d178b1d1e 1614 #endif
wolfSSL 16:8e0d178b1d1e 1615 {
wolfSSL 16:8e0d178b1d1e 1616 ret = wc_RsaSSL_Sign(in, inSz, esd->encContentDigest,
wolfSSL 16:8e0d178b1d1e 1617 sizeof(esd->encContentDigest),
wolfSSL 16:8e0d178b1d1e 1618 privKey, pkcs7->rng);
wolfSSL 16:8e0d178b1d1e 1619 }
wolfSSL 16:8e0d178b1d1e 1620 #ifdef WOLFSSL_ASYNC_CRYPT
wolfSSL 16:8e0d178b1d1e 1621 } while (ret == WC_PENDING_E);
wolfSSL 16:8e0d178b1d1e 1622 #endif
wolfSSL 15:117db924cf7c 1623 }
wolfSSL 15:117db924cf7c 1624
wolfSSL 15:117db924cf7c 1625 wc_FreeRsaKey(privKey);
wolfSSL 15:117db924cf7c 1626 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 1627 XFREE(privKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1628 #endif
wolfSSL 15:117db924cf7c 1629
wolfSSL 15:117db924cf7c 1630 return ret;
wolfSSL 15:117db924cf7c 1631 }
wolfSSL 15:117db924cf7c 1632
wolfSSL 15:117db924cf7c 1633 #endif /* NO_RSA */
wolfSSL 15:117db924cf7c 1634
wolfSSL 15:117db924cf7c 1635
wolfSSL 15:117db924cf7c 1636 #ifdef HAVE_ECC
wolfSSL 15:117db924cf7c 1637
wolfSSL 15:117db924cf7c 1638 /* returns size of signature put into out, negative on error */
wolfSSL 15:117db924cf7c 1639 static int wc_PKCS7_EcdsaSign(PKCS7* pkcs7, byte* in, word32 inSz, ESD* esd)
wolfSSL 15:117db924cf7c 1640 {
wolfSSL 15:117db924cf7c 1641 int ret;
wolfSSL 15:117db924cf7c 1642 word32 outSz, idx;
wolfSSL 15:117db924cf7c 1643 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 1644 ecc_key* privKey;
wolfSSL 15:117db924cf7c 1645 #else
wolfSSL 16:8e0d178b1d1e 1646 ecc_key privKey[1];
wolfSSL 15:117db924cf7c 1647 #endif
wolfSSL 15:117db924cf7c 1648
wolfSSL 15:117db924cf7c 1649 if (pkcs7 == NULL || pkcs7->rng == NULL || in == NULL || esd == NULL) {
wolfSSL 15:117db924cf7c 1650 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 1651 }
wolfSSL 15:117db924cf7c 1652
wolfSSL 15:117db924cf7c 1653 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 1654 privKey = (ecc_key*)XMALLOC(sizeof(ecc_key), pkcs7->heap,
wolfSSL 15:117db924cf7c 1655 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1656 if (privKey == NULL)
wolfSSL 15:117db924cf7c 1657 return MEMORY_E;
wolfSSL 15:117db924cf7c 1658 #endif
wolfSSL 15:117db924cf7c 1659
wolfSSL 15:117db924cf7c 1660 ret = wc_ecc_init_ex(privKey, pkcs7->heap, pkcs7->devId);
wolfSSL 15:117db924cf7c 1661 if (ret == 0) {
wolfSSL 15:117db924cf7c 1662 if (pkcs7->privateKey != NULL && pkcs7->privateKeySz > 0) {
wolfSSL 15:117db924cf7c 1663 idx = 0;
wolfSSL 15:117db924cf7c 1664 ret = wc_EccPrivateKeyDecode(pkcs7->privateKey, &idx, privKey,
wolfSSL 15:117db924cf7c 1665 pkcs7->privateKeySz);
wolfSSL 15:117db924cf7c 1666 }
wolfSSL 15:117db924cf7c 1667 else if (pkcs7->devId == INVALID_DEVID) {
wolfSSL 15:117db924cf7c 1668 ret = BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 1669 }
wolfSSL 15:117db924cf7c 1670 }
wolfSSL 15:117db924cf7c 1671 if (ret == 0) {
wolfSSL 15:117db924cf7c 1672 outSz = sizeof(esd->encContentDigest);
wolfSSL 16:8e0d178b1d1e 1673 #ifdef WOLFSSL_ASYNC_CRYPT
wolfSSL 16:8e0d178b1d1e 1674 do {
wolfSSL 16:8e0d178b1d1e 1675 ret = wc_AsyncWait(ret, &privKey->asyncDev,
wolfSSL 16:8e0d178b1d1e 1676 WC_ASYNC_FLAG_CALL_AGAIN);
wolfSSL 16:8e0d178b1d1e 1677 if (ret >= 0)
wolfSSL 16:8e0d178b1d1e 1678 #endif
wolfSSL 16:8e0d178b1d1e 1679 {
wolfSSL 16:8e0d178b1d1e 1680 ret = wc_ecc_sign_hash(in, inSz, esd->encContentDigest,
wolfSSL 16:8e0d178b1d1e 1681 &outSz, pkcs7->rng, privKey);
wolfSSL 16:8e0d178b1d1e 1682 }
wolfSSL 16:8e0d178b1d1e 1683 #ifdef WOLFSSL_ASYNC_CRYPT
wolfSSL 16:8e0d178b1d1e 1684 } while (ret == WC_PENDING_E);
wolfSSL 16:8e0d178b1d1e 1685 #endif
wolfSSL 15:117db924cf7c 1686 if (ret == 0)
wolfSSL 15:117db924cf7c 1687 ret = (int)outSz;
wolfSSL 15:117db924cf7c 1688 }
wolfSSL 15:117db924cf7c 1689
wolfSSL 15:117db924cf7c 1690 wc_ecc_free(privKey);
wolfSSL 15:117db924cf7c 1691 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 1692 XFREE(privKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1693 #endif
wolfSSL 15:117db924cf7c 1694
wolfSSL 15:117db924cf7c 1695 return ret;
wolfSSL 15:117db924cf7c 1696 }
wolfSSL 15:117db924cf7c 1697
wolfSSL 15:117db924cf7c 1698 #endif /* HAVE_ECC */
wolfSSL 15:117db924cf7c 1699
wolfSSL 15:117db924cf7c 1700
wolfSSL 15:117db924cf7c 1701 /* builds up SignedData signed attributes, including default ones.
wolfSSL 15:117db924cf7c 1702 *
wolfSSL 15:117db924cf7c 1703 * pkcs7 - pointer to initialized PKCS7 structure
wolfSSL 15:117db924cf7c 1704 * esd - pointer to initialized ESD structure, used for output
wolfSSL 15:117db924cf7c 1705 *
wolfSSL 15:117db924cf7c 1706 * return 0 on success, negative on error */
wolfSSL 15:117db924cf7c 1707 static int wc_PKCS7_BuildSignedAttributes(PKCS7* pkcs7, ESD* esd,
wolfSSL 16:8e0d178b1d1e 1708 const byte* contentType, word32 contentTypeSz,
wolfSSL 16:8e0d178b1d1e 1709 const byte* contentTypeOid, word32 contentTypeOidSz,
wolfSSL 16:8e0d178b1d1e 1710 const byte* messageDigestOid, word32 messageDigestOidSz,
wolfSSL 16:8e0d178b1d1e 1711 const byte* signingTimeOid, word32 signingTimeOidSz,
wolfSSL 16:8e0d178b1d1e 1712 byte* signingTime, word32 signingTimeSz)
wolfSSL 15:117db924cf7c 1713 {
wolfSSL 15:117db924cf7c 1714 int hashSz;
wolfSSL 16:8e0d178b1d1e 1715 #ifdef NO_ASN_TIME
wolfSSL 15:117db924cf7c 1716 PKCS7Attrib cannedAttribs[2];
wolfSSL 16:8e0d178b1d1e 1717 #else
wolfSSL 16:8e0d178b1d1e 1718 time_t tm;
wolfSSL 16:8e0d178b1d1e 1719 int timeSz;
wolfSSL 16:8e0d178b1d1e 1720 PKCS7Attrib cannedAttribs[3];
wolfSSL 16:8e0d178b1d1e 1721 #endif
wolfSSL 16:8e0d178b1d1e 1722 word32 idx = 0;
wolfSSL 15:117db924cf7c 1723 word32 cannedAttribsCount;
wolfSSL 15:117db924cf7c 1724
wolfSSL 16:8e0d178b1d1e 1725 if (pkcs7 == NULL || esd == NULL || contentType == NULL ||
wolfSSL 16:8e0d178b1d1e 1726 contentTypeOid == NULL || messageDigestOid == NULL ||
wolfSSL 16:8e0d178b1d1e 1727 signingTimeOid == NULL) {
wolfSSL 16:8e0d178b1d1e 1728 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 1729 }
wolfSSL 16:8e0d178b1d1e 1730
wolfSSL 16:8e0d178b1d1e 1731 if (pkcs7->skipDefaultSignedAttribs == 0) {
wolfSSL 16:8e0d178b1d1e 1732 hashSz = wc_HashGetDigestSize(esd->hashType);
wolfSSL 16:8e0d178b1d1e 1733 if (hashSz < 0)
wolfSSL 16:8e0d178b1d1e 1734 return hashSz;
wolfSSL 16:8e0d178b1d1e 1735
wolfSSL 16:8e0d178b1d1e 1736 #ifndef NO_ASN_TIME
wolfSSL 16:8e0d178b1d1e 1737 if (signingTime == NULL || signingTimeSz == 0)
wolfSSL 16:8e0d178b1d1e 1738 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 1739
wolfSSL 16:8e0d178b1d1e 1740 tm = XTIME(0);
wolfSSL 16:8e0d178b1d1e 1741 timeSz = GetAsnTimeString(&tm, signingTime, signingTimeSz);
wolfSSL 16:8e0d178b1d1e 1742 if (timeSz < 0)
wolfSSL 16:8e0d178b1d1e 1743 return timeSz;
wolfSSL 16:8e0d178b1d1e 1744 #endif
wolfSSL 16:8e0d178b1d1e 1745
wolfSSL 16:8e0d178b1d1e 1746 cannedAttribsCount = sizeof(cannedAttribs)/sizeof(PKCS7Attrib);
wolfSSL 16:8e0d178b1d1e 1747
wolfSSL 16:8e0d178b1d1e 1748 cannedAttribs[idx].oid = contentTypeOid;
wolfSSL 16:8e0d178b1d1e 1749 cannedAttribs[idx].oidSz = contentTypeOidSz;
wolfSSL 16:8e0d178b1d1e 1750 cannedAttribs[idx].value = contentType;
wolfSSL 16:8e0d178b1d1e 1751 cannedAttribs[idx].valueSz = contentTypeSz;
wolfSSL 16:8e0d178b1d1e 1752 idx++;
wolfSSL 16:8e0d178b1d1e 1753 #ifndef NO_ASN_TIME
wolfSSL 16:8e0d178b1d1e 1754 cannedAttribs[idx].oid = signingTimeOid;
wolfSSL 16:8e0d178b1d1e 1755 cannedAttribs[idx].oidSz = signingTimeOidSz;
wolfSSL 16:8e0d178b1d1e 1756 cannedAttribs[idx].value = signingTime;
wolfSSL 16:8e0d178b1d1e 1757 cannedAttribs[idx].valueSz = timeSz;
wolfSSL 16:8e0d178b1d1e 1758 idx++;
wolfSSL 16:8e0d178b1d1e 1759 #endif
wolfSSL 16:8e0d178b1d1e 1760 cannedAttribs[idx].oid = messageDigestOid;
wolfSSL 16:8e0d178b1d1e 1761 cannedAttribs[idx].oidSz = messageDigestOidSz;
wolfSSL 16:8e0d178b1d1e 1762 cannedAttribs[idx].value = esd->contentDigest;
wolfSSL 16:8e0d178b1d1e 1763 cannedAttribs[idx].valueSz = hashSz + 2; /* ASN.1 heading */
wolfSSL 16:8e0d178b1d1e 1764
wolfSSL 16:8e0d178b1d1e 1765 esd->signedAttribsCount += cannedAttribsCount;
wolfSSL 16:8e0d178b1d1e 1766 esd->signedAttribsSz += EncodeAttributes(&esd->signedAttribs[0], 3,
wolfSSL 16:8e0d178b1d1e 1767 cannedAttribs, cannedAttribsCount);
wolfSSL 16:8e0d178b1d1e 1768 } else {
wolfSSL 16:8e0d178b1d1e 1769 esd->signedAttribsCount = 0;
wolfSSL 16:8e0d178b1d1e 1770 esd->signedAttribsSz = 0;
wolfSSL 16:8e0d178b1d1e 1771 }
wolfSSL 16:8e0d178b1d1e 1772
wolfSSL 16:8e0d178b1d1e 1773 /* add custom signed attributes if set */
wolfSSL 16:8e0d178b1d1e 1774 if (pkcs7->signedAttribsSz > 0 && pkcs7->signedAttribs != NULL) {
wolfSSL 16:8e0d178b1d1e 1775 esd->signedAttribsCount += pkcs7->signedAttribsSz;
wolfSSL 16:8e0d178b1d1e 1776 #ifdef NO_ASN_TIME
wolfSSL 16:8e0d178b1d1e 1777 esd->signedAttribsSz += EncodeAttributes(&esd->signedAttribs[2], 4,
wolfSSL 16:8e0d178b1d1e 1778 pkcs7->signedAttribs, pkcs7->signedAttribsSz);
wolfSSL 16:8e0d178b1d1e 1779 #else
wolfSSL 16:8e0d178b1d1e 1780 esd->signedAttribsSz += EncodeAttributes(&esd->signedAttribs[3], 4,
wolfSSL 16:8e0d178b1d1e 1781 pkcs7->signedAttribs, pkcs7->signedAttribsSz);
wolfSSL 16:8e0d178b1d1e 1782 #endif
wolfSSL 16:8e0d178b1d1e 1783 }
wolfSSL 16:8e0d178b1d1e 1784
wolfSSL 16:8e0d178b1d1e 1785 #ifdef NO_ASN_TIME
wolfSSL 16:8e0d178b1d1e 1786 (void)signingTimeOidSz;
wolfSSL 16:8e0d178b1d1e 1787 (void)signingTime;
wolfSSL 16:8e0d178b1d1e 1788 (void)signingTimeSz;
wolfSSL 16:8e0d178b1d1e 1789 #endif
wolfSSL 15:117db924cf7c 1790
wolfSSL 15:117db924cf7c 1791 return 0;
wolfSSL 15:117db924cf7c 1792 }
wolfSSL 15:117db924cf7c 1793
wolfSSL 15:117db924cf7c 1794
wolfSSL 15:117db924cf7c 1795 /* gets correct encryption algo ID for SignedData, either CTC_<hash>wRSA or
wolfSSL 15:117db924cf7c 1796 * CTC_<hash>wECDSA, from pkcs7->publicKeyOID and pkcs7->hashOID.
wolfSSL 15:117db924cf7c 1797 *
wolfSSL 15:117db924cf7c 1798 * pkcs7 - pointer to PKCS7 structure
wolfSSL 15:117db924cf7c 1799 * digEncAlgoId - [OUT] output int to store correct algo ID in
wolfSSL 15:117db924cf7c 1800 * digEncAlgoType - [OUT] output for algo ID type
wolfSSL 15:117db924cf7c 1801 *
wolfSSL 15:117db924cf7c 1802 * return 0 on success, negative on error */
wolfSSL 15:117db924cf7c 1803 static int wc_PKCS7_SignedDataGetEncAlgoId(PKCS7* pkcs7, int* digEncAlgoId,
wolfSSL 15:117db924cf7c 1804 int* digEncAlgoType)
wolfSSL 15:117db924cf7c 1805 {
wolfSSL 15:117db924cf7c 1806 int algoId = 0;
wolfSSL 15:117db924cf7c 1807 int algoType = 0;
wolfSSL 15:117db924cf7c 1808
wolfSSL 15:117db924cf7c 1809 if (pkcs7 == NULL || digEncAlgoId == NULL || digEncAlgoType == NULL)
wolfSSL 15:117db924cf7c 1810 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 1811
wolfSSL 15:117db924cf7c 1812 if (pkcs7->publicKeyOID == RSAk) {
wolfSSL 15:117db924cf7c 1813
wolfSSL 15:117db924cf7c 1814 algoType = oidSigType;
wolfSSL 15:117db924cf7c 1815
wolfSSL 15:117db924cf7c 1816 switch (pkcs7->hashOID) {
wolfSSL 15:117db924cf7c 1817 #ifndef NO_SHA
wolfSSL 15:117db924cf7c 1818 case SHAh:
wolfSSL 15:117db924cf7c 1819 algoId = CTC_SHAwRSA;
wolfSSL 15:117db924cf7c 1820 break;
wolfSSL 15:117db924cf7c 1821 #endif
wolfSSL 15:117db924cf7c 1822 #ifdef WOLFSSL_SHA224
wolfSSL 15:117db924cf7c 1823 case SHA224h:
wolfSSL 15:117db924cf7c 1824 algoId = CTC_SHA224wRSA;
wolfSSL 15:117db924cf7c 1825 break;
wolfSSL 15:117db924cf7c 1826 #endif
wolfSSL 15:117db924cf7c 1827 #ifndef NO_SHA256
wolfSSL 15:117db924cf7c 1828 case SHA256h:
wolfSSL 15:117db924cf7c 1829 algoId = CTC_SHA256wRSA;
wolfSSL 15:117db924cf7c 1830 break;
wolfSSL 15:117db924cf7c 1831 #endif
wolfSSL 15:117db924cf7c 1832 #ifdef WOLFSSL_SHA384
wolfSSL 15:117db924cf7c 1833 case SHA384h:
wolfSSL 15:117db924cf7c 1834 algoId = CTC_SHA384wRSA;
wolfSSL 15:117db924cf7c 1835 break;
wolfSSL 15:117db924cf7c 1836 #endif
wolfSSL 15:117db924cf7c 1837 #ifdef WOLFSSL_SHA512
wolfSSL 15:117db924cf7c 1838 case SHA512h:
wolfSSL 15:117db924cf7c 1839 algoId = CTC_SHA512wRSA;
wolfSSL 15:117db924cf7c 1840 break;
wolfSSL 15:117db924cf7c 1841 #endif
wolfSSL 15:117db924cf7c 1842 }
wolfSSL 15:117db924cf7c 1843
wolfSSL 15:117db924cf7c 1844 }
wolfSSL 15:117db924cf7c 1845 #ifdef HAVE_ECC
wolfSSL 15:117db924cf7c 1846 else if (pkcs7->publicKeyOID == ECDSAk) {
wolfSSL 15:117db924cf7c 1847
wolfSSL 15:117db924cf7c 1848 algoType = oidSigType;
wolfSSL 15:117db924cf7c 1849
wolfSSL 15:117db924cf7c 1850 switch (pkcs7->hashOID) {
wolfSSL 15:117db924cf7c 1851 #ifndef NO_SHA
wolfSSL 15:117db924cf7c 1852 case SHAh:
wolfSSL 15:117db924cf7c 1853 algoId = CTC_SHAwECDSA;
wolfSSL 15:117db924cf7c 1854 break;
wolfSSL 15:117db924cf7c 1855 #endif
wolfSSL 15:117db924cf7c 1856 #ifdef WOLFSSL_SHA224
wolfSSL 15:117db924cf7c 1857 case SHA224h:
wolfSSL 15:117db924cf7c 1858 algoId = CTC_SHA224wECDSA;
wolfSSL 15:117db924cf7c 1859 break;
wolfSSL 15:117db924cf7c 1860 #endif
wolfSSL 15:117db924cf7c 1861 #ifndef NO_SHA256
wolfSSL 15:117db924cf7c 1862 case SHA256h:
wolfSSL 15:117db924cf7c 1863 algoId = CTC_SHA256wECDSA;
wolfSSL 15:117db924cf7c 1864 break;
wolfSSL 15:117db924cf7c 1865 #endif
wolfSSL 15:117db924cf7c 1866 #ifdef WOLFSSL_SHA384
wolfSSL 15:117db924cf7c 1867 case SHA384h:
wolfSSL 15:117db924cf7c 1868 algoId = CTC_SHA384wECDSA;
wolfSSL 15:117db924cf7c 1869 break;
wolfSSL 15:117db924cf7c 1870 #endif
wolfSSL 15:117db924cf7c 1871 #ifdef WOLFSSL_SHA512
wolfSSL 15:117db924cf7c 1872 case SHA512h:
wolfSSL 15:117db924cf7c 1873 algoId = CTC_SHA512wECDSA;
wolfSSL 15:117db924cf7c 1874 break;
wolfSSL 15:117db924cf7c 1875 #endif
wolfSSL 15:117db924cf7c 1876 }
wolfSSL 15:117db924cf7c 1877 }
wolfSSL 15:117db924cf7c 1878 #endif /* HAVE_ECC */
wolfSSL 15:117db924cf7c 1879
wolfSSL 15:117db924cf7c 1880 if (algoId == 0) {
wolfSSL 15:117db924cf7c 1881 WOLFSSL_MSG("Invalid signature algorithm type");
wolfSSL 15:117db924cf7c 1882 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 1883 }
wolfSSL 15:117db924cf7c 1884
wolfSSL 15:117db924cf7c 1885 *digEncAlgoId = algoId;
wolfSSL 15:117db924cf7c 1886 *digEncAlgoType = algoType;
wolfSSL 15:117db924cf7c 1887
wolfSSL 15:117db924cf7c 1888 return 0;
wolfSSL 15:117db924cf7c 1889 }
wolfSSL 15:117db924cf7c 1890
wolfSSL 15:117db924cf7c 1891
wolfSSL 15:117db924cf7c 1892 /* build SignedData DigestInfo for use with PKCS#7/RSA
wolfSSL 15:117db924cf7c 1893 *
wolfSSL 15:117db924cf7c 1894 * pkcs7 - pointer to initialized PKCS7 struct
wolfSSL 15:117db924cf7c 1895 * flatSignedAttribs - flattened, signed attributes
wolfSSL 15:117db924cf7c 1896 * flatSignedAttrbsSz - size of flatSignedAttribs, octets
wolfSSL 15:117db924cf7c 1897 * esd - pointer to initialized ESD struct
wolfSSL 15:117db924cf7c 1898 * digestInfo - [OUT] output array for DigestInfo
wolfSSL 15:117db924cf7c 1899 * digestInfoSz - [IN/OUT] - input size of array, size of digestInfo
wolfSSL 15:117db924cf7c 1900 *
wolfSSL 15:117db924cf7c 1901 * return 0 on success, negative on error */
wolfSSL 15:117db924cf7c 1902 static int wc_PKCS7_BuildDigestInfo(PKCS7* pkcs7, byte* flatSignedAttribs,
wolfSSL 15:117db924cf7c 1903 word32 flatSignedAttribsSz, ESD* esd,
wolfSSL 15:117db924cf7c 1904 byte* digestInfo, word32* digestInfoSz)
wolfSSL 15:117db924cf7c 1905 {
wolfSSL 15:117db924cf7c 1906 int ret, hashSz, digIdx = 0;
wolfSSL 15:117db924cf7c 1907 byte digestInfoSeq[MAX_SEQ_SZ];
wolfSSL 15:117db924cf7c 1908 byte digestStr[MAX_OCTET_STR_SZ];
wolfSSL 15:117db924cf7c 1909 byte attribSet[MAX_SET_SZ];
wolfSSL 15:117db924cf7c 1910 byte algoId[MAX_ALGO_SZ];
wolfSSL 15:117db924cf7c 1911 word32 digestInfoSeqSz, digestStrSz, algoIdSz;
wolfSSL 15:117db924cf7c 1912 word32 attribSetSz;
wolfSSL 15:117db924cf7c 1913
wolfSSL 15:117db924cf7c 1914 if (pkcs7 == NULL || esd == NULL || digestInfo == NULL ||
wolfSSL 15:117db924cf7c 1915 digestInfoSz == NULL) {
wolfSSL 15:117db924cf7c 1916 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 1917 }
wolfSSL 15:117db924cf7c 1918
wolfSSL 15:117db924cf7c 1919 hashSz = wc_HashGetDigestSize(esd->hashType);
wolfSSL 15:117db924cf7c 1920 if (hashSz < 0)
wolfSSL 15:117db924cf7c 1921 return hashSz;
wolfSSL 15:117db924cf7c 1922
wolfSSL 16:8e0d178b1d1e 1923 if (flatSignedAttribsSz != 0) {
wolfSSL 15:117db924cf7c 1924
wolfSSL 15:117db924cf7c 1925 if (flatSignedAttribs == NULL)
wolfSSL 15:117db924cf7c 1926 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 1927
wolfSSL 15:117db924cf7c 1928 attribSetSz = SetSet(flatSignedAttribsSz, attribSet);
wolfSSL 15:117db924cf7c 1929
wolfSSL 15:117db924cf7c 1930 ret = wc_HashInit(&esd->hash, esd->hashType);
wolfSSL 15:117db924cf7c 1931 if (ret < 0)
wolfSSL 15:117db924cf7c 1932 return ret;
wolfSSL 15:117db924cf7c 1933
wolfSSL 15:117db924cf7c 1934 ret = wc_HashUpdate(&esd->hash, esd->hashType,
wolfSSL 15:117db924cf7c 1935 attribSet, attribSetSz);
wolfSSL 16:8e0d178b1d1e 1936 if (ret == 0)
wolfSSL 16:8e0d178b1d1e 1937 ret = wc_HashUpdate(&esd->hash, esd->hashType,
wolfSSL 16:8e0d178b1d1e 1938 flatSignedAttribs, flatSignedAttribsSz);
wolfSSL 16:8e0d178b1d1e 1939 if (ret == 0)
wolfSSL 16:8e0d178b1d1e 1940 ret = wc_HashFinal(&esd->hash, esd->hashType,
wolfSSL 16:8e0d178b1d1e 1941 esd->contentAttribsDigest);
wolfSSL 16:8e0d178b1d1e 1942 wc_HashFree(&esd->hash, esd->hashType);
wolfSSL 16:8e0d178b1d1e 1943
wolfSSL 15:117db924cf7c 1944 if (ret < 0)
wolfSSL 15:117db924cf7c 1945 return ret;
wolfSSL 15:117db924cf7c 1946
wolfSSL 15:117db924cf7c 1947 } else {
wolfSSL 15:117db924cf7c 1948 /* when no attrs, digest is contentDigest without tag and length */
wolfSSL 15:117db924cf7c 1949 XMEMCPY(esd->contentAttribsDigest, esd->contentDigest + 2, hashSz);
wolfSSL 15:117db924cf7c 1950 }
wolfSSL 15:117db924cf7c 1951
wolfSSL 15:117db924cf7c 1952 /* set algoID, with NULL attributes */
wolfSSL 15:117db924cf7c 1953 algoIdSz = SetAlgoID(pkcs7->hashOID, algoId, oidHashType, 0);
wolfSSL 15:117db924cf7c 1954
wolfSSL 15:117db924cf7c 1955 digestStrSz = SetOctetString(hashSz, digestStr);
wolfSSL 15:117db924cf7c 1956 digestInfoSeqSz = SetSequence(algoIdSz + digestStrSz + hashSz,
wolfSSL 15:117db924cf7c 1957 digestInfoSeq);
wolfSSL 15:117db924cf7c 1958
wolfSSL 15:117db924cf7c 1959 if (*digestInfoSz < (digestInfoSeqSz + algoIdSz + digestStrSz + hashSz)) {
wolfSSL 15:117db924cf7c 1960 return BUFFER_E;
wolfSSL 15:117db924cf7c 1961 }
wolfSSL 15:117db924cf7c 1962
wolfSSL 15:117db924cf7c 1963 XMEMCPY(digestInfo + digIdx, digestInfoSeq, digestInfoSeqSz);
wolfSSL 15:117db924cf7c 1964 digIdx += digestInfoSeqSz;
wolfSSL 15:117db924cf7c 1965 XMEMCPY(digestInfo + digIdx, algoId, algoIdSz);
wolfSSL 15:117db924cf7c 1966 digIdx += algoIdSz;
wolfSSL 15:117db924cf7c 1967 XMEMCPY(digestInfo + digIdx, digestStr, digestStrSz);
wolfSSL 15:117db924cf7c 1968 digIdx += digestStrSz;
wolfSSL 15:117db924cf7c 1969 XMEMCPY(digestInfo + digIdx, esd->contentAttribsDigest, hashSz);
wolfSSL 15:117db924cf7c 1970 digIdx += hashSz;
wolfSSL 15:117db924cf7c 1971
wolfSSL 15:117db924cf7c 1972 *digestInfoSz = digIdx;
wolfSSL 15:117db924cf7c 1973
wolfSSL 15:117db924cf7c 1974 return 0;
wolfSSL 15:117db924cf7c 1975 }
wolfSSL 15:117db924cf7c 1976
wolfSSL 15:117db924cf7c 1977
wolfSSL 15:117db924cf7c 1978 /* build SignedData signature over DigestInfo or content digest
wolfSSL 15:117db924cf7c 1979 *
wolfSSL 16:8e0d178b1d1e 1980 * pkcs7 - pointer to initialized PKCS7 struct
wolfSSL 15:117db924cf7c 1981 * flatSignedAttribs - flattened, signed attributes
wolfSSL 15:117db924cf7c 1982 * flatSignedAttribsSz - size of flatSignedAttribs, octets
wolfSSL 15:117db924cf7c 1983 * esd - pointer to initialized ESD struct
wolfSSL 15:117db924cf7c 1984 *
wolfSSL 15:117db924cf7c 1985 * returns length of signature on success, negative on error */
wolfSSL 15:117db924cf7c 1986 static int wc_PKCS7_SignedDataBuildSignature(PKCS7* pkcs7,
wolfSSL 15:117db924cf7c 1987 byte* flatSignedAttribs,
wolfSSL 15:117db924cf7c 1988 word32 flatSignedAttribsSz,
wolfSSL 15:117db924cf7c 1989 ESD* esd)
wolfSSL 15:117db924cf7c 1990 {
wolfSSL 16:8e0d178b1d1e 1991 int ret = 0;
wolfSSL 16:8e0d178b1d1e 1992 #if defined(HAVE_ECC) || \
wolfSSL 16:8e0d178b1d1e 1993 (defined(HAVE_PKCS7_RSA_RAW_SIGN_CALLBACK) && !defined(NO_RSA))
wolfSSL 16:8e0d178b1d1e 1994 int hashSz = 0;
wolfSSL 16:8e0d178b1d1e 1995 #endif
wolfSSL 16:8e0d178b1d1e 1996 #if defined(HAVE_PKCS7_RSA_RAW_SIGN_CALLBACK) && !defined(NO_RSA)
wolfSSL 16:8e0d178b1d1e 1997 int hashOID;
wolfSSL 15:117db924cf7c 1998 #endif
wolfSSL 15:117db924cf7c 1999 word32 digestInfoSz = MAX_PKCS7_DIGEST_SZ;
wolfSSL 15:117db924cf7c 2000 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 2001 byte* digestInfo;
wolfSSL 15:117db924cf7c 2002 #else
wolfSSL 16:8e0d178b1d1e 2003 byte digestInfo[MAX_PKCS7_DIGEST_SZ];
wolfSSL 15:117db924cf7c 2004 #endif
wolfSSL 15:117db924cf7c 2005
wolfSSL 15:117db924cf7c 2006 if (pkcs7 == NULL || esd == NULL)
wolfSSL 15:117db924cf7c 2007 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 2008
wolfSSL 15:117db924cf7c 2009 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 2010 digestInfo = (byte*)XMALLOC(digestInfoSz, pkcs7->heap,
wolfSSL 15:117db924cf7c 2011 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 2012 if (digestInfo == NULL) {
wolfSSL 15:117db924cf7c 2013 return MEMORY_E;
wolfSSL 15:117db924cf7c 2014 }
wolfSSL 15:117db924cf7c 2015 #endif
wolfSSL 16:8e0d178b1d1e 2016 XMEMSET(digestInfo, 0, digestInfoSz);
wolfSSL 15:117db924cf7c 2017
wolfSSL 15:117db924cf7c 2018 ret = wc_PKCS7_BuildDigestInfo(pkcs7, flatSignedAttribs,
wolfSSL 15:117db924cf7c 2019 flatSignedAttribsSz, esd, digestInfo,
wolfSSL 15:117db924cf7c 2020 &digestInfoSz);
wolfSSL 15:117db924cf7c 2021 if (ret < 0) {
wolfSSL 15:117db924cf7c 2022 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 2023 XFREE(digestInfo, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 2024 #endif
wolfSSL 15:117db924cf7c 2025 return ret;
wolfSSL 15:117db924cf7c 2026 }
wolfSSL 15:117db924cf7c 2027
wolfSSL 16:8e0d178b1d1e 2028 #if defined(HAVE_ECC) || \
wolfSSL 16:8e0d178b1d1e 2029 (defined(HAVE_PKCS7_RSA_RAW_SIGN_CALLBACK) && !defined(NO_RSA))
wolfSSL 16:8e0d178b1d1e 2030 /* get digest size from hash type */
wolfSSL 16:8e0d178b1d1e 2031 hashSz = wc_HashGetDigestSize(esd->hashType);
wolfSSL 16:8e0d178b1d1e 2032 if (hashSz < 0) {
wolfSSL 16:8e0d178b1d1e 2033 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 2034 XFREE(digestInfo, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 2035 #endif
wolfSSL 16:8e0d178b1d1e 2036 return hashSz;
wolfSSL 16:8e0d178b1d1e 2037 }
wolfSSL 16:8e0d178b1d1e 2038 #endif
wolfSSL 16:8e0d178b1d1e 2039
wolfSSL 15:117db924cf7c 2040 /* sign digestInfo */
wolfSSL 15:117db924cf7c 2041 switch (pkcs7->publicKeyOID) {
wolfSSL 15:117db924cf7c 2042
wolfSSL 15:117db924cf7c 2043 #ifndef NO_RSA
wolfSSL 15:117db924cf7c 2044 case RSAk:
wolfSSL 16:8e0d178b1d1e 2045 #ifdef HAVE_PKCS7_RSA_RAW_SIGN_CALLBACK
wolfSSL 16:8e0d178b1d1e 2046 if (pkcs7->rsaSignRawDigestCb != NULL) {
wolfSSL 16:8e0d178b1d1e 2047 /* get hash OID */
wolfSSL 16:8e0d178b1d1e 2048 hashOID = wc_HashGetOID(esd->hashType);
wolfSSL 16:8e0d178b1d1e 2049
wolfSSL 16:8e0d178b1d1e 2050 /* user signing plain digest, build DigestInfo themselves */
wolfSSL 16:8e0d178b1d1e 2051 ret = pkcs7->rsaSignRawDigestCb(pkcs7,
wolfSSL 16:8e0d178b1d1e 2052 esd->contentAttribsDigest, hashSz,
wolfSSL 16:8e0d178b1d1e 2053 esd->encContentDigest, sizeof(esd->encContentDigest),
wolfSSL 16:8e0d178b1d1e 2054 pkcs7->privateKey, pkcs7->privateKeySz, pkcs7->devId,
wolfSSL 16:8e0d178b1d1e 2055 hashOID);
wolfSSL 16:8e0d178b1d1e 2056 break;
wolfSSL 16:8e0d178b1d1e 2057 }
wolfSSL 16:8e0d178b1d1e 2058 #endif
wolfSSL 15:117db924cf7c 2059 ret = wc_PKCS7_RsaSign(pkcs7, digestInfo, digestInfoSz, esd);
wolfSSL 15:117db924cf7c 2060 break;
wolfSSL 15:117db924cf7c 2061 #endif
wolfSSL 15:117db924cf7c 2062
wolfSSL 15:117db924cf7c 2063 #ifdef HAVE_ECC
wolfSSL 15:117db924cf7c 2064 case ECDSAk:
wolfSSL 15:117db924cf7c 2065 /* CMS with ECDSA does not sign DigestInfo structure
wolfSSL 15:117db924cf7c 2066 * like PKCS#7 with RSA does */
wolfSSL 15:117db924cf7c 2067 ret = wc_PKCS7_EcdsaSign(pkcs7, esd->contentAttribsDigest,
wolfSSL 15:117db924cf7c 2068 hashSz, esd);
wolfSSL 15:117db924cf7c 2069 break;
wolfSSL 15:117db924cf7c 2070 #endif
wolfSSL 15:117db924cf7c 2071
wolfSSL 15:117db924cf7c 2072 default:
wolfSSL 15:117db924cf7c 2073 WOLFSSL_MSG("Unsupported public key type");
wolfSSL 15:117db924cf7c 2074 ret = BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 2075 }
wolfSSL 15:117db924cf7c 2076
wolfSSL 15:117db924cf7c 2077 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 2078 XFREE(digestInfo, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 2079 #endif
wolfSSL 15:117db924cf7c 2080
wolfSSL 15:117db924cf7c 2081 if (ret >= 0) {
wolfSSL 15:117db924cf7c 2082 esd->encContentDigestSz = (word32)ret;
wolfSSL 15:117db924cf7c 2083 }
wolfSSL 15:117db924cf7c 2084
wolfSSL 15:117db924cf7c 2085 return ret;
wolfSSL 15:117db924cf7c 2086 }
wolfSSL 15:117db924cf7c 2087
wolfSSL 16:8e0d178b1d1e 2088
wolfSSL 15:117db924cf7c 2089 /* build PKCS#7 signedData content type */
wolfSSL 16:8e0d178b1d1e 2090 static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd,
wolfSSL 16:8e0d178b1d1e 2091 const byte* hashBuf, word32 hashSz, byte* output, word32* outputSz,
wolfSSL 16:8e0d178b1d1e 2092 byte* output2, word32* output2Sz)
wolfSSL 16:8e0d178b1d1e 2093 {
wolfSSL 16:8e0d178b1d1e 2094 /* contentType OID (1.2.840.113549.1.9.3) */
wolfSSL 16:8e0d178b1d1e 2095 const byte contentTypeOid[] =
wolfSSL 15:117db924cf7c 2096 { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xF7, 0x0d, 0x01,
wolfSSL 15:117db924cf7c 2097 0x09, 0x03 };
wolfSSL 16:8e0d178b1d1e 2098
wolfSSL 16:8e0d178b1d1e 2099 /* messageDigest OID (1.2.840.113549.1.9.4) */
wolfSSL 16:8e0d178b1d1e 2100 const byte messageDigestOid[] =
wolfSSL 15:117db924cf7c 2101 { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
wolfSSL 15:117db924cf7c 2102 0x09, 0x04 };
wolfSSL 15:117db924cf7c 2103
wolfSSL 16:8e0d178b1d1e 2104 /* signingTime OID () */
wolfSSL 16:8e0d178b1d1e 2105 byte signingTimeOid[] =
wolfSSL 16:8e0d178b1d1e 2106 { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
wolfSSL 16:8e0d178b1d1e 2107 0x09, 0x05};
wolfSSL 16:8e0d178b1d1e 2108
wolfSSL 16:8e0d178b1d1e 2109 Pkcs7Cert* certPtr = NULL;
wolfSSL 16:8e0d178b1d1e 2110 word32 certSetSz = 0;
wolfSSL 15:117db924cf7c 2111
wolfSSL 15:117db924cf7c 2112 word32 signerInfoSz = 0;
wolfSSL 16:8e0d178b1d1e 2113 word32 totalSz, total2Sz;
wolfSSL 15:117db924cf7c 2114 int idx = 0, ret = 0;
wolfSSL 16:8e0d178b1d1e 2115 int digEncAlgoId, digEncAlgoType;
wolfSSL 15:117db924cf7c 2116 byte* flatSignedAttribs = NULL;
wolfSSL 15:117db924cf7c 2117 word32 flatSignedAttribsSz = 0;
wolfSSL 16:8e0d178b1d1e 2118
wolfSSL 16:8e0d178b1d1e 2119 byte signedDataOid[MAX_OID_SZ];
wolfSSL 16:8e0d178b1d1e 2120 word32 signedDataOidSz;
wolfSSL 16:8e0d178b1d1e 2121
wolfSSL 16:8e0d178b1d1e 2122 byte signingTime[MAX_TIME_STRING_SZ];
wolfSSL 16:8e0d178b1d1e 2123
wolfSSL 16:8e0d178b1d1e 2124 if (pkcs7 == NULL || pkcs7->contentSz == 0 ||
wolfSSL 15:117db924cf7c 2125 pkcs7->encryptOID == 0 || pkcs7->hashOID == 0 || pkcs7->rng == 0 ||
wolfSSL 16:8e0d178b1d1e 2126 output == NULL || outputSz == NULL || *outputSz == 0 || hashSz == 0 ||
wolfSSL 16:8e0d178b1d1e 2127 hashBuf == NULL) {
wolfSSL 16:8e0d178b1d1e 2128 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 2129 }
wolfSSL 16:8e0d178b1d1e 2130
wolfSSL 16:8e0d178b1d1e 2131 /* verify the hash size matches */
wolfSSL 15:117db924cf7c 2132 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 2133 esd = (ESD*)XMALLOC(sizeof(ESD), pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 2134 if (esd == NULL)
wolfSSL 15:117db924cf7c 2135 return MEMORY_E;
wolfSSL 15:117db924cf7c 2136 #endif
wolfSSL 15:117db924cf7c 2137
wolfSSL 15:117db924cf7c 2138 XMEMSET(esd, 0, sizeof(ESD));
wolfSSL 15:117db924cf7c 2139
wolfSSL 16:8e0d178b1d1e 2140 /* set content type based on contentOID, unless user has set custom one
wolfSSL 16:8e0d178b1d1e 2141 with wc_PKCS7_SetContentType() */
wolfSSL 16:8e0d178b1d1e 2142 if (pkcs7->contentTypeSz == 0) {
wolfSSL 16:8e0d178b1d1e 2143
wolfSSL 16:8e0d178b1d1e 2144 /* default to DATA content type if user has not set */
wolfSSL 16:8e0d178b1d1e 2145 if (pkcs7->contentOID == 0) {
wolfSSL 16:8e0d178b1d1e 2146 pkcs7->contentOID = DATA;
wolfSSL 16:8e0d178b1d1e 2147 }
wolfSSL 16:8e0d178b1d1e 2148
wolfSSL 16:8e0d178b1d1e 2149 ret = wc_SetContentType(pkcs7->contentOID, pkcs7->contentType,
wolfSSL 16:8e0d178b1d1e 2150 sizeof(pkcs7->contentType));
wolfSSL 16:8e0d178b1d1e 2151 if (ret < 0) {
wolfSSL 15:117db924cf7c 2152 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 2153 XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 2154 #endif
wolfSSL 16:8e0d178b1d1e 2155 return ret;
wolfSSL 16:8e0d178b1d1e 2156 }
wolfSSL 16:8e0d178b1d1e 2157 pkcs7->contentTypeSz = ret;
wolfSSL 16:8e0d178b1d1e 2158 }
wolfSSL 16:8e0d178b1d1e 2159
wolfSSL 16:8e0d178b1d1e 2160 /* set signedData outer content type */
wolfSSL 16:8e0d178b1d1e 2161 ret = wc_SetContentType(SIGNED_DATA, signedDataOid, sizeof(signedDataOid));
wolfSSL 15:117db924cf7c 2162 if (ret < 0) {
wolfSSL 15:117db924cf7c 2163 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 2164 XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 2165 #endif
wolfSSL 15:117db924cf7c 2166 return ret;
wolfSSL 15:117db924cf7c 2167 }
wolfSSL 16:8e0d178b1d1e 2168 signedDataOidSz = ret;
wolfSSL 16:8e0d178b1d1e 2169
wolfSSL 16:8e0d178b1d1e 2170 if (pkcs7->sidType != DEGENERATE_SID) {
wolfSSL 16:8e0d178b1d1e 2171 esd->hashType = wc_OidGetHash(pkcs7->hashOID);
wolfSSL 16:8e0d178b1d1e 2172 if (wc_HashGetDigestSize(esd->hashType) != (int)hashSz) {
wolfSSL 16:8e0d178b1d1e 2173 WOLFSSL_MSG("hashSz did not match hashOID");
wolfSSL 16:8e0d178b1d1e 2174 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 2175 XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 2176 #endif
wolfSSL 16:8e0d178b1d1e 2177 return BUFFER_E;
wolfSSL 16:8e0d178b1d1e 2178 }
wolfSSL 16:8e0d178b1d1e 2179
wolfSSL 16:8e0d178b1d1e 2180 /* include hash */
wolfSSL 16:8e0d178b1d1e 2181 esd->contentDigest[0] = ASN_OCTET_STRING;
wolfSSL 16:8e0d178b1d1e 2182 esd->contentDigest[1] = (byte)hashSz;
wolfSSL 16:8e0d178b1d1e 2183 XMEMCPY(&esd->contentDigest[2], hashBuf, hashSz);
wolfSSL 16:8e0d178b1d1e 2184 }
wolfSSL 16:8e0d178b1d1e 2185
wolfSSL 16:8e0d178b1d1e 2186 if (pkcs7->detached == 1) {
wolfSSL 16:8e0d178b1d1e 2187 /* do not include content if generating detached signature */
wolfSSL 16:8e0d178b1d1e 2188 esd->innerOctetsSz = 0;
wolfSSL 16:8e0d178b1d1e 2189 esd->innerContSeqSz = 0;
wolfSSL 16:8e0d178b1d1e 2190 esd->contentInfoSeqSz = SetSequence(pkcs7->contentTypeSz,
wolfSSL 16:8e0d178b1d1e 2191 esd->contentInfoSeq);
wolfSSL 16:8e0d178b1d1e 2192 } else {
wolfSSL 16:8e0d178b1d1e 2193 esd->innerOctetsSz = SetOctetString(pkcs7->contentSz, esd->innerOctets);
wolfSSL 16:8e0d178b1d1e 2194 esd->innerContSeqSz = SetExplicit(0, esd->innerOctetsSz +
wolfSSL 16:8e0d178b1d1e 2195 pkcs7->contentSz, esd->innerContSeq);
wolfSSL 16:8e0d178b1d1e 2196 esd->contentInfoSeqSz = SetSequence(pkcs7->contentSz +
wolfSSL 16:8e0d178b1d1e 2197 esd->innerOctetsSz + pkcs7->contentTypeSz +
wolfSSL 16:8e0d178b1d1e 2198 esd->innerContSeqSz, esd->contentInfoSeq);
wolfSSL 16:8e0d178b1d1e 2199 }
wolfSSL 16:8e0d178b1d1e 2200
wolfSSL 16:8e0d178b1d1e 2201 /* SignerIdentifier */
wolfSSL 16:8e0d178b1d1e 2202 if (pkcs7->sidType == CMS_ISSUER_AND_SERIAL_NUMBER) {
wolfSSL 16:8e0d178b1d1e 2203 /* IssuerAndSerialNumber */
wolfSSL 16:8e0d178b1d1e 2204 esd->issuerSnSz = SetSerialNumber(pkcs7->issuerSn, pkcs7->issuerSnSz,
wolfSSL 16:8e0d178b1d1e 2205 esd->issuerSn, MAX_SN_SZ, MAX_SN_SZ);
wolfSSL 16:8e0d178b1d1e 2206 signerInfoSz += esd->issuerSnSz;
wolfSSL 16:8e0d178b1d1e 2207 esd->issuerNameSz = SetSequence(pkcs7->issuerSz, esd->issuerName);
wolfSSL 16:8e0d178b1d1e 2208 signerInfoSz += esd->issuerNameSz + pkcs7->issuerSz;
wolfSSL 16:8e0d178b1d1e 2209 esd->issuerSnSeqSz = SetSequence(signerInfoSz, esd->issuerSnSeq);
wolfSSL 16:8e0d178b1d1e 2210 signerInfoSz += esd->issuerSnSeqSz;
wolfSSL 16:8e0d178b1d1e 2211
wolfSSL 16:8e0d178b1d1e 2212 if (pkcs7->version == 3) {
wolfSSL 16:8e0d178b1d1e 2213 /* RFC 4108 version MUST be 3 for firmware package signer */
wolfSSL 16:8e0d178b1d1e 2214 esd->signerVersionSz = SetMyVersion(3, esd->signerVersion, 0);
wolfSSL 16:8e0d178b1d1e 2215 }
wolfSSL 16:8e0d178b1d1e 2216 else {
wolfSSL 16:8e0d178b1d1e 2217 /* version MUST be 1 otherwise*/
wolfSSL 16:8e0d178b1d1e 2218 esd->signerVersionSz = SetMyVersion(1, esd->signerVersion, 0);
wolfSSL 16:8e0d178b1d1e 2219 }
wolfSSL 16:8e0d178b1d1e 2220
wolfSSL 16:8e0d178b1d1e 2221 } else if (pkcs7->sidType == CMS_SKID) {
wolfSSL 16:8e0d178b1d1e 2222 /* SubjectKeyIdentifier */
wolfSSL 16:8e0d178b1d1e 2223 esd->issuerSKIDSz = SetOctetString(KEYID_SIZE, esd->issuerSKID);
wolfSSL 16:8e0d178b1d1e 2224 esd->issuerSKIDSeqSz = SetExplicit(0, esd->issuerSKIDSz + KEYID_SIZE,
wolfSSL 16:8e0d178b1d1e 2225 esd->issuerSKIDSeq);
wolfSSL 16:8e0d178b1d1e 2226 signerInfoSz += (esd->issuerSKIDSz + esd->issuerSKIDSeqSz +
wolfSSL 16:8e0d178b1d1e 2227 KEYID_SIZE);
wolfSSL 16:8e0d178b1d1e 2228
wolfSSL 16:8e0d178b1d1e 2229 /* version MUST be 3 */
wolfSSL 16:8e0d178b1d1e 2230 esd->signerVersionSz = SetMyVersion(3, esd->signerVersion, 0);
wolfSSL 16:8e0d178b1d1e 2231 } else if (pkcs7->sidType == DEGENERATE_SID) {
wolfSSL 16:8e0d178b1d1e 2232 /* no signer info added */
wolfSSL 16:8e0d178b1d1e 2233 } else {
wolfSSL 16:8e0d178b1d1e 2234 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 2235 XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 2236 #endif
wolfSSL 16:8e0d178b1d1e 2237 return SKID_E;
wolfSSL 16:8e0d178b1d1e 2238 }
wolfSSL 16:8e0d178b1d1e 2239
wolfSSL 16:8e0d178b1d1e 2240 if (pkcs7->sidType != DEGENERATE_SID) {
wolfSSL 16:8e0d178b1d1e 2241 signerInfoSz += esd->signerVersionSz;
wolfSSL 16:8e0d178b1d1e 2242 esd->signerDigAlgoIdSz = SetAlgoID(pkcs7->hashOID, esd->signerDigAlgoId,
wolfSSL 16:8e0d178b1d1e 2243 oidHashType, 0);
wolfSSL 16:8e0d178b1d1e 2244 signerInfoSz += esd->signerDigAlgoIdSz;
wolfSSL 16:8e0d178b1d1e 2245
wolfSSL 16:8e0d178b1d1e 2246 /* set signatureAlgorithm */
wolfSSL 16:8e0d178b1d1e 2247 ret = wc_PKCS7_SignedDataGetEncAlgoId(pkcs7, &digEncAlgoId,
wolfSSL 16:8e0d178b1d1e 2248 &digEncAlgoType);
wolfSSL 15:117db924cf7c 2249 if (ret < 0) {
wolfSSL 16:8e0d178b1d1e 2250 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 2251 XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 2252 #endif
wolfSSL 16:8e0d178b1d1e 2253 return ret;
wolfSSL 16:8e0d178b1d1e 2254 }
wolfSSL 16:8e0d178b1d1e 2255 esd->digEncAlgoIdSz = SetAlgoID(digEncAlgoId, esd->digEncAlgoId,
wolfSSL 16:8e0d178b1d1e 2256 digEncAlgoType, 0);
wolfSSL 16:8e0d178b1d1e 2257 signerInfoSz += esd->digEncAlgoIdSz;
wolfSSL 16:8e0d178b1d1e 2258
wolfSSL 16:8e0d178b1d1e 2259 /* build up signed attributes, include contentType, signingTime, and
wolfSSL 16:8e0d178b1d1e 2260 messageDigest by default */
wolfSSL 16:8e0d178b1d1e 2261 ret = wc_PKCS7_BuildSignedAttributes(pkcs7, esd, pkcs7->contentType,
wolfSSL 16:8e0d178b1d1e 2262 pkcs7->contentTypeSz,
wolfSSL 16:8e0d178b1d1e 2263 contentTypeOid, sizeof(contentTypeOid),
wolfSSL 16:8e0d178b1d1e 2264 messageDigestOid, sizeof(messageDigestOid),
wolfSSL 16:8e0d178b1d1e 2265 signingTimeOid, sizeof(signingTimeOid),
wolfSSL 16:8e0d178b1d1e 2266 signingTime, sizeof(signingTime));
wolfSSL 16:8e0d178b1d1e 2267 if (ret < 0) {
wolfSSL 16:8e0d178b1d1e 2268 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 2269 XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 2270 #endif
wolfSSL 16:8e0d178b1d1e 2271 return ret;
wolfSSL 16:8e0d178b1d1e 2272 }
wolfSSL 16:8e0d178b1d1e 2273
wolfSSL 16:8e0d178b1d1e 2274 if (esd->signedAttribsSz > 0) {
wolfSSL 16:8e0d178b1d1e 2275 flatSignedAttribs = (byte*)XMALLOC(esd->signedAttribsSz, pkcs7->heap,
wolfSSL 16:8e0d178b1d1e 2276 DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 2277 flatSignedAttribsSz = esd->signedAttribsSz;
wolfSSL 16:8e0d178b1d1e 2278 if (flatSignedAttribs == NULL) {
wolfSSL 16:8e0d178b1d1e 2279 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 2280 XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 2281 #endif
wolfSSL 16:8e0d178b1d1e 2282 return MEMORY_E;
wolfSSL 16:8e0d178b1d1e 2283 }
wolfSSL 16:8e0d178b1d1e 2284
wolfSSL 16:8e0d178b1d1e 2285 FlattenAttributes(pkcs7, flatSignedAttribs,
wolfSSL 16:8e0d178b1d1e 2286 esd->signedAttribs, esd->signedAttribsCount);
wolfSSL 16:8e0d178b1d1e 2287 esd->signedAttribSetSz = SetImplicit(ASN_SET, 0, esd->signedAttribsSz,
wolfSSL 16:8e0d178b1d1e 2288 esd->signedAttribSet);
wolfSSL 16:8e0d178b1d1e 2289 } else {
wolfSSL 16:8e0d178b1d1e 2290 esd->signedAttribSetSz = 0;
wolfSSL 16:8e0d178b1d1e 2291 }
wolfSSL 16:8e0d178b1d1e 2292
wolfSSL 16:8e0d178b1d1e 2293 /* Calculate the final hash and encrypt it. */
wolfSSL 16:8e0d178b1d1e 2294 ret = wc_PKCS7_SignedDataBuildSignature(pkcs7, flatSignedAttribs,
wolfSSL 16:8e0d178b1d1e 2295 flatSignedAttribsSz, esd);
wolfSSL 16:8e0d178b1d1e 2296 if (ret < 0) {
wolfSSL 16:8e0d178b1d1e 2297 if (pkcs7->signedAttribsSz != 0)
wolfSSL 16:8e0d178b1d1e 2298 XFREE(flatSignedAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 2299 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 2300 XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 2301 #endif
wolfSSL 16:8e0d178b1d1e 2302 return ret;
wolfSSL 16:8e0d178b1d1e 2303 }
wolfSSL 16:8e0d178b1d1e 2304
wolfSSL 16:8e0d178b1d1e 2305 signerInfoSz += flatSignedAttribsSz + esd->signedAttribSetSz;
wolfSSL 16:8e0d178b1d1e 2306
wolfSSL 16:8e0d178b1d1e 2307 esd->signerDigestSz = SetOctetString(esd->encContentDigestSz,
wolfSSL 16:8e0d178b1d1e 2308 esd->signerDigest);
wolfSSL 16:8e0d178b1d1e 2309 signerInfoSz += esd->signerDigestSz + esd->encContentDigestSz;
wolfSSL 16:8e0d178b1d1e 2310
wolfSSL 16:8e0d178b1d1e 2311 esd->signerInfoSeqSz = SetSequence(signerInfoSz, esd->signerInfoSeq);
wolfSSL 16:8e0d178b1d1e 2312 signerInfoSz += esd->signerInfoSeqSz;
wolfSSL 16:8e0d178b1d1e 2313 }
wolfSSL 16:8e0d178b1d1e 2314 esd->signerInfoSetSz = SetSet(signerInfoSz, esd->signerInfoSet);
wolfSSL 16:8e0d178b1d1e 2315 signerInfoSz += esd->signerInfoSetSz;
wolfSSL 16:8e0d178b1d1e 2316
wolfSSL 16:8e0d178b1d1e 2317 /* certificates [0] IMPLICIT CertificateSet */
wolfSSL 16:8e0d178b1d1e 2318 /* get total certificates size */
wolfSSL 16:8e0d178b1d1e 2319 certPtr = pkcs7->certList;
wolfSSL 16:8e0d178b1d1e 2320 while (certPtr != NULL) {
wolfSSL 16:8e0d178b1d1e 2321 certSetSz += certPtr->derSz;
wolfSSL 16:8e0d178b1d1e 2322 certPtr = certPtr->next;
wolfSSL 16:8e0d178b1d1e 2323 }
wolfSSL 16:8e0d178b1d1e 2324 certPtr = NULL;
wolfSSL 16:8e0d178b1d1e 2325
wolfSSL 16:8e0d178b1d1e 2326 if (certSetSz > 0)
wolfSSL 16:8e0d178b1d1e 2327 esd->certsSetSz = SetImplicit(ASN_SET, 0, certSetSz, esd->certsSet);
wolfSSL 16:8e0d178b1d1e 2328
wolfSSL 16:8e0d178b1d1e 2329 if (pkcs7->sidType != DEGENERATE_SID) {
wolfSSL 16:8e0d178b1d1e 2330 esd->singleDigAlgoIdSz = SetAlgoID(pkcs7->hashOID, esd->singleDigAlgoId,
wolfSSL 16:8e0d178b1d1e 2331 oidHashType, 0);
wolfSSL 16:8e0d178b1d1e 2332 }
wolfSSL 16:8e0d178b1d1e 2333 esd->digAlgoIdSetSz = SetSet(esd->singleDigAlgoIdSz, esd->digAlgoIdSet);
wolfSSL 16:8e0d178b1d1e 2334
wolfSSL 16:8e0d178b1d1e 2335 if (pkcs7->version == 3) {
wolfSSL 16:8e0d178b1d1e 2336 /* RFC 4108 version MUST be 3 for firmware package signer */
wolfSSL 16:8e0d178b1d1e 2337 esd->versionSz = SetMyVersion(3, esd->version, 0);
wolfSSL 16:8e0d178b1d1e 2338 }
wolfSSL 16:8e0d178b1d1e 2339 else {
wolfSSL 16:8e0d178b1d1e 2340 esd->versionSz = SetMyVersion(1, esd->version, 0);
wolfSSL 16:8e0d178b1d1e 2341 }
wolfSSL 16:8e0d178b1d1e 2342
wolfSSL 16:8e0d178b1d1e 2343 totalSz = esd->versionSz + esd->singleDigAlgoIdSz + esd->digAlgoIdSetSz +
wolfSSL 16:8e0d178b1d1e 2344 esd->contentInfoSeqSz + pkcs7->contentTypeSz +
wolfSSL 16:8e0d178b1d1e 2345 esd->innerContSeqSz + esd->innerOctetsSz + pkcs7->contentSz;
wolfSSL 16:8e0d178b1d1e 2346 total2Sz = esd->certsSetSz + certSetSz + signerInfoSz;
wolfSSL 16:8e0d178b1d1e 2347
wolfSSL 16:8e0d178b1d1e 2348 if (pkcs7->detached) {
wolfSSL 16:8e0d178b1d1e 2349 totalSz -= pkcs7->contentSz;
wolfSSL 16:8e0d178b1d1e 2350 }
wolfSSL 16:8e0d178b1d1e 2351
wolfSSL 16:8e0d178b1d1e 2352 esd->innerSeqSz = SetSequence(totalSz + total2Sz, esd->innerSeq);
wolfSSL 16:8e0d178b1d1e 2353 totalSz += esd->innerSeqSz;
wolfSSL 16:8e0d178b1d1e 2354 esd->outerContentSz = SetExplicit(0, totalSz + total2Sz, esd->outerContent);
wolfSSL 16:8e0d178b1d1e 2355 totalSz += esd->outerContentSz + signedDataOidSz;
wolfSSL 16:8e0d178b1d1e 2356 esd->outerSeqSz = SetSequence(totalSz + total2Sz, esd->outerSeq);
wolfSSL 16:8e0d178b1d1e 2357 totalSz += esd->outerSeqSz;
wolfSSL 16:8e0d178b1d1e 2358
wolfSSL 16:8e0d178b1d1e 2359 /* if using header/footer, we are not returning the content */
wolfSSL 16:8e0d178b1d1e 2360 if (output2 && output2Sz) {
wolfSSL 16:8e0d178b1d1e 2361 if (total2Sz > *output2Sz) {
wolfSSL 16:8e0d178b1d1e 2362 if (pkcs7->signedAttribsSz != 0)
wolfSSL 16:8e0d178b1d1e 2363 XFREE(flatSignedAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 2364 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 2365 XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 2366 #endif
wolfSSL 16:8e0d178b1d1e 2367 return BUFFER_E;
wolfSSL 16:8e0d178b1d1e 2368 }
wolfSSL 16:8e0d178b1d1e 2369
wolfSSL 16:8e0d178b1d1e 2370 if (!pkcs7->detached) {
wolfSSL 16:8e0d178b1d1e 2371 totalSz -= pkcs7->contentSz;
wolfSSL 16:8e0d178b1d1e 2372 }
wolfSSL 16:8e0d178b1d1e 2373 }
wolfSSL 16:8e0d178b1d1e 2374 else {
wolfSSL 16:8e0d178b1d1e 2375 /* if using single output buffer include content and footer */
wolfSSL 16:8e0d178b1d1e 2376 totalSz += total2Sz;
wolfSSL 16:8e0d178b1d1e 2377 }
wolfSSL 16:8e0d178b1d1e 2378
wolfSSL 16:8e0d178b1d1e 2379 if (totalSz > *outputSz) {
wolfSSL 15:117db924cf7c 2380 if (pkcs7->signedAttribsSz != 0)
wolfSSL 15:117db924cf7c 2381 XFREE(flatSignedAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 2382 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 2383 XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 2384 #endif
wolfSSL 15:117db924cf7c 2385 return BUFFER_E;
wolfSSL 15:117db924cf7c 2386 }
wolfSSL 15:117db924cf7c 2387
wolfSSL 15:117db924cf7c 2388 idx = 0;
wolfSSL 15:117db924cf7c 2389 XMEMCPY(output + idx, esd->outerSeq, esd->outerSeqSz);
wolfSSL 15:117db924cf7c 2390 idx += esd->outerSeqSz;
wolfSSL 16:8e0d178b1d1e 2391 XMEMCPY(output + idx, signedDataOid, signedDataOidSz);
wolfSSL 16:8e0d178b1d1e 2392 idx += signedDataOidSz;
wolfSSL 15:117db924cf7c 2393 XMEMCPY(output + idx, esd->outerContent, esd->outerContentSz);
wolfSSL 15:117db924cf7c 2394 idx += esd->outerContentSz;
wolfSSL 15:117db924cf7c 2395 XMEMCPY(output + idx, esd->innerSeq, esd->innerSeqSz);
wolfSSL 15:117db924cf7c 2396 idx += esd->innerSeqSz;
wolfSSL 15:117db924cf7c 2397 XMEMCPY(output + idx, esd->version, esd->versionSz);
wolfSSL 15:117db924cf7c 2398 idx += esd->versionSz;
wolfSSL 15:117db924cf7c 2399 XMEMCPY(output + idx, esd->digAlgoIdSet, esd->digAlgoIdSetSz);
wolfSSL 15:117db924cf7c 2400 idx += esd->digAlgoIdSetSz;
wolfSSL 15:117db924cf7c 2401 XMEMCPY(output + idx, esd->singleDigAlgoId, esd->singleDigAlgoIdSz);
wolfSSL 15:117db924cf7c 2402 idx += esd->singleDigAlgoIdSz;
wolfSSL 15:117db924cf7c 2403 XMEMCPY(output + idx, esd->contentInfoSeq, esd->contentInfoSeqSz);
wolfSSL 15:117db924cf7c 2404 idx += esd->contentInfoSeqSz;
wolfSSL 16:8e0d178b1d1e 2405 XMEMCPY(output + idx, pkcs7->contentType, pkcs7->contentTypeSz);
wolfSSL 16:8e0d178b1d1e 2406 idx += pkcs7->contentTypeSz;
wolfSSL 15:117db924cf7c 2407 XMEMCPY(output + idx, esd->innerContSeq, esd->innerContSeqSz);
wolfSSL 15:117db924cf7c 2408 idx += esd->innerContSeqSz;
wolfSSL 15:117db924cf7c 2409 XMEMCPY(output + idx, esd->innerOctets, esd->innerOctetsSz);
wolfSSL 15:117db924cf7c 2410 idx += esd->innerOctetsSz;
wolfSSL 16:8e0d178b1d1e 2411
wolfSSL 16:8e0d178b1d1e 2412 /* support returning header and footer without content */
wolfSSL 16:8e0d178b1d1e 2413 if (output2 && output2Sz) {
wolfSSL 16:8e0d178b1d1e 2414 *outputSz = idx;
wolfSSL 16:8e0d178b1d1e 2415 idx = 0;
wolfSSL 16:8e0d178b1d1e 2416 }
wolfSSL 16:8e0d178b1d1e 2417 else {
wolfSSL 16:8e0d178b1d1e 2418 if (!pkcs7->detached) {
wolfSSL 16:8e0d178b1d1e 2419 XMEMCPY(output + idx, pkcs7->content, pkcs7->contentSz);
wolfSSL 16:8e0d178b1d1e 2420 idx += pkcs7->contentSz;
wolfSSL 16:8e0d178b1d1e 2421 }
wolfSSL 16:8e0d178b1d1e 2422 output2 = output;
wolfSSL 16:8e0d178b1d1e 2423 }
wolfSSL 16:8e0d178b1d1e 2424
wolfSSL 16:8e0d178b1d1e 2425 /* certificates */
wolfSSL 16:8e0d178b1d1e 2426 XMEMCPY(output2 + idx, esd->certsSet, esd->certsSetSz);
wolfSSL 15:117db924cf7c 2427 idx += esd->certsSetSz;
wolfSSL 16:8e0d178b1d1e 2428 certPtr = pkcs7->certList;
wolfSSL 16:8e0d178b1d1e 2429 while (certPtr != NULL) {
wolfSSL 16:8e0d178b1d1e 2430 XMEMCPY(output2 + idx, certPtr->der, certPtr->derSz);
wolfSSL 16:8e0d178b1d1e 2431 idx += certPtr->derSz;
wolfSSL 16:8e0d178b1d1e 2432 certPtr = certPtr->next;
wolfSSL 16:8e0d178b1d1e 2433 }
wolfSSL 16:8e0d178b1d1e 2434 wc_PKCS7_FreeCertSet(pkcs7);
wolfSSL 16:8e0d178b1d1e 2435
wolfSSL 16:8e0d178b1d1e 2436 XMEMCPY(output2 + idx, esd->signerInfoSet, esd->signerInfoSetSz);
wolfSSL 15:117db924cf7c 2437 idx += esd->signerInfoSetSz;
wolfSSL 16:8e0d178b1d1e 2438 XMEMCPY(output2 + idx, esd->signerInfoSeq, esd->signerInfoSeqSz);
wolfSSL 15:117db924cf7c 2439 idx += esd->signerInfoSeqSz;
wolfSSL 16:8e0d178b1d1e 2440 XMEMCPY(output2 + idx, esd->signerVersion, esd->signerVersionSz);
wolfSSL 15:117db924cf7c 2441 idx += esd->signerVersionSz;
wolfSSL 16:8e0d178b1d1e 2442 /* SignerIdentifier */
wolfSSL 16:8e0d178b1d1e 2443 if (pkcs7->sidType == CMS_ISSUER_AND_SERIAL_NUMBER) {
wolfSSL 16:8e0d178b1d1e 2444 /* IssuerAndSerialNumber */
wolfSSL 16:8e0d178b1d1e 2445 XMEMCPY(output2 + idx, esd->issuerSnSeq, esd->issuerSnSeqSz);
wolfSSL 16:8e0d178b1d1e 2446 idx += esd->issuerSnSeqSz;
wolfSSL 16:8e0d178b1d1e 2447 XMEMCPY(output2 + idx, esd->issuerName, esd->issuerNameSz);
wolfSSL 16:8e0d178b1d1e 2448 idx += esd->issuerNameSz;
wolfSSL 16:8e0d178b1d1e 2449 XMEMCPY(output2 + idx, pkcs7->issuer, pkcs7->issuerSz);
wolfSSL 16:8e0d178b1d1e 2450 idx += pkcs7->issuerSz;
wolfSSL 16:8e0d178b1d1e 2451 XMEMCPY(output2 + idx, esd->issuerSn, esd->issuerSnSz);
wolfSSL 16:8e0d178b1d1e 2452 idx += esd->issuerSnSz;
wolfSSL 16:8e0d178b1d1e 2453 } else if (pkcs7->sidType == CMS_SKID) {
wolfSSL 16:8e0d178b1d1e 2454 /* SubjectKeyIdentifier */
wolfSSL 16:8e0d178b1d1e 2455 XMEMCPY(output2 + idx, esd->issuerSKIDSeq, esd->issuerSKIDSeqSz);
wolfSSL 16:8e0d178b1d1e 2456 idx += esd->issuerSKIDSeqSz;
wolfSSL 16:8e0d178b1d1e 2457 XMEMCPY(output2 + idx, esd->issuerSKID, esd->issuerSKIDSz);
wolfSSL 16:8e0d178b1d1e 2458 idx += esd->issuerSKIDSz;
wolfSSL 16:8e0d178b1d1e 2459 XMEMCPY(output2 + idx, pkcs7->issuerSubjKeyId, KEYID_SIZE);
wolfSSL 16:8e0d178b1d1e 2460 idx += KEYID_SIZE;
wolfSSL 16:8e0d178b1d1e 2461 } else if (pkcs7->sidType == DEGENERATE_SID) {
wolfSSL 16:8e0d178b1d1e 2462 /* no signer infos in degenerate case */
wolfSSL 16:8e0d178b1d1e 2463 } else {
wolfSSL 16:8e0d178b1d1e 2464 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 2465 XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 2466 #endif
wolfSSL 16:8e0d178b1d1e 2467 return SKID_E;
wolfSSL 16:8e0d178b1d1e 2468 }
wolfSSL 16:8e0d178b1d1e 2469 XMEMCPY(output2 + idx, esd->signerDigAlgoId, esd->signerDigAlgoIdSz);
wolfSSL 15:117db924cf7c 2470 idx += esd->signerDigAlgoIdSz;
wolfSSL 15:117db924cf7c 2471
wolfSSL 15:117db924cf7c 2472 /* SignerInfo:Attributes */
wolfSSL 15:117db924cf7c 2473 if (flatSignedAttribsSz > 0) {
wolfSSL 16:8e0d178b1d1e 2474 XMEMCPY(output2 + idx, esd->signedAttribSet, esd->signedAttribSetSz);
wolfSSL 15:117db924cf7c 2475 idx += esd->signedAttribSetSz;
wolfSSL 16:8e0d178b1d1e 2476 XMEMCPY(output2 + idx, flatSignedAttribs, flatSignedAttribsSz);
wolfSSL 15:117db924cf7c 2477 idx += flatSignedAttribsSz;
wolfSSL 15:117db924cf7c 2478 XFREE(flatSignedAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 2479 }
wolfSSL 15:117db924cf7c 2480
wolfSSL 16:8e0d178b1d1e 2481 XMEMCPY(output2 + idx, esd->digEncAlgoId, esd->digEncAlgoIdSz);
wolfSSL 15:117db924cf7c 2482 idx += esd->digEncAlgoIdSz;
wolfSSL 16:8e0d178b1d1e 2483 XMEMCPY(output2 + idx, esd->signerDigest, esd->signerDigestSz);
wolfSSL 15:117db924cf7c 2484 idx += esd->signerDigestSz;
wolfSSL 16:8e0d178b1d1e 2485 XMEMCPY(output2 + idx, esd->encContentDigest, esd->encContentDigestSz);
wolfSSL 15:117db924cf7c 2486 idx += esd->encContentDigestSz;
wolfSSL 15:117db924cf7c 2487
wolfSSL 16:8e0d178b1d1e 2488 if (output2 && output2Sz) {
wolfSSL 16:8e0d178b1d1e 2489 *output2Sz = idx;
wolfSSL 16:8e0d178b1d1e 2490 idx = 0; /* success */
wolfSSL 16:8e0d178b1d1e 2491 }
wolfSSL 16:8e0d178b1d1e 2492 else {
wolfSSL 16:8e0d178b1d1e 2493 *outputSz = idx;
wolfSSL 16:8e0d178b1d1e 2494 }
wolfSSL 16:8e0d178b1d1e 2495
wolfSSL 16:8e0d178b1d1e 2496 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 2497 XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 2498 #endif
wolfSSL 16:8e0d178b1d1e 2499 return idx;
wolfSSL 16:8e0d178b1d1e 2500 }
wolfSSL 16:8e0d178b1d1e 2501
wolfSSL 16:8e0d178b1d1e 2502 /* hashBuf: The computed digest for the pkcs7->content
wolfSSL 16:8e0d178b1d1e 2503 * hashSz: The size of computed digest for the pkcs7->content based on hashOID
wolfSSL 16:8e0d178b1d1e 2504 * outputHead: The PKCS7 header that goes on top of the raw data signed.
wolfSSL 16:8e0d178b1d1e 2505 * outputFoot: The PKCS7 footer that goes at the end of the raw data signed.
wolfSSL 16:8e0d178b1d1e 2506 * pkcs7->content: Not used
wolfSSL 16:8e0d178b1d1e 2507 * pkcs7->contentSz: Must be provided as actual sign of raw data
wolfSSL 16:8e0d178b1d1e 2508 * return codes: 0=success, negative=error
wolfSSL 16:8e0d178b1d1e 2509 */
wolfSSL 16:8e0d178b1d1e 2510 int wc_PKCS7_EncodeSignedData_ex(PKCS7* pkcs7, const byte* hashBuf,
wolfSSL 16:8e0d178b1d1e 2511 word32 hashSz, byte* outputHead, word32* outputHeadSz, byte* outputFoot,
wolfSSL 16:8e0d178b1d1e 2512 word32* outputFootSz)
wolfSSL 16:8e0d178b1d1e 2513 {
wolfSSL 16:8e0d178b1d1e 2514 int ret;
wolfSSL 16:8e0d178b1d1e 2515 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 2516 ESD* esd;
wolfSSL 16:8e0d178b1d1e 2517 #else
wolfSSL 16:8e0d178b1d1e 2518 ESD esd[1];
wolfSSL 16:8e0d178b1d1e 2519 #endif
wolfSSL 16:8e0d178b1d1e 2520
wolfSSL 16:8e0d178b1d1e 2521 /* other args checked in wc_PKCS7_EncodeSigned_ex */
wolfSSL 16:8e0d178b1d1e 2522 if (pkcs7 == NULL || outputFoot == NULL || outputFootSz == NULL) {
wolfSSL 16:8e0d178b1d1e 2523 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 2524 }
wolfSSL 16:8e0d178b1d1e 2525
wolfSSL 16:8e0d178b1d1e 2526 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 2527 esd = (ESD*)XMALLOC(sizeof(ESD), pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 2528 if (esd == NULL)
wolfSSL 16:8e0d178b1d1e 2529 return MEMORY_E;
wolfSSL 16:8e0d178b1d1e 2530 #endif
wolfSSL 16:8e0d178b1d1e 2531
wolfSSL 16:8e0d178b1d1e 2532 XMEMSET(esd, 0, sizeof(ESD));
wolfSSL 16:8e0d178b1d1e 2533
wolfSSL 16:8e0d178b1d1e 2534 ret = PKCS7_EncodeSigned(pkcs7, esd, hashBuf, hashSz,
wolfSSL 16:8e0d178b1d1e 2535 outputHead, outputHeadSz, outputFoot, outputFootSz);
wolfSSL 16:8e0d178b1d1e 2536
wolfSSL 16:8e0d178b1d1e 2537 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 2538 XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 2539 #endif
wolfSSL 16:8e0d178b1d1e 2540
wolfSSL 16:8e0d178b1d1e 2541 return ret;
wolfSSL 16:8e0d178b1d1e 2542 }
wolfSSL 16:8e0d178b1d1e 2543
wolfSSL 16:8e0d178b1d1e 2544 /* Toggle detached signature mode on/off for PKCS#7/CMS SignedData content type.
wolfSSL 16:8e0d178b1d1e 2545 * By default wolfCrypt includes the data to be signed in the SignedData
wolfSSL 16:8e0d178b1d1e 2546 * bundle. This data can be omitted in the case when a detached signature is
wolfSSL 16:8e0d178b1d1e 2547 * being created. To enable generation of detached signatures, set flag to "1",
wolfSSL 16:8e0d178b1d1e 2548 * otherwise set to "0":
wolfSSL 16:8e0d178b1d1e 2549 *
wolfSSL 16:8e0d178b1d1e 2550 * flag 1 turns on support
wolfSSL 16:8e0d178b1d1e 2551 * flag 0 turns off support
wolfSSL 16:8e0d178b1d1e 2552 *
wolfSSL 16:8e0d178b1d1e 2553 * pkcs7 - pointer to initialized PKCS7 structure
wolfSSL 16:8e0d178b1d1e 2554 * flag - turn on/off detached signature generation (1 or 0)
wolfSSL 16:8e0d178b1d1e 2555 *
wolfSSL 16:8e0d178b1d1e 2556 * Returns 0 on success, negative upon error. */
wolfSSL 16:8e0d178b1d1e 2557 int wc_PKCS7_SetDetached(PKCS7* pkcs7, word16 flag)
wolfSSL 16:8e0d178b1d1e 2558 {
wolfSSL 16:8e0d178b1d1e 2559 if (pkcs7 == NULL || (flag != 0 && flag != 1))
wolfSSL 16:8e0d178b1d1e 2560 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 2561
wolfSSL 16:8e0d178b1d1e 2562 pkcs7->detached = flag;
wolfSSL 16:8e0d178b1d1e 2563
wolfSSL 16:8e0d178b1d1e 2564 return 0;
wolfSSL 16:8e0d178b1d1e 2565 }
wolfSSL 16:8e0d178b1d1e 2566
wolfSSL 16:8e0d178b1d1e 2567 /* By default, SignedData bundles have the following signed attributes attached:
wolfSSL 16:8e0d178b1d1e 2568 * contentType (1.2.840.113549.1.9.3)
wolfSSL 16:8e0d178b1d1e 2569 * signgingTime (1.2.840.113549.1.9.5)
wolfSSL 16:8e0d178b1d1e 2570 * messageDigest (1.2.840.113549.1.9.4)
wolfSSL 16:8e0d178b1d1e 2571 *
wolfSSL 16:8e0d178b1d1e 2572 * Calling this API before wc_PKCS7_EncodeSignedData() will disable the
wolfSSL 16:8e0d178b1d1e 2573 * inclusion of those attributes.
wolfSSL 16:8e0d178b1d1e 2574 *
wolfSSL 16:8e0d178b1d1e 2575 * pkcs7 - pointer to initialized PKCS7 structure
wolfSSL 16:8e0d178b1d1e 2576 *
wolfSSL 16:8e0d178b1d1e 2577 * Returns 0 on success, negative upon error. */
wolfSSL 16:8e0d178b1d1e 2578 int wc_PKCS7_NoDefaultSignedAttribs(PKCS7* pkcs7)
wolfSSL 16:8e0d178b1d1e 2579 {
wolfSSL 16:8e0d178b1d1e 2580 if (pkcs7 == NULL)
wolfSSL 16:8e0d178b1d1e 2581 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 2582
wolfSSL 16:8e0d178b1d1e 2583 pkcs7->skipDefaultSignedAttribs = 1;
wolfSSL 16:8e0d178b1d1e 2584
wolfSSL 16:8e0d178b1d1e 2585 return 0;
wolfSSL 16:8e0d178b1d1e 2586 }
wolfSSL 16:8e0d178b1d1e 2587
wolfSSL 16:8e0d178b1d1e 2588 /* return codes: >0: Size of signed PKCS7 output buffer, negative: error */
wolfSSL 16:8e0d178b1d1e 2589 int wc_PKCS7_EncodeSignedData(PKCS7* pkcs7, byte* output, word32 outputSz)
wolfSSL 16:8e0d178b1d1e 2590 {
wolfSSL 16:8e0d178b1d1e 2591 int ret;
wolfSSL 16:8e0d178b1d1e 2592 int hashSz;
wolfSSL 16:8e0d178b1d1e 2593 enum wc_HashType hashType;
wolfSSL 16:8e0d178b1d1e 2594 byte hashBuf[WC_MAX_DIGEST_SIZE];
wolfSSL 16:8e0d178b1d1e 2595 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 2596 ESD* esd;
wolfSSL 16:8e0d178b1d1e 2597 #else
wolfSSL 16:8e0d178b1d1e 2598 ESD esd[1];
wolfSSL 16:8e0d178b1d1e 2599 #endif
wolfSSL 16:8e0d178b1d1e 2600
wolfSSL 16:8e0d178b1d1e 2601 /* other args checked in wc_PKCS7_EncodeSigned_ex */
wolfSSL 16:8e0d178b1d1e 2602 if (pkcs7 == NULL || pkcs7->contentSz == 0 || pkcs7->content == NULL) {
wolfSSL 16:8e0d178b1d1e 2603 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 2604 }
wolfSSL 16:8e0d178b1d1e 2605
wolfSSL 16:8e0d178b1d1e 2606 /* get hash type and size, validate hashOID */
wolfSSL 16:8e0d178b1d1e 2607 hashType = wc_OidGetHash(pkcs7->hashOID);
wolfSSL 16:8e0d178b1d1e 2608 hashSz = wc_HashGetDigestSize(hashType);
wolfSSL 16:8e0d178b1d1e 2609 if (hashSz < 0)
wolfSSL 16:8e0d178b1d1e 2610 return hashSz;
wolfSSL 16:8e0d178b1d1e 2611
wolfSSL 16:8e0d178b1d1e 2612 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 2613 esd = (ESD*)XMALLOC(sizeof(ESD), pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 2614 if (esd == NULL)
wolfSSL 16:8e0d178b1d1e 2615 return MEMORY_E;
wolfSSL 16:8e0d178b1d1e 2616 #endif
wolfSSL 16:8e0d178b1d1e 2617
wolfSSL 16:8e0d178b1d1e 2618 XMEMSET(esd, 0, sizeof(ESD));
wolfSSL 16:8e0d178b1d1e 2619 esd->hashType = hashType;
wolfSSL 16:8e0d178b1d1e 2620
wolfSSL 16:8e0d178b1d1e 2621 /* calculate hash for content */
wolfSSL 16:8e0d178b1d1e 2622 ret = wc_HashInit(&esd->hash, esd->hashType);
wolfSSL 16:8e0d178b1d1e 2623 if (ret == 0) {
wolfSSL 16:8e0d178b1d1e 2624 ret = wc_HashUpdate(&esd->hash, esd->hashType,
wolfSSL 16:8e0d178b1d1e 2625 pkcs7->content, pkcs7->contentSz);
wolfSSL 16:8e0d178b1d1e 2626 if (ret == 0) {
wolfSSL 16:8e0d178b1d1e 2627 ret = wc_HashFinal(&esd->hash, esd->hashType, hashBuf);
wolfSSL 16:8e0d178b1d1e 2628 }
wolfSSL 16:8e0d178b1d1e 2629 wc_HashFree(&esd->hash, esd->hashType);
wolfSSL 16:8e0d178b1d1e 2630 }
wolfSSL 16:8e0d178b1d1e 2631
wolfSSL 16:8e0d178b1d1e 2632 if (ret == 0) {
wolfSSL 16:8e0d178b1d1e 2633 ret = PKCS7_EncodeSigned(pkcs7, esd, hashBuf, hashSz,
wolfSSL 16:8e0d178b1d1e 2634 output, &outputSz, NULL, NULL);
wolfSSL 16:8e0d178b1d1e 2635 }
wolfSSL 16:8e0d178b1d1e 2636
wolfSSL 15:117db924cf7c 2637 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 2638 XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 2639 #endif
wolfSSL 15:117db924cf7c 2640
wolfSSL 16:8e0d178b1d1e 2641 return ret;
wolfSSL 16:8e0d178b1d1e 2642 }
wolfSSL 16:8e0d178b1d1e 2643
wolfSSL 16:8e0d178b1d1e 2644
wolfSSL 16:8e0d178b1d1e 2645 /* Single-shot API to generate a CMS SignedData bundle that encapsulates a
wolfSSL 16:8e0d178b1d1e 2646 * content of type FirmwarePkgData. Any recipient certificates should be
wolfSSL 16:8e0d178b1d1e 2647 * loaded into the PKCS7 structure prior to calling this function, using
wolfSSL 16:8e0d178b1d1e 2648 * wc_PKCS7_InitWithCert() and/or wc_PKCS7_AddCertificate().
wolfSSL 16:8e0d178b1d1e 2649 *
wolfSSL 16:8e0d178b1d1e 2650 * pkcs7 - pointer to initialized PKCS7 struct
wolfSSL 16:8e0d178b1d1e 2651 * privateKey - private RSA/ECC key, used for signing SignedData
wolfSSL 16:8e0d178b1d1e 2652 * privateKeySz - size of privateKey, octets
wolfSSL 16:8e0d178b1d1e 2653 * signOID - public key algorithm OID, used for sign operation
wolfSSL 16:8e0d178b1d1e 2654 * hashOID - hash algorithm OID, used for signature generation
wolfSSL 16:8e0d178b1d1e 2655 * content - content to be encapsulated, of type FirmwarePkgData
wolfSSL 16:8e0d178b1d1e 2656 * contentSz - size of content, octets
wolfSSL 16:8e0d178b1d1e 2657 * signedAttribs - optional signed attributes
wolfSSL 16:8e0d178b1d1e 2658 * signedAttribsSz - number of PKCS7Attrib members in signedAttribs
wolfSSL 16:8e0d178b1d1e 2659 * output - output buffer for final bundle
wolfSSL 16:8e0d178b1d1e 2660 * outputSz - size of output buffer, octets
wolfSSL 16:8e0d178b1d1e 2661 *
wolfSSL 16:8e0d178b1d1e 2662 * Returns length of generated bundle on success, negative upon error. */
wolfSSL 16:8e0d178b1d1e 2663 int wc_PKCS7_EncodeSignedFPD(PKCS7* pkcs7, byte* privateKey,
wolfSSL 16:8e0d178b1d1e 2664 word32 privateKeySz, int signOID, int hashOID,
wolfSSL 16:8e0d178b1d1e 2665 byte* content, word32 contentSz,
wolfSSL 16:8e0d178b1d1e 2666 PKCS7Attrib* signedAttribs, word32 signedAttribsSz,
wolfSSL 16:8e0d178b1d1e 2667 byte* output, word32 outputSz)
wolfSSL 16:8e0d178b1d1e 2668 {
wolfSSL 16:8e0d178b1d1e 2669 int ret = 0;
wolfSSL 16:8e0d178b1d1e 2670 WC_RNG rng;
wolfSSL 16:8e0d178b1d1e 2671
wolfSSL 16:8e0d178b1d1e 2672 if (pkcs7 == NULL || privateKey == NULL || privateKeySz == 0 ||
wolfSSL 16:8e0d178b1d1e 2673 content == NULL || contentSz == 0 || output == NULL || outputSz == 0)
wolfSSL 16:8e0d178b1d1e 2674 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 2675
wolfSSL 16:8e0d178b1d1e 2676 ret = wc_InitRng(&rng);
wolfSSL 16:8e0d178b1d1e 2677 if (ret != 0)
wolfSSL 16:8e0d178b1d1e 2678 return ret;
wolfSSL 16:8e0d178b1d1e 2679
wolfSSL 16:8e0d178b1d1e 2680 pkcs7->rng = &rng;
wolfSSL 16:8e0d178b1d1e 2681 pkcs7->content = content;
wolfSSL 16:8e0d178b1d1e 2682 pkcs7->contentSz = contentSz;
wolfSSL 16:8e0d178b1d1e 2683 pkcs7->contentOID = FIRMWARE_PKG_DATA;
wolfSSL 16:8e0d178b1d1e 2684 pkcs7->hashOID = hashOID;
wolfSSL 16:8e0d178b1d1e 2685 pkcs7->encryptOID = signOID;
wolfSSL 16:8e0d178b1d1e 2686 pkcs7->privateKey = privateKey;
wolfSSL 16:8e0d178b1d1e 2687 pkcs7->privateKeySz = privateKeySz;
wolfSSL 16:8e0d178b1d1e 2688 pkcs7->signedAttribs = signedAttribs;
wolfSSL 16:8e0d178b1d1e 2689 pkcs7->signedAttribsSz = signedAttribsSz;
wolfSSL 16:8e0d178b1d1e 2690 pkcs7->version = 3;
wolfSSL 16:8e0d178b1d1e 2691
wolfSSL 16:8e0d178b1d1e 2692 ret = wc_PKCS7_EncodeSignedData(pkcs7, output, outputSz);
wolfSSL 16:8e0d178b1d1e 2693 if (ret <= 0) {
wolfSSL 16:8e0d178b1d1e 2694 WOLFSSL_MSG("Error encoding CMS SignedData content type");
wolfSSL 16:8e0d178b1d1e 2695 }
wolfSSL 16:8e0d178b1d1e 2696
wolfSSL 16:8e0d178b1d1e 2697 pkcs7->rng = NULL;
wolfSSL 16:8e0d178b1d1e 2698 wc_FreeRng(&rng);
wolfSSL 16:8e0d178b1d1e 2699
wolfSSL 16:8e0d178b1d1e 2700 return ret;
wolfSSL 16:8e0d178b1d1e 2701 }
wolfSSL 16:8e0d178b1d1e 2702
wolfSSL 16:8e0d178b1d1e 2703 #ifndef NO_PKCS7_ENCRYPTED_DATA
wolfSSL 16:8e0d178b1d1e 2704
wolfSSL 16:8e0d178b1d1e 2705 /* Single-shot API to generate a CMS SignedData bundle that encapsulates a
wolfSSL 16:8e0d178b1d1e 2706 * CMS EncryptedData bundle. Content of inner EncryptedData is set to that
wolfSSL 16:8e0d178b1d1e 2707 * of FirmwarePkgData. Any recipient certificates should be loaded into the
wolfSSL 16:8e0d178b1d1e 2708 * PKCS7 structure prior to calling this function, using wc_PKCS7_InitWithCert()
wolfSSL 16:8e0d178b1d1e 2709 * and/or wc_PKCS7_AddCertificate().
wolfSSL 16:8e0d178b1d1e 2710 *
wolfSSL 16:8e0d178b1d1e 2711 * pkcs7 - pointer to initialized PKCS7 struct
wolfSSL 16:8e0d178b1d1e 2712 * encryptKey - encryption key used for encrypting EncryptedData
wolfSSL 16:8e0d178b1d1e 2713 * encryptKeySz - size of encryptKey, octets
wolfSSL 16:8e0d178b1d1e 2714 * privateKey - private RSA/ECC key, used for signing SignedData
wolfSSL 16:8e0d178b1d1e 2715 * privateKeySz - size of privateKey, octets
wolfSSL 16:8e0d178b1d1e 2716 * encryptOID - encryption algorithm OID, to be used as encryption
wolfSSL 16:8e0d178b1d1e 2717 * algorithm for EncryptedData
wolfSSL 16:8e0d178b1d1e 2718 * signOID - public key algorithm OID, to be used for sign
wolfSSL 16:8e0d178b1d1e 2719 * operation in SignedData generation
wolfSSL 16:8e0d178b1d1e 2720 * hashOID - hash algorithm OID, to be used for signature in
wolfSSL 16:8e0d178b1d1e 2721 * SignedData generation
wolfSSL 16:8e0d178b1d1e 2722 * content - content to be encapsulated
wolfSSL 16:8e0d178b1d1e 2723 * contentSz - size of content, octets
wolfSSL 16:8e0d178b1d1e 2724 * unprotectedAttribs - optional unprotected attributes, for EncryptedData
wolfSSL 16:8e0d178b1d1e 2725 * unprotectedAttribsSz - number of PKCS7Attrib members in unprotectedAttribs
wolfSSL 16:8e0d178b1d1e 2726 * signedAttribs - optional signed attributes, for SignedData
wolfSSL 16:8e0d178b1d1e 2727 * signedAttribsSz - number of PKCS7Attrib members in signedAttribs
wolfSSL 16:8e0d178b1d1e 2728 * output - output buffer for final bundle
wolfSSL 16:8e0d178b1d1e 2729 * outputSz - size of output buffer, octets
wolfSSL 16:8e0d178b1d1e 2730 *
wolfSSL 16:8e0d178b1d1e 2731 * Returns length of generated bundle on success, negative upon error. */
wolfSSL 16:8e0d178b1d1e 2732 int wc_PKCS7_EncodeSignedEncryptedFPD(PKCS7* pkcs7, byte* encryptKey,
wolfSSL 16:8e0d178b1d1e 2733 word32 encryptKeySz, byte* privateKey,
wolfSSL 16:8e0d178b1d1e 2734 word32 privateKeySz, int encryptOID,
wolfSSL 16:8e0d178b1d1e 2735 int signOID, int hashOID,
wolfSSL 16:8e0d178b1d1e 2736 byte* content, word32 contentSz,
wolfSSL 16:8e0d178b1d1e 2737 PKCS7Attrib* unprotectedAttribs,
wolfSSL 16:8e0d178b1d1e 2738 word32 unprotectedAttribsSz,
wolfSSL 16:8e0d178b1d1e 2739 PKCS7Attrib* signedAttribs,
wolfSSL 16:8e0d178b1d1e 2740 word32 signedAttribsSz,
wolfSSL 16:8e0d178b1d1e 2741 byte* output, word32 outputSz)
wolfSSL 16:8e0d178b1d1e 2742 {
wolfSSL 16:8e0d178b1d1e 2743 int ret = 0, encryptedSz = 0;
wolfSSL 16:8e0d178b1d1e 2744 byte* encrypted = NULL;
wolfSSL 16:8e0d178b1d1e 2745 WC_RNG rng;
wolfSSL 16:8e0d178b1d1e 2746
wolfSSL 16:8e0d178b1d1e 2747 if (pkcs7 == NULL || encryptKey == NULL || encryptKeySz == 0 ||
wolfSSL 16:8e0d178b1d1e 2748 privateKey == NULL || privateKeySz == 0 || content == NULL ||
wolfSSL 16:8e0d178b1d1e 2749 contentSz == 0 || output == NULL || outputSz == 0) {
wolfSSL 16:8e0d178b1d1e 2750 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 2751 }
wolfSSL 16:8e0d178b1d1e 2752
wolfSSL 16:8e0d178b1d1e 2753 /* 1: build up EncryptedData using FirmwarePkgData type, use output
wolfSSL 16:8e0d178b1d1e 2754 * buffer as tmp for storage and to get size */
wolfSSL 16:8e0d178b1d1e 2755
wolfSSL 16:8e0d178b1d1e 2756 /* set struct elements, inner content type is FirmwarePkgData */
wolfSSL 16:8e0d178b1d1e 2757 pkcs7->content = content;
wolfSSL 16:8e0d178b1d1e 2758 pkcs7->contentSz = contentSz;
wolfSSL 16:8e0d178b1d1e 2759 pkcs7->contentOID = FIRMWARE_PKG_DATA;
wolfSSL 16:8e0d178b1d1e 2760 pkcs7->encryptOID = encryptOID;
wolfSSL 16:8e0d178b1d1e 2761 pkcs7->encryptionKey = encryptKey;
wolfSSL 16:8e0d178b1d1e 2762 pkcs7->encryptionKeySz = encryptKeySz;
wolfSSL 16:8e0d178b1d1e 2763 pkcs7->unprotectedAttribs = unprotectedAttribs;
wolfSSL 16:8e0d178b1d1e 2764 pkcs7->unprotectedAttribsSz = unprotectedAttribsSz;
wolfSSL 16:8e0d178b1d1e 2765 pkcs7->version = 3;
wolfSSL 16:8e0d178b1d1e 2766
wolfSSL 16:8e0d178b1d1e 2767 encryptedSz = wc_PKCS7_EncodeEncryptedData(pkcs7, output, outputSz);
wolfSSL 16:8e0d178b1d1e 2768 if (encryptedSz < 0) {
wolfSSL 16:8e0d178b1d1e 2769 WOLFSSL_MSG("Error encoding CMS EncryptedData content type");
wolfSSL 16:8e0d178b1d1e 2770 return encryptedSz;
wolfSSL 16:8e0d178b1d1e 2771 }
wolfSSL 16:8e0d178b1d1e 2772
wolfSSL 16:8e0d178b1d1e 2773 /* save encryptedData, reset output buffer and struct */
wolfSSL 16:8e0d178b1d1e 2774 encrypted = (byte*)XMALLOC(encryptedSz, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 2775 if (encrypted == NULL) {
wolfSSL 16:8e0d178b1d1e 2776 ForceZero(output, outputSz);
wolfSSL 16:8e0d178b1d1e 2777 return MEMORY_E;
wolfSSL 16:8e0d178b1d1e 2778 }
wolfSSL 16:8e0d178b1d1e 2779
wolfSSL 16:8e0d178b1d1e 2780 XMEMCPY(encrypted, output, encryptedSz);
wolfSSL 16:8e0d178b1d1e 2781 ForceZero(output, outputSz);
wolfSSL 16:8e0d178b1d1e 2782
wolfSSL 16:8e0d178b1d1e 2783 ret = wc_InitRng(&rng);
wolfSSL 16:8e0d178b1d1e 2784 if (ret != 0) {
wolfSSL 16:8e0d178b1d1e 2785 ForceZero(encrypted, encryptedSz);
wolfSSL 16:8e0d178b1d1e 2786 XFREE(encrypted, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 2787 return ret;
wolfSSL 16:8e0d178b1d1e 2788 }
wolfSSL 16:8e0d178b1d1e 2789
wolfSSL 16:8e0d178b1d1e 2790 /* 2: build up SignedData, encapsulating EncryptedData */
wolfSSL 16:8e0d178b1d1e 2791 pkcs7->rng = &rng;
wolfSSL 16:8e0d178b1d1e 2792 pkcs7->content = encrypted;
wolfSSL 16:8e0d178b1d1e 2793 pkcs7->contentSz = encryptedSz;
wolfSSL 16:8e0d178b1d1e 2794 pkcs7->contentOID = ENCRYPTED_DATA;
wolfSSL 16:8e0d178b1d1e 2795 pkcs7->hashOID = hashOID;
wolfSSL 16:8e0d178b1d1e 2796 pkcs7->encryptOID = signOID;
wolfSSL 16:8e0d178b1d1e 2797 pkcs7->privateKey = privateKey;
wolfSSL 16:8e0d178b1d1e 2798 pkcs7->privateKeySz = privateKeySz;
wolfSSL 16:8e0d178b1d1e 2799 pkcs7->signedAttribs = signedAttribs;
wolfSSL 16:8e0d178b1d1e 2800 pkcs7->signedAttribsSz = signedAttribsSz;
wolfSSL 16:8e0d178b1d1e 2801
wolfSSL 16:8e0d178b1d1e 2802 ret = wc_PKCS7_EncodeSignedData(pkcs7, output, outputSz);
wolfSSL 16:8e0d178b1d1e 2803 if (ret <= 0) {
wolfSSL 16:8e0d178b1d1e 2804 WOLFSSL_MSG("Error encoding CMS SignedData content type");
wolfSSL 16:8e0d178b1d1e 2805 }
wolfSSL 16:8e0d178b1d1e 2806
wolfSSL 16:8e0d178b1d1e 2807 ForceZero(encrypted, encryptedSz);
wolfSSL 16:8e0d178b1d1e 2808 XFREE(encrypted, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 2809 pkcs7->rng = NULL;
wolfSSL 16:8e0d178b1d1e 2810 wc_FreeRng(&rng);
wolfSSL 16:8e0d178b1d1e 2811
wolfSSL 16:8e0d178b1d1e 2812 return ret;
wolfSSL 16:8e0d178b1d1e 2813 }
wolfSSL 16:8e0d178b1d1e 2814
wolfSSL 16:8e0d178b1d1e 2815 #endif /* NO_PKCS7_ENCRYPTED_DATA */
wolfSSL 16:8e0d178b1d1e 2816
wolfSSL 16:8e0d178b1d1e 2817 #if defined(HAVE_LIBZ) && !defined(NO_PKCS7_COMPRESSED_DATA)
wolfSSL 16:8e0d178b1d1e 2818 /* Single-shot API to generate a CMS SignedData bundle that encapsulates a
wolfSSL 16:8e0d178b1d1e 2819 * CMS CompressedData bundle. Content of inner CompressedData is set to that
wolfSSL 16:8e0d178b1d1e 2820 * of FirmwarePkgData. Any recipient certificates should be loaded into the
wolfSSL 16:8e0d178b1d1e 2821 * PKCS7 structure prior to calling this function, using wc_PKCS7_InitWithCert()
wolfSSL 16:8e0d178b1d1e 2822 * and/or wc_PKCS7_AddCertificate().
wolfSSL 16:8e0d178b1d1e 2823 *
wolfSSL 16:8e0d178b1d1e 2824 * pkcs7 - pointer to initialized PKCS7 struct
wolfSSL 16:8e0d178b1d1e 2825 * privateKey - private RSA/ECC key, used for signing SignedData
wolfSSL 16:8e0d178b1d1e 2826 * privateKeySz - size of privateKey, octets
wolfSSL 16:8e0d178b1d1e 2827 * signOID - public key algorithm OID, to be used for sign
wolfSSL 16:8e0d178b1d1e 2828 * operation in SignedData generation
wolfSSL 16:8e0d178b1d1e 2829 * hashOID - hash algorithm OID, to be used for signature in
wolfSSL 16:8e0d178b1d1e 2830 * SignedData generation
wolfSSL 16:8e0d178b1d1e 2831 * content - content to be encapsulated
wolfSSL 16:8e0d178b1d1e 2832 * contentSz - size of content, octets
wolfSSL 16:8e0d178b1d1e 2833 * signedAttribs - optional signed attributes, for SignedData
wolfSSL 16:8e0d178b1d1e 2834 * signedAttribsSz - number of PKCS7Attrib members in signedAttribs
wolfSSL 16:8e0d178b1d1e 2835 * output - output buffer for final bundle
wolfSSL 16:8e0d178b1d1e 2836 * outputSz - size of output buffer, octets
wolfSSL 16:8e0d178b1d1e 2837 *
wolfSSL 16:8e0d178b1d1e 2838 * Returns length of generated bundle on success, negative upon error. */
wolfSSL 16:8e0d178b1d1e 2839 int wc_PKCS7_EncodeSignedCompressedFPD(PKCS7* pkcs7, byte* privateKey,
wolfSSL 16:8e0d178b1d1e 2840 word32 privateKeySz, int signOID,
wolfSSL 16:8e0d178b1d1e 2841 int hashOID, byte* content,
wolfSSL 16:8e0d178b1d1e 2842 word32 contentSz,
wolfSSL 16:8e0d178b1d1e 2843 PKCS7Attrib* signedAttribs,
wolfSSL 16:8e0d178b1d1e 2844 word32 signedAttribsSz, byte* output,
wolfSSL 16:8e0d178b1d1e 2845 word32 outputSz)
wolfSSL 16:8e0d178b1d1e 2846 {
wolfSSL 16:8e0d178b1d1e 2847 int ret = 0, compressedSz = 0;
wolfSSL 16:8e0d178b1d1e 2848 byte* compressed = NULL;
wolfSSL 16:8e0d178b1d1e 2849 WC_RNG rng;
wolfSSL 16:8e0d178b1d1e 2850
wolfSSL 16:8e0d178b1d1e 2851 if (pkcs7 == NULL || privateKey == NULL || privateKeySz == 0 ||
wolfSSL 16:8e0d178b1d1e 2852 content == NULL || contentSz == 0 || output == NULL || outputSz == 0) {
wolfSSL 16:8e0d178b1d1e 2853 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 2854 }
wolfSSL 16:8e0d178b1d1e 2855
wolfSSL 16:8e0d178b1d1e 2856 /* 1: build up CompressedData using FirmwarePkgData type, use output
wolfSSL 16:8e0d178b1d1e 2857 * buffer as tmp for storage and to get size */
wolfSSL 16:8e0d178b1d1e 2858
wolfSSL 16:8e0d178b1d1e 2859 /* set struct elements, inner content type is FirmwarePkgData */
wolfSSL 16:8e0d178b1d1e 2860 pkcs7->content = content;
wolfSSL 16:8e0d178b1d1e 2861 pkcs7->contentSz = contentSz;
wolfSSL 16:8e0d178b1d1e 2862 pkcs7->contentOID = FIRMWARE_PKG_DATA;
wolfSSL 16:8e0d178b1d1e 2863 pkcs7->version = 3;
wolfSSL 16:8e0d178b1d1e 2864
wolfSSL 16:8e0d178b1d1e 2865 compressedSz = wc_PKCS7_EncodeCompressedData(pkcs7, output, outputSz);
wolfSSL 16:8e0d178b1d1e 2866 if (compressedSz < 0) {
wolfSSL 16:8e0d178b1d1e 2867 WOLFSSL_MSG("Error encoding CMS CompressedData content type");
wolfSSL 16:8e0d178b1d1e 2868 return compressedSz;
wolfSSL 16:8e0d178b1d1e 2869 }
wolfSSL 16:8e0d178b1d1e 2870
wolfSSL 16:8e0d178b1d1e 2871 /* save compressedData, reset output buffer and struct */
wolfSSL 16:8e0d178b1d1e 2872 compressed = (byte*)XMALLOC(compressedSz, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 2873 if (compressed == NULL) {
wolfSSL 16:8e0d178b1d1e 2874 ForceZero(output, outputSz);
wolfSSL 16:8e0d178b1d1e 2875 return MEMORY_E;
wolfSSL 16:8e0d178b1d1e 2876 }
wolfSSL 16:8e0d178b1d1e 2877
wolfSSL 16:8e0d178b1d1e 2878 XMEMCPY(compressed, output, compressedSz);
wolfSSL 16:8e0d178b1d1e 2879 ForceZero(output, outputSz);
wolfSSL 16:8e0d178b1d1e 2880
wolfSSL 16:8e0d178b1d1e 2881 ret = wc_InitRng(&rng);
wolfSSL 16:8e0d178b1d1e 2882 if (ret != 0) {
wolfSSL 16:8e0d178b1d1e 2883 ForceZero(compressed, compressedSz);
wolfSSL 16:8e0d178b1d1e 2884 XFREE(compressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 2885 return ret;
wolfSSL 16:8e0d178b1d1e 2886 }
wolfSSL 16:8e0d178b1d1e 2887
wolfSSL 16:8e0d178b1d1e 2888 /* 2: build up SignedData, encapsulating EncryptedData */
wolfSSL 16:8e0d178b1d1e 2889 pkcs7->rng = &rng;
wolfSSL 16:8e0d178b1d1e 2890 pkcs7->content = compressed;
wolfSSL 16:8e0d178b1d1e 2891 pkcs7->contentSz = compressedSz;
wolfSSL 16:8e0d178b1d1e 2892 pkcs7->contentOID = COMPRESSED_DATA;
wolfSSL 16:8e0d178b1d1e 2893 pkcs7->hashOID = hashOID;
wolfSSL 16:8e0d178b1d1e 2894 pkcs7->encryptOID = signOID;
wolfSSL 16:8e0d178b1d1e 2895 pkcs7->privateKey = privateKey;
wolfSSL 16:8e0d178b1d1e 2896 pkcs7->privateKeySz = privateKeySz;
wolfSSL 16:8e0d178b1d1e 2897 pkcs7->signedAttribs = signedAttribs;
wolfSSL 16:8e0d178b1d1e 2898 pkcs7->signedAttribsSz = signedAttribsSz;
wolfSSL 16:8e0d178b1d1e 2899
wolfSSL 16:8e0d178b1d1e 2900 ret = wc_PKCS7_EncodeSignedData(pkcs7, output, outputSz);
wolfSSL 16:8e0d178b1d1e 2901 if (ret <= 0) {
wolfSSL 16:8e0d178b1d1e 2902 WOLFSSL_MSG("Error encoding CMS SignedData content type");
wolfSSL 16:8e0d178b1d1e 2903 }
wolfSSL 16:8e0d178b1d1e 2904
wolfSSL 16:8e0d178b1d1e 2905 ForceZero(compressed, compressedSz);
wolfSSL 16:8e0d178b1d1e 2906 XFREE(compressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 2907 pkcs7->rng = NULL;
wolfSSL 16:8e0d178b1d1e 2908 wc_FreeRng(&rng);
wolfSSL 16:8e0d178b1d1e 2909
wolfSSL 16:8e0d178b1d1e 2910 return ret;
wolfSSL 16:8e0d178b1d1e 2911 }
wolfSSL 16:8e0d178b1d1e 2912
wolfSSL 16:8e0d178b1d1e 2913 #ifndef NO_PKCS7_ENCRYPTED_DATA
wolfSSL 16:8e0d178b1d1e 2914
wolfSSL 16:8e0d178b1d1e 2915 /* Single-shot API to generate a CMS SignedData bundle that encapsulates a
wolfSSL 16:8e0d178b1d1e 2916 * CMS EncryptedData bundle, which then encapsulates a CMS CompressedData
wolfSSL 16:8e0d178b1d1e 2917 * bundle. Content of inner CompressedData is set to that of FirmwarePkgData.
wolfSSL 16:8e0d178b1d1e 2918 * Any recipient certificates should be loaded into the PKCS7 structure prior
wolfSSL 16:8e0d178b1d1e 2919 * to calling this function, using wc_PKCS7_InitWithCert() and/or
wolfSSL 16:8e0d178b1d1e 2920 * wc_PKCS7_AddCertificate().
wolfSSL 16:8e0d178b1d1e 2921 *
wolfSSL 16:8e0d178b1d1e 2922 * pkcs7 - pointer to initialized PKCS7 struct
wolfSSL 16:8e0d178b1d1e 2923 * encryptKey - encryption key used for encrypting EncryptedData
wolfSSL 16:8e0d178b1d1e 2924 * encryptKeySz - size of encryptKey, octets
wolfSSL 16:8e0d178b1d1e 2925 * privateKey - private RSA/ECC key, used for signing SignedData
wolfSSL 16:8e0d178b1d1e 2926 * privateKeySz - size of privateKey, octets
wolfSSL 16:8e0d178b1d1e 2927 * encryptOID - encryption algorithm OID, to be used as encryption
wolfSSL 16:8e0d178b1d1e 2928 * algorithm for EncryptedData
wolfSSL 16:8e0d178b1d1e 2929 * signOID - public key algorithm OID, to be used for sign
wolfSSL 16:8e0d178b1d1e 2930 * operation in SignedData generation
wolfSSL 16:8e0d178b1d1e 2931 * hashOID - hash algorithm OID, to be used for signature in
wolfSSL 16:8e0d178b1d1e 2932 * SignedData generation
wolfSSL 16:8e0d178b1d1e 2933 * content - content to be encapsulated
wolfSSL 16:8e0d178b1d1e 2934 * contentSz - size of content, octets
wolfSSL 16:8e0d178b1d1e 2935 * unprotectedAttribs - optional unprotected attributes, for EncryptedData
wolfSSL 16:8e0d178b1d1e 2936 * unprotectedAttribsSz - number of PKCS7Attrib members in unprotectedAttribs
wolfSSL 16:8e0d178b1d1e 2937 * signedAttribs - optional signed attributes, for SignedData
wolfSSL 16:8e0d178b1d1e 2938 * signedAttribsSz - number of PKCS7Attrib members in signedAttribs
wolfSSL 16:8e0d178b1d1e 2939 * output - output buffer for final bundle
wolfSSL 16:8e0d178b1d1e 2940 * outputSz - size of output buffer, octets
wolfSSL 16:8e0d178b1d1e 2941 *
wolfSSL 16:8e0d178b1d1e 2942 * Returns length of generated bundle on success, negative upon error. */
wolfSSL 16:8e0d178b1d1e 2943 int wc_PKCS7_EncodeSignedEncryptedCompressedFPD(PKCS7* pkcs7, byte* encryptKey,
wolfSSL 16:8e0d178b1d1e 2944 word32 encryptKeySz, byte* privateKey,
wolfSSL 16:8e0d178b1d1e 2945 word32 privateKeySz, int encryptOID,
wolfSSL 16:8e0d178b1d1e 2946 int signOID, int hashOID, byte* content,
wolfSSL 16:8e0d178b1d1e 2947 word32 contentSz,
wolfSSL 16:8e0d178b1d1e 2948 PKCS7Attrib* unprotectedAttribs,
wolfSSL 16:8e0d178b1d1e 2949 word32 unprotectedAttribsSz,
wolfSSL 16:8e0d178b1d1e 2950 PKCS7Attrib* signedAttribs,
wolfSSL 16:8e0d178b1d1e 2951 word32 signedAttribsSz,
wolfSSL 16:8e0d178b1d1e 2952 byte* output, word32 outputSz)
wolfSSL 16:8e0d178b1d1e 2953 {
wolfSSL 16:8e0d178b1d1e 2954 int ret = 0, compressedSz = 0, encryptedSz = 0;
wolfSSL 16:8e0d178b1d1e 2955 byte* compressed = NULL;
wolfSSL 16:8e0d178b1d1e 2956 byte* encrypted = NULL;
wolfSSL 16:8e0d178b1d1e 2957 WC_RNG rng;
wolfSSL 16:8e0d178b1d1e 2958
wolfSSL 16:8e0d178b1d1e 2959 if (pkcs7 == NULL || encryptKey == NULL || encryptKeySz == 0 ||
wolfSSL 16:8e0d178b1d1e 2960 privateKey == NULL || privateKeySz == 0 || content == NULL ||
wolfSSL 16:8e0d178b1d1e 2961 contentSz == 0 || output == NULL || outputSz == 0) {
wolfSSL 16:8e0d178b1d1e 2962 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 2963 }
wolfSSL 16:8e0d178b1d1e 2964
wolfSSL 16:8e0d178b1d1e 2965 /* 1: build up CompressedData using FirmwarePkgData type, use output
wolfSSL 16:8e0d178b1d1e 2966 * buffer as tmp for storage and to get size */
wolfSSL 16:8e0d178b1d1e 2967 pkcs7->content = content;
wolfSSL 16:8e0d178b1d1e 2968 pkcs7->contentSz = contentSz;
wolfSSL 16:8e0d178b1d1e 2969 pkcs7->contentOID = FIRMWARE_PKG_DATA;
wolfSSL 16:8e0d178b1d1e 2970 pkcs7->version = 3;
wolfSSL 16:8e0d178b1d1e 2971
wolfSSL 16:8e0d178b1d1e 2972 compressedSz = wc_PKCS7_EncodeCompressedData(pkcs7, output, outputSz);
wolfSSL 16:8e0d178b1d1e 2973 if (compressedSz < 0) {
wolfSSL 16:8e0d178b1d1e 2974 WOLFSSL_MSG("Error encoding CMS CompressedData content type");
wolfSSL 16:8e0d178b1d1e 2975 return compressedSz;
wolfSSL 16:8e0d178b1d1e 2976 }
wolfSSL 16:8e0d178b1d1e 2977
wolfSSL 16:8e0d178b1d1e 2978 /* save compressedData, reset output buffer and struct */
wolfSSL 16:8e0d178b1d1e 2979 compressed = (byte*)XMALLOC(compressedSz, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 2980 if (compressed == NULL)
wolfSSL 16:8e0d178b1d1e 2981 return MEMORY_E;
wolfSSL 16:8e0d178b1d1e 2982
wolfSSL 16:8e0d178b1d1e 2983 XMEMCPY(compressed, output, compressedSz);
wolfSSL 16:8e0d178b1d1e 2984 ForceZero(output, outputSz);
wolfSSL 16:8e0d178b1d1e 2985
wolfSSL 16:8e0d178b1d1e 2986 /* 2: build up EncryptedData using CompressedData, use output
wolfSSL 16:8e0d178b1d1e 2987 * buffer as tmp for storage and to get size */
wolfSSL 16:8e0d178b1d1e 2988 pkcs7->content = compressed;
wolfSSL 16:8e0d178b1d1e 2989 pkcs7->contentSz = compressedSz;
wolfSSL 16:8e0d178b1d1e 2990 pkcs7->contentOID = COMPRESSED_DATA;
wolfSSL 16:8e0d178b1d1e 2991 pkcs7->encryptOID = encryptOID;
wolfSSL 16:8e0d178b1d1e 2992 pkcs7->encryptionKey = encryptKey;
wolfSSL 16:8e0d178b1d1e 2993 pkcs7->encryptionKeySz = encryptKeySz;
wolfSSL 16:8e0d178b1d1e 2994 pkcs7->unprotectedAttribs = unprotectedAttribs;
wolfSSL 16:8e0d178b1d1e 2995 pkcs7->unprotectedAttribsSz = unprotectedAttribsSz;
wolfSSL 16:8e0d178b1d1e 2996
wolfSSL 16:8e0d178b1d1e 2997 encryptedSz = wc_PKCS7_EncodeEncryptedData(pkcs7, output, outputSz);
wolfSSL 16:8e0d178b1d1e 2998 if (encryptedSz < 0) {
wolfSSL 16:8e0d178b1d1e 2999 WOLFSSL_MSG("Error encoding CMS EncryptedData content type");
wolfSSL 16:8e0d178b1d1e 3000 XFREE(compressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 3001 return encryptedSz;
wolfSSL 16:8e0d178b1d1e 3002 }
wolfSSL 16:8e0d178b1d1e 3003
wolfSSL 16:8e0d178b1d1e 3004 /* save encryptedData, reset output buffer and struct */
wolfSSL 16:8e0d178b1d1e 3005 encrypted = (byte*)XMALLOC(encryptedSz, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 3006 if (encrypted == NULL) {
wolfSSL 16:8e0d178b1d1e 3007 ForceZero(compressed, compressedSz);
wolfSSL 16:8e0d178b1d1e 3008 XFREE(compressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 3009 return MEMORY_E;
wolfSSL 16:8e0d178b1d1e 3010 }
wolfSSL 16:8e0d178b1d1e 3011
wolfSSL 16:8e0d178b1d1e 3012 XMEMCPY(encrypted, output, encryptedSz);
wolfSSL 16:8e0d178b1d1e 3013 ForceZero(compressed, compressedSz);
wolfSSL 16:8e0d178b1d1e 3014 XFREE(compressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 3015 ForceZero(output, outputSz);
wolfSSL 16:8e0d178b1d1e 3016
wolfSSL 16:8e0d178b1d1e 3017 ret = wc_InitRng(&rng);
wolfSSL 16:8e0d178b1d1e 3018 if (ret != 0) {
wolfSSL 16:8e0d178b1d1e 3019 ForceZero(encrypted, encryptedSz);
wolfSSL 16:8e0d178b1d1e 3020 XFREE(encrypted, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 3021 return ret;
wolfSSL 16:8e0d178b1d1e 3022 }
wolfSSL 16:8e0d178b1d1e 3023
wolfSSL 16:8e0d178b1d1e 3024 /* 3: build up SignedData, encapsulating EncryptedData */
wolfSSL 16:8e0d178b1d1e 3025 pkcs7->rng = &rng;
wolfSSL 16:8e0d178b1d1e 3026 pkcs7->content = encrypted;
wolfSSL 16:8e0d178b1d1e 3027 pkcs7->contentSz = encryptedSz;
wolfSSL 16:8e0d178b1d1e 3028 pkcs7->contentOID = ENCRYPTED_DATA;
wolfSSL 16:8e0d178b1d1e 3029 pkcs7->hashOID = hashOID;
wolfSSL 16:8e0d178b1d1e 3030 pkcs7->encryptOID = signOID;
wolfSSL 16:8e0d178b1d1e 3031 pkcs7->privateKey = privateKey;
wolfSSL 16:8e0d178b1d1e 3032 pkcs7->privateKeySz = privateKeySz;
wolfSSL 16:8e0d178b1d1e 3033 pkcs7->signedAttribs = signedAttribs;
wolfSSL 16:8e0d178b1d1e 3034 pkcs7->signedAttribsSz = signedAttribsSz;
wolfSSL 16:8e0d178b1d1e 3035
wolfSSL 16:8e0d178b1d1e 3036 ret = wc_PKCS7_EncodeSignedData(pkcs7, output, outputSz);
wolfSSL 16:8e0d178b1d1e 3037 if (ret <= 0) {
wolfSSL 16:8e0d178b1d1e 3038 WOLFSSL_MSG("Error encoding CMS SignedData content type");
wolfSSL 16:8e0d178b1d1e 3039 }
wolfSSL 16:8e0d178b1d1e 3040
wolfSSL 16:8e0d178b1d1e 3041 ForceZero(encrypted, encryptedSz);
wolfSSL 16:8e0d178b1d1e 3042 XFREE(encrypted, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 3043 pkcs7->rng = NULL;
wolfSSL 16:8e0d178b1d1e 3044 wc_FreeRng(&rng);
wolfSSL 16:8e0d178b1d1e 3045
wolfSSL 16:8e0d178b1d1e 3046 return ret;
wolfSSL 16:8e0d178b1d1e 3047 }
wolfSSL 16:8e0d178b1d1e 3048
wolfSSL 16:8e0d178b1d1e 3049 #endif /* !NO_PKCS7_ENCRYPTED_DATA */
wolfSSL 16:8e0d178b1d1e 3050 #endif /* HAVE_LIBZ && !NO_PKCS7_COMPRESSED_DATA */
wolfSSL 15:117db924cf7c 3051
wolfSSL 15:117db924cf7c 3052
wolfSSL 15:117db924cf7c 3053 #ifndef NO_RSA
wolfSSL 15:117db924cf7c 3054
wolfSSL 16:8e0d178b1d1e 3055 #ifdef HAVE_PKCS7_RSA_RAW_SIGN_CALLBACK
wolfSSL 16:8e0d178b1d1e 3056 /* register raw RSA sign digest callback */
wolfSSL 16:8e0d178b1d1e 3057 int wc_PKCS7_SetRsaSignRawDigestCb(PKCS7* pkcs7, CallbackRsaSignRawDigest cb)
wolfSSL 16:8e0d178b1d1e 3058 {
wolfSSL 16:8e0d178b1d1e 3059 if (pkcs7 == NULL || cb == NULL) {
wolfSSL 16:8e0d178b1d1e 3060 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 3061 }
wolfSSL 16:8e0d178b1d1e 3062
wolfSSL 16:8e0d178b1d1e 3063 pkcs7->rsaSignRawDigestCb = cb;
wolfSSL 16:8e0d178b1d1e 3064
wolfSSL 16:8e0d178b1d1e 3065 return 0;
wolfSSL 16:8e0d178b1d1e 3066 }
wolfSSL 16:8e0d178b1d1e 3067 #endif
wolfSSL 16:8e0d178b1d1e 3068
wolfSSL 15:117db924cf7c 3069 /* returns size of signature put into out, negative on error */
wolfSSL 15:117db924cf7c 3070 static int wc_PKCS7_RsaVerify(PKCS7* pkcs7, byte* sig, int sigSz,
wolfSSL 15:117db924cf7c 3071 byte* hash, word32 hashSz)
wolfSSL 15:117db924cf7c 3072 {
wolfSSL 16:8e0d178b1d1e 3073 int ret = 0, i;
wolfSSL 16:8e0d178b1d1e 3074 word32 scratch = 0, verified = 0;
wolfSSL 15:117db924cf7c 3075 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 3076 byte* digest;
wolfSSL 15:117db924cf7c 3077 RsaKey* key;
wolfSSL 16:8e0d178b1d1e 3078 DecodedCert* dCert;
wolfSSL 15:117db924cf7c 3079 #else
wolfSSL 15:117db924cf7c 3080 byte digest[MAX_PKCS7_DIGEST_SZ];
wolfSSL 16:8e0d178b1d1e 3081 RsaKey key[1];
wolfSSL 16:8e0d178b1d1e 3082 DecodedCert stack_dCert;
wolfSSL 16:8e0d178b1d1e 3083 DecodedCert* dCert = &stack_dCert;
wolfSSL 15:117db924cf7c 3084 #endif
wolfSSL 15:117db924cf7c 3085
wolfSSL 15:117db924cf7c 3086 if (pkcs7 == NULL || sig == NULL || hash == NULL) {
wolfSSL 15:117db924cf7c 3087 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 3088 }
wolfSSL 15:117db924cf7c 3089
wolfSSL 15:117db924cf7c 3090 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 3091 digest = (byte*)XMALLOC(MAX_PKCS7_DIGEST_SZ, pkcs7->heap,
wolfSSL 15:117db924cf7c 3092 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3093 if (digest == NULL)
wolfSSL 15:117db924cf7c 3094 return MEMORY_E;
wolfSSL 15:117db924cf7c 3095
wolfSSL 15:117db924cf7c 3096 key = (RsaKey*)XMALLOC(sizeof(RsaKey), pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3097 if (key == NULL) {
wolfSSL 15:117db924cf7c 3098 XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3099 return MEMORY_E;
wolfSSL 15:117db924cf7c 3100 }
wolfSSL 16:8e0d178b1d1e 3101
wolfSSL 16:8e0d178b1d1e 3102 dCert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), pkcs7->heap,
wolfSSL 16:8e0d178b1d1e 3103 DYNAMIC_TYPE_DCERT);
wolfSSL 16:8e0d178b1d1e 3104 if (dCert == NULL) {
wolfSSL 16:8e0d178b1d1e 3105 XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 3106 XFREE(key, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 3107 return MEMORY_E;
wolfSSL 16:8e0d178b1d1e 3108 }
wolfSSL 15:117db924cf7c 3109 #endif
wolfSSL 15:117db924cf7c 3110
wolfSSL 15:117db924cf7c 3111 XMEMSET(digest, 0, MAX_PKCS7_DIGEST_SZ);
wolfSSL 15:117db924cf7c 3112
wolfSSL 16:8e0d178b1d1e 3113 /* loop over certs received in certificates set, try to find one
wolfSSL 16:8e0d178b1d1e 3114 * that will validate signature */
wolfSSL 16:8e0d178b1d1e 3115 for (i = 0; i < MAX_PKCS7_CERTS; i++) {
wolfSSL 16:8e0d178b1d1e 3116
wolfSSL 16:8e0d178b1d1e 3117 verified = 0;
wolfSSL 16:8e0d178b1d1e 3118 scratch = 0;
wolfSSL 16:8e0d178b1d1e 3119
wolfSSL 16:8e0d178b1d1e 3120 if (pkcs7->certSz[i] == 0)
wolfSSL 16:8e0d178b1d1e 3121 continue;
wolfSSL 16:8e0d178b1d1e 3122
wolfSSL 16:8e0d178b1d1e 3123 ret = wc_InitRsaKey_ex(key, pkcs7->heap, pkcs7->devId);
wolfSSL 16:8e0d178b1d1e 3124 if (ret != 0) {
wolfSSL 16:8e0d178b1d1e 3125 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 3126 XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 3127 XFREE(key, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 3128 XFREE(dCert, pkcs7->heap, DYNAMIC_TYPE_DCERT);
wolfSSL 16:8e0d178b1d1e 3129 #endif
wolfSSL 16:8e0d178b1d1e 3130 return ret;
wolfSSL 16:8e0d178b1d1e 3131 }
wolfSSL 16:8e0d178b1d1e 3132
wolfSSL 16:8e0d178b1d1e 3133 InitDecodedCert(dCert, pkcs7->cert[i], pkcs7->certSz[i], pkcs7->heap);
wolfSSL 16:8e0d178b1d1e 3134 /* not verifying, only using this to extract public key */
wolfSSL 16:8e0d178b1d1e 3135 ret = ParseCert(dCert, CA_TYPE, NO_VERIFY, 0);
wolfSSL 16:8e0d178b1d1e 3136 if (ret < 0) {
wolfSSL 16:8e0d178b1d1e 3137 WOLFSSL_MSG("ASN RSA cert parse error");
wolfSSL 16:8e0d178b1d1e 3138 FreeDecodedCert(dCert);
wolfSSL 16:8e0d178b1d1e 3139 wc_FreeRsaKey(key);
wolfSSL 16:8e0d178b1d1e 3140 continue;
wolfSSL 16:8e0d178b1d1e 3141 }
wolfSSL 16:8e0d178b1d1e 3142
wolfSSL 16:8e0d178b1d1e 3143 if (wc_RsaPublicKeyDecode(dCert->publicKey, &scratch, key,
wolfSSL 16:8e0d178b1d1e 3144 dCert->pubKeySize) < 0) {
wolfSSL 16:8e0d178b1d1e 3145 WOLFSSL_MSG("ASN RSA key decode error");
wolfSSL 16:8e0d178b1d1e 3146 FreeDecodedCert(dCert);
wolfSSL 16:8e0d178b1d1e 3147 wc_FreeRsaKey(key);
wolfSSL 16:8e0d178b1d1e 3148 continue;
wolfSSL 16:8e0d178b1d1e 3149 }
wolfSSL 16:8e0d178b1d1e 3150
wolfSSL 16:8e0d178b1d1e 3151 #ifdef WOLFSSL_ASYNC_CRYPT
wolfSSL 16:8e0d178b1d1e 3152 do {
wolfSSL 16:8e0d178b1d1e 3153 ret = wc_AsyncWait(ret, &key->asyncDev,
wolfSSL 16:8e0d178b1d1e 3154 WC_ASYNC_FLAG_CALL_AGAIN);
wolfSSL 16:8e0d178b1d1e 3155 #endif
wolfSSL 16:8e0d178b1d1e 3156 if (ret >= 0) {
wolfSSL 16:8e0d178b1d1e 3157 ret = wc_RsaSSL_Verify(sig, sigSz, digest, MAX_PKCS7_DIGEST_SZ,
wolfSSL 16:8e0d178b1d1e 3158 key);
wolfSSL 16:8e0d178b1d1e 3159 }
wolfSSL 16:8e0d178b1d1e 3160 #ifdef WOLFSSL_ASYNC_CRYPT
wolfSSL 16:8e0d178b1d1e 3161 } while (ret == WC_PENDING_E);
wolfSSL 16:8e0d178b1d1e 3162 #endif
wolfSSL 16:8e0d178b1d1e 3163 FreeDecodedCert(dCert);
wolfSSL 15:117db924cf7c 3164 wc_FreeRsaKey(key);
wolfSSL 16:8e0d178b1d1e 3165
wolfSSL 16:8e0d178b1d1e 3166 if ((ret > 0) && (hashSz == (word32)ret)) {
wolfSSL 16:8e0d178b1d1e 3167 if (XMEMCMP(digest, hash, hashSz) == 0) {
wolfSSL 16:8e0d178b1d1e 3168 /* found signer that successfully verified signature */
wolfSSL 16:8e0d178b1d1e 3169 verified = 1;
wolfSSL 16:8e0d178b1d1e 3170 break;
wolfSSL 16:8e0d178b1d1e 3171 }
wolfSSL 16:8e0d178b1d1e 3172 }
wolfSSL 16:8e0d178b1d1e 3173 }
wolfSSL 16:8e0d178b1d1e 3174
wolfSSL 16:8e0d178b1d1e 3175 if (verified == 0) {
wolfSSL 15:117db924cf7c 3176 ret = SIG_VERIFY_E;
wolfSSL 15:117db924cf7c 3177 }
wolfSSL 15:117db924cf7c 3178
wolfSSL 15:117db924cf7c 3179 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 3180 XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3181 XFREE(key, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 3182 XFREE(dCert, pkcs7->heap, DYNAMIC_TYPE_DCERT);
wolfSSL 15:117db924cf7c 3183 #endif
wolfSSL 15:117db924cf7c 3184
wolfSSL 15:117db924cf7c 3185 return ret;
wolfSSL 15:117db924cf7c 3186 }
wolfSSL 15:117db924cf7c 3187
wolfSSL 15:117db924cf7c 3188 #endif /* NO_RSA */
wolfSSL 15:117db924cf7c 3189
wolfSSL 15:117db924cf7c 3190
wolfSSL 15:117db924cf7c 3191 #ifdef HAVE_ECC
wolfSSL 15:117db924cf7c 3192
wolfSSL 15:117db924cf7c 3193 /* returns size of signature put into out, negative on error */
wolfSSL 15:117db924cf7c 3194 static int wc_PKCS7_EcdsaVerify(PKCS7* pkcs7, byte* sig, int sigSz,
wolfSSL 15:117db924cf7c 3195 byte* hash, word32 hashSz)
wolfSSL 15:117db924cf7c 3196 {
wolfSSL 16:8e0d178b1d1e 3197 int ret = 0, i;
wolfSSL 15:117db924cf7c 3198 int res = 0;
wolfSSL 16:8e0d178b1d1e 3199 int verified = 0;
wolfSSL 15:117db924cf7c 3200 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 3201 byte* digest;
wolfSSL 15:117db924cf7c 3202 ecc_key* key;
wolfSSL 16:8e0d178b1d1e 3203 DecodedCert* dCert;
wolfSSL 15:117db924cf7c 3204 #else
wolfSSL 15:117db924cf7c 3205 byte digest[MAX_PKCS7_DIGEST_SZ];
wolfSSL 16:8e0d178b1d1e 3206 ecc_key key[1];
wolfSSL 16:8e0d178b1d1e 3207 DecodedCert stack_dCert;
wolfSSL 16:8e0d178b1d1e 3208 DecodedCert* dCert = &stack_dCert;
wolfSSL 15:117db924cf7c 3209 #endif
wolfSSL 15:117db924cf7c 3210 word32 idx = 0;
wolfSSL 15:117db924cf7c 3211
wolfSSL 15:117db924cf7c 3212 if (pkcs7 == NULL || sig == NULL)
wolfSSL 15:117db924cf7c 3213 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 3214
wolfSSL 15:117db924cf7c 3215 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 3216 digest = (byte*)XMALLOC(MAX_PKCS7_DIGEST_SZ, pkcs7->heap,
wolfSSL 15:117db924cf7c 3217 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3218 if (digest == NULL)
wolfSSL 15:117db924cf7c 3219 return MEMORY_E;
wolfSSL 15:117db924cf7c 3220
wolfSSL 15:117db924cf7c 3221 key = (ecc_key*)XMALLOC(sizeof(ecc_key), pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3222 if (key == NULL) {
wolfSSL 15:117db924cf7c 3223 XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3224 return MEMORY_E;
wolfSSL 15:117db924cf7c 3225 }
wolfSSL 16:8e0d178b1d1e 3226
wolfSSL 16:8e0d178b1d1e 3227 dCert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), pkcs7->heap,
wolfSSL 16:8e0d178b1d1e 3228 DYNAMIC_TYPE_DCERT);
wolfSSL 16:8e0d178b1d1e 3229 if (dCert == NULL) {
wolfSSL 16:8e0d178b1d1e 3230 XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 3231 XFREE(key, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 3232 return MEMORY_E;
wolfSSL 16:8e0d178b1d1e 3233 }
wolfSSL 15:117db924cf7c 3234 #endif
wolfSSL 15:117db924cf7c 3235
wolfSSL 15:117db924cf7c 3236 XMEMSET(digest, 0, MAX_PKCS7_DIGEST_SZ);
wolfSSL 15:117db924cf7c 3237
wolfSSL 16:8e0d178b1d1e 3238 /* loop over certs received in certificates set, try to find one
wolfSSL 16:8e0d178b1d1e 3239 * that will validate signature */
wolfSSL 16:8e0d178b1d1e 3240 for (i = 0; i < MAX_PKCS7_CERTS; i++) {
wolfSSL 16:8e0d178b1d1e 3241
wolfSSL 16:8e0d178b1d1e 3242 verified = 0;
wolfSSL 16:8e0d178b1d1e 3243
wolfSSL 16:8e0d178b1d1e 3244 if (pkcs7->certSz[i] == 0)
wolfSSL 16:8e0d178b1d1e 3245 continue;
wolfSSL 16:8e0d178b1d1e 3246
wolfSSL 16:8e0d178b1d1e 3247 ret = wc_ecc_init_ex(key, pkcs7->heap, pkcs7->devId);
wolfSSL 16:8e0d178b1d1e 3248 if (ret != 0) {
wolfSSL 16:8e0d178b1d1e 3249 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 3250 XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 3251 XFREE(key, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 3252 XFREE(dCert, pkcs7->heap, DYNAMIC_TYPE_DCERT);
wolfSSL 16:8e0d178b1d1e 3253 #endif
wolfSSL 16:8e0d178b1d1e 3254 return ret;
wolfSSL 16:8e0d178b1d1e 3255 }
wolfSSL 16:8e0d178b1d1e 3256
wolfSSL 16:8e0d178b1d1e 3257 InitDecodedCert(dCert, pkcs7->cert[i], pkcs7->certSz[i], pkcs7->heap);
wolfSSL 16:8e0d178b1d1e 3258 /* not verifying, only using this to extract public key */
wolfSSL 16:8e0d178b1d1e 3259 ret = ParseCert(dCert, CA_TYPE, NO_VERIFY, 0);
wolfSSL 16:8e0d178b1d1e 3260 if (ret < 0) {
wolfSSL 16:8e0d178b1d1e 3261 WOLFSSL_MSG("ASN ECC cert parse error");
wolfSSL 16:8e0d178b1d1e 3262 FreeDecodedCert(dCert);
wolfSSL 16:8e0d178b1d1e 3263 wc_ecc_free(key);
wolfSSL 16:8e0d178b1d1e 3264 continue;
wolfSSL 16:8e0d178b1d1e 3265 }
wolfSSL 16:8e0d178b1d1e 3266
wolfSSL 16:8e0d178b1d1e 3267 if (wc_EccPublicKeyDecode(pkcs7->publicKey, &idx, key,
wolfSSL 16:8e0d178b1d1e 3268 pkcs7->publicKeySz) < 0) {
wolfSSL 16:8e0d178b1d1e 3269 WOLFSSL_MSG("ASN ECC key decode error");
wolfSSL 16:8e0d178b1d1e 3270 FreeDecodedCert(dCert);
wolfSSL 16:8e0d178b1d1e 3271 wc_ecc_free(key);
wolfSSL 16:8e0d178b1d1e 3272 continue;
wolfSSL 16:8e0d178b1d1e 3273 }
wolfSSL 16:8e0d178b1d1e 3274
wolfSSL 16:8e0d178b1d1e 3275 #ifdef WOLFSSL_ASYNC_CRYPT
wolfSSL 16:8e0d178b1d1e 3276 do {
wolfSSL 16:8e0d178b1d1e 3277 ret = wc_AsyncWait(ret, &key->asyncDev,
wolfSSL 16:8e0d178b1d1e 3278 WC_ASYNC_FLAG_CALL_AGAIN);
wolfSSL 16:8e0d178b1d1e 3279 #endif
wolfSSL 16:8e0d178b1d1e 3280 if (ret >= 0) {
wolfSSL 16:8e0d178b1d1e 3281 ret = wc_ecc_verify_hash(sig, sigSz, hash, hashSz, &res, key);
wolfSSL 16:8e0d178b1d1e 3282 }
wolfSSL 16:8e0d178b1d1e 3283 #ifdef WOLFSSL_ASYNC_CRYPT
wolfSSL 16:8e0d178b1d1e 3284 } while (ret == WC_PENDING_E);
wolfSSL 16:8e0d178b1d1e 3285 #endif
wolfSSL 16:8e0d178b1d1e 3286
wolfSSL 16:8e0d178b1d1e 3287 FreeDecodedCert(dCert);
wolfSSL 15:117db924cf7c 3288 wc_ecc_free(key);
wolfSSL 16:8e0d178b1d1e 3289
wolfSSL 16:8e0d178b1d1e 3290 if (ret == 0 && res == 1) {
wolfSSL 16:8e0d178b1d1e 3291 /* found signer that successfully verified signature */
wolfSSL 16:8e0d178b1d1e 3292 verified = 1;
wolfSSL 16:8e0d178b1d1e 3293 break;
wolfSSL 16:8e0d178b1d1e 3294 }
wolfSSL 16:8e0d178b1d1e 3295 }
wolfSSL 16:8e0d178b1d1e 3296
wolfSSL 16:8e0d178b1d1e 3297 if (verified == 0) {
wolfSSL 15:117db924cf7c 3298 ret = SIG_VERIFY_E;
wolfSSL 15:117db924cf7c 3299 }
wolfSSL 15:117db924cf7c 3300
wolfSSL 15:117db924cf7c 3301 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 3302 XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3303 XFREE(key, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 3304 XFREE(dCert, pkcs7->heap, DYNAMIC_TYPE_DCERT);
wolfSSL 15:117db924cf7c 3305 #endif
wolfSSL 15:117db924cf7c 3306
wolfSSL 15:117db924cf7c 3307 return ret;
wolfSSL 15:117db924cf7c 3308 }
wolfSSL 15:117db924cf7c 3309
wolfSSL 15:117db924cf7c 3310 #endif /* HAVE_ECC */
wolfSSL 15:117db924cf7c 3311
wolfSSL 15:117db924cf7c 3312
wolfSSL 15:117db924cf7c 3313 /* build SignedData digest, both in PKCS#7 DigestInfo format and
wolfSSL 15:117db924cf7c 3314 * as plain digest for CMS.
wolfSSL 15:117db924cf7c 3315 *
wolfSSL 15:117db924cf7c 3316 * pkcs7 - pointer to initialized PKCS7 struct
wolfSSL 15:117db924cf7c 3317 * signedAttrib - signed attributes
wolfSSL 15:117db924cf7c 3318 * signedAttribSz - size of signedAttrib, octets
wolfSSL 15:117db924cf7c 3319 * pkcs7Digest - [OUT] PKCS#7 DigestInfo
wolfSSL 15:117db924cf7c 3320 * pkcs7DigestSz - [IN/OUT] size of pkcs7Digest
wolfSSL 15:117db924cf7c 3321 * plainDigest - [OUT] pointer to plain digest, offset into pkcs7Digest
wolfSSL 15:117db924cf7c 3322 * plainDigestSz - [OUT] size of digest at plainDigest
wolfSSL 15:117db924cf7c 3323 *
wolfSSL 15:117db924cf7c 3324 * returns 0 on success, negative on error */
wolfSSL 15:117db924cf7c 3325 static int wc_PKCS7_BuildSignedDataDigest(PKCS7* pkcs7, byte* signedAttrib,
wolfSSL 15:117db924cf7c 3326 word32 signedAttribSz, byte* pkcs7Digest,
wolfSSL 15:117db924cf7c 3327 word32* pkcs7DigestSz, byte** plainDigest,
wolfSSL 16:8e0d178b1d1e 3328 word32* plainDigestSz,
wolfSSL 16:8e0d178b1d1e 3329 const byte* hashBuf, word32 hashBufSz)
wolfSSL 16:8e0d178b1d1e 3330 {
wolfSSL 16:8e0d178b1d1e 3331 int ret = 0, digIdx = 0;
wolfSSL 16:8e0d178b1d1e 3332 word32 attribSetSz = 0, hashSz = 0;
wolfSSL 15:117db924cf7c 3333 byte attribSet[MAX_SET_SZ];
wolfSSL 15:117db924cf7c 3334 byte digest[WC_MAX_DIGEST_SIZE];
wolfSSL 15:117db924cf7c 3335 byte digestInfoSeq[MAX_SEQ_SZ];
wolfSSL 15:117db924cf7c 3336 byte digestStr[MAX_OCTET_STR_SZ];
wolfSSL 15:117db924cf7c 3337 byte algoId[MAX_ALGO_SZ];
wolfSSL 15:117db924cf7c 3338 word32 digestInfoSeqSz, digestStrSz, algoIdSz;
wolfSSL 15:117db924cf7c 3339 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 3340 byte* digestInfo;
wolfSSL 15:117db924cf7c 3341 #else
wolfSSL 16:8e0d178b1d1e 3342 byte digestInfo[MAX_PKCS7_DIGEST_SZ];
wolfSSL 15:117db924cf7c 3343 #endif
wolfSSL 15:117db924cf7c 3344
wolfSSL 15:117db924cf7c 3345 wc_HashAlg hash;
wolfSSL 15:117db924cf7c 3346 enum wc_HashType hashType;
wolfSSL 15:117db924cf7c 3347
wolfSSL 16:8e0d178b1d1e 3348 /* check arguments */
wolfSSL 15:117db924cf7c 3349 if (pkcs7 == NULL || pkcs7Digest == NULL ||
wolfSSL 15:117db924cf7c 3350 pkcs7DigestSz == NULL || plainDigest == NULL) {
wolfSSL 15:117db924cf7c 3351 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 3352 }
wolfSSL 15:117db924cf7c 3353
wolfSSL 16:8e0d178b1d1e 3354 hashType = wc_OidGetHash(pkcs7->hashOID);
wolfSSL 16:8e0d178b1d1e 3355 ret = wc_HashGetDigestSize(hashType);
wolfSSL 16:8e0d178b1d1e 3356 if (ret < 0)
wolfSSL 16:8e0d178b1d1e 3357 return ret;
wolfSSL 16:8e0d178b1d1e 3358 hashSz = ret;
wolfSSL 16:8e0d178b1d1e 3359
wolfSSL 16:8e0d178b1d1e 3360 if (signedAttribSz > 0) {
wolfSSL 16:8e0d178b1d1e 3361 if (signedAttrib == NULL)
wolfSSL 16:8e0d178b1d1e 3362 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 3363 }
wolfSSL 16:8e0d178b1d1e 3364 else {
wolfSSL 16:8e0d178b1d1e 3365 if (hashBuf && hashBufSz > 0) {
wolfSSL 16:8e0d178b1d1e 3366 if (hashSz != hashBufSz)
wolfSSL 16:8e0d178b1d1e 3367 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 3368 }
wolfSSL 16:8e0d178b1d1e 3369 else if (pkcs7->content == NULL)
wolfSSL 16:8e0d178b1d1e 3370 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 3371 }
wolfSSL 16:8e0d178b1d1e 3372
wolfSSL 15:117db924cf7c 3373 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 3374 digestInfo = (byte*)XMALLOC(MAX_PKCS7_DIGEST_SZ, pkcs7->heap,
wolfSSL 15:117db924cf7c 3375 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3376 if (digestInfo == NULL)
wolfSSL 15:117db924cf7c 3377 return MEMORY_E;
wolfSSL 15:117db924cf7c 3378 #endif
wolfSSL 15:117db924cf7c 3379
wolfSSL 15:117db924cf7c 3380 XMEMSET(pkcs7Digest, 0, *pkcs7DigestSz);
wolfSSL 15:117db924cf7c 3381 XMEMSET(digest, 0, WC_MAX_DIGEST_SIZE);
wolfSSL 15:117db924cf7c 3382 XMEMSET(digestInfo, 0, MAX_PKCS7_DIGEST_SZ);
wolfSSL 15:117db924cf7c 3383
wolfSSL 15:117db924cf7c 3384
wolfSSL 15:117db924cf7c 3385 /* calculate digest */
wolfSSL 16:8e0d178b1d1e 3386 if (hashBuf && hashBufSz > 0 && signedAttribSz == 0) {
wolfSSL 16:8e0d178b1d1e 3387 XMEMCPY(digest, hashBuf, hashBufSz);
wolfSSL 16:8e0d178b1d1e 3388 }
wolfSSL 16:8e0d178b1d1e 3389 else {
wolfSSL 16:8e0d178b1d1e 3390 ret = wc_HashInit(&hash, hashType);
wolfSSL 16:8e0d178b1d1e 3391 if (ret < 0) {
wolfSSL 16:8e0d178b1d1e 3392 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 3393 XFREE(digestInfo, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 3394 #endif
wolfSSL 15:117db924cf7c 3395 return ret;
wolfSSL 15:117db924cf7c 3396 }
wolfSSL 15:117db924cf7c 3397
wolfSSL 16:8e0d178b1d1e 3398 if (signedAttribSz > 0) {
wolfSSL 16:8e0d178b1d1e 3399 attribSetSz = SetSet(signedAttribSz, attribSet);
wolfSSL 16:8e0d178b1d1e 3400
wolfSSL 16:8e0d178b1d1e 3401 /* calculate digest */
wolfSSL 16:8e0d178b1d1e 3402 ret = wc_HashUpdate(&hash, hashType, attribSet, attribSetSz);
wolfSSL 16:8e0d178b1d1e 3403 if (ret == 0)
wolfSSL 16:8e0d178b1d1e 3404 ret = wc_HashUpdate(&hash, hashType, signedAttrib, signedAttribSz);
wolfSSL 16:8e0d178b1d1e 3405 if (ret == 0)
wolfSSL 16:8e0d178b1d1e 3406 ret = wc_HashFinal(&hash, hashType, digest);
wolfSSL 16:8e0d178b1d1e 3407 } else {
wolfSSL 16:8e0d178b1d1e 3408 ret = wc_HashUpdate(&hash, hashType, pkcs7->content, pkcs7->contentSz);
wolfSSL 16:8e0d178b1d1e 3409 if (ret == 0)
wolfSSL 16:8e0d178b1d1e 3410 ret = wc_HashFinal(&hash, hashType, digest);
wolfSSL 16:8e0d178b1d1e 3411 }
wolfSSL 16:8e0d178b1d1e 3412
wolfSSL 16:8e0d178b1d1e 3413 wc_HashFree(&hash, hashType);
wolfSSL 15:117db924cf7c 3414 if (ret < 0) {
wolfSSL 16:8e0d178b1d1e 3415 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 3416 XFREE(digestInfo, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 3417 #endif
wolfSSL 15:117db924cf7c 3418 return ret;
wolfSSL 15:117db924cf7c 3419 }
wolfSSL 15:117db924cf7c 3420 }
wolfSSL 15:117db924cf7c 3421
wolfSSL 15:117db924cf7c 3422 /* Set algoID, with NULL attributes */
wolfSSL 15:117db924cf7c 3423 algoIdSz = SetAlgoID(pkcs7->hashOID, algoId, oidHashType, 0);
wolfSSL 15:117db924cf7c 3424
wolfSSL 15:117db924cf7c 3425 digestStrSz = SetOctetString(hashSz, digestStr);
wolfSSL 15:117db924cf7c 3426 digestInfoSeqSz = SetSequence(algoIdSz + digestStrSz + hashSz,
wolfSSL 15:117db924cf7c 3427 digestInfoSeq);
wolfSSL 15:117db924cf7c 3428
wolfSSL 15:117db924cf7c 3429 XMEMCPY(digestInfo + digIdx, digestInfoSeq, digestInfoSeqSz);
wolfSSL 15:117db924cf7c 3430 digIdx += digestInfoSeqSz;
wolfSSL 15:117db924cf7c 3431 XMEMCPY(digestInfo + digIdx, algoId, algoIdSz);
wolfSSL 15:117db924cf7c 3432 digIdx += algoIdSz;
wolfSSL 15:117db924cf7c 3433 XMEMCPY(digestInfo + digIdx, digestStr, digestStrSz);
wolfSSL 15:117db924cf7c 3434 digIdx += digestStrSz;
wolfSSL 15:117db924cf7c 3435 XMEMCPY(digestInfo + digIdx, digest, hashSz);
wolfSSL 15:117db924cf7c 3436 digIdx += hashSz;
wolfSSL 15:117db924cf7c 3437
wolfSSL 15:117db924cf7c 3438 XMEMCPY(pkcs7Digest, digestInfo, digIdx);
wolfSSL 15:117db924cf7c 3439 *pkcs7DigestSz = digIdx;
wolfSSL 15:117db924cf7c 3440
wolfSSL 15:117db924cf7c 3441 /* set plain digest pointer */
wolfSSL 15:117db924cf7c 3442 *plainDigest = pkcs7Digest + digIdx - hashSz;
wolfSSL 15:117db924cf7c 3443 *plainDigestSz = hashSz;
wolfSSL 15:117db924cf7c 3444
wolfSSL 15:117db924cf7c 3445 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 3446 XFREE(digestInfo, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3447 #endif
wolfSSL 15:117db924cf7c 3448 return 0;
wolfSSL 15:117db924cf7c 3449 }
wolfSSL 15:117db924cf7c 3450
wolfSSL 15:117db924cf7c 3451
wolfSSL 16:8e0d178b1d1e 3452 /* Verifies CMS/PKCS7 SignedData content digest matches that which is
wolfSSL 16:8e0d178b1d1e 3453 * included in the messageDigest signed attribute. Only called when
wolfSSL 16:8e0d178b1d1e 3454 * signed attributes are present, otherwise original signature verification
wolfSSL 16:8e0d178b1d1e 3455 * is done over content.
wolfSSL 16:8e0d178b1d1e 3456 *
wolfSSL 16:8e0d178b1d1e 3457 * pkcs7 - pointer to initialized PKCS7 struct
wolfSSL 16:8e0d178b1d1e 3458 * hashBuf - pointer to user-provided hash buffer, used with
wolfSSL 16:8e0d178b1d1e 3459 * wc_PKCS7_VerifySignedData_ex()
wolfSSL 16:8e0d178b1d1e 3460 * hashBufSz - size of hashBuf, octets
wolfSSL 16:8e0d178b1d1e 3461 *
wolfSSL 16:8e0d178b1d1e 3462 * return 0 on success, negative on error */
wolfSSL 16:8e0d178b1d1e 3463 static int wc_PKCS7_VerifyContentMessageDigest(PKCS7* pkcs7,
wolfSSL 16:8e0d178b1d1e 3464 const byte* hashBuf,
wolfSSL 16:8e0d178b1d1e 3465 word32 hashSz)
wolfSSL 16:8e0d178b1d1e 3466 {
wolfSSL 16:8e0d178b1d1e 3467 int ret = 0, digestSz = 0, innerAttribSz = 0;
wolfSSL 16:8e0d178b1d1e 3468 word32 idx = 0;
wolfSSL 16:8e0d178b1d1e 3469 byte* digestBuf = NULL;
wolfSSL 16:8e0d178b1d1e 3470 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 3471 byte* digest = NULL;
wolfSSL 16:8e0d178b1d1e 3472 #else
wolfSSL 16:8e0d178b1d1e 3473 byte digest[MAX_PKCS7_DIGEST_SZ];
wolfSSL 16:8e0d178b1d1e 3474 #endif
wolfSSL 16:8e0d178b1d1e 3475 PKCS7DecodedAttrib* attrib;
wolfSSL 16:8e0d178b1d1e 3476 enum wc_HashType hashType;
wolfSSL 16:8e0d178b1d1e 3477
wolfSSL 16:8e0d178b1d1e 3478 /* messageDigest OID (1.2.840.113549.1.9.4) */
wolfSSL 16:8e0d178b1d1e 3479 const byte mdOid[] =
wolfSSL 16:8e0d178b1d1e 3480 { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x04 };
wolfSSL 16:8e0d178b1d1e 3481
wolfSSL 16:8e0d178b1d1e 3482 if (pkcs7 == NULL)
wolfSSL 16:8e0d178b1d1e 3483 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 3484
wolfSSL 16:8e0d178b1d1e 3485 if ((pkcs7->content == NULL || pkcs7->contentSz == 0) &&
wolfSSL 16:8e0d178b1d1e 3486 (hashBuf == NULL || hashSz == 0)) {
wolfSSL 16:8e0d178b1d1e 3487 WOLFSSL_MSG("SignedData bundle has no content or hash to verify");
wolfSSL 16:8e0d178b1d1e 3488 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 3489 }
wolfSSL 16:8e0d178b1d1e 3490
wolfSSL 16:8e0d178b1d1e 3491 /* lookup messageDigest attribute */
wolfSSL 16:8e0d178b1d1e 3492 attrib = findAttrib(pkcs7, mdOid, sizeof(mdOid));
wolfSSL 16:8e0d178b1d1e 3493 if (attrib == NULL) {
wolfSSL 16:8e0d178b1d1e 3494 WOLFSSL_MSG("messageDigest attribute not in bundle, must be when "
wolfSSL 16:8e0d178b1d1e 3495 "signed attribs are present");
wolfSSL 16:8e0d178b1d1e 3496 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 3497 }
wolfSSL 16:8e0d178b1d1e 3498
wolfSSL 16:8e0d178b1d1e 3499 /* advance past attrib->value ASN.1 header and length */
wolfSSL 16:8e0d178b1d1e 3500 if (attrib->value == NULL || attrib->valueSz == 0)
wolfSSL 16:8e0d178b1d1e 3501 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 3502
wolfSSL 16:8e0d178b1d1e 3503 if (attrib->value[idx++] != ASN_OCTET_STRING)
wolfSSL 16:8e0d178b1d1e 3504 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 3505
wolfSSL 16:8e0d178b1d1e 3506 if (GetLength(attrib->value, &idx, &innerAttribSz, attrib->valueSz) < 0)
wolfSSL 16:8e0d178b1d1e 3507 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 3508
wolfSSL 16:8e0d178b1d1e 3509 /* get hash type and size */
wolfSSL 16:8e0d178b1d1e 3510 hashType = wc_OidGetHash(pkcs7->hashOID);
wolfSSL 16:8e0d178b1d1e 3511 if (hashType == WC_HASH_TYPE_NONE) {
wolfSSL 16:8e0d178b1d1e 3512 WOLFSSL_MSG("Error getting hash type for PKCS7 content verification");
wolfSSL 16:8e0d178b1d1e 3513 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 3514 }
wolfSSL 16:8e0d178b1d1e 3515
wolfSSL 16:8e0d178b1d1e 3516 /* build content hash if needed, or use existing hash value */
wolfSSL 16:8e0d178b1d1e 3517 if (hashBuf == NULL) {
wolfSSL 16:8e0d178b1d1e 3518
wolfSSL 16:8e0d178b1d1e 3519 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 3520 digest = (byte*)XMALLOC(MAX_PKCS7_DIGEST_SZ, pkcs7->heap,
wolfSSL 16:8e0d178b1d1e 3521 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 3522 if (digest == NULL)
wolfSSL 16:8e0d178b1d1e 3523 return MEMORY_E;
wolfSSL 16:8e0d178b1d1e 3524 #endif
wolfSSL 16:8e0d178b1d1e 3525 XMEMSET(digest, 0, MAX_PKCS7_DIGEST_SZ);
wolfSSL 16:8e0d178b1d1e 3526
wolfSSL 16:8e0d178b1d1e 3527 ret = wc_Hash(hashType, pkcs7->content, pkcs7->contentSz, digest,
wolfSSL 16:8e0d178b1d1e 3528 MAX_PKCS7_DIGEST_SZ);
wolfSSL 16:8e0d178b1d1e 3529 if (ret < 0) {
wolfSSL 16:8e0d178b1d1e 3530 WOLFSSL_MSG("Error hashing PKCS7 content for verification");
wolfSSL 16:8e0d178b1d1e 3531 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 3532 XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 3533 #endif
wolfSSL 16:8e0d178b1d1e 3534 return ret;
wolfSSL 16:8e0d178b1d1e 3535 }
wolfSSL 16:8e0d178b1d1e 3536
wolfSSL 16:8e0d178b1d1e 3537 digestBuf = digest;
wolfSSL 16:8e0d178b1d1e 3538 digestSz = wc_HashGetDigestSize(hashType);
wolfSSL 16:8e0d178b1d1e 3539 if (digestSz < 0) {
wolfSSL 16:8e0d178b1d1e 3540 WOLFSSL_MSG("Invalid hash type");
wolfSSL 16:8e0d178b1d1e 3541 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 3542 XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 3543 #endif
wolfSSL 16:8e0d178b1d1e 3544 return digestSz;
wolfSSL 16:8e0d178b1d1e 3545 }
wolfSSL 16:8e0d178b1d1e 3546 } else {
wolfSSL 16:8e0d178b1d1e 3547
wolfSSL 16:8e0d178b1d1e 3548 /* user passed in pre-computed hash */
wolfSSL 16:8e0d178b1d1e 3549 digestBuf = (byte*)hashBuf;
wolfSSL 16:8e0d178b1d1e 3550 digestSz = (int)hashSz;
wolfSSL 16:8e0d178b1d1e 3551 }
wolfSSL 16:8e0d178b1d1e 3552
wolfSSL 16:8e0d178b1d1e 3553 /* compare generated to hash in messageDigest attribute */
wolfSSL 16:8e0d178b1d1e 3554 if ((innerAttribSz != digestSz) ||
wolfSSL 16:8e0d178b1d1e 3555 (XMEMCMP(attrib->value + idx, digestBuf, (word32)digestSz) != 0)) {
wolfSSL 16:8e0d178b1d1e 3556 WOLFSSL_MSG("Content digest does not match messageDigest attrib value");
wolfSSL 16:8e0d178b1d1e 3557 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 3558 XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 3559 #endif
wolfSSL 16:8e0d178b1d1e 3560 return SIG_VERIFY_E;
wolfSSL 16:8e0d178b1d1e 3561 }
wolfSSL 16:8e0d178b1d1e 3562
wolfSSL 16:8e0d178b1d1e 3563 if (hashBuf == NULL) {
wolfSSL 16:8e0d178b1d1e 3564 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 3565 XFREE(digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 3566 #endif
wolfSSL 16:8e0d178b1d1e 3567 }
wolfSSL 16:8e0d178b1d1e 3568
wolfSSL 16:8e0d178b1d1e 3569 return 0;
wolfSSL 16:8e0d178b1d1e 3570 }
wolfSSL 16:8e0d178b1d1e 3571
wolfSSL 16:8e0d178b1d1e 3572
wolfSSL 15:117db924cf7c 3573 /* verifies SignedData signature, over either PKCS#7 DigestInfo or
wolfSSL 15:117db924cf7c 3574 * content digest.
wolfSSL 15:117db924cf7c 3575 *
wolfSSL 15:117db924cf7c 3576 * pkcs7 - pointer to initialized PKCS7 struct
wolfSSL 15:117db924cf7c 3577 * sig - signature to verify
wolfSSL 15:117db924cf7c 3578 * sigSz - size of sig
wolfSSL 15:117db924cf7c 3579 * signedAttrib - signed attributes, or null if empty
wolfSSL 15:117db924cf7c 3580 * signedAttribSz - size of signedAttributes
wolfSSL 15:117db924cf7c 3581 *
wolfSSL 15:117db924cf7c 3582 * return 0 on success, negative on error */
wolfSSL 15:117db924cf7c 3583 static int wc_PKCS7_SignedDataVerifySignature(PKCS7* pkcs7, byte* sig,
wolfSSL 16:8e0d178b1d1e 3584 word32 sigSz, byte* signedAttrib,
wolfSSL 16:8e0d178b1d1e 3585 word32 signedAttribSz,
wolfSSL 16:8e0d178b1d1e 3586 const byte* hashBuf, word32 hashSz)
wolfSSL 15:117db924cf7c 3587 {
wolfSSL 15:117db924cf7c 3588 int ret = 0;
wolfSSL 15:117db924cf7c 3589 word32 plainDigestSz = 0, pkcs7DigestSz;
wolfSSL 15:117db924cf7c 3590 byte* plainDigest = NULL; /* offset into pkcs7Digest */
wolfSSL 15:117db924cf7c 3591 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 3592 byte* pkcs7Digest;
wolfSSL 15:117db924cf7c 3593 #else
wolfSSL 15:117db924cf7c 3594 byte pkcs7Digest[MAX_PKCS7_DIGEST_SZ];
wolfSSL 15:117db924cf7c 3595 #endif
wolfSSL 15:117db924cf7c 3596
wolfSSL 15:117db924cf7c 3597 if (pkcs7 == NULL)
wolfSSL 15:117db924cf7c 3598 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 3599
wolfSSL 16:8e0d178b1d1e 3600 /* allocate space to build hash */
wolfSSL 16:8e0d178b1d1e 3601 pkcs7DigestSz = MAX_PKCS7_DIGEST_SZ;
wolfSSL 16:8e0d178b1d1e 3602 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 3603 pkcs7Digest = (byte*)XMALLOC(pkcs7DigestSz, pkcs7->heap,
wolfSSL 15:117db924cf7c 3604 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3605 if (pkcs7Digest == NULL)
wolfSSL 15:117db924cf7c 3606 return MEMORY_E;
wolfSSL 15:117db924cf7c 3607 #endif
wolfSSL 15:117db924cf7c 3608
wolfSSL 16:8e0d178b1d1e 3609 XMEMSET(pkcs7Digest, 0, pkcs7DigestSz);
wolfSSL 16:8e0d178b1d1e 3610
wolfSSL 16:8e0d178b1d1e 3611 /* verify signed attrib digest matches that of content */
wolfSSL 16:8e0d178b1d1e 3612 if (signedAttrib != NULL) {
wolfSSL 16:8e0d178b1d1e 3613 ret = wc_PKCS7_VerifyContentMessageDigest(pkcs7, hashBuf, hashSz);
wolfSSL 16:8e0d178b1d1e 3614 if (ret != 0) {
wolfSSL 16:8e0d178b1d1e 3615 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 3616 XFREE(pkcs7Digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 3617 #endif
wolfSSL 16:8e0d178b1d1e 3618 return ret;
wolfSSL 16:8e0d178b1d1e 3619 }
wolfSSL 16:8e0d178b1d1e 3620 }
wolfSSL 16:8e0d178b1d1e 3621
wolfSSL 15:117db924cf7c 3622 /* build hash to verify against */
wolfSSL 15:117db924cf7c 3623 ret = wc_PKCS7_BuildSignedDataDigest(pkcs7, signedAttrib,
wolfSSL 15:117db924cf7c 3624 signedAttribSz, pkcs7Digest,
wolfSSL 15:117db924cf7c 3625 &pkcs7DigestSz, &plainDigest,
wolfSSL 16:8e0d178b1d1e 3626 &plainDigestSz, hashBuf, hashSz);
wolfSSL 15:117db924cf7c 3627 if (ret < 0) {
wolfSSL 15:117db924cf7c 3628 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 3629 XFREE(pkcs7Digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3630 #endif
wolfSSL 15:117db924cf7c 3631 return ret;
wolfSSL 15:117db924cf7c 3632 }
wolfSSL 15:117db924cf7c 3633
wolfSSL 16:8e0d178b1d1e 3634 /* If no certificates are available then store the signature and hash for
wolfSSL 16:8e0d178b1d1e 3635 * user to verify. Make sure that different return value than success is
wolfSSL 16:8e0d178b1d1e 3636 * returned because the signature was not verified here. */
wolfSSL 16:8e0d178b1d1e 3637 if (ret == 0) {
wolfSSL 16:8e0d178b1d1e 3638 byte haveCert = 0;
wolfSSL 16:8e0d178b1d1e 3639 int i;
wolfSSL 16:8e0d178b1d1e 3640
wolfSSL 16:8e0d178b1d1e 3641 for (i = 0; i < MAX_PKCS7_CERTS; i++) {
wolfSSL 16:8e0d178b1d1e 3642 if (pkcs7->certSz[i] == 0)
wolfSSL 16:8e0d178b1d1e 3643 continue;
wolfSSL 16:8e0d178b1d1e 3644 haveCert = 1;
wolfSSL 16:8e0d178b1d1e 3645 }
wolfSSL 16:8e0d178b1d1e 3646
wolfSSL 16:8e0d178b1d1e 3647 if (!haveCert) {
wolfSSL 16:8e0d178b1d1e 3648 WOLFSSL_MSG("No certificates in bundle to verify signature");
wolfSSL 16:8e0d178b1d1e 3649
wolfSSL 16:8e0d178b1d1e 3650 /* store signature */
wolfSSL 16:8e0d178b1d1e 3651 XFREE(pkcs7->signature, pkcs7->heap, DYNAMIC_TYPE_SIGNATURE);
wolfSSL 16:8e0d178b1d1e 3652 pkcs7->signature = NULL;
wolfSSL 16:8e0d178b1d1e 3653 pkcs7->signatureSz = 0;
wolfSSL 16:8e0d178b1d1e 3654 pkcs7->signature = (byte*)XMALLOC(sigSz, pkcs7->heap,
wolfSSL 16:8e0d178b1d1e 3655 DYNAMIC_TYPE_SIGNATURE);
wolfSSL 16:8e0d178b1d1e 3656 if (pkcs7->signature == NULL) {
wolfSSL 16:8e0d178b1d1e 3657 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 3658 XFREE(pkcs7Digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 3659 #endif
wolfSSL 16:8e0d178b1d1e 3660 return MEMORY_E;
wolfSSL 16:8e0d178b1d1e 3661 }
wolfSSL 16:8e0d178b1d1e 3662 XMEMCPY(pkcs7->signature, sig, sigSz);
wolfSSL 16:8e0d178b1d1e 3663 pkcs7->signatureSz = sigSz;
wolfSSL 16:8e0d178b1d1e 3664
wolfSSL 16:8e0d178b1d1e 3665 /* store plain digest (CMS and ECC) */
wolfSSL 16:8e0d178b1d1e 3666 XFREE(pkcs7->plainDigest, pkcs7->heap, DYNAMIC_TYPE_DIGEST);
wolfSSL 16:8e0d178b1d1e 3667 pkcs7->plainDigest = NULL;
wolfSSL 16:8e0d178b1d1e 3668 pkcs7->plainDigestSz = 0;
wolfSSL 16:8e0d178b1d1e 3669 pkcs7->plainDigest = (byte*)XMALLOC(plainDigestSz, pkcs7->heap,
wolfSSL 16:8e0d178b1d1e 3670 DYNAMIC_TYPE_DIGEST);
wolfSSL 16:8e0d178b1d1e 3671 if (pkcs7->plainDigest == NULL) {
wolfSSL 16:8e0d178b1d1e 3672 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 3673 XFREE(pkcs7Digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 3674 #endif
wolfSSL 16:8e0d178b1d1e 3675 return MEMORY_E;
wolfSSL 16:8e0d178b1d1e 3676 }
wolfSSL 16:8e0d178b1d1e 3677 XMEMCPY(pkcs7->plainDigest, plainDigest, plainDigestSz);
wolfSSL 16:8e0d178b1d1e 3678 pkcs7->plainDigestSz = plainDigestSz;
wolfSSL 16:8e0d178b1d1e 3679
wolfSSL 16:8e0d178b1d1e 3680 /* store pkcs7 digest (default RSA) */
wolfSSL 16:8e0d178b1d1e 3681 XFREE(pkcs7->pkcs7Digest, pkcs7->heap, DYNAMIC_TYPE_DIGEST);
wolfSSL 16:8e0d178b1d1e 3682 pkcs7->pkcs7Digest = NULL;
wolfSSL 16:8e0d178b1d1e 3683 pkcs7->pkcs7DigestSz = 0;
wolfSSL 16:8e0d178b1d1e 3684 pkcs7->pkcs7Digest = (byte*)XMALLOC(pkcs7DigestSz, pkcs7->heap,
wolfSSL 16:8e0d178b1d1e 3685 DYNAMIC_TYPE_DIGEST);
wolfSSL 16:8e0d178b1d1e 3686 if (pkcs7->pkcs7Digest == NULL) {
wolfSSL 16:8e0d178b1d1e 3687 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 3688 XFREE(pkcs7Digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 3689 #endif
wolfSSL 16:8e0d178b1d1e 3690 return MEMORY_E;
wolfSSL 16:8e0d178b1d1e 3691 }
wolfSSL 16:8e0d178b1d1e 3692 XMEMCPY(pkcs7->pkcs7Digest, pkcs7Digest, pkcs7DigestSz);
wolfSSL 16:8e0d178b1d1e 3693 pkcs7->pkcs7DigestSz = pkcs7DigestSz;
wolfSSL 16:8e0d178b1d1e 3694
wolfSSL 16:8e0d178b1d1e 3695 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 3696 XFREE(pkcs7Digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 3697 #endif
wolfSSL 16:8e0d178b1d1e 3698 return PKCS7_SIGNEEDS_CHECK;
wolfSSL 16:8e0d178b1d1e 3699 }
wolfSSL 16:8e0d178b1d1e 3700 }
wolfSSL 16:8e0d178b1d1e 3701
wolfSSL 16:8e0d178b1d1e 3702
wolfSSL 16:8e0d178b1d1e 3703
wolfSSL 15:117db924cf7c 3704 switch (pkcs7->publicKeyOID) {
wolfSSL 15:117db924cf7c 3705
wolfSSL 15:117db924cf7c 3706 #ifndef NO_RSA
wolfSSL 15:117db924cf7c 3707 case RSAk:
wolfSSL 15:117db924cf7c 3708 ret = wc_PKCS7_RsaVerify(pkcs7, sig, sigSz, pkcs7Digest,
wolfSSL 15:117db924cf7c 3709 pkcs7DigestSz);
wolfSSL 15:117db924cf7c 3710 if (ret < 0) {
wolfSSL 15:117db924cf7c 3711 WOLFSSL_MSG("PKCS#7 verification failed, trying CMS");
wolfSSL 15:117db924cf7c 3712 ret = wc_PKCS7_RsaVerify(pkcs7, sig, sigSz, plainDigest,
wolfSSL 15:117db924cf7c 3713 plainDigestSz);
wolfSSL 15:117db924cf7c 3714 }
wolfSSL 15:117db924cf7c 3715 break;
wolfSSL 15:117db924cf7c 3716 #endif
wolfSSL 15:117db924cf7c 3717
wolfSSL 15:117db924cf7c 3718 #ifdef HAVE_ECC
wolfSSL 15:117db924cf7c 3719 case ECDSAk:
wolfSSL 15:117db924cf7c 3720 ret = wc_PKCS7_EcdsaVerify(pkcs7, sig, sigSz, plainDigest,
wolfSSL 15:117db924cf7c 3721 plainDigestSz);
wolfSSL 15:117db924cf7c 3722 break;
wolfSSL 15:117db924cf7c 3723 #endif
wolfSSL 15:117db924cf7c 3724
wolfSSL 15:117db924cf7c 3725 default:
wolfSSL 15:117db924cf7c 3726 WOLFSSL_MSG("Unsupported public key type");
wolfSSL 15:117db924cf7c 3727 ret = BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 3728 }
wolfSSL 15:117db924cf7c 3729
wolfSSL 15:117db924cf7c 3730 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 3731 XFREE(pkcs7Digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 3732 #endif
wolfSSL 15:117db924cf7c 3733 return ret;
wolfSSL 15:117db924cf7c 3734 }
wolfSSL 15:117db924cf7c 3735
wolfSSL 15:117db924cf7c 3736
wolfSSL 15:117db924cf7c 3737 /* set correct public key OID based on signature OID, stores in
wolfSSL 15:117db924cf7c 3738 * pkcs7->publicKeyOID and returns same value */
wolfSSL 15:117db924cf7c 3739 static int wc_PKCS7_SetPublicKeyOID(PKCS7* pkcs7, int sigOID)
wolfSSL 15:117db924cf7c 3740 {
wolfSSL 15:117db924cf7c 3741 if (pkcs7 == NULL)
wolfSSL 15:117db924cf7c 3742 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 3743
wolfSSL 15:117db924cf7c 3744 pkcs7->publicKeyOID = 0;
wolfSSL 15:117db924cf7c 3745
wolfSSL 15:117db924cf7c 3746 switch (sigOID) {
wolfSSL 15:117db924cf7c 3747
wolfSSL 15:117db924cf7c 3748 #ifndef NO_RSA
wolfSSL 15:117db924cf7c 3749 /* RSA signature types */
wolfSSL 15:117db924cf7c 3750 case CTC_MD2wRSA:
wolfSSL 15:117db924cf7c 3751 case CTC_MD5wRSA:
wolfSSL 15:117db924cf7c 3752 case CTC_SHAwRSA:
wolfSSL 15:117db924cf7c 3753 case CTC_SHA224wRSA:
wolfSSL 15:117db924cf7c 3754 case CTC_SHA256wRSA:
wolfSSL 15:117db924cf7c 3755 case CTC_SHA384wRSA:
wolfSSL 15:117db924cf7c 3756 case CTC_SHA512wRSA:
wolfSSL 15:117db924cf7c 3757 pkcs7->publicKeyOID = RSAk;
wolfSSL 15:117db924cf7c 3758 break;
wolfSSL 15:117db924cf7c 3759
wolfSSL 15:117db924cf7c 3760 /* if sigOID is already RSAk */
wolfSSL 15:117db924cf7c 3761 case RSAk:
wolfSSL 15:117db924cf7c 3762 pkcs7->publicKeyOID = sigOID;
wolfSSL 15:117db924cf7c 3763 break;
wolfSSL 15:117db924cf7c 3764 #endif
wolfSSL 15:117db924cf7c 3765
wolfSSL 15:117db924cf7c 3766 #ifndef NO_DSA
wolfSSL 15:117db924cf7c 3767 /* DSA signature types */
wolfSSL 15:117db924cf7c 3768 case CTC_SHAwDSA:
wolfSSL 15:117db924cf7c 3769 pkcs7->publicKeyOID = DSAk;
wolfSSL 15:117db924cf7c 3770 break;
wolfSSL 15:117db924cf7c 3771
wolfSSL 15:117db924cf7c 3772 /* if sigOID is already DSAk */
wolfSSL 15:117db924cf7c 3773 case DSAk:
wolfSSL 15:117db924cf7c 3774 pkcs7->publicKeyOID = sigOID;
wolfSSL 15:117db924cf7c 3775 break;
wolfSSL 15:117db924cf7c 3776 #endif
wolfSSL 15:117db924cf7c 3777
wolfSSL 15:117db924cf7c 3778 #ifdef HAVE_ECC
wolfSSL 15:117db924cf7c 3779 /* ECDSA signature types */
wolfSSL 15:117db924cf7c 3780 case CTC_SHAwECDSA:
wolfSSL 15:117db924cf7c 3781 case CTC_SHA224wECDSA:
wolfSSL 15:117db924cf7c 3782 case CTC_SHA256wECDSA:
wolfSSL 15:117db924cf7c 3783 case CTC_SHA384wECDSA:
wolfSSL 15:117db924cf7c 3784 case CTC_SHA512wECDSA:
wolfSSL 15:117db924cf7c 3785 pkcs7->publicKeyOID = ECDSAk;
wolfSSL 15:117db924cf7c 3786 break;
wolfSSL 15:117db924cf7c 3787
wolfSSL 15:117db924cf7c 3788 /* if sigOID is already ECDSAk */
wolfSSL 15:117db924cf7c 3789 case ECDSAk:
wolfSSL 15:117db924cf7c 3790 pkcs7->publicKeyOID = sigOID;
wolfSSL 15:117db924cf7c 3791 break;
wolfSSL 15:117db924cf7c 3792 #endif
wolfSSL 15:117db924cf7c 3793
wolfSSL 15:117db924cf7c 3794 default:
wolfSSL 15:117db924cf7c 3795 WOLFSSL_MSG("Unsupported public key algorithm");
wolfSSL 15:117db924cf7c 3796 return ASN_SIG_KEY_E;
wolfSSL 15:117db924cf7c 3797 }
wolfSSL 15:117db924cf7c 3798
wolfSSL 15:117db924cf7c 3799 return pkcs7->publicKeyOID;
wolfSSL 15:117db924cf7c 3800 }
wolfSSL 15:117db924cf7c 3801
wolfSSL 15:117db924cf7c 3802
wolfSSL 15:117db924cf7c 3803 /* Parses through the attributes and adds them to the PKCS7 structure
wolfSSL 15:117db924cf7c 3804 * Creates dynamic attribute structures that are free'd with calling
wolfSSL 15:117db924cf7c 3805 * wc_PKCS7_Free()
wolfSSL 15:117db924cf7c 3806 *
wolfSSL 15:117db924cf7c 3807 * NOTE: An attribute has the ASN1 format of
wolfSSL 15:117db924cf7c 3808 ** Sequence
wolfSSL 15:117db924cf7c 3809 ****** Object ID
wolfSSL 15:117db924cf7c 3810 ****** Set
wolfSSL 15:117db924cf7c 3811 ********** {PritnableString, UTCTime, OCTET STRING ...}
wolfSSL 15:117db924cf7c 3812 *
wolfSSL 15:117db924cf7c 3813 * pkcs7 the PKCS7 structure to put the parsed attributes into
wolfSSL 15:117db924cf7c 3814 * in buffer holding all attributes
wolfSSL 15:117db924cf7c 3815 * inSz size of in buffer
wolfSSL 15:117db924cf7c 3816 *
wolfSSL 15:117db924cf7c 3817 * returns the number of attributes parsed on success
wolfSSL 15:117db924cf7c 3818 */
wolfSSL 15:117db924cf7c 3819 static int wc_PKCS7_ParseAttribs(PKCS7* pkcs7, byte* in, int inSz)
wolfSSL 15:117db924cf7c 3820 {
wolfSSL 15:117db924cf7c 3821 int found = 0;
wolfSSL 15:117db924cf7c 3822 word32 idx = 0;
wolfSSL 15:117db924cf7c 3823 word32 oid;
wolfSSL 15:117db924cf7c 3824
wolfSSL 15:117db924cf7c 3825 if (pkcs7 == NULL || in == NULL || inSz < 0) {
wolfSSL 15:117db924cf7c 3826 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 3827 }
wolfSSL 15:117db924cf7c 3828
wolfSSL 15:117db924cf7c 3829 while (idx < (word32)inSz) {
wolfSSL 15:117db924cf7c 3830 int length = 0;
wolfSSL 15:117db924cf7c 3831 int oidIdx;
wolfSSL 15:117db924cf7c 3832 PKCS7DecodedAttrib* attrib;
wolfSSL 15:117db924cf7c 3833
wolfSSL 15:117db924cf7c 3834 if (GetSequence(in, &idx, &length, inSz) < 0)
wolfSSL 15:117db924cf7c 3835 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 3836
wolfSSL 15:117db924cf7c 3837 attrib = (PKCS7DecodedAttrib*)XMALLOC(sizeof(PKCS7DecodedAttrib),
wolfSSL 15:117db924cf7c 3838 pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 3839 if (attrib == NULL) {
wolfSSL 15:117db924cf7c 3840 return MEMORY_E;
wolfSSL 15:117db924cf7c 3841 }
wolfSSL 15:117db924cf7c 3842 XMEMSET(attrib, 0, sizeof(PKCS7DecodedAttrib));
wolfSSL 15:117db924cf7c 3843
wolfSSL 15:117db924cf7c 3844 oidIdx = idx;
wolfSSL 15:117db924cf7c 3845 if (GetObjectId(in, &idx, &oid, oidIgnoreType, inSz)
wolfSSL 15:117db924cf7c 3846 < 0) {
wolfSSL 15:117db924cf7c 3847 XFREE(attrib, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 3848 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 3849 }
wolfSSL 15:117db924cf7c 3850 attrib->oidSz = idx - oidIdx;
wolfSSL 15:117db924cf7c 3851 attrib->oid = (byte*)XMALLOC(attrib->oidSz, pkcs7->heap,
wolfSSL 15:117db924cf7c 3852 DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 3853 if (attrib->oid == NULL) {
wolfSSL 15:117db924cf7c 3854 XFREE(attrib, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 3855 return MEMORY_E;
wolfSSL 15:117db924cf7c 3856 }
wolfSSL 15:117db924cf7c 3857 XMEMCPY(attrib->oid, in + oidIdx, attrib->oidSz);
wolfSSL 15:117db924cf7c 3858
wolfSSL 15:117db924cf7c 3859 /* Get Set that contains the printable string value */
wolfSSL 15:117db924cf7c 3860 if (GetSet(in, &idx, &length, inSz) < 0) {
wolfSSL 15:117db924cf7c 3861 XFREE(attrib->oid, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 3862 XFREE(attrib, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 3863 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 3864 }
wolfSSL 15:117db924cf7c 3865
wolfSSL 15:117db924cf7c 3866 if ((inSz - idx) < (word32)length) {
wolfSSL 15:117db924cf7c 3867 XFREE(attrib->oid, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 3868 XFREE(attrib, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 3869 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 3870 }
wolfSSL 15:117db924cf7c 3871
wolfSSL 15:117db924cf7c 3872 attrib->valueSz = (word32)length;
wolfSSL 15:117db924cf7c 3873 attrib->value = (byte*)XMALLOC(attrib->valueSz, pkcs7->heap,
wolfSSL 15:117db924cf7c 3874 DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 3875 if (attrib->value == NULL) {
wolfSSL 15:117db924cf7c 3876 XFREE(attrib->oid, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 3877 XFREE(attrib, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 3878 return MEMORY_E;
wolfSSL 15:117db924cf7c 3879 }
wolfSSL 15:117db924cf7c 3880 XMEMCPY(attrib->value, in + idx, attrib->valueSz);
wolfSSL 15:117db924cf7c 3881 idx += length;
wolfSSL 15:117db924cf7c 3882
wolfSSL 15:117db924cf7c 3883 /* store attribute in linked list */
wolfSSL 15:117db924cf7c 3884 if (pkcs7->decodedAttrib != NULL) {
wolfSSL 15:117db924cf7c 3885 attrib->next = pkcs7->decodedAttrib;
wolfSSL 15:117db924cf7c 3886 pkcs7->decodedAttrib = attrib;
wolfSSL 15:117db924cf7c 3887 } else {
wolfSSL 15:117db924cf7c 3888 pkcs7->decodedAttrib = attrib;
wolfSSL 15:117db924cf7c 3889 }
wolfSSL 15:117db924cf7c 3890 found++;
wolfSSL 15:117db924cf7c 3891 }
wolfSSL 15:117db924cf7c 3892
wolfSSL 15:117db924cf7c 3893 return found;
wolfSSL 15:117db924cf7c 3894 }
wolfSSL 15:117db924cf7c 3895
wolfSSL 15:117db924cf7c 3896
wolfSSL 16:8e0d178b1d1e 3897 /* option to turn off support for degenerate cases
wolfSSL 16:8e0d178b1d1e 3898 * flag 0 turns off support
wolfSSL 16:8e0d178b1d1e 3899 * flag 1 turns on support
wolfSSL 16:8e0d178b1d1e 3900 *
wolfSSL 16:8e0d178b1d1e 3901 * by default support for SignedData degenerate cases is on
wolfSSL 16:8e0d178b1d1e 3902 */
wolfSSL 16:8e0d178b1d1e 3903 void wc_PKCS7_AllowDegenerate(PKCS7* pkcs7, word16 flag)
wolfSSL 16:8e0d178b1d1e 3904 {
wolfSSL 16:8e0d178b1d1e 3905 if (pkcs7) {
wolfSSL 16:8e0d178b1d1e 3906 if (flag) { /* flag of 1 turns on support for degenerate */
wolfSSL 16:8e0d178b1d1e 3907 pkcs7->noDegenerate = 0;
wolfSSL 16:8e0d178b1d1e 3908 }
wolfSSL 16:8e0d178b1d1e 3909 else { /* flag of 0 turns off support */
wolfSSL 16:8e0d178b1d1e 3910 pkcs7->noDegenerate = 1;
wolfSSL 16:8e0d178b1d1e 3911 }
wolfSSL 16:8e0d178b1d1e 3912 }
wolfSSL 16:8e0d178b1d1e 3913 }
wolfSSL 16:8e0d178b1d1e 3914
wolfSSL 16:8e0d178b1d1e 3915 /* Parses through a signerInfo set. Reads buffer "in" from "idxIn" to "idxIn" +
wolfSSL 16:8e0d178b1d1e 3916 * length treating the current "idxIn" plus the length of set as max possible
wolfSSL 16:8e0d178b1d1e 3917 * index.
wolfSSL 16:8e0d178b1d1e 3918 *
wolfSSL 16:8e0d178b1d1e 3919 * In the case that signed attributes are found "signedAttrib" gets set to point
wolfSSL 16:8e0d178b1d1e 3920 * at their location in the buffer "in". Also in this case signedAttribSz gets
wolfSSL 16:8e0d178b1d1e 3921 * set to the size of the signedAttrib buffer.
wolfSSL 16:8e0d178b1d1e 3922 *
wolfSSL 16:8e0d178b1d1e 3923 * returns 0 on success
wolfSSL 16:8e0d178b1d1e 3924 */
wolfSSL 16:8e0d178b1d1e 3925 static int wc_PKCS7_ParseSignerInfo(PKCS7* pkcs7, byte* in, word32 inSz,
wolfSSL 16:8e0d178b1d1e 3926 word32* idxIn, int degenerate, byte** signedAttrib, int* signedAttribSz)
wolfSSL 16:8e0d178b1d1e 3927 {
wolfSSL 16:8e0d178b1d1e 3928 int ret = 0;
wolfSSL 16:8e0d178b1d1e 3929 int length;
wolfSSL 16:8e0d178b1d1e 3930 int version;
wolfSSL 16:8e0d178b1d1e 3931 word32 sigOID = 0, hashOID = 0;
wolfSSL 16:8e0d178b1d1e 3932 word32 idx = *idxIn, localIdx;
wolfSSL 16:8e0d178b1d1e 3933 byte tag;
wolfSSL 16:8e0d178b1d1e 3934
wolfSSL 16:8e0d178b1d1e 3935 WOLFSSL_ENTER("wc_PKCS7_ParseSignerInfo");
wolfSSL 16:8e0d178b1d1e 3936 /* require a signer if degenerate case not allowed */
wolfSSL 16:8e0d178b1d1e 3937 if (inSz == 0 && pkcs7->noDegenerate == 1) {
wolfSSL 16:8e0d178b1d1e 3938 WOLFSSL_MSG("Set to not allow degenerate cases");
wolfSSL 16:8e0d178b1d1e 3939 return PKCS7_NO_SIGNER_E;
wolfSSL 16:8e0d178b1d1e 3940 }
wolfSSL 16:8e0d178b1d1e 3941
wolfSSL 16:8e0d178b1d1e 3942 if (inSz == 0 && degenerate == 0) {
wolfSSL 16:8e0d178b1d1e 3943 WOLFSSL_MSG("PKCS7 signers expected");
wolfSSL 16:8e0d178b1d1e 3944 return PKCS7_NO_SIGNER_E;
wolfSSL 16:8e0d178b1d1e 3945 }
wolfSSL 16:8e0d178b1d1e 3946
wolfSSL 16:8e0d178b1d1e 3947 /* not a degenerate case and there is elements in the set */
wolfSSL 16:8e0d178b1d1e 3948 if (inSz > 0 && degenerate == 0) {
wolfSSL 16:8e0d178b1d1e 3949 ret = wc_PKCS7_SignerInfoNew(pkcs7);
wolfSSL 16:8e0d178b1d1e 3950
wolfSSL 16:8e0d178b1d1e 3951 /* Get the sequence of the first signerInfo */
wolfSSL 16:8e0d178b1d1e 3952 if (ret == 0 && GetSequence(in, &idx, &length, inSz) < 0)
wolfSSL 15:117db924cf7c 3953 ret = ASN_PARSE_E;
wolfSSL 15:117db924cf7c 3954
wolfSSL 15:117db924cf7c 3955 /* Get the version */
wolfSSL 16:8e0d178b1d1e 3956 if (ret == 0 && GetMyVersion(in, &idx, &version, inSz) < 0)
wolfSSL 16:8e0d178b1d1e 3957 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 3958
wolfSSL 16:8e0d178b1d1e 3959 if (ret == 0) {
wolfSSL 16:8e0d178b1d1e 3960 pkcs7->signerInfo->version = version;
wolfSSL 16:8e0d178b1d1e 3961 }
wolfSSL 16:8e0d178b1d1e 3962
wolfSSL 16:8e0d178b1d1e 3963 if (ret == 0 && version == 1) {
wolfSSL 16:8e0d178b1d1e 3964 /* Get the sequence of IssuerAndSerialNumber */
wolfSSL 16:8e0d178b1d1e 3965 if (GetSequence(in, &idx, &length, inSz) < 0)
wolfSSL 16:8e0d178b1d1e 3966 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 3967
wolfSSL 16:8e0d178b1d1e 3968 if (ret == 0) {
wolfSSL 16:8e0d178b1d1e 3969 ret = wc_PKCS7_SignerInfoSetSID(pkcs7, in + idx, length);
wolfSSL 16:8e0d178b1d1e 3970 idx += length;
wolfSSL 16:8e0d178b1d1e 3971 }
wolfSSL 16:8e0d178b1d1e 3972
wolfSSL 16:8e0d178b1d1e 3973 } else if (ret == 0 && version == 3) {
wolfSSL 16:8e0d178b1d1e 3974 /* Get the sequence of SubjectKeyIdentifier */
wolfSSL 16:8e0d178b1d1e 3975 if (idx + 1 > inSz)
wolfSSL 16:8e0d178b1d1e 3976 ret = BUFFER_E;
wolfSSL 16:8e0d178b1d1e 3977
wolfSSL 16:8e0d178b1d1e 3978 localIdx = idx;
wolfSSL 16:8e0d178b1d1e 3979 if (ret == 0 && GetASNTag(in, &localIdx, &tag, inSz) == 0 &&
wolfSSL 16:8e0d178b1d1e 3980 tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) {
wolfSSL 16:8e0d178b1d1e 3981 idx++;
wolfSSL 16:8e0d178b1d1e 3982
wolfSSL 16:8e0d178b1d1e 3983 if (GetLength(in, &idx, &length, inSz) <= 0)
wolfSSL 16:8e0d178b1d1e 3984 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 3985
wolfSSL 16:8e0d178b1d1e 3986 if (ret == 0 && idx + 1 > inSz)
wolfSSL 16:8e0d178b1d1e 3987 ret = BUFFER_E;
wolfSSL 16:8e0d178b1d1e 3988
wolfSSL 16:8e0d178b1d1e 3989 if (ret == 0 && GetASNTag(in, &idx, &tag, inSz) < 0)
wolfSSL 16:8e0d178b1d1e 3990 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 3991
wolfSSL 16:8e0d178b1d1e 3992 if (ret == 0 && tag != ASN_OCTET_STRING)
wolfSSL 16:8e0d178b1d1e 3993 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 3994
wolfSSL 16:8e0d178b1d1e 3995 if (ret == 0 && GetLength(in, &idx, &length, inSz) < 0)
wolfSSL 16:8e0d178b1d1e 3996 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 3997 }
wolfSSL 16:8e0d178b1d1e 3998 else {
wolfSSL 16:8e0d178b1d1e 3999 /* check if SKID with ASN_CONTEXT_SPECIFIC otherwise in version
wolfSSL 16:8e0d178b1d1e 4000 * 3 try to get issuerAndSerial */
wolfSSL 16:8e0d178b1d1e 4001 localIdx = idx;
wolfSSL 16:8e0d178b1d1e 4002 if (GetASNTag(in, &localIdx, &tag, inSz) == 0 &&
wolfSSL 16:8e0d178b1d1e 4003 tag == ASN_CONTEXT_SPECIFIC) {
wolfSSL 16:8e0d178b1d1e 4004 idx++;
wolfSSL 16:8e0d178b1d1e 4005 if (ret == 0 && GetLength(in, &idx, &length, inSz) < 0)
wolfSSL 16:8e0d178b1d1e 4006 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 4007 }
wolfSSL 16:8e0d178b1d1e 4008 else {
wolfSSL 16:8e0d178b1d1e 4009 if (pkcs7->version != 3) {
wolfSSL 16:8e0d178b1d1e 4010 WOLFSSL_MSG("Unexpected signer info found with version");
wolfSSL 16:8e0d178b1d1e 4011 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 4012 }
wolfSSL 16:8e0d178b1d1e 4013
wolfSSL 16:8e0d178b1d1e 4014 if (ret == 0 && GetSequence(in, &idx, &length, inSz) < 0)
wolfSSL 16:8e0d178b1d1e 4015 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 4016 }
wolfSSL 16:8e0d178b1d1e 4017 }
wolfSSL 16:8e0d178b1d1e 4018
wolfSSL 16:8e0d178b1d1e 4019 if (ret == 0) {
wolfSSL 16:8e0d178b1d1e 4020 ret = wc_PKCS7_SignerInfoSetSID(pkcs7, in + idx, length);
wolfSSL 16:8e0d178b1d1e 4021 idx += length;
wolfSSL 16:8e0d178b1d1e 4022 }
wolfSSL 16:8e0d178b1d1e 4023
wolfSSL 16:8e0d178b1d1e 4024 } else {
wolfSSL 16:8e0d178b1d1e 4025 WOLFSSL_MSG("PKCS#7 signerInfo version must be 1 or 3");
wolfSSL 16:8e0d178b1d1e 4026 ret = ASN_VERSION_E;
wolfSSL 16:8e0d178b1d1e 4027 }
wolfSSL 15:117db924cf7c 4028
wolfSSL 15:117db924cf7c 4029 /* Get the sequence of digestAlgorithm */
wolfSSL 16:8e0d178b1d1e 4030 if (ret == 0 && GetAlgoId(in, &idx, &hashOID, oidHashType, inSz) < 0) {
wolfSSL 16:8e0d178b1d1e 4031 ret = ASN_PARSE_E;
wolfSSL 15:117db924cf7c 4032 }
wolfSSL 15:117db924cf7c 4033 pkcs7->hashOID = (int)hashOID;
wolfSSL 15:117db924cf7c 4034
wolfSSL 15:117db924cf7c 4035 /* Get the IMPLICIT[0] SET OF signedAttributes */
wolfSSL 16:8e0d178b1d1e 4036 localIdx = idx;
wolfSSL 16:8e0d178b1d1e 4037 if (ret == 0 && GetASNTag(in, &localIdx, &tag, inSz) == 0 &&
wolfSSL 16:8e0d178b1d1e 4038 tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) {
wolfSSL 15:117db924cf7c 4039 idx++;
wolfSSL 15:117db924cf7c 4040
wolfSSL 16:8e0d178b1d1e 4041 if (GetLength(in, &idx, &length, inSz) < 0)
wolfSSL 16:8e0d178b1d1e 4042 ret = ASN_PARSE_E;
wolfSSL 15:117db924cf7c 4043
wolfSSL 15:117db924cf7c 4044 /* save pointer and length */
wolfSSL 16:8e0d178b1d1e 4045 *signedAttrib = &in[idx];
wolfSSL 16:8e0d178b1d1e 4046 *signedAttribSz = length;
wolfSSL 16:8e0d178b1d1e 4047
wolfSSL 16:8e0d178b1d1e 4048 if (ret == 0 && wc_PKCS7_ParseAttribs(pkcs7, *signedAttrib,
wolfSSL 16:8e0d178b1d1e 4049 *signedAttribSz) < 0) {
wolfSSL 15:117db924cf7c 4050 WOLFSSL_MSG("Error parsing signed attributes");
wolfSSL 16:8e0d178b1d1e 4051 ret = ASN_PARSE_E;
wolfSSL 15:117db924cf7c 4052 }
wolfSSL 15:117db924cf7c 4053
wolfSSL 15:117db924cf7c 4054 idx += length;
wolfSSL 15:117db924cf7c 4055 }
wolfSSL 15:117db924cf7c 4056
wolfSSL 15:117db924cf7c 4057 /* Get digestEncryptionAlgorithm */
wolfSSL 16:8e0d178b1d1e 4058 if (ret == 0 && GetAlgoId(in, &idx, &sigOID, oidSigType, inSz) < 0) {
wolfSSL 16:8e0d178b1d1e 4059 ret = ASN_PARSE_E;
wolfSSL 15:117db924cf7c 4060 }
wolfSSL 15:117db924cf7c 4061
wolfSSL 15:117db924cf7c 4062 /* store public key type based on digestEncryptionAlgorithm */
wolfSSL 16:8e0d178b1d1e 4063 if (ret == 0) {
wolfSSL 16:8e0d178b1d1e 4064 ret = wc_PKCS7_SetPublicKeyOID(pkcs7, sigOID);
wolfSSL 16:8e0d178b1d1e 4065 if (ret < 0) {
wolfSSL 16:8e0d178b1d1e 4066 WOLFSSL_MSG("Failed to set public key OID from signature");
wolfSSL 16:8e0d178b1d1e 4067 }
wolfSSL 16:8e0d178b1d1e 4068 else {
wolfSSL 16:8e0d178b1d1e 4069 /* if previous return was positive then was success */
wolfSSL 16:8e0d178b1d1e 4070 ret = 0;
wolfSSL 16:8e0d178b1d1e 4071 }
wolfSSL 16:8e0d178b1d1e 4072 }
wolfSSL 16:8e0d178b1d1e 4073 }
wolfSSL 16:8e0d178b1d1e 4074
wolfSSL 16:8e0d178b1d1e 4075 /* update index on success */
wolfSSL 16:8e0d178b1d1e 4076 if (ret == 0) {
wolfSSL 16:8e0d178b1d1e 4077 *idxIn = idx;
wolfSSL 16:8e0d178b1d1e 4078 }
wolfSSL 16:8e0d178b1d1e 4079
wolfSSL 16:8e0d178b1d1e 4080 return ret;
wolfSSL 16:8e0d178b1d1e 4081 }
wolfSSL 16:8e0d178b1d1e 4082
wolfSSL 16:8e0d178b1d1e 4083
wolfSSL 16:8e0d178b1d1e 4084 /* Finds the certificates in the message and saves it. By default allows
wolfSSL 16:8e0d178b1d1e 4085 * degenerate cases which can have no signer.
wolfSSL 16:8e0d178b1d1e 4086 *
wolfSSL 16:8e0d178b1d1e 4087 * By default expects type SIGNED_DATA (SignedData) which can have any number of
wolfSSL 16:8e0d178b1d1e 4088 * elements in signerInfos collection, including zero. (RFC2315 section 9.1)
wolfSSL 16:8e0d178b1d1e 4089 * When adding support for the case of SignedAndEnvelopedData content types a
wolfSSL 16:8e0d178b1d1e 4090 * signer is required. In this case the PKCS7 flag noDegenerate could be set.
wolfSSL 16:8e0d178b1d1e 4091 */
wolfSSL 16:8e0d178b1d1e 4092 static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
wolfSSL 16:8e0d178b1d1e 4093 word32 hashSz, byte* in, word32 inSz,
wolfSSL 16:8e0d178b1d1e 4094 byte* in2, word32 in2Sz)
wolfSSL 16:8e0d178b1d1e 4095 {
wolfSSL 16:8e0d178b1d1e 4096 word32 idx, maxIdx = inSz, outerContentType, contentTypeSz = 0, totalSz = 0;
wolfSSL 16:8e0d178b1d1e 4097 int length = 0, version = 0, ret = 0;
wolfSSL 16:8e0d178b1d1e 4098 byte* content = NULL;
wolfSSL 16:8e0d178b1d1e 4099 byte* contentDynamic = NULL;
wolfSSL 16:8e0d178b1d1e 4100 byte* sig = NULL;
wolfSSL 16:8e0d178b1d1e 4101 byte* cert = NULL;
wolfSSL 16:8e0d178b1d1e 4102 byte* signedAttrib = NULL;
wolfSSL 16:8e0d178b1d1e 4103 byte* contentType = NULL;
wolfSSL 16:8e0d178b1d1e 4104 int contentSz = 0, sigSz = 0, certSz = 0, signedAttribSz = 0;
wolfSSL 16:8e0d178b1d1e 4105 word32 localIdx, start;
wolfSSL 16:8e0d178b1d1e 4106 byte degenerate = 0;
wolfSSL 16:8e0d178b1d1e 4107 byte detached = 0;
wolfSSL 16:8e0d178b1d1e 4108 byte tag = 0;
wolfSSL 16:8e0d178b1d1e 4109 #ifdef ASN_BER_TO_DER
wolfSSL 16:8e0d178b1d1e 4110 byte* der;
wolfSSL 16:8e0d178b1d1e 4111 #endif
wolfSSL 16:8e0d178b1d1e 4112 int multiPart = 0, keepContent;
wolfSSL 16:8e0d178b1d1e 4113 int contentLen = 0;
wolfSSL 16:8e0d178b1d1e 4114
wolfSSL 16:8e0d178b1d1e 4115 byte* pkiMsg = in;
wolfSSL 16:8e0d178b1d1e 4116 word32 pkiMsgSz = inSz;
wolfSSL 16:8e0d178b1d1e 4117 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 4118 word32 stateIdx = 0;
wolfSSL 16:8e0d178b1d1e 4119 long rc;
wolfSSL 16:8e0d178b1d1e 4120 #endif
wolfSSL 16:8e0d178b1d1e 4121
wolfSSL 16:8e0d178b1d1e 4122 byte* pkiMsg2 = in2;
wolfSSL 16:8e0d178b1d1e 4123 word32 pkiMsg2Sz = in2Sz;
wolfSSL 16:8e0d178b1d1e 4124
wolfSSL 16:8e0d178b1d1e 4125 if (pkcs7 == NULL)
wolfSSL 16:8e0d178b1d1e 4126 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 4127
wolfSSL 16:8e0d178b1d1e 4128 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 4129 /* allow for 0 size inputs with stream mode */
wolfSSL 16:8e0d178b1d1e 4130 if (pkiMsg == NULL && pkiMsgSz > 0)
wolfSSL 16:8e0d178b1d1e 4131 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 4132
wolfSSL 16:8e0d178b1d1e 4133 #else
wolfSSL 16:8e0d178b1d1e 4134 if (pkiMsg == NULL || pkiMsgSz == 0)
wolfSSL 16:8e0d178b1d1e 4135 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 4136 #endif
wolfSSL 16:8e0d178b1d1e 4137
wolfSSL 16:8e0d178b1d1e 4138 if ((hashSz > 0 && hashBuf == NULL) || (pkiMsg2Sz > 0 && pkiMsg2 == NULL)) {
wolfSSL 16:8e0d178b1d1e 4139 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 4140 }
wolfSSL 16:8e0d178b1d1e 4141 idx = 0;
wolfSSL 16:8e0d178b1d1e 4142
wolfSSL 16:8e0d178b1d1e 4143 #ifdef ASN_BER_TO_DER
wolfSSL 16:8e0d178b1d1e 4144 if (pkcs7->derSz > 0 && pkcs7->der) {
wolfSSL 16:8e0d178b1d1e 4145 pkiMsg = in = pkcs7->der;
wolfSSL 16:8e0d178b1d1e 4146 }
wolfSSL 16:8e0d178b1d1e 4147 #endif
wolfSSL 16:8e0d178b1d1e 4148
wolfSSL 16:8e0d178b1d1e 4149 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 4150 if (pkcs7->stream == NULL) {
wolfSSL 16:8e0d178b1d1e 4151 if ((ret = wc_PKCS7_CreateStream(pkcs7)) != 0) {
wolfSSL 15:117db924cf7c 4152 return ret;
wolfSSL 15:117db924cf7c 4153 }
wolfSSL 16:8e0d178b1d1e 4154 }
wolfSSL 16:8e0d178b1d1e 4155 #endif
wolfSSL 16:8e0d178b1d1e 4156
wolfSSL 16:8e0d178b1d1e 4157 switch (pkcs7->state) {
wolfSSL 16:8e0d178b1d1e 4158 case WC_PKCS7_START:
wolfSSL 16:8e0d178b1d1e 4159 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 4160 if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_SEQ_SZ +
wolfSSL 16:8e0d178b1d1e 4161 MAX_VERSION_SZ + MAX_SEQ_SZ + MAX_LENGTH_SZ +
wolfSSL 16:8e0d178b1d1e 4162 ASN_TAG_SZ + MAX_OID_SZ + MAX_SEQ_SZ,
wolfSSL 16:8e0d178b1d1e 4163 &pkiMsg, &idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 4164 break;
wolfSSL 16:8e0d178b1d1e 4165 }
wolfSSL 16:8e0d178b1d1e 4166
wolfSSL 16:8e0d178b1d1e 4167 rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_SEQ_PEEK, in, inSz);
wolfSSL 16:8e0d178b1d1e 4168 if (rc < 0) {
wolfSSL 16:8e0d178b1d1e 4169 ret = (int)rc;
wolfSSL 16:8e0d178b1d1e 4170 break;
wolfSSL 16:8e0d178b1d1e 4171 }
wolfSSL 16:8e0d178b1d1e 4172 pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length :inSz;
wolfSSL 16:8e0d178b1d1e 4173 #endif
wolfSSL 16:8e0d178b1d1e 4174
wolfSSL 16:8e0d178b1d1e 4175 /* determine total message size */
wolfSSL 16:8e0d178b1d1e 4176 totalSz = pkiMsgSz;
wolfSSL 16:8e0d178b1d1e 4177 if (pkiMsg2 && pkiMsg2Sz > 0) {
wolfSSL 16:8e0d178b1d1e 4178 totalSz += pkiMsg2Sz + pkcs7->contentSz;
wolfSSL 16:8e0d178b1d1e 4179 }
wolfSSL 16:8e0d178b1d1e 4180
wolfSSL 16:8e0d178b1d1e 4181 /* Get the contentInfo sequence */
wolfSSL 16:8e0d178b1d1e 4182 if (ret == 0 && GetSequence_ex(pkiMsg, &idx, &length, totalSz,
wolfSSL 16:8e0d178b1d1e 4183 NO_USER_CHECK) < 0)
wolfSSL 16:8e0d178b1d1e 4184 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 4185
wolfSSL 16:8e0d178b1d1e 4186 if (ret == 0 && length == 0 && pkiMsg[idx-1] == 0x80) {
wolfSSL 16:8e0d178b1d1e 4187 #ifdef ASN_BER_TO_DER
wolfSSL 16:8e0d178b1d1e 4188 word32 len = 0;
wolfSSL 16:8e0d178b1d1e 4189
wolfSSL 16:8e0d178b1d1e 4190 ret = wc_BerToDer(pkiMsg, pkiMsgSz, NULL, &len);
wolfSSL 16:8e0d178b1d1e 4191 if (ret != LENGTH_ONLY_E)
wolfSSL 16:8e0d178b1d1e 4192 return ret;
wolfSSL 16:8e0d178b1d1e 4193 pkcs7->der = (byte*)XMALLOC(len, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 4194 if (pkcs7->der == NULL)
wolfSSL 16:8e0d178b1d1e 4195 return MEMORY_E;
wolfSSL 16:8e0d178b1d1e 4196 ret = wc_BerToDer(pkiMsg, pkiMsgSz, pkcs7->der, &len);
wolfSSL 16:8e0d178b1d1e 4197 if (ret < 0)
wolfSSL 16:8e0d178b1d1e 4198 return ret;
wolfSSL 16:8e0d178b1d1e 4199
wolfSSL 16:8e0d178b1d1e 4200 pkiMsg = in = pkcs7->der;
wolfSSL 16:8e0d178b1d1e 4201 pkiMsgSz = pkcs7->derSz = len;
wolfSSL 16:8e0d178b1d1e 4202 idx = 0;
wolfSSL 16:8e0d178b1d1e 4203 if (GetSequence_ex(pkiMsg, &idx, &length, pkiMsgSz,
wolfSSL 16:8e0d178b1d1e 4204 NO_USER_CHECK) < 0)
wolfSSL 16:8e0d178b1d1e 4205 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 4206
wolfSSL 16:8e0d178b1d1e 4207 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 4208 rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_SEQ_PEEK,
wolfSSL 16:8e0d178b1d1e 4209 pkiMsg, pkiMsgSz);
wolfSSL 16:8e0d178b1d1e 4210 if (rc < 0) {
wolfSSL 16:8e0d178b1d1e 4211 ret = (int)rc;
wolfSSL 16:8e0d178b1d1e 4212 break;
wolfSSL 16:8e0d178b1d1e 4213 }
wolfSSL 16:8e0d178b1d1e 4214 #endif
wolfSSL 16:8e0d178b1d1e 4215 #else
wolfSSL 16:8e0d178b1d1e 4216 ret = BER_INDEF_E;
wolfSSL 16:8e0d178b1d1e 4217 #endif
wolfSSL 16:8e0d178b1d1e 4218 }
wolfSSL 16:8e0d178b1d1e 4219
wolfSSL 16:8e0d178b1d1e 4220 /* Get the contentInfo contentType */
wolfSSL 16:8e0d178b1d1e 4221 if (ret == 0 && wc_GetContentType(pkiMsg, &idx, &outerContentType,
wolfSSL 16:8e0d178b1d1e 4222 pkiMsgSz) < 0)
wolfSSL 16:8e0d178b1d1e 4223 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 4224
wolfSSL 16:8e0d178b1d1e 4225 if (ret == 0 && outerContentType != SIGNED_DATA) {
wolfSSL 16:8e0d178b1d1e 4226 WOLFSSL_MSG("PKCS#7 input not of type SignedData");
wolfSSL 16:8e0d178b1d1e 4227 ret = PKCS7_OID_E;
wolfSSL 16:8e0d178b1d1e 4228 }
wolfSSL 16:8e0d178b1d1e 4229
wolfSSL 16:8e0d178b1d1e 4230 /* get the ContentInfo content */
wolfSSL 16:8e0d178b1d1e 4231 if (ret == 0 && GetASNTag(pkiMsg, &idx, &tag, totalSz) != 0)
wolfSSL 16:8e0d178b1d1e 4232 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 4233
wolfSSL 16:8e0d178b1d1e 4234 if (ret == 0 && tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
wolfSSL 16:8e0d178b1d1e 4235 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 4236
wolfSSL 16:8e0d178b1d1e 4237 if (ret == 0 && GetLength_ex(pkiMsg, &idx, &length, totalSz,
wolfSSL 16:8e0d178b1d1e 4238 NO_USER_CHECK) < 0)
wolfSSL 16:8e0d178b1d1e 4239 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 4240
wolfSSL 16:8e0d178b1d1e 4241 /* Get the signedData sequence */
wolfSSL 16:8e0d178b1d1e 4242 if (ret == 0 && GetSequence_ex(pkiMsg, &idx, &length, totalSz,
wolfSSL 16:8e0d178b1d1e 4243 NO_USER_CHECK) < 0)
wolfSSL 16:8e0d178b1d1e 4244 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 4245
wolfSSL 16:8e0d178b1d1e 4246 /* Get the version */
wolfSSL 16:8e0d178b1d1e 4247 if (ret == 0 && GetMyVersion(pkiMsg, &idx, &version, pkiMsgSz) < 0)
wolfSSL 16:8e0d178b1d1e 4248 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 4249
wolfSSL 16:8e0d178b1d1e 4250
wolfSSL 16:8e0d178b1d1e 4251 /* version 1 follows RFC 2315 */
wolfSSL 16:8e0d178b1d1e 4252 /* version 3 follows RFC 4108 */
wolfSSL 16:8e0d178b1d1e 4253 if (ret == 0 && (version != 1 && version != 3)) {
wolfSSL 16:8e0d178b1d1e 4254 WOLFSSL_MSG("PKCS#7 signedData needs to be version 1 or 3");
wolfSSL 16:8e0d178b1d1e 4255 ret = ASN_VERSION_E;
wolfSSL 16:8e0d178b1d1e 4256 }
wolfSSL 16:8e0d178b1d1e 4257 pkcs7->version = version;
wolfSSL 16:8e0d178b1d1e 4258
wolfSSL 16:8e0d178b1d1e 4259 /* Get the set of DigestAlgorithmIdentifiers */
wolfSSL 16:8e0d178b1d1e 4260 if (ret == 0 && GetSet(pkiMsg, &idx, &length, pkiMsgSz) < 0)
wolfSSL 16:8e0d178b1d1e 4261 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 4262
wolfSSL 16:8e0d178b1d1e 4263 /* Skip the set. */
wolfSSL 15:117db924cf7c 4264 idx += length;
wolfSSL 16:8e0d178b1d1e 4265 degenerate = (length == 0)? 1 : 0;
wolfSSL 16:8e0d178b1d1e 4266 if (pkcs7->noDegenerate == 1 && degenerate == 1) {
wolfSSL 16:8e0d178b1d1e 4267 ret = PKCS7_NO_SIGNER_E;
wolfSSL 16:8e0d178b1d1e 4268 }
wolfSSL 16:8e0d178b1d1e 4269
wolfSSL 16:8e0d178b1d1e 4270 if (ret != 0)
wolfSSL 16:8e0d178b1d1e 4271 break;
wolfSSL 16:8e0d178b1d1e 4272
wolfSSL 16:8e0d178b1d1e 4273 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 4274 if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &stateIdx, &idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 4275 break;
wolfSSL 16:8e0d178b1d1e 4276 }
wolfSSL 16:8e0d178b1d1e 4277 if (pkiMsg2 && pkiMsg2Sz > 0) {
wolfSSL 16:8e0d178b1d1e 4278 pkcs7->stream->maxLen += pkiMsg2Sz + pkcs7->contentSz;
wolfSSL 16:8e0d178b1d1e 4279 }
wolfSSL 16:8e0d178b1d1e 4280 wc_PKCS7_StreamStoreVar(pkcs7, totalSz, 0, 0);
wolfSSL 16:8e0d178b1d1e 4281 #endif
wolfSSL 16:8e0d178b1d1e 4282
wolfSSL 16:8e0d178b1d1e 4283 wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_VERIFY_STAGE2);
wolfSSL 16:8e0d178b1d1e 4284 FALL_THROUGH;
wolfSSL 16:8e0d178b1d1e 4285
wolfSSL 16:8e0d178b1d1e 4286 case WC_PKCS7_VERIFY_STAGE2:
wolfSSL 16:8e0d178b1d1e 4287 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 4288 if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz + in2Sz,
wolfSSL 16:8e0d178b1d1e 4289 MAX_SEQ_SZ + MAX_OID_SZ + ASN_TAG_SZ + MAX_LENGTH_SZ
wolfSSL 16:8e0d178b1d1e 4290 + ASN_TAG_SZ + MAX_LENGTH_SZ, &pkiMsg, &idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 4291 break;
wolfSSL 16:8e0d178b1d1e 4292 }
wolfSSL 16:8e0d178b1d1e 4293
wolfSSL 16:8e0d178b1d1e 4294 wc_PKCS7_StreamGetVar(pkcs7, &totalSz, 0, 0);
wolfSSL 16:8e0d178b1d1e 4295 if (pkcs7->stream->length > 0)
wolfSSL 16:8e0d178b1d1e 4296 pkiMsgSz = pkcs7->stream->length;
wolfSSL 16:8e0d178b1d1e 4297 #ifdef ASN_BER_TO_DER
wolfSSL 16:8e0d178b1d1e 4298 else if (pkcs7->der)
wolfSSL 16:8e0d178b1d1e 4299 pkiMsgSz = pkcs7->derSz;
wolfSSL 16:8e0d178b1d1e 4300 #endif
wolfSSL 16:8e0d178b1d1e 4301 else
wolfSSL 16:8e0d178b1d1e 4302 pkiMsgSz = inSz;
wolfSSL 16:8e0d178b1d1e 4303
wolfSSL 16:8e0d178b1d1e 4304 #endif
wolfSSL 16:8e0d178b1d1e 4305 /* Get the inner ContentInfo sequence */
wolfSSL 16:8e0d178b1d1e 4306 if (GetSequence_ex(pkiMsg, &idx, &length, pkiMsgSz,
wolfSSL 16:8e0d178b1d1e 4307 NO_USER_CHECK) < 0)
wolfSSL 16:8e0d178b1d1e 4308 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 4309
wolfSSL 16:8e0d178b1d1e 4310 /* Get the inner ContentInfo contentType */
wolfSSL 16:8e0d178b1d1e 4311 if (ret == 0) {
wolfSSL 16:8e0d178b1d1e 4312 word32 tmpIdx = idx;
wolfSSL 16:8e0d178b1d1e 4313
wolfSSL 16:8e0d178b1d1e 4314 if (GetASNObjectId(pkiMsg, &idx, &length, pkiMsgSz) != 0)
wolfSSL 16:8e0d178b1d1e 4315 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 4316
wolfSSL 16:8e0d178b1d1e 4317 contentType = pkiMsg + tmpIdx;
wolfSSL 16:8e0d178b1d1e 4318 contentTypeSz = length + (idx - tmpIdx);
wolfSSL 16:8e0d178b1d1e 4319
wolfSSL 16:8e0d178b1d1e 4320 idx += length;
wolfSSL 16:8e0d178b1d1e 4321 }
wolfSSL 16:8e0d178b1d1e 4322
wolfSSL 16:8e0d178b1d1e 4323 if (ret != 0)
wolfSSL 16:8e0d178b1d1e 4324 break;
wolfSSL 16:8e0d178b1d1e 4325
wolfSSL 16:8e0d178b1d1e 4326 /* Check for content info, it could be omitted when degenerate */
wolfSSL 16:8e0d178b1d1e 4327 localIdx = idx;
wolfSSL 16:8e0d178b1d1e 4328 ret = 0;
wolfSSL 16:8e0d178b1d1e 4329 if (localIdx + 1 > pkiMsgSz) {
wolfSSL 16:8e0d178b1d1e 4330 ret = BUFFER_E;
wolfSSL 16:8e0d178b1d1e 4331 break;
wolfSSL 16:8e0d178b1d1e 4332 }
wolfSSL 16:8e0d178b1d1e 4333
wolfSSL 16:8e0d178b1d1e 4334 if (ret == 0 && GetASNTag(pkiMsg, &localIdx, &tag, pkiMsgSz) != 0)
wolfSSL 16:8e0d178b1d1e 4335 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 4336
wolfSSL 16:8e0d178b1d1e 4337 if (ret == 0 && tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
wolfSSL 16:8e0d178b1d1e 4338 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 4339
wolfSSL 16:8e0d178b1d1e 4340 if (ret == 0 && GetLength_ex(pkiMsg, &localIdx, &length, pkiMsgSz,
wolfSSL 16:8e0d178b1d1e 4341 NO_USER_CHECK) <= 0)
wolfSSL 16:8e0d178b1d1e 4342 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 4343
wolfSSL 16:8e0d178b1d1e 4344 if (localIdx >= pkiMsgSz) {
wolfSSL 16:8e0d178b1d1e 4345 ret = BUFFER_E;
wolfSSL 16:8e0d178b1d1e 4346 }
wolfSSL 16:8e0d178b1d1e 4347
wolfSSL 16:8e0d178b1d1e 4348 /* get length of content in the case that there is multiple parts */
wolfSSL 16:8e0d178b1d1e 4349 if (ret == 0 && GetASNTag(pkiMsg, &localIdx, &tag, pkiMsgSz) < 0)
wolfSSL 16:8e0d178b1d1e 4350 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 4351
wolfSSL 16:8e0d178b1d1e 4352 if (ret == 0 && tag == (ASN_OCTET_STRING | ASN_CONSTRUCTED)) {
wolfSSL 16:8e0d178b1d1e 4353 multiPart = 1;
wolfSSL 16:8e0d178b1d1e 4354
wolfSSL 16:8e0d178b1d1e 4355 /* Get length of all OCTET_STRINGs. */
wolfSSL 16:8e0d178b1d1e 4356 if (GetLength_ex(pkiMsg, &localIdx, &contentLen, pkiMsgSz,
wolfSSL 16:8e0d178b1d1e 4357 NO_USER_CHECK) < 0)
wolfSSL 16:8e0d178b1d1e 4358 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 4359
wolfSSL 16:8e0d178b1d1e 4360 /* Check whether there is one OCTET_STRING inside. */
wolfSSL 16:8e0d178b1d1e 4361 start = localIdx;
wolfSSL 16:8e0d178b1d1e 4362 if (localIdx >= pkiMsgSz) {
wolfSSL 16:8e0d178b1d1e 4363 ret = BUFFER_E;
wolfSSL 16:8e0d178b1d1e 4364 }
wolfSSL 16:8e0d178b1d1e 4365
wolfSSL 16:8e0d178b1d1e 4366 if (ret == 0 && GetASNTag(pkiMsg, &localIdx, &tag, pkiMsgSz)
wolfSSL 16:8e0d178b1d1e 4367 != 0)
wolfSSL 16:8e0d178b1d1e 4368 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 4369
wolfSSL 16:8e0d178b1d1e 4370 if (ret == 0 && tag != ASN_OCTET_STRING)
wolfSSL 16:8e0d178b1d1e 4371 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 4372
wolfSSL 16:8e0d178b1d1e 4373 if (ret == 0 && GetLength_ex(pkiMsg, &localIdx, &length, pkiMsgSz,
wolfSSL 16:8e0d178b1d1e 4374 NO_USER_CHECK) < 0)
wolfSSL 16:8e0d178b1d1e 4375 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 4376
wolfSSL 16:8e0d178b1d1e 4377 if (ret == 0) {
wolfSSL 16:8e0d178b1d1e 4378 /* Use single OCTET_STRING directly. */
wolfSSL 16:8e0d178b1d1e 4379 if (localIdx - start + length == (word32)contentLen)
wolfSSL 16:8e0d178b1d1e 4380 multiPart = 0;
wolfSSL 16:8e0d178b1d1e 4381 localIdx = start;
wolfSSL 16:8e0d178b1d1e 4382 }
wolfSSL 16:8e0d178b1d1e 4383 }
wolfSSL 16:8e0d178b1d1e 4384
wolfSSL 16:8e0d178b1d1e 4385 /* get length of content in case of single part */
wolfSSL 16:8e0d178b1d1e 4386 if (ret == 0 && !multiPart) {
wolfSSL 16:8e0d178b1d1e 4387 if (tag != ASN_OCTET_STRING)
wolfSSL 16:8e0d178b1d1e 4388 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 4389
wolfSSL 16:8e0d178b1d1e 4390 if (ret == 0 && GetLength_ex(pkiMsg, &localIdx,
wolfSSL 16:8e0d178b1d1e 4391 &length, pkiMsgSz, NO_USER_CHECK) < 0)
wolfSSL 16:8e0d178b1d1e 4392 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 4393 }
wolfSSL 16:8e0d178b1d1e 4394
wolfSSL 16:8e0d178b1d1e 4395 /* update idx if successful */
wolfSSL 16:8e0d178b1d1e 4396 if (ret == 0) {
wolfSSL 16:8e0d178b1d1e 4397 /* support using header and footer without content */
wolfSSL 16:8e0d178b1d1e 4398 if (pkiMsg2 && pkiMsg2Sz > 0 && hashBuf && hashSz > 0) {
wolfSSL 16:8e0d178b1d1e 4399 localIdx = 0;
wolfSSL 16:8e0d178b1d1e 4400 }
wolfSSL 16:8e0d178b1d1e 4401 idx = localIdx;
wolfSSL 16:8e0d178b1d1e 4402 }
wolfSSL 16:8e0d178b1d1e 4403 else {
wolfSSL 16:8e0d178b1d1e 4404
wolfSSL 16:8e0d178b1d1e 4405 /* if pkcs7->content and pkcs7->contentSz are set, try to
wolfSSL 16:8e0d178b1d1e 4406 process as a detached signature */
wolfSSL 16:8e0d178b1d1e 4407 if (!degenerate &&
wolfSSL 16:8e0d178b1d1e 4408 (pkcs7->content != NULL && pkcs7->contentSz != 0)) {
wolfSSL 16:8e0d178b1d1e 4409 detached = 1;
wolfSSL 16:8e0d178b1d1e 4410 }
wolfSSL 16:8e0d178b1d1e 4411
wolfSSL 16:8e0d178b1d1e 4412 if (!degenerate && !detached && ret != 0)
wolfSSL 16:8e0d178b1d1e 4413 break;
wolfSSL 16:8e0d178b1d1e 4414
wolfSSL 16:8e0d178b1d1e 4415 length = 0; /* no content to read */
wolfSSL 16:8e0d178b1d1e 4416 pkiMsg2 = pkiMsg;
wolfSSL 16:8e0d178b1d1e 4417 pkiMsg2Sz = pkiMsgSz;
wolfSSL 16:8e0d178b1d1e 4418 }
wolfSSL 16:8e0d178b1d1e 4419
wolfSSL 16:8e0d178b1d1e 4420 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 4421 /* save detached flag value */
wolfSSL 16:8e0d178b1d1e 4422 pkcs7->stream->detached = detached;
wolfSSL 16:8e0d178b1d1e 4423
wolfSSL 16:8e0d178b1d1e 4424 /* save contentType */
wolfSSL 16:8e0d178b1d1e 4425 pkcs7->stream->nonce = (byte*)XMALLOC(contentTypeSz, pkcs7->heap,
wolfSSL 16:8e0d178b1d1e 4426 DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 4427 if (pkcs7->stream->nonce == NULL) {
wolfSSL 16:8e0d178b1d1e 4428 ret = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 4429 break;
wolfSSL 16:8e0d178b1d1e 4430 }
wolfSSL 16:8e0d178b1d1e 4431 else {
wolfSSL 16:8e0d178b1d1e 4432 pkcs7->stream->nonceSz = contentTypeSz;
wolfSSL 16:8e0d178b1d1e 4433 XMEMCPY(pkcs7->stream->nonce, contentType, contentTypeSz);
wolfSSL 16:8e0d178b1d1e 4434 }
wolfSSL 16:8e0d178b1d1e 4435
wolfSSL 16:8e0d178b1d1e 4436 /* content expected? */
wolfSSL 16:8e0d178b1d1e 4437 if ((ret == 0 && length > 0) &&
wolfSSL 16:8e0d178b1d1e 4438 !(pkiMsg2 && pkiMsg2Sz > 0 && hashBuf && hashSz > 0)) {
wolfSSL 16:8e0d178b1d1e 4439 pkcs7->stream->expected = length + ASN_TAG_SZ + MAX_LENGTH_SZ;
wolfSSL 16:8e0d178b1d1e 4440 }
wolfSSL 16:8e0d178b1d1e 4441 else {
wolfSSL 16:8e0d178b1d1e 4442 pkcs7->stream->expected = ASN_TAG_SZ + MAX_LENGTH_SZ;
wolfSSL 16:8e0d178b1d1e 4443 }
wolfSSL 16:8e0d178b1d1e 4444
wolfSSL 16:8e0d178b1d1e 4445 if (pkcs7->stream->expected > (pkcs7->stream->maxLen - idx)) {
wolfSSL 16:8e0d178b1d1e 4446 pkcs7->stream->expected = pkcs7->stream->maxLen - idx;
wolfSSL 16:8e0d178b1d1e 4447 }
wolfSSL 16:8e0d178b1d1e 4448
wolfSSL 16:8e0d178b1d1e 4449 if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &stateIdx, &idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 4450 break;
wolfSSL 16:8e0d178b1d1e 4451 }
wolfSSL 16:8e0d178b1d1e 4452 wc_PKCS7_StreamStoreVar(pkcs7, pkiMsg2Sz, localIdx, length);
wolfSSL 16:8e0d178b1d1e 4453
wolfSSL 16:8e0d178b1d1e 4454 /* content length is in multiple parts */
wolfSSL 16:8e0d178b1d1e 4455 if (multiPart) {
wolfSSL 16:8e0d178b1d1e 4456 pkcs7->stream->expected = contentLen + ASN_TAG_SZ;
wolfSSL 16:8e0d178b1d1e 4457 }
wolfSSL 16:8e0d178b1d1e 4458 pkcs7->stream->multi = multiPart;
wolfSSL 16:8e0d178b1d1e 4459
wolfSSL 16:8e0d178b1d1e 4460 #endif
wolfSSL 16:8e0d178b1d1e 4461 wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_VERIFY_STAGE3);
wolfSSL 16:8e0d178b1d1e 4462 FALL_THROUGH;
wolfSSL 16:8e0d178b1d1e 4463
wolfSSL 16:8e0d178b1d1e 4464 case WC_PKCS7_VERIFY_STAGE3:
wolfSSL 16:8e0d178b1d1e 4465 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 4466 if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz + in2Sz,
wolfSSL 16:8e0d178b1d1e 4467 pkcs7->stream->expected, &pkiMsg, &idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 4468 break;
wolfSSL 16:8e0d178b1d1e 4469 }
wolfSSL 16:8e0d178b1d1e 4470
wolfSSL 16:8e0d178b1d1e 4471 rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK,
wolfSSL 16:8e0d178b1d1e 4472 pkiMsg, pkiMsgSz);
wolfSSL 16:8e0d178b1d1e 4473 if (rc < 0) {
wolfSSL 16:8e0d178b1d1e 4474 ret = (int)rc;
wolfSSL 16:8e0d178b1d1e 4475 break;
wolfSSL 16:8e0d178b1d1e 4476 }
wolfSSL 16:8e0d178b1d1e 4477 #ifdef ASN_BER_TO_DER
wolfSSL 16:8e0d178b1d1e 4478 if (pkcs7->derSz != 0)
wolfSSL 16:8e0d178b1d1e 4479 pkiMsgSz = pkcs7->derSz;
wolfSSL 16:8e0d178b1d1e 4480 else
wolfSSL 16:8e0d178b1d1e 4481 #endif
wolfSSL 16:8e0d178b1d1e 4482 pkiMsgSz = (word32)rc;
wolfSSL 16:8e0d178b1d1e 4483 wc_PKCS7_StreamGetVar(pkcs7, &pkiMsg2Sz, (int*)&localIdx, &length);
wolfSSL 16:8e0d178b1d1e 4484
wolfSSL 16:8e0d178b1d1e 4485 if (pkcs7->stream->length > 0) {
wolfSSL 16:8e0d178b1d1e 4486 localIdx = 0;
wolfSSL 16:8e0d178b1d1e 4487 }
wolfSSL 16:8e0d178b1d1e 4488 multiPart = pkcs7->stream->multi;
wolfSSL 16:8e0d178b1d1e 4489 detached = pkcs7->stream->detached;
wolfSSL 16:8e0d178b1d1e 4490 maxIdx = idx + pkcs7->stream->expected;
wolfSSL 16:8e0d178b1d1e 4491 #endif
wolfSSL 16:8e0d178b1d1e 4492
wolfSSL 16:8e0d178b1d1e 4493 /* Break out before content because it can be optional in degenerate
wolfSSL 16:8e0d178b1d1e 4494 * cases. */
wolfSSL 16:8e0d178b1d1e 4495 if (ret != 0 && !degenerate)
wolfSSL 16:8e0d178b1d1e 4496 break;
wolfSSL 16:8e0d178b1d1e 4497
wolfSSL 16:8e0d178b1d1e 4498 /* get parts of content */
wolfSSL 16:8e0d178b1d1e 4499 if (ret == 0 && multiPart) {
wolfSSL 16:8e0d178b1d1e 4500 int i = 0;
wolfSSL 16:8e0d178b1d1e 4501 keepContent = !(pkiMsg2 && pkiMsg2Sz > 0 && hashBuf && hashSz > 0);
wolfSSL 16:8e0d178b1d1e 4502
wolfSSL 16:8e0d178b1d1e 4503 if (keepContent) {
wolfSSL 16:8e0d178b1d1e 4504 /* Create a buffer to hold content of OCTET_STRINGs. */
wolfSSL 16:8e0d178b1d1e 4505 pkcs7->contentDynamic = (byte*)XMALLOC(contentLen, pkcs7->heap,
wolfSSL 16:8e0d178b1d1e 4506 DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 4507 if (pkcs7->contentDynamic == NULL)
wolfSSL 16:8e0d178b1d1e 4508 ret = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 4509 }
wolfSSL 16:8e0d178b1d1e 4510
wolfSSL 16:8e0d178b1d1e 4511 start = localIdx;
wolfSSL 16:8e0d178b1d1e 4512 /* Use the data from each OCTET_STRING. */
wolfSSL 16:8e0d178b1d1e 4513 while (ret == 0 && localIdx < start + contentLen) {
wolfSSL 16:8e0d178b1d1e 4514 if (GetASNTag(pkiMsg, &localIdx, &tag, totalSz) < 0)
wolfSSL 16:8e0d178b1d1e 4515 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 4516 if (ret == 0 && tag != ASN_OCTET_STRING)
wolfSSL 16:8e0d178b1d1e 4517 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 4518
wolfSSL 16:8e0d178b1d1e 4519 if (ret == 0 && GetLength(pkiMsg, &localIdx, &length, totalSz) < 0)
wolfSSL 16:8e0d178b1d1e 4520 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 4521 if (ret == 0 && length + localIdx > start + contentLen)
wolfSSL 16:8e0d178b1d1e 4522 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 4523
wolfSSL 16:8e0d178b1d1e 4524 if (ret == 0) {
wolfSSL 16:8e0d178b1d1e 4525 if (keepContent) {
wolfSSL 16:8e0d178b1d1e 4526 XMEMCPY(pkcs7->contentDynamic + i, pkiMsg + localIdx,
wolfSSL 16:8e0d178b1d1e 4527 length);
wolfSSL 16:8e0d178b1d1e 4528 }
wolfSSL 16:8e0d178b1d1e 4529 i += length;
wolfSSL 16:8e0d178b1d1e 4530 localIdx += length;
wolfSSL 16:8e0d178b1d1e 4531 }
wolfSSL 16:8e0d178b1d1e 4532 }
wolfSSL 16:8e0d178b1d1e 4533 localIdx = start; /* reset for sanity check, increment later */
wolfSSL 16:8e0d178b1d1e 4534 length = i;
wolfSSL 16:8e0d178b1d1e 4535 }
wolfSSL 16:8e0d178b1d1e 4536
wolfSSL 16:8e0d178b1d1e 4537 /* Save the inner data as the content. */
wolfSSL 16:8e0d178b1d1e 4538 if (ret == 0 && length > 0) {
wolfSSL 16:8e0d178b1d1e 4539 contentSz = length;
wolfSSL 16:8e0d178b1d1e 4540
wolfSSL 16:8e0d178b1d1e 4541 /* support using header and footer without content */
wolfSSL 16:8e0d178b1d1e 4542 if (pkiMsg2 && pkiMsg2Sz > 0 && hashBuf && hashSz > 0) {
wolfSSL 16:8e0d178b1d1e 4543 /* Content not provided, use provided pkiMsg2 footer */
wolfSSL 16:8e0d178b1d1e 4544 content = NULL;
wolfSSL 16:8e0d178b1d1e 4545 localIdx = 0;
wolfSSL 16:8e0d178b1d1e 4546 if (contentSz != (int)pkcs7->contentSz) {
wolfSSL 16:8e0d178b1d1e 4547 WOLFSSL_MSG("Data signed does not match contentSz provided");
wolfSSL 16:8e0d178b1d1e 4548 ret = BUFFER_E;
wolfSSL 16:8e0d178b1d1e 4549 }
wolfSSL 16:8e0d178b1d1e 4550 }
wolfSSL 16:8e0d178b1d1e 4551 else {
wolfSSL 16:8e0d178b1d1e 4552 if ((word32)length > pkiMsgSz - localIdx) {
wolfSSL 16:8e0d178b1d1e 4553 ret = BUFFER_E;
wolfSSL 16:8e0d178b1d1e 4554 }
wolfSSL 16:8e0d178b1d1e 4555
wolfSSL 16:8e0d178b1d1e 4556 /* Content pointer for calculating hashes later */
wolfSSL 16:8e0d178b1d1e 4557 if (ret == 0 && !multiPart) {
wolfSSL 16:8e0d178b1d1e 4558 content = &pkiMsg[localIdx];
wolfSSL 16:8e0d178b1d1e 4559 }
wolfSSL 16:8e0d178b1d1e 4560 if (ret == 0 && multiPart) {
wolfSSL 16:8e0d178b1d1e 4561 content = pkcs7->contentDynamic;
wolfSSL 16:8e0d178b1d1e 4562 }
wolfSSL 16:8e0d178b1d1e 4563
wolfSSL 16:8e0d178b1d1e 4564 if (ret == 0) {
wolfSSL 16:8e0d178b1d1e 4565 idx += length;
wolfSSL 16:8e0d178b1d1e 4566
wolfSSL 16:8e0d178b1d1e 4567 pkiMsg2 = pkiMsg;
wolfSSL 16:8e0d178b1d1e 4568 pkiMsg2Sz = pkiMsgSz;
wolfSSL 16:8e0d178b1d1e 4569 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 4570 pkcs7->stream->varOne = pkiMsg2Sz;
wolfSSL 16:8e0d178b1d1e 4571 pkcs7->stream->flagOne = 1;
wolfSSL 16:8e0d178b1d1e 4572 #endif
wolfSSL 16:8e0d178b1d1e 4573 }
wolfSSL 16:8e0d178b1d1e 4574 }
wolfSSL 16:8e0d178b1d1e 4575 }
wolfSSL 16:8e0d178b1d1e 4576 else {
wolfSSL 16:8e0d178b1d1e 4577 pkiMsg2 = pkiMsg;
wolfSSL 16:8e0d178b1d1e 4578 pkiMsg2Sz = pkiMsgSz;
wolfSSL 16:8e0d178b1d1e 4579 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 4580 pkcs7->stream->varOne = pkiMsg2Sz;
wolfSSL 16:8e0d178b1d1e 4581 pkcs7->stream->flagOne = 1;
wolfSSL 16:8e0d178b1d1e 4582 #endif
wolfSSL 16:8e0d178b1d1e 4583 }
wolfSSL 16:8e0d178b1d1e 4584
wolfSSL 16:8e0d178b1d1e 4585 /* If getting the content info failed with non degenerate then return the
wolfSSL 16:8e0d178b1d1e 4586 * error case. Otherwise with a degenerate it is ok if the content
wolfSSL 16:8e0d178b1d1e 4587 * info was omitted */
wolfSSL 16:8e0d178b1d1e 4588 if (!degenerate && !detached && (ret != 0)) {
wolfSSL 16:8e0d178b1d1e 4589 break;
wolfSSL 16:8e0d178b1d1e 4590 }
wolfSSL 16:8e0d178b1d1e 4591 else {
wolfSSL 16:8e0d178b1d1e 4592 ret = 0; /* reset ret state on degenerate case */
wolfSSL 16:8e0d178b1d1e 4593 }
wolfSSL 16:8e0d178b1d1e 4594
wolfSSL 16:8e0d178b1d1e 4595 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 4596 /* save content */
wolfSSL 16:8e0d178b1d1e 4597 if (detached == 1) {
wolfSSL 16:8e0d178b1d1e 4598 /* if detached, use content from user in pkcs7 struct */
wolfSSL 16:8e0d178b1d1e 4599 content = pkcs7->content;
wolfSSL 16:8e0d178b1d1e 4600 contentSz = pkcs7->contentSz;
wolfSSL 16:8e0d178b1d1e 4601 }
wolfSSL 16:8e0d178b1d1e 4602
wolfSSL 16:8e0d178b1d1e 4603 if (content != NULL) {
wolfSSL 16:8e0d178b1d1e 4604 XFREE(pkcs7->stream->content, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 4605 pkcs7->stream->content = (byte*)XMALLOC(contentSz, pkcs7->heap,
wolfSSL 16:8e0d178b1d1e 4606 DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 4607 if (pkcs7->stream->content == NULL) {
wolfSSL 16:8e0d178b1d1e 4608 ret = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 4609 break;
wolfSSL 16:8e0d178b1d1e 4610 }
wolfSSL 16:8e0d178b1d1e 4611 else {
wolfSSL 16:8e0d178b1d1e 4612 XMEMCPY(pkcs7->stream->content, content, contentSz);
wolfSSL 16:8e0d178b1d1e 4613 pkcs7->stream->contentSz = contentSz;
wolfSSL 16:8e0d178b1d1e 4614 }
wolfSSL 16:8e0d178b1d1e 4615 }
wolfSSL 16:8e0d178b1d1e 4616 #endif /* !NO_PKCS7_STREAM */
wolfSSL 16:8e0d178b1d1e 4617
wolfSSL 16:8e0d178b1d1e 4618 /* Get the implicit[0] set of certificates */
wolfSSL 16:8e0d178b1d1e 4619 if (ret == 0 && idx >= pkiMsg2Sz)
wolfSSL 16:8e0d178b1d1e 4620 ret = BUFFER_E;
wolfSSL 16:8e0d178b1d1e 4621
wolfSSL 16:8e0d178b1d1e 4622 length = 0; /* set length to 0 to check if reading in any certs */
wolfSSL 16:8e0d178b1d1e 4623 localIdx = idx;
wolfSSL 16:8e0d178b1d1e 4624 if (ret == 0 && GetASNTag(pkiMsg2, &localIdx, &tag, pkiMsg2Sz) == 0
wolfSSL 16:8e0d178b1d1e 4625 && tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) {
wolfSSL 16:8e0d178b1d1e 4626 idx++;
wolfSSL 16:8e0d178b1d1e 4627 if (GetLength_ex(pkiMsg2, &idx, &length, maxIdx, NO_USER_CHECK)
wolfSSL 16:8e0d178b1d1e 4628 < 0)
wolfSSL 16:8e0d178b1d1e 4629 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 4630 }
wolfSSL 16:8e0d178b1d1e 4631
wolfSSL 16:8e0d178b1d1e 4632 if (ret != 0) {
wolfSSL 16:8e0d178b1d1e 4633 break;
wolfSSL 16:8e0d178b1d1e 4634 }
wolfSSL 16:8e0d178b1d1e 4635 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 4636 if (in2 && in2Sz > 0 && hashBuf && hashSz > 0) {
wolfSSL 16:8e0d178b1d1e 4637 stateIdx = idx; /* case where all data was read from in2 */
wolfSSL 16:8e0d178b1d1e 4638 }
wolfSSL 16:8e0d178b1d1e 4639
wolfSSL 16:8e0d178b1d1e 4640 if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &stateIdx, &idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 4641 break;
wolfSSL 16:8e0d178b1d1e 4642 }
wolfSSL 16:8e0d178b1d1e 4643 wc_PKCS7_StreamStoreVar(pkcs7, pkiMsg2Sz, 0, length);
wolfSSL 16:8e0d178b1d1e 4644 if (length > 0) {
wolfSSL 16:8e0d178b1d1e 4645 pkcs7->stream->expected = length;
wolfSSL 16:8e0d178b1d1e 4646 }
wolfSSL 16:8e0d178b1d1e 4647 else {
wolfSSL 16:8e0d178b1d1e 4648 pkcs7->stream->expected = MAX_SEQ_SZ;
wolfSSL 16:8e0d178b1d1e 4649 if (pkcs7->stream->expected > (pkcs7->stream->maxLen -
wolfSSL 16:8e0d178b1d1e 4650 pkcs7->stream->totalRd) + pkcs7->stream->length) {
wolfSSL 16:8e0d178b1d1e 4651 pkcs7->stream->expected = (pkcs7->stream->maxLen -
wolfSSL 16:8e0d178b1d1e 4652 pkcs7->stream->totalRd) + pkcs7->stream->length;
wolfSSL 16:8e0d178b1d1e 4653 }
wolfSSL 16:8e0d178b1d1e 4654 }
wolfSSL 16:8e0d178b1d1e 4655 #endif
wolfSSL 16:8e0d178b1d1e 4656 wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_VERIFY_STAGE4);
wolfSSL 16:8e0d178b1d1e 4657 FALL_THROUGH;
wolfSSL 16:8e0d178b1d1e 4658
wolfSSL 16:8e0d178b1d1e 4659 case WC_PKCS7_VERIFY_STAGE4:
wolfSSL 16:8e0d178b1d1e 4660 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 4661 if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz + in2Sz,
wolfSSL 16:8e0d178b1d1e 4662 pkcs7->stream->expected, &pkiMsg, &idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 4663 break;
wolfSSL 16:8e0d178b1d1e 4664 }
wolfSSL 16:8e0d178b1d1e 4665
wolfSSL 16:8e0d178b1d1e 4666 wc_PKCS7_StreamGetVar(pkcs7, &pkiMsg2Sz, 0, &length);
wolfSSL 16:8e0d178b1d1e 4667 if (pkcs7->stream->flagOne) {
wolfSSL 16:8e0d178b1d1e 4668 pkiMsg2 = pkiMsg;
wolfSSL 16:8e0d178b1d1e 4669 }
wolfSSL 16:8e0d178b1d1e 4670
wolfSSL 16:8e0d178b1d1e 4671 /* restore content */
wolfSSL 16:8e0d178b1d1e 4672 content = pkcs7->stream->content;
wolfSSL 16:8e0d178b1d1e 4673 contentSz = pkcs7->stream->contentSz;
wolfSSL 16:8e0d178b1d1e 4674
wolfSSL 16:8e0d178b1d1e 4675 /* restore detached flag */
wolfSSL 16:8e0d178b1d1e 4676 detached = pkcs7->stream->detached;
wolfSSL 16:8e0d178b1d1e 4677
wolfSSL 16:8e0d178b1d1e 4678 /* store certificate if needed */
wolfSSL 16:8e0d178b1d1e 4679 if (length > 0 && in2Sz == 0) {
wolfSSL 16:8e0d178b1d1e 4680 /* free tmpCert if not NULL */
wolfSSL 16:8e0d178b1d1e 4681 XFREE(pkcs7->stream->tmpCert, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 4682 pkcs7->stream->tmpCert = (byte*)XMALLOC(length,
wolfSSL 16:8e0d178b1d1e 4683 pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 4684 if ((pkiMsg2 == NULL) || (pkcs7->stream->tmpCert == NULL)) {
wolfSSL 16:8e0d178b1d1e 4685 ret = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 4686 break;
wolfSSL 16:8e0d178b1d1e 4687 }
wolfSSL 16:8e0d178b1d1e 4688 XMEMCPY(pkcs7->stream->tmpCert, pkiMsg2 + idx, length);
wolfSSL 16:8e0d178b1d1e 4689 pkiMsg2 = pkcs7->stream->tmpCert;
wolfSSL 16:8e0d178b1d1e 4690 pkiMsg2Sz = length;
wolfSSL 16:8e0d178b1d1e 4691 idx = 0;
wolfSSL 16:8e0d178b1d1e 4692 }
wolfSSL 16:8e0d178b1d1e 4693 #endif
wolfSSL 16:8e0d178b1d1e 4694
wolfSSL 16:8e0d178b1d1e 4695 if (length > 0) {
wolfSSL 16:8e0d178b1d1e 4696 /* At this point, idx is at the first certificate in
wolfSSL 16:8e0d178b1d1e 4697 * a set of certificates. There may be more than one,
wolfSSL 16:8e0d178b1d1e 4698 * or none, or they may be a PKCS 6 extended
wolfSSL 16:8e0d178b1d1e 4699 * certificate. We want to save the first cert if it
wolfSSL 16:8e0d178b1d1e 4700 * is X.509. */
wolfSSL 16:8e0d178b1d1e 4701
wolfSSL 16:8e0d178b1d1e 4702 word32 certIdx = idx;
wolfSSL 16:8e0d178b1d1e 4703
wolfSSL 16:8e0d178b1d1e 4704 if (length < MAX_LENGTH_SZ + ASN_TAG_SZ)
wolfSSL 16:8e0d178b1d1e 4705 ret = BUFFER_E;
wolfSSL 16:8e0d178b1d1e 4706
wolfSSL 16:8e0d178b1d1e 4707 if (ret == 0)
wolfSSL 16:8e0d178b1d1e 4708 ret = GetASNTag(pkiMsg2, &certIdx, &tag, pkiMsg2Sz);
wolfSSL 16:8e0d178b1d1e 4709
wolfSSL 16:8e0d178b1d1e 4710 if (ret == 0 && tag == (ASN_CONSTRUCTED | ASN_SEQUENCE)) {
wolfSSL 16:8e0d178b1d1e 4711 if (GetLength(pkiMsg2, &certIdx, &certSz, pkiMsg2Sz) < 0)
wolfSSL 16:8e0d178b1d1e 4712 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 4713
wolfSSL 16:8e0d178b1d1e 4714 cert = &pkiMsg2[idx];
wolfSSL 16:8e0d178b1d1e 4715 certSz += (certIdx - idx);
wolfSSL 16:8e0d178b1d1e 4716 if (certSz > length) {
wolfSSL 16:8e0d178b1d1e 4717 ret = BUFFER_E;
wolfSSL 16:8e0d178b1d1e 4718 break;
wolfSSL 16:8e0d178b1d1e 4719 }
wolfSSL 16:8e0d178b1d1e 4720 }
wolfSSL 16:8e0d178b1d1e 4721 #ifdef ASN_BER_TO_DER
wolfSSL 16:8e0d178b1d1e 4722 der = pkcs7->der;
wolfSSL 16:8e0d178b1d1e 4723 #endif
wolfSSL 16:8e0d178b1d1e 4724 contentDynamic = pkcs7->contentDynamic;
wolfSSL 16:8e0d178b1d1e 4725 version = pkcs7->version;
wolfSSL 16:8e0d178b1d1e 4726
wolfSSL 16:8e0d178b1d1e 4727
wolfSSL 16:8e0d178b1d1e 4728 if (ret == 0) {
wolfSSL 16:8e0d178b1d1e 4729 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 4730 PKCS7State* stream = pkcs7->stream;
wolfSSL 16:8e0d178b1d1e 4731 #endif
wolfSSL 16:8e0d178b1d1e 4732 /* This will reset PKCS7 structure and then set the
wolfSSL 16:8e0d178b1d1e 4733 * certificate */
wolfSSL 16:8e0d178b1d1e 4734 ret = wc_PKCS7_InitWithCert(pkcs7, cert, certSz);
wolfSSL 16:8e0d178b1d1e 4735 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 4736 pkcs7->stream = stream;
wolfSSL 16:8e0d178b1d1e 4737 #endif
wolfSSL 16:8e0d178b1d1e 4738 }
wolfSSL 16:8e0d178b1d1e 4739 pkcs7->contentDynamic = contentDynamic;
wolfSSL 16:8e0d178b1d1e 4740 pkcs7->version = version;
wolfSSL 16:8e0d178b1d1e 4741 #ifdef ASN_BER_TO_DER
wolfSSL 16:8e0d178b1d1e 4742 pkcs7->der = der;
wolfSSL 16:8e0d178b1d1e 4743 #endif
wolfSSL 16:8e0d178b1d1e 4744 if (ret != 0)
wolfSSL 16:8e0d178b1d1e 4745 break;
wolfSSL 16:8e0d178b1d1e 4746
wolfSSL 16:8e0d178b1d1e 4747 /* iterate through any additional certificates */
wolfSSL 16:8e0d178b1d1e 4748 if (ret == 0 && MAX_PKCS7_CERTS > 0) {
wolfSSL 16:8e0d178b1d1e 4749 int sz = 0;
wolfSSL 16:8e0d178b1d1e 4750 int i;
wolfSSL 16:8e0d178b1d1e 4751
wolfSSL 16:8e0d178b1d1e 4752 pkcs7->cert[0] = cert;
wolfSSL 16:8e0d178b1d1e 4753 pkcs7->certSz[0] = certSz;
wolfSSL 16:8e0d178b1d1e 4754 certIdx = idx + certSz;
wolfSSL 16:8e0d178b1d1e 4755
wolfSSL 16:8e0d178b1d1e 4756 for (i = 1; i < MAX_PKCS7_CERTS &&
wolfSSL 16:8e0d178b1d1e 4757 certIdx + 1 < pkiMsg2Sz &&
wolfSSL 16:8e0d178b1d1e 4758 certIdx + 1 < (word32)length; i++) {
wolfSSL 16:8e0d178b1d1e 4759 localIdx = certIdx;
wolfSSL 16:8e0d178b1d1e 4760
wolfSSL 16:8e0d178b1d1e 4761 if (ret == 0 && GetASNTag(pkiMsg2, &certIdx, &tag,
wolfSSL 16:8e0d178b1d1e 4762 pkiMsg2Sz) < 0) {
wolfSSL 16:8e0d178b1d1e 4763 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 4764 break;
wolfSSL 16:8e0d178b1d1e 4765 }
wolfSSL 16:8e0d178b1d1e 4766
wolfSSL 16:8e0d178b1d1e 4767 if (ret == 0 &&
wolfSSL 16:8e0d178b1d1e 4768 tag == (ASN_CONSTRUCTED | ASN_SEQUENCE)) {
wolfSSL 16:8e0d178b1d1e 4769 if (GetLength(pkiMsg2, &certIdx, &sz,
wolfSSL 16:8e0d178b1d1e 4770 pkiMsg2Sz) < 0) {
wolfSSL 16:8e0d178b1d1e 4771 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 4772 break;
wolfSSL 16:8e0d178b1d1e 4773 }
wolfSSL 16:8e0d178b1d1e 4774
wolfSSL 16:8e0d178b1d1e 4775 pkcs7->cert[i] = &pkiMsg2[localIdx];
wolfSSL 16:8e0d178b1d1e 4776 pkcs7->certSz[i] = sz + (certIdx - localIdx);
wolfSSL 16:8e0d178b1d1e 4777 certIdx += sz;
wolfSSL 16:8e0d178b1d1e 4778 }
wolfSSL 16:8e0d178b1d1e 4779 }
wolfSSL 16:8e0d178b1d1e 4780 }
wolfSSL 16:8e0d178b1d1e 4781 }
wolfSSL 16:8e0d178b1d1e 4782 idx += length;
wolfSSL 16:8e0d178b1d1e 4783
wolfSSL 16:8e0d178b1d1e 4784 if (!detached) {
wolfSSL 16:8e0d178b1d1e 4785 /* set content and size after init of PKCS7 structure */
wolfSSL 16:8e0d178b1d1e 4786 pkcs7->content = content;
wolfSSL 16:8e0d178b1d1e 4787 pkcs7->contentSz = contentSz;
wolfSSL 16:8e0d178b1d1e 4788 }
wolfSSL 16:8e0d178b1d1e 4789 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 4790 else {
wolfSSL 16:8e0d178b1d1e 4791 /* save content if detached and using streaming API */
wolfSSL 16:8e0d178b1d1e 4792 if (pkcs7->content != NULL) {
wolfSSL 16:8e0d178b1d1e 4793 XFREE(pkcs7->stream->content, pkcs7->heap,
wolfSSL 16:8e0d178b1d1e 4794 DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 4795 pkcs7->stream->content = (byte*)XMALLOC(pkcs7->contentSz,
wolfSSL 16:8e0d178b1d1e 4796 pkcs7->heap,
wolfSSL 16:8e0d178b1d1e 4797 DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 4798 if (pkcs7->stream->content == NULL) {
wolfSSL 16:8e0d178b1d1e 4799 ret = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 4800 break;
wolfSSL 16:8e0d178b1d1e 4801 }
wolfSSL 16:8e0d178b1d1e 4802 else {
wolfSSL 16:8e0d178b1d1e 4803 XMEMCPY(pkcs7->stream->content, pkcs7->content,
wolfSSL 16:8e0d178b1d1e 4804 contentSz);
wolfSSL 16:8e0d178b1d1e 4805 pkcs7->stream->contentSz = pkcs7->contentSz;
wolfSSL 16:8e0d178b1d1e 4806 }
wolfSSL 16:8e0d178b1d1e 4807 }
wolfSSL 16:8e0d178b1d1e 4808 }
wolfSSL 16:8e0d178b1d1e 4809 #endif
wolfSSL 16:8e0d178b1d1e 4810
wolfSSL 16:8e0d178b1d1e 4811 if (ret != 0) {
wolfSSL 16:8e0d178b1d1e 4812 break;
wolfSSL 16:8e0d178b1d1e 4813 }
wolfSSL 16:8e0d178b1d1e 4814 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 4815 /* factor in that recent idx was in cert buffer. If in2 buffer was
wolfSSL 16:8e0d178b1d1e 4816 * used then don't advance idx. */
wolfSSL 16:8e0d178b1d1e 4817 if (length > 0 && pkcs7->stream->flagOne &&
wolfSSL 16:8e0d178b1d1e 4818 pkcs7->stream->length == 0) {
wolfSSL 16:8e0d178b1d1e 4819 idx = stateIdx + idx;
wolfSSL 16:8e0d178b1d1e 4820 if (idx > inSz) {
wolfSSL 16:8e0d178b1d1e 4821 /* index is more than input size */
wolfSSL 16:8e0d178b1d1e 4822 ret = BUFFER_E;
wolfSSL 16:8e0d178b1d1e 4823 break;
wolfSSL 16:8e0d178b1d1e 4824 }
wolfSSL 16:8e0d178b1d1e 4825 }
wolfSSL 16:8e0d178b1d1e 4826 else {
wolfSSL 16:8e0d178b1d1e 4827 stateIdx = idx; /* didn't read any from internal buffer */
wolfSSL 16:8e0d178b1d1e 4828 }
wolfSSL 16:8e0d178b1d1e 4829
wolfSSL 16:8e0d178b1d1e 4830 if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &stateIdx, &idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 4831 break;
wolfSSL 16:8e0d178b1d1e 4832 }
wolfSSL 16:8e0d178b1d1e 4833 if (pkcs7->stream->flagOne && pkcs7->stream->length > 0) {
wolfSSL 16:8e0d178b1d1e 4834 idx = stateIdx + idx;
wolfSSL 16:8e0d178b1d1e 4835 }
wolfSSL 16:8e0d178b1d1e 4836
wolfSSL 16:8e0d178b1d1e 4837 pkcs7->stream->expected = MAX_OID_SZ + ASN_TAG_SZ + MAX_LENGTH_SZ +
wolfSSL 16:8e0d178b1d1e 4838 MAX_SET_SZ;
wolfSSL 16:8e0d178b1d1e 4839
wolfSSL 16:8e0d178b1d1e 4840 if (pkcs7->stream->expected > (pkcs7->stream->maxLen -
wolfSSL 16:8e0d178b1d1e 4841 pkcs7->stream->totalRd) + pkcs7->stream->length)
wolfSSL 16:8e0d178b1d1e 4842 pkcs7->stream->expected = (pkcs7->stream->maxLen -
wolfSSL 16:8e0d178b1d1e 4843 pkcs7->stream->totalRd) + pkcs7->stream->length;
wolfSSL 16:8e0d178b1d1e 4844
wolfSSL 16:8e0d178b1d1e 4845 wc_PKCS7_StreamGetVar(pkcs7, &pkiMsg2Sz, 0, 0);
wolfSSL 16:8e0d178b1d1e 4846 wc_PKCS7_StreamStoreVar(pkcs7, pkiMsg2Sz, 0, length);
wolfSSL 16:8e0d178b1d1e 4847 #endif
wolfSSL 16:8e0d178b1d1e 4848 wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_VERIFY_STAGE5);
wolfSSL 16:8e0d178b1d1e 4849 FALL_THROUGH;
wolfSSL 16:8e0d178b1d1e 4850
wolfSSL 16:8e0d178b1d1e 4851 case WC_PKCS7_VERIFY_STAGE5:
wolfSSL 16:8e0d178b1d1e 4852 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 4853 if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz + in2Sz,
wolfSSL 16:8e0d178b1d1e 4854 pkcs7->stream->expected, &pkiMsg, &idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 4855 break;
wolfSSL 16:8e0d178b1d1e 4856 }
wolfSSL 16:8e0d178b1d1e 4857 wc_PKCS7_StreamGetVar(pkcs7, &pkiMsg2Sz, 0, &length);
wolfSSL 16:8e0d178b1d1e 4858 if (pkcs7->stream->flagOne) {
wolfSSL 16:8e0d178b1d1e 4859 pkiMsg2 = pkiMsg;
wolfSSL 16:8e0d178b1d1e 4860 }
wolfSSL 16:8e0d178b1d1e 4861
wolfSSL 16:8e0d178b1d1e 4862 /* restore content type */
wolfSSL 16:8e0d178b1d1e 4863 contentType = pkcs7->stream->nonce;
wolfSSL 16:8e0d178b1d1e 4864 contentTypeSz = pkcs7->stream->nonceSz;
wolfSSL 16:8e0d178b1d1e 4865
wolfSSL 16:8e0d178b1d1e 4866 maxIdx = idx + pkcs7->stream->expected;
wolfSSL 16:8e0d178b1d1e 4867 if (maxIdx > pkiMsg2Sz) {
wolfSSL 16:8e0d178b1d1e 4868 ret = BUFFER_E;
wolfSSL 16:8e0d178b1d1e 4869 break;
wolfSSL 16:8e0d178b1d1e 4870 }
wolfSSL 16:8e0d178b1d1e 4871 stateIdx = idx;
wolfSSL 16:8e0d178b1d1e 4872 #endif
wolfSSL 16:8e0d178b1d1e 4873
wolfSSL 16:8e0d178b1d1e 4874 /* set contentType and size after init of PKCS7 structure */
wolfSSL 16:8e0d178b1d1e 4875 if (ret == 0 && wc_PKCS7_SetContentType(pkcs7, contentType,
wolfSSL 16:8e0d178b1d1e 4876 contentTypeSz) < 0)
wolfSSL 16:8e0d178b1d1e 4877 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 4878
wolfSSL 16:8e0d178b1d1e 4879 /* Get the implicit[1] set of crls */
wolfSSL 16:8e0d178b1d1e 4880 if (ret == 0 && idx >= maxIdx)
wolfSSL 16:8e0d178b1d1e 4881 ret = BUFFER_E;
wolfSSL 16:8e0d178b1d1e 4882
wolfSSL 16:8e0d178b1d1e 4883 localIdx = idx;
wolfSSL 16:8e0d178b1d1e 4884 if (ret == 0 && GetASNTag(pkiMsg2, &localIdx, &tag, pkiMsg2Sz) == 0
wolfSSL 16:8e0d178b1d1e 4885 && tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) {
wolfSSL 16:8e0d178b1d1e 4886 idx++;
wolfSSL 16:8e0d178b1d1e 4887 if (GetLength(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0)
wolfSSL 16:8e0d178b1d1e 4888 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 4889
wolfSSL 16:8e0d178b1d1e 4890 /* Skip the set */
wolfSSL 16:8e0d178b1d1e 4891 idx += length;
wolfSSL 16:8e0d178b1d1e 4892 }
wolfSSL 16:8e0d178b1d1e 4893
wolfSSL 16:8e0d178b1d1e 4894 /* Get the set of signerInfos */
wolfSSL 16:8e0d178b1d1e 4895 if (ret == 0 && GetSet_ex(pkiMsg2, &idx, &length, maxIdx,
wolfSSL 16:8e0d178b1d1e 4896 NO_USER_CHECK) < 0)
wolfSSL 16:8e0d178b1d1e 4897 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 4898
wolfSSL 16:8e0d178b1d1e 4899 if (ret != 0)
wolfSSL 16:8e0d178b1d1e 4900 break;
wolfSSL 16:8e0d178b1d1e 4901 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 4902 if (!pkcs7->stream->flagOne) {
wolfSSL 16:8e0d178b1d1e 4903 stateIdx = idx; /* didn't read any from internal buffer */
wolfSSL 16:8e0d178b1d1e 4904 }
wolfSSL 16:8e0d178b1d1e 4905 if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &stateIdx, &idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 4906 break;
wolfSSL 16:8e0d178b1d1e 4907 }
wolfSSL 16:8e0d178b1d1e 4908 wc_PKCS7_StreamStoreVar(pkcs7, pkiMsg2Sz, 0, length);
wolfSSL 16:8e0d178b1d1e 4909
wolfSSL 16:8e0d178b1d1e 4910 if (in2 && in2Sz > 0 && hashBuf && hashSz > 0) {
wolfSSL 16:8e0d178b1d1e 4911 if (length > 0) {
wolfSSL 16:8e0d178b1d1e 4912 pkcs7->stream->expected = length;
wolfSSL 16:8e0d178b1d1e 4913 }
wolfSSL 16:8e0d178b1d1e 4914 else {
wolfSSL 16:8e0d178b1d1e 4915 pkcs7->stream->expected = 0;
wolfSSL 16:8e0d178b1d1e 4916 }
wolfSSL 16:8e0d178b1d1e 4917 }
wolfSSL 16:8e0d178b1d1e 4918 else {
wolfSSL 16:8e0d178b1d1e 4919 /* last state expect the reset of the buffer */
wolfSSL 16:8e0d178b1d1e 4920 pkcs7->stream->expected = (pkcs7->stream->maxLen -
wolfSSL 16:8e0d178b1d1e 4921 pkcs7->stream->totalRd) + pkcs7->stream->length;
wolfSSL 16:8e0d178b1d1e 4922 }
wolfSSL 16:8e0d178b1d1e 4923
wolfSSL 16:8e0d178b1d1e 4924 #endif
wolfSSL 16:8e0d178b1d1e 4925 wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_VERIFY_STAGE6);
wolfSSL 16:8e0d178b1d1e 4926 FALL_THROUGH;
wolfSSL 16:8e0d178b1d1e 4927
wolfSSL 16:8e0d178b1d1e 4928 case WC_PKCS7_VERIFY_STAGE6:
wolfSSL 16:8e0d178b1d1e 4929 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 4930 if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz + in2Sz,
wolfSSL 16:8e0d178b1d1e 4931 pkcs7->stream->expected, &pkiMsg, &idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 4932 break;
wolfSSL 16:8e0d178b1d1e 4933 }
wolfSSL 16:8e0d178b1d1e 4934
wolfSSL 16:8e0d178b1d1e 4935 wc_PKCS7_StreamGetVar(pkcs7, &pkiMsg2Sz, 0, &length);
wolfSSL 16:8e0d178b1d1e 4936 if (pkcs7->stream->flagOne) {
wolfSSL 16:8e0d178b1d1e 4937 pkiMsg2 = pkiMsg;
wolfSSL 16:8e0d178b1d1e 4938 }
wolfSSL 16:8e0d178b1d1e 4939
wolfSSL 16:8e0d178b1d1e 4940 /* restore content */
wolfSSL 16:8e0d178b1d1e 4941 content = pkcs7->stream->content;
wolfSSL 16:8e0d178b1d1e 4942 contentSz = pkcs7->stream->contentSz;
wolfSSL 16:8e0d178b1d1e 4943 #endif
wolfSSL 16:8e0d178b1d1e 4944
wolfSSL 16:8e0d178b1d1e 4945 ret = wc_PKCS7_ParseSignerInfo(pkcs7, pkiMsg2, pkiMsg2Sz, &idx,
wolfSSL 16:8e0d178b1d1e 4946 degenerate, &signedAttrib, &signedAttribSz);
wolfSSL 16:8e0d178b1d1e 4947
wolfSSL 16:8e0d178b1d1e 4948 /* parse out the signature if present and verify it */
wolfSSL 16:8e0d178b1d1e 4949 if (ret == 0 && length > 0 && degenerate == 0) {
wolfSSL 16:8e0d178b1d1e 4950 WOLFSSL_MSG("Parsing signature and verifying");
wolfSSL 16:8e0d178b1d1e 4951 if (idx >= pkiMsg2Sz)
wolfSSL 16:8e0d178b1d1e 4952 ret = BUFFER_E;
wolfSSL 16:8e0d178b1d1e 4953
wolfSSL 16:8e0d178b1d1e 4954 /* Get the signature */
wolfSSL 16:8e0d178b1d1e 4955 localIdx = idx;
wolfSSL 16:8e0d178b1d1e 4956 if (ret == 0 && GetASNTag(pkiMsg2, &localIdx, &tag,
wolfSSL 16:8e0d178b1d1e 4957 pkiMsg2Sz) == 0 && tag == ASN_OCTET_STRING) {
wolfSSL 16:8e0d178b1d1e 4958 idx++;
wolfSSL 16:8e0d178b1d1e 4959
wolfSSL 16:8e0d178b1d1e 4960 if (GetLength(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0)
wolfSSL 16:8e0d178b1d1e 4961 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 4962
wolfSSL 16:8e0d178b1d1e 4963 /* save pointer and length */
wolfSSL 16:8e0d178b1d1e 4964 sig = &pkiMsg2[idx];
wolfSSL 16:8e0d178b1d1e 4965 sigSz = length;
wolfSSL 16:8e0d178b1d1e 4966
wolfSSL 16:8e0d178b1d1e 4967 idx += length;
wolfSSL 16:8e0d178b1d1e 4968 }
wolfSSL 16:8e0d178b1d1e 4969
wolfSSL 16:8e0d178b1d1e 4970 pkcs7->content = content;
wolfSSL 16:8e0d178b1d1e 4971 pkcs7->contentSz = contentSz;
wolfSSL 16:8e0d178b1d1e 4972
wolfSSL 16:8e0d178b1d1e 4973 if (ret == 0) {
wolfSSL 16:8e0d178b1d1e 4974 ret = wc_PKCS7_SignedDataVerifySignature(pkcs7, sig, sigSz,
wolfSSL 16:8e0d178b1d1e 4975 signedAttrib, signedAttribSz,
wolfSSL 16:8e0d178b1d1e 4976 hashBuf, hashSz);
wolfSSL 16:8e0d178b1d1e 4977 }
wolfSSL 16:8e0d178b1d1e 4978 }
wolfSSL 16:8e0d178b1d1e 4979
wolfSSL 16:8e0d178b1d1e 4980 if (ret < 0)
wolfSSL 16:8e0d178b1d1e 4981 break;
wolfSSL 16:8e0d178b1d1e 4982
wolfSSL 16:8e0d178b1d1e 4983 ret = 0; /* success */
wolfSSL 16:8e0d178b1d1e 4984 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 4985 wc_PKCS7_ResetStream(pkcs7);
wolfSSL 16:8e0d178b1d1e 4986 #endif
wolfSSL 16:8e0d178b1d1e 4987 wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_START);
wolfSSL 16:8e0d178b1d1e 4988 break;
wolfSSL 16:8e0d178b1d1e 4989
wolfSSL 16:8e0d178b1d1e 4990 default:
wolfSSL 16:8e0d178b1d1e 4991 WOLFSSL_MSG("PKCS7 Unknown verify state");
wolfSSL 16:8e0d178b1d1e 4992 ret = BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 4993 }
wolfSSL 16:8e0d178b1d1e 4994
wolfSSL 16:8e0d178b1d1e 4995 if (ret != 0 && ret != WC_PKCS7_WANT_READ_E) {
wolfSSL 16:8e0d178b1d1e 4996 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 4997 wc_PKCS7_ResetStream(pkcs7);
wolfSSL 16:8e0d178b1d1e 4998 #endif
wolfSSL 16:8e0d178b1d1e 4999 wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_START);
wolfSSL 16:8e0d178b1d1e 5000 }
wolfSSL 16:8e0d178b1d1e 5001 return ret;
wolfSSL 16:8e0d178b1d1e 5002 }
wolfSSL 16:8e0d178b1d1e 5003
wolfSSL 16:8e0d178b1d1e 5004
wolfSSL 16:8e0d178b1d1e 5005 /* Gets a copy of the SID parsed from signerInfo. This can be called after
wolfSSL 16:8e0d178b1d1e 5006 * wc_PKCS7_VerifySignedData has been called. SID can be SKID in version 3 case
wolfSSL 16:8e0d178b1d1e 5007 * or issuerAndSerialNumber.
wolfSSL 16:8e0d178b1d1e 5008 *
wolfSSL 16:8e0d178b1d1e 5009 * return 0 on success and LENGTH_ONLY_E if just setting "outSz" for buffer
wolfSSL 16:8e0d178b1d1e 5010 * length needed.
wolfSSL 16:8e0d178b1d1e 5011 */
wolfSSL 16:8e0d178b1d1e 5012 int wc_PKCS7_GetSignerSID(PKCS7* pkcs7, byte* out, word32* outSz)
wolfSSL 16:8e0d178b1d1e 5013 {
wolfSSL 16:8e0d178b1d1e 5014 if (outSz == NULL || pkcs7 == NULL) {
wolfSSL 16:8e0d178b1d1e 5015 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 5016 }
wolfSSL 16:8e0d178b1d1e 5017
wolfSSL 16:8e0d178b1d1e 5018 if (pkcs7->signerInfo == NULL) {
wolfSSL 16:8e0d178b1d1e 5019 WOLFSSL_MSG("Either the bundle had no signers or"
wolfSSL 16:8e0d178b1d1e 5020 "wc_PKCS7_VerifySignedData needs called yet");
wolfSSL 16:8e0d178b1d1e 5021 return PKCS7_NO_SIGNER_E;
wolfSSL 16:8e0d178b1d1e 5022 }
wolfSSL 16:8e0d178b1d1e 5023
wolfSSL 16:8e0d178b1d1e 5024 if (pkcs7->signerInfo->sidSz == 0) {
wolfSSL 16:8e0d178b1d1e 5025 WOLFSSL_MSG("Bundle had no signer SID set");
wolfSSL 16:8e0d178b1d1e 5026 return PKCS7_NO_SIGNER_E;
wolfSSL 16:8e0d178b1d1e 5027 }
wolfSSL 16:8e0d178b1d1e 5028
wolfSSL 16:8e0d178b1d1e 5029 if (out == NULL) {
wolfSSL 16:8e0d178b1d1e 5030 *outSz = pkcs7->signerInfo->sidSz;
wolfSSL 16:8e0d178b1d1e 5031 return LENGTH_ONLY_E;
wolfSSL 16:8e0d178b1d1e 5032 }
wolfSSL 16:8e0d178b1d1e 5033
wolfSSL 16:8e0d178b1d1e 5034 if (*outSz < pkcs7->signerInfo->sidSz) {
wolfSSL 16:8e0d178b1d1e 5035 WOLFSSL_MSG("Buffer being passed in is not large enough for SKID");
wolfSSL 16:8e0d178b1d1e 5036 return BUFFER_E;
wolfSSL 16:8e0d178b1d1e 5037 }
wolfSSL 16:8e0d178b1d1e 5038 XMEMCPY(out, pkcs7->signerInfo->sid, pkcs7->signerInfo->sidSz);
wolfSSL 16:8e0d178b1d1e 5039 *outSz = pkcs7->signerInfo->sidSz;
wolfSSL 16:8e0d178b1d1e 5040 return 0;
wolfSSL 16:8e0d178b1d1e 5041 }
wolfSSL 16:8e0d178b1d1e 5042
wolfSSL 16:8e0d178b1d1e 5043
wolfSSL 16:8e0d178b1d1e 5044 /* variant that allows computed data hash and header/foot,
wolfSSL 16:8e0d178b1d1e 5045 * which is useful for large data signing */
wolfSSL 16:8e0d178b1d1e 5046 int wc_PKCS7_VerifySignedData_ex(PKCS7* pkcs7, const byte* hashBuf,
wolfSSL 16:8e0d178b1d1e 5047 word32 hashSz, byte* pkiMsgHead, word32 pkiMsgHeadSz, byte* pkiMsgFoot,
wolfSSL 16:8e0d178b1d1e 5048 word32 pkiMsgFootSz)
wolfSSL 16:8e0d178b1d1e 5049 {
wolfSSL 16:8e0d178b1d1e 5050 return PKCS7_VerifySignedData(pkcs7, hashBuf, hashSz,
wolfSSL 16:8e0d178b1d1e 5051 pkiMsgHead, pkiMsgHeadSz, pkiMsgFoot, pkiMsgFootSz);
wolfSSL 16:8e0d178b1d1e 5052 }
wolfSSL 16:8e0d178b1d1e 5053
wolfSSL 16:8e0d178b1d1e 5054 int wc_PKCS7_VerifySignedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz)
wolfSSL 16:8e0d178b1d1e 5055 {
wolfSSL 16:8e0d178b1d1e 5056 return PKCS7_VerifySignedData(pkcs7, NULL, 0, pkiMsg, pkiMsgSz, NULL, 0);
wolfSSL 16:8e0d178b1d1e 5057 }
wolfSSL 16:8e0d178b1d1e 5058
wolfSSL 16:8e0d178b1d1e 5059
wolfSSL 16:8e0d178b1d1e 5060 /* Generate random content encryption key, store into pkcs7->cek and
wolfSSL 16:8e0d178b1d1e 5061 * pkcs7->cekSz.
wolfSSL 16:8e0d178b1d1e 5062 *
wolfSSL 16:8e0d178b1d1e 5063 * pkcs7 - pointer to initialized PKCS7 structure
wolfSSL 16:8e0d178b1d1e 5064 * len - length of key to be generated
wolfSSL 16:8e0d178b1d1e 5065 *
wolfSSL 16:8e0d178b1d1e 5066 * Returns 0 on success, negative upon error */
wolfSSL 16:8e0d178b1d1e 5067 static int PKCS7_GenerateContentEncryptionKey(PKCS7* pkcs7, word32 len)
wolfSSL 16:8e0d178b1d1e 5068 {
wolfSSL 16:8e0d178b1d1e 5069 int ret;
wolfSSL 16:8e0d178b1d1e 5070 WC_RNG rng;
wolfSSL 16:8e0d178b1d1e 5071 byte* tmpKey;
wolfSSL 16:8e0d178b1d1e 5072
wolfSSL 16:8e0d178b1d1e 5073 if (pkcs7 == NULL || len == 0)
wolfSSL 16:8e0d178b1d1e 5074 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 5075
wolfSSL 16:8e0d178b1d1e 5076 /* if key already exists, don't need to re-generate */
wolfSSL 16:8e0d178b1d1e 5077 if (pkcs7->cek != NULL && pkcs7->cekSz != 0) {
wolfSSL 16:8e0d178b1d1e 5078
wolfSSL 16:8e0d178b1d1e 5079 /* if key exists, but is different size, return error */
wolfSSL 16:8e0d178b1d1e 5080 if (pkcs7->cekSz != len) {
wolfSSL 16:8e0d178b1d1e 5081 WOLFSSL_MSG("Random content-encryption key size is inconsistent "
wolfSSL 16:8e0d178b1d1e 5082 "between CMS recipients");
wolfSSL 16:8e0d178b1d1e 5083 return WC_KEY_SIZE_E;
wolfSSL 16:8e0d178b1d1e 5084 }
wolfSSL 16:8e0d178b1d1e 5085
wolfSSL 16:8e0d178b1d1e 5086 return 0;
wolfSSL 16:8e0d178b1d1e 5087 }
wolfSSL 16:8e0d178b1d1e 5088
wolfSSL 16:8e0d178b1d1e 5089 /* allocate space for cek */
wolfSSL 16:8e0d178b1d1e 5090 tmpKey = (byte*)XMALLOC(len, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 5091 if (tmpKey == NULL)
wolfSSL 16:8e0d178b1d1e 5092 return MEMORY_E;
wolfSSL 16:8e0d178b1d1e 5093
wolfSSL 16:8e0d178b1d1e 5094 XMEMSET(tmpKey, 0, len);
wolfSSL 16:8e0d178b1d1e 5095
wolfSSL 16:8e0d178b1d1e 5096 ret = wc_InitRng_ex(&rng, pkcs7->heap, pkcs7->devId);
wolfSSL 16:8e0d178b1d1e 5097 if (ret != 0) {
wolfSSL 16:8e0d178b1d1e 5098 XFREE(tmpKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 5099 return ret;
wolfSSL 16:8e0d178b1d1e 5100 }
wolfSSL 16:8e0d178b1d1e 5101
wolfSSL 16:8e0d178b1d1e 5102 ret = wc_RNG_GenerateBlock(&rng, tmpKey, len);
wolfSSL 16:8e0d178b1d1e 5103 if (ret != 0) {
wolfSSL 16:8e0d178b1d1e 5104 wc_FreeRng(&rng);
wolfSSL 16:8e0d178b1d1e 5105 XFREE(tmpKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 5106 return ret;
wolfSSL 16:8e0d178b1d1e 5107 }
wolfSSL 16:8e0d178b1d1e 5108
wolfSSL 16:8e0d178b1d1e 5109 /* store into PKCS7, memory freed during final cleanup */
wolfSSL 16:8e0d178b1d1e 5110 pkcs7->cek = tmpKey;
wolfSSL 16:8e0d178b1d1e 5111 pkcs7->cekSz = len;
wolfSSL 16:8e0d178b1d1e 5112
wolfSSL 16:8e0d178b1d1e 5113 wc_FreeRng(&rng);
wolfSSL 15:117db924cf7c 5114
wolfSSL 15:117db924cf7c 5115 return 0;
wolfSSL 15:117db924cf7c 5116 }
wolfSSL 15:117db924cf7c 5117
wolfSSL 15:117db924cf7c 5118
wolfSSL 15:117db924cf7c 5119 /* wrap CEK (content encryption key) with KEK, 0 on success, < 0 on error */
wolfSSL 16:8e0d178b1d1e 5120 static int wc_PKCS7_KeyWrap(byte* cek, word32 cekSz, byte* kek,
wolfSSL 16:8e0d178b1d1e 5121 word32 kekSz, byte* out, word32 outSz,
wolfSSL 16:8e0d178b1d1e 5122 int keyWrapAlgo, int direction)
wolfSSL 16:8e0d178b1d1e 5123 {
wolfSSL 16:8e0d178b1d1e 5124 int ret = 0;
wolfSSL 15:117db924cf7c 5125
wolfSSL 15:117db924cf7c 5126 if (cek == NULL || kek == NULL || out == NULL)
wolfSSL 15:117db924cf7c 5127 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 5128
wolfSSL 15:117db924cf7c 5129 switch (keyWrapAlgo) {
wolfSSL 15:117db924cf7c 5130 #ifndef NO_AES
wolfSSL 15:117db924cf7c 5131 #ifdef WOLFSSL_AES_128
wolfSSL 15:117db924cf7c 5132 case AES128_WRAP:
wolfSSL 15:117db924cf7c 5133 #endif
wolfSSL 15:117db924cf7c 5134 #ifdef WOLFSSL_AES_192
wolfSSL 15:117db924cf7c 5135 case AES192_WRAP:
wolfSSL 15:117db924cf7c 5136 #endif
wolfSSL 15:117db924cf7c 5137 #ifdef WOLFSSL_AES_256
wolfSSL 15:117db924cf7c 5138 case AES256_WRAP:
wolfSSL 15:117db924cf7c 5139 #endif
wolfSSL 15:117db924cf7c 5140
wolfSSL 15:117db924cf7c 5141 if (direction == AES_ENCRYPTION) {
wolfSSL 15:117db924cf7c 5142
wolfSSL 15:117db924cf7c 5143 ret = wc_AesKeyWrap(kek, kekSz, cek, cekSz,
wolfSSL 15:117db924cf7c 5144 out, outSz, NULL);
wolfSSL 15:117db924cf7c 5145
wolfSSL 15:117db924cf7c 5146 } else if (direction == AES_DECRYPTION) {
wolfSSL 15:117db924cf7c 5147
wolfSSL 15:117db924cf7c 5148 ret = wc_AesKeyUnWrap(kek, kekSz, cek, cekSz,
wolfSSL 15:117db924cf7c 5149 out, outSz, NULL);
wolfSSL 15:117db924cf7c 5150 } else {
wolfSSL 15:117db924cf7c 5151 WOLFSSL_MSG("Bad key un/wrap direction");
wolfSSL 15:117db924cf7c 5152 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 5153 }
wolfSSL 15:117db924cf7c 5154
wolfSSL 15:117db924cf7c 5155 if (ret <= 0)
wolfSSL 15:117db924cf7c 5156 return ret;
wolfSSL 15:117db924cf7c 5157 break;
wolfSSL 15:117db924cf7c 5158 #endif /* NO_AES */
wolfSSL 15:117db924cf7c 5159
wolfSSL 15:117db924cf7c 5160 default:
wolfSSL 15:117db924cf7c 5161 WOLFSSL_MSG("Unsupported key wrap algorithm");
wolfSSL 15:117db924cf7c 5162 return BAD_KEYWRAP_ALG_E;
wolfSSL 15:117db924cf7c 5163 };
wolfSSL 15:117db924cf7c 5164
wolfSSL 15:117db924cf7c 5165 (void)cekSz;
wolfSSL 15:117db924cf7c 5166 (void)kekSz;
wolfSSL 15:117db924cf7c 5167 (void)outSz;
wolfSSL 15:117db924cf7c 5168 (void)direction;
wolfSSL 15:117db924cf7c 5169 return ret;
wolfSSL 15:117db924cf7c 5170 }
wolfSSL 15:117db924cf7c 5171
wolfSSL 15:117db924cf7c 5172
wolfSSL 16:8e0d178b1d1e 5173 #ifdef HAVE_ECC
wolfSSL 16:8e0d178b1d1e 5174
wolfSSL 16:8e0d178b1d1e 5175 /* KARI == KeyAgreeRecipientInfo (key agreement) */
wolfSSL 16:8e0d178b1d1e 5176 typedef struct WC_PKCS7_KARI {
wolfSSL 16:8e0d178b1d1e 5177 DecodedCert* decoded; /* decoded recip cert */
wolfSSL 16:8e0d178b1d1e 5178 void* heap; /* user heap, points to PKCS7->heap */
wolfSSL 16:8e0d178b1d1e 5179 int devId; /* device ID for HW based private key */
wolfSSL 16:8e0d178b1d1e 5180 ecc_key* recipKey; /* recip key (pub | priv) */
wolfSSL 16:8e0d178b1d1e 5181 ecc_key* senderKey; /* sender key (pub | priv) */
wolfSSL 16:8e0d178b1d1e 5182 byte* senderKeyExport; /* sender ephemeral key DER */
wolfSSL 16:8e0d178b1d1e 5183 byte* kek; /* key encryption key */
wolfSSL 16:8e0d178b1d1e 5184 byte* ukm; /* OPTIONAL user keying material */
wolfSSL 16:8e0d178b1d1e 5185 byte* sharedInfo; /* ECC-CMS-SharedInfo ASN.1 encoded blob */
wolfSSL 16:8e0d178b1d1e 5186 word32 senderKeyExportSz; /* size of sender ephemeral key DER */
wolfSSL 16:8e0d178b1d1e 5187 word32 kekSz; /* size of key encryption key */
wolfSSL 16:8e0d178b1d1e 5188 word32 ukmSz; /* size of user keying material */
wolfSSL 16:8e0d178b1d1e 5189 word32 sharedInfoSz; /* size of ECC-CMS-SharedInfo encoded */
wolfSSL 16:8e0d178b1d1e 5190 byte ukmOwner; /* do we own ukm buffer? 1:yes, 0:no */
wolfSSL 16:8e0d178b1d1e 5191 byte direction; /* WC_PKCS7_ENCODE | WC_PKCS7_DECODE */
wolfSSL 16:8e0d178b1d1e 5192 byte decodedInit : 1; /* indicates decoded was initialized */
wolfSSL 16:8e0d178b1d1e 5193 byte recipKeyInit : 1; /* indicates recipKey was initialized */
wolfSSL 16:8e0d178b1d1e 5194 byte senderKeyInit : 1; /* indicates senderKey was initialized */
wolfSSL 16:8e0d178b1d1e 5195 } WC_PKCS7_KARI;
wolfSSL 16:8e0d178b1d1e 5196
wolfSSL 16:8e0d178b1d1e 5197
wolfSSL 15:117db924cf7c 5198 /* allocate and create new WC_PKCS7_KARI struct,
wolfSSL 15:117db924cf7c 5199 * returns struct pointer on success, NULL on failure */
wolfSSL 15:117db924cf7c 5200 static WC_PKCS7_KARI* wc_PKCS7_KariNew(PKCS7* pkcs7, byte direction)
wolfSSL 15:117db924cf7c 5201 {
wolfSSL 15:117db924cf7c 5202 WC_PKCS7_KARI* kari = NULL;
wolfSSL 15:117db924cf7c 5203
wolfSSL 15:117db924cf7c 5204 if (pkcs7 == NULL)
wolfSSL 15:117db924cf7c 5205 return NULL;
wolfSSL 15:117db924cf7c 5206
wolfSSL 15:117db924cf7c 5207 kari = (WC_PKCS7_KARI*)XMALLOC(sizeof(WC_PKCS7_KARI), pkcs7->heap,
wolfSSL 15:117db924cf7c 5208 DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 5209 if (kari == NULL) {
wolfSSL 15:117db924cf7c 5210 WOLFSSL_MSG("Failed to allocate WC_PKCS7_KARI");
wolfSSL 15:117db924cf7c 5211 return NULL;
wolfSSL 15:117db924cf7c 5212 }
wolfSSL 15:117db924cf7c 5213
wolfSSL 15:117db924cf7c 5214 kari->decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), pkcs7->heap,
wolfSSL 15:117db924cf7c 5215 DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 5216 if (kari->decoded == NULL) {
wolfSSL 15:117db924cf7c 5217 WOLFSSL_MSG("Failed to allocate DecodedCert");
wolfSSL 15:117db924cf7c 5218 XFREE(kari, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 5219 return NULL;
wolfSSL 15:117db924cf7c 5220 }
wolfSSL 15:117db924cf7c 5221
wolfSSL 15:117db924cf7c 5222 kari->recipKey = (ecc_key*)XMALLOC(sizeof(ecc_key), pkcs7->heap,
wolfSSL 15:117db924cf7c 5223 DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 5224 if (kari->recipKey == NULL) {
wolfSSL 15:117db924cf7c 5225 WOLFSSL_MSG("Failed to allocate recipient ecc_key");
wolfSSL 15:117db924cf7c 5226 XFREE(kari->decoded, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 5227 XFREE(kari, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 5228 return NULL;
wolfSSL 15:117db924cf7c 5229 }
wolfSSL 15:117db924cf7c 5230
wolfSSL 15:117db924cf7c 5231 kari->senderKey = (ecc_key*)XMALLOC(sizeof(ecc_key), pkcs7->heap,
wolfSSL 15:117db924cf7c 5232 DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 5233 if (kari->senderKey == NULL) {
wolfSSL 15:117db924cf7c 5234 WOLFSSL_MSG("Failed to allocate sender ecc_key");
wolfSSL 15:117db924cf7c 5235 XFREE(kari->recipKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 5236 XFREE(kari->decoded, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 5237 XFREE(kari, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 5238 return NULL;
wolfSSL 15:117db924cf7c 5239 }
wolfSSL 15:117db924cf7c 5240
wolfSSL 15:117db924cf7c 5241 kari->senderKeyExport = NULL;
wolfSSL 15:117db924cf7c 5242 kari->senderKeyExportSz = 0;
wolfSSL 15:117db924cf7c 5243 kari->kek = NULL;
wolfSSL 15:117db924cf7c 5244 kari->kekSz = 0;
wolfSSL 15:117db924cf7c 5245 kari->ukm = NULL;
wolfSSL 15:117db924cf7c 5246 kari->ukmSz = 0;
wolfSSL 15:117db924cf7c 5247 kari->ukmOwner = 0;
wolfSSL 15:117db924cf7c 5248 kari->sharedInfo = NULL;
wolfSSL 15:117db924cf7c 5249 kari->sharedInfoSz = 0;
wolfSSL 15:117db924cf7c 5250 kari->direction = direction;
wolfSSL 15:117db924cf7c 5251 kari->decodedInit = 0;
wolfSSL 15:117db924cf7c 5252 kari->recipKeyInit = 0;
wolfSSL 15:117db924cf7c 5253 kari->senderKeyInit = 0;
wolfSSL 15:117db924cf7c 5254
wolfSSL 15:117db924cf7c 5255 kari->heap = pkcs7->heap;
wolfSSL 15:117db924cf7c 5256 kari->devId = pkcs7->devId;
wolfSSL 15:117db924cf7c 5257
wolfSSL 15:117db924cf7c 5258 return kari;
wolfSSL 15:117db924cf7c 5259 }
wolfSSL 15:117db924cf7c 5260
wolfSSL 15:117db924cf7c 5261
wolfSSL 15:117db924cf7c 5262 /* free WC_PKCS7_KARI struct, return 0 on success */
wolfSSL 15:117db924cf7c 5263 static int wc_PKCS7_KariFree(WC_PKCS7_KARI* kari)
wolfSSL 15:117db924cf7c 5264 {
wolfSSL 15:117db924cf7c 5265 void* heap;
wolfSSL 15:117db924cf7c 5266
wolfSSL 15:117db924cf7c 5267 if (kari) {
wolfSSL 15:117db924cf7c 5268 heap = kari->heap;
wolfSSL 15:117db924cf7c 5269
wolfSSL 15:117db924cf7c 5270 if (kari->decoded) {
wolfSSL 15:117db924cf7c 5271 if (kari->decodedInit)
wolfSSL 15:117db924cf7c 5272 FreeDecodedCert(kari->decoded);
wolfSSL 15:117db924cf7c 5273 XFREE(kari->decoded, heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 5274 }
wolfSSL 15:117db924cf7c 5275 if (kari->senderKey) {
wolfSSL 15:117db924cf7c 5276 if (kari->senderKeyInit)
wolfSSL 15:117db924cf7c 5277 wc_ecc_free(kari->senderKey);
wolfSSL 15:117db924cf7c 5278 XFREE(kari->senderKey, heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 5279 }
wolfSSL 15:117db924cf7c 5280 if (kari->recipKey) {
wolfSSL 15:117db924cf7c 5281 if (kari->recipKeyInit)
wolfSSL 15:117db924cf7c 5282 wc_ecc_free(kari->recipKey);
wolfSSL 15:117db924cf7c 5283 XFREE(kari->recipKey, heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 5284 }
wolfSSL 15:117db924cf7c 5285 if (kari->senderKeyExport) {
wolfSSL 15:117db924cf7c 5286 ForceZero(kari->senderKeyExport, kari->senderKeyExportSz);
wolfSSL 15:117db924cf7c 5287 XFREE(kari->senderKeyExport, heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 5288 kari->senderKeyExportSz = 0;
wolfSSL 15:117db924cf7c 5289 }
wolfSSL 15:117db924cf7c 5290 if (kari->kek) {
wolfSSL 15:117db924cf7c 5291 ForceZero(kari->kek, kari->kekSz);
wolfSSL 15:117db924cf7c 5292 XFREE(kari->kek, heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 5293 kari->kekSz = 0;
wolfSSL 15:117db924cf7c 5294 }
wolfSSL 15:117db924cf7c 5295 if (kari->ukm) {
wolfSSL 15:117db924cf7c 5296 if (kari->ukmOwner == 1) {
wolfSSL 15:117db924cf7c 5297 XFREE(kari->ukm, heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 5298 }
wolfSSL 15:117db924cf7c 5299 kari->ukmSz = 0;
wolfSSL 15:117db924cf7c 5300 }
wolfSSL 15:117db924cf7c 5301 if (kari->sharedInfo) {
wolfSSL 15:117db924cf7c 5302 ForceZero(kari->sharedInfo, kari->sharedInfoSz);
wolfSSL 15:117db924cf7c 5303 XFREE(kari->sharedInfo, heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 5304 kari->sharedInfoSz = 0;
wolfSSL 15:117db924cf7c 5305 }
wolfSSL 15:117db924cf7c 5306 XFREE(kari, heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 5307 }
wolfSSL 15:117db924cf7c 5308
wolfSSL 15:117db924cf7c 5309 (void)heap;
wolfSSL 15:117db924cf7c 5310
wolfSSL 15:117db924cf7c 5311 return 0;
wolfSSL 15:117db924cf7c 5312 }
wolfSSL 15:117db924cf7c 5313
wolfSSL 15:117db924cf7c 5314
wolfSSL 15:117db924cf7c 5315 /* parse recipient cert/key, return 0 on success, negative on error
wolfSSL 15:117db924cf7c 5316 * key/keySz only needed during decoding (WC_PKCS7_DECODE) */
wolfSSL 15:117db924cf7c 5317 static int wc_PKCS7_KariParseRecipCert(WC_PKCS7_KARI* kari, const byte* cert,
wolfSSL 15:117db924cf7c 5318 word32 certSz, const byte* key,
wolfSSL 15:117db924cf7c 5319 word32 keySz)
wolfSSL 15:117db924cf7c 5320 {
wolfSSL 15:117db924cf7c 5321 int ret;
wolfSSL 15:117db924cf7c 5322 word32 idx;
wolfSSL 15:117db924cf7c 5323
wolfSSL 15:117db924cf7c 5324 if (kari == NULL || kari->decoded == NULL ||
wolfSSL 15:117db924cf7c 5325 cert == NULL || certSz == 0)
wolfSSL 15:117db924cf7c 5326 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 5327
wolfSSL 15:117db924cf7c 5328 /* decode certificate */
wolfSSL 15:117db924cf7c 5329 InitDecodedCert(kari->decoded, (byte*)cert, certSz, kari->heap);
wolfSSL 15:117db924cf7c 5330 kari->decodedInit = 1;
wolfSSL 15:117db924cf7c 5331 ret = ParseCert(kari->decoded, CA_TYPE, NO_VERIFY, 0);
wolfSSL 15:117db924cf7c 5332 if (ret < 0)
wolfSSL 15:117db924cf7c 5333 return ret;
wolfSSL 15:117db924cf7c 5334
wolfSSL 16:8e0d178b1d1e 5335 /* only supports ECDSA for now */
wolfSSL 16:8e0d178b1d1e 5336 if (kari->decoded->keyOID != ECDSAk) {
wolfSSL 16:8e0d178b1d1e 5337 WOLFSSL_MSG("CMS KARI only supports ECDSA key types");
wolfSSL 16:8e0d178b1d1e 5338 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 5339 }
wolfSSL 16:8e0d178b1d1e 5340
wolfSSL 15:117db924cf7c 5341 /* make sure subject key id was read from cert */
wolfSSL 15:117db924cf7c 5342 if (kari->decoded->extSubjKeyIdSet == 0) {
wolfSSL 15:117db924cf7c 5343 WOLFSSL_MSG("Failed to read subject key ID from recipient cert");
wolfSSL 15:117db924cf7c 5344 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 5345 }
wolfSSL 15:117db924cf7c 5346
wolfSSL 15:117db924cf7c 5347 ret = wc_ecc_init_ex(kari->recipKey, kari->heap, kari->devId);
wolfSSL 15:117db924cf7c 5348 if (ret != 0)
wolfSSL 15:117db924cf7c 5349 return ret;
wolfSSL 15:117db924cf7c 5350
wolfSSL 15:117db924cf7c 5351 kari->recipKeyInit = 1;
wolfSSL 15:117db924cf7c 5352
wolfSSL 15:117db924cf7c 5353 /* get recip public key */
wolfSSL 15:117db924cf7c 5354 if (kari->direction == WC_PKCS7_ENCODE) {
wolfSSL 15:117db924cf7c 5355
wolfSSL 15:117db924cf7c 5356 idx = 0;
wolfSSL 15:117db924cf7c 5357 ret = wc_EccPublicKeyDecode(kari->decoded->publicKey, &idx,
wolfSSL 15:117db924cf7c 5358 kari->recipKey, kari->decoded->pubKeySize);
wolfSSL 15:117db924cf7c 5359 if (ret != 0)
wolfSSL 15:117db924cf7c 5360 return ret;
wolfSSL 15:117db924cf7c 5361 }
wolfSSL 15:117db924cf7c 5362 /* get recip private key */
wolfSSL 15:117db924cf7c 5363 else if (kari->direction == WC_PKCS7_DECODE) {
wolfSSL 15:117db924cf7c 5364 if (key != NULL && keySz > 0) {
wolfSSL 15:117db924cf7c 5365 idx = 0;
wolfSSL 15:117db924cf7c 5366 ret = wc_EccPrivateKeyDecode(key, &idx, kari->recipKey, keySz);
wolfSSL 15:117db924cf7c 5367 }
wolfSSL 15:117db924cf7c 5368 else if (kari->devId == INVALID_DEVID) {
wolfSSL 15:117db924cf7c 5369 ret = BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 5370 }
wolfSSL 15:117db924cf7c 5371 if (ret != 0)
wolfSSL 15:117db924cf7c 5372 return ret;
wolfSSL 15:117db924cf7c 5373
wolfSSL 15:117db924cf7c 5374 } else {
wolfSSL 15:117db924cf7c 5375 /* bad direction */
wolfSSL 15:117db924cf7c 5376 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 5377 }
wolfSSL 15:117db924cf7c 5378
wolfSSL 15:117db924cf7c 5379 (void)idx;
wolfSSL 15:117db924cf7c 5380
wolfSSL 15:117db924cf7c 5381 return 0;
wolfSSL 15:117db924cf7c 5382 }
wolfSSL 15:117db924cf7c 5383
wolfSSL 15:117db924cf7c 5384
wolfSSL 15:117db924cf7c 5385 /* create ephemeral ECC key, places ecc_key in kari->senderKey,
wolfSSL 15:117db924cf7c 5386 * DER encoded in kari->senderKeyExport. return 0 on success,
wolfSSL 15:117db924cf7c 5387 * negative on error */
wolfSSL 16:8e0d178b1d1e 5388 static int wc_PKCS7_KariGenerateEphemeralKey(WC_PKCS7_KARI* kari)
wolfSSL 15:117db924cf7c 5389 {
wolfSSL 15:117db924cf7c 5390 int ret;
wolfSSL 16:8e0d178b1d1e 5391 WC_RNG rng;
wolfSSL 15:117db924cf7c 5392
wolfSSL 15:117db924cf7c 5393 if (kari == NULL || kari->decoded == NULL ||
wolfSSL 16:8e0d178b1d1e 5394 kari->recipKey == NULL || kari->recipKey->dp == NULL)
wolfSSL 15:117db924cf7c 5395 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 5396
wolfSSL 15:117db924cf7c 5397 kari->senderKeyExport = (byte*)XMALLOC(kari->decoded->pubKeySize,
wolfSSL 15:117db924cf7c 5398 kari->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 5399 if (kari->senderKeyExport == NULL)
wolfSSL 15:117db924cf7c 5400 return MEMORY_E;
wolfSSL 15:117db924cf7c 5401
wolfSSL 15:117db924cf7c 5402 kari->senderKeyExportSz = kari->decoded->pubKeySize;
wolfSSL 15:117db924cf7c 5403
wolfSSL 15:117db924cf7c 5404 ret = wc_ecc_init_ex(kari->senderKey, kari->heap, kari->devId);
wolfSSL 16:8e0d178b1d1e 5405 if (ret != 0) {
wolfSSL 16:8e0d178b1d1e 5406 XFREE(kari->senderKeyExport, kari->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 5407 return ret;
wolfSSL 16:8e0d178b1d1e 5408 }
wolfSSL 15:117db924cf7c 5409
wolfSSL 15:117db924cf7c 5410 kari->senderKeyInit = 1;
wolfSSL 15:117db924cf7c 5411
wolfSSL 16:8e0d178b1d1e 5412 ret = wc_InitRng_ex(&rng, kari->heap, kari->devId);
wolfSSL 16:8e0d178b1d1e 5413 if (ret != 0) {
wolfSSL 16:8e0d178b1d1e 5414 XFREE(kari->senderKeyExport, kari->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 5415 return ret;
wolfSSL 16:8e0d178b1d1e 5416 }
wolfSSL 16:8e0d178b1d1e 5417
wolfSSL 16:8e0d178b1d1e 5418 ret = wc_ecc_make_key_ex(&rng, kari->recipKey->dp->size,
wolfSSL 15:117db924cf7c 5419 kari->senderKey, kari->recipKey->dp->id);
wolfSSL 16:8e0d178b1d1e 5420 if (ret != 0) {
wolfSSL 16:8e0d178b1d1e 5421 XFREE(kari->senderKeyExport, kari->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 5422 wc_FreeRng(&rng);
wolfSSL 15:117db924cf7c 5423 return ret;
wolfSSL 16:8e0d178b1d1e 5424 }
wolfSSL 16:8e0d178b1d1e 5425
wolfSSL 16:8e0d178b1d1e 5426 wc_FreeRng(&rng);
wolfSSL 15:117db924cf7c 5427
wolfSSL 15:117db924cf7c 5428 /* dump generated key to X.963 DER for output in CMS bundle */
wolfSSL 15:117db924cf7c 5429 ret = wc_ecc_export_x963(kari->senderKey, kari->senderKeyExport,
wolfSSL 15:117db924cf7c 5430 &kari->senderKeyExportSz);
wolfSSL 16:8e0d178b1d1e 5431 if (ret != 0) {
wolfSSL 16:8e0d178b1d1e 5432 XFREE(kari->senderKeyExport, kari->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 5433 return ret;
wolfSSL 16:8e0d178b1d1e 5434 }
wolfSSL 15:117db924cf7c 5435
wolfSSL 15:117db924cf7c 5436 return 0;
wolfSSL 15:117db924cf7c 5437 }
wolfSSL 15:117db924cf7c 5438
wolfSSL 15:117db924cf7c 5439
wolfSSL 15:117db924cf7c 5440 /* create ASN.1 encoded ECC-CMS-SharedInfo using specified key wrap algorithm,
wolfSSL 15:117db924cf7c 5441 * place in kari->sharedInfo. returns 0 on success, negative on error */
wolfSSL 15:117db924cf7c 5442 static int wc_PKCS7_KariGenerateSharedInfo(WC_PKCS7_KARI* kari, int keyWrapOID)
wolfSSL 15:117db924cf7c 5443 {
wolfSSL 15:117db924cf7c 5444 int idx = 0;
wolfSSL 15:117db924cf7c 5445 int sharedInfoSeqSz = 0;
wolfSSL 15:117db924cf7c 5446 int keyInfoSz = 0;
wolfSSL 15:117db924cf7c 5447 int suppPubInfoSeqSz = 0;
wolfSSL 15:117db924cf7c 5448 int entityUInfoOctetSz = 0;
wolfSSL 15:117db924cf7c 5449 int entityUInfoExplicitSz = 0;
wolfSSL 15:117db924cf7c 5450 int kekOctetSz = 0;
wolfSSL 15:117db924cf7c 5451 int sharedInfoSz = 0;
wolfSSL 15:117db924cf7c 5452
wolfSSL 15:117db924cf7c 5453 word32 kekBitSz = 0;
wolfSSL 15:117db924cf7c 5454
wolfSSL 15:117db924cf7c 5455 byte sharedInfoSeq[MAX_SEQ_SZ];
wolfSSL 15:117db924cf7c 5456 byte keyInfo[MAX_ALGO_SZ];
wolfSSL 15:117db924cf7c 5457 byte suppPubInfoSeq[MAX_SEQ_SZ];
wolfSSL 15:117db924cf7c 5458 byte entityUInfoOctet[MAX_OCTET_STR_SZ];
wolfSSL 15:117db924cf7c 5459 byte entityUInfoExplicitSeq[MAX_SEQ_SZ];
wolfSSL 15:117db924cf7c 5460 byte kekOctet[MAX_OCTET_STR_SZ];
wolfSSL 15:117db924cf7c 5461
wolfSSL 15:117db924cf7c 5462 if (kari == NULL)
wolfSSL 15:117db924cf7c 5463 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 5464
wolfSSL 15:117db924cf7c 5465 if ((kari->ukmSz > 0) && (kari->ukm == NULL))
wolfSSL 15:117db924cf7c 5466 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 5467
wolfSSL 15:117db924cf7c 5468 /* kekOctet */
wolfSSL 15:117db924cf7c 5469 kekOctetSz = SetOctetString(sizeof(word32), kekOctet);
wolfSSL 15:117db924cf7c 5470 sharedInfoSz += (kekOctetSz + sizeof(word32));
wolfSSL 15:117db924cf7c 5471
wolfSSL 15:117db924cf7c 5472 /* suppPubInfo */
wolfSSL 15:117db924cf7c 5473 suppPubInfoSeqSz = SetImplicit(ASN_SEQUENCE, 2,
wolfSSL 15:117db924cf7c 5474 kekOctetSz + sizeof(word32),
wolfSSL 15:117db924cf7c 5475 suppPubInfoSeq);
wolfSSL 15:117db924cf7c 5476 sharedInfoSz += suppPubInfoSeqSz;
wolfSSL 15:117db924cf7c 5477
wolfSSL 15:117db924cf7c 5478 /* optional ukm/entityInfo */
wolfSSL 15:117db924cf7c 5479 if (kari->ukmSz > 0) {
wolfSSL 15:117db924cf7c 5480 entityUInfoOctetSz = SetOctetString(kari->ukmSz, entityUInfoOctet);
wolfSSL 15:117db924cf7c 5481 sharedInfoSz += (entityUInfoOctetSz + kari->ukmSz);
wolfSSL 15:117db924cf7c 5482
wolfSSL 15:117db924cf7c 5483 entityUInfoExplicitSz = SetExplicit(0, entityUInfoOctetSz +
wolfSSL 15:117db924cf7c 5484 kari->ukmSz,
wolfSSL 15:117db924cf7c 5485 entityUInfoExplicitSeq);
wolfSSL 15:117db924cf7c 5486 sharedInfoSz += entityUInfoExplicitSz;
wolfSSL 15:117db924cf7c 5487 }
wolfSSL 15:117db924cf7c 5488
wolfSSL 15:117db924cf7c 5489 /* keyInfo */
wolfSSL 15:117db924cf7c 5490 keyInfoSz = SetAlgoID(keyWrapOID, keyInfo, oidKeyWrapType, 0);
wolfSSL 15:117db924cf7c 5491 sharedInfoSz += keyInfoSz;
wolfSSL 15:117db924cf7c 5492
wolfSSL 15:117db924cf7c 5493 /* sharedInfo */
wolfSSL 15:117db924cf7c 5494 sharedInfoSeqSz = SetSequence(sharedInfoSz, sharedInfoSeq);
wolfSSL 15:117db924cf7c 5495 sharedInfoSz += sharedInfoSeqSz;
wolfSSL 15:117db924cf7c 5496
wolfSSL 15:117db924cf7c 5497 kari->sharedInfo = (byte*)XMALLOC(sharedInfoSz, kari->heap,
wolfSSL 15:117db924cf7c 5498 DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 5499 if (kari->sharedInfo == NULL)
wolfSSL 15:117db924cf7c 5500 return MEMORY_E;
wolfSSL 15:117db924cf7c 5501
wolfSSL 15:117db924cf7c 5502 kari->sharedInfoSz = sharedInfoSz;
wolfSSL 15:117db924cf7c 5503
wolfSSL 15:117db924cf7c 5504 XMEMCPY(kari->sharedInfo + idx, sharedInfoSeq, sharedInfoSeqSz);
wolfSSL 15:117db924cf7c 5505 idx += sharedInfoSeqSz;
wolfSSL 15:117db924cf7c 5506 XMEMCPY(kari->sharedInfo + idx, keyInfo, keyInfoSz);
wolfSSL 15:117db924cf7c 5507 idx += keyInfoSz;
wolfSSL 15:117db924cf7c 5508 if (kari->ukmSz > 0) {
wolfSSL 15:117db924cf7c 5509 XMEMCPY(kari->sharedInfo + idx, entityUInfoExplicitSeq,
wolfSSL 15:117db924cf7c 5510 entityUInfoExplicitSz);
wolfSSL 15:117db924cf7c 5511 idx += entityUInfoExplicitSz;
wolfSSL 15:117db924cf7c 5512 XMEMCPY(kari->sharedInfo + idx, entityUInfoOctet, entityUInfoOctetSz);
wolfSSL 15:117db924cf7c 5513 idx += entityUInfoOctetSz;
wolfSSL 15:117db924cf7c 5514 XMEMCPY(kari->sharedInfo + idx, kari->ukm, kari->ukmSz);
wolfSSL 15:117db924cf7c 5515 idx += kari->ukmSz;
wolfSSL 15:117db924cf7c 5516 }
wolfSSL 15:117db924cf7c 5517 XMEMCPY(kari->sharedInfo + idx, suppPubInfoSeq, suppPubInfoSeqSz);
wolfSSL 15:117db924cf7c 5518 idx += suppPubInfoSeqSz;
wolfSSL 15:117db924cf7c 5519 XMEMCPY(kari->sharedInfo + idx, kekOctet, kekOctetSz);
wolfSSL 15:117db924cf7c 5520 idx += kekOctetSz;
wolfSSL 15:117db924cf7c 5521
wolfSSL 15:117db924cf7c 5522 kekBitSz = (kari->kekSz) * 8; /* convert to bits */
wolfSSL 15:117db924cf7c 5523 #ifdef LITTLE_ENDIAN_ORDER
wolfSSL 15:117db924cf7c 5524 kekBitSz = ByteReverseWord32(kekBitSz); /* network byte order */
wolfSSL 15:117db924cf7c 5525 #endif
wolfSSL 15:117db924cf7c 5526 XMEMCPY(kari->sharedInfo + idx, &kekBitSz, sizeof(kekBitSz));
wolfSSL 15:117db924cf7c 5527
wolfSSL 15:117db924cf7c 5528 return 0;
wolfSSL 15:117db924cf7c 5529 }
wolfSSL 15:117db924cf7c 5530
wolfSSL 15:117db924cf7c 5531
wolfSSL 15:117db924cf7c 5532 /* create key encryption key (KEK) using key wrap algorithm and key encryption
wolfSSL 15:117db924cf7c 5533 * algorithm, place in kari->kek. return 0 on success, <0 on error. */
wolfSSL 15:117db924cf7c 5534 static int wc_PKCS7_KariGenerateKEK(WC_PKCS7_KARI* kari,
wolfSSL 15:117db924cf7c 5535 int keyWrapOID, int keyEncOID)
wolfSSL 15:117db924cf7c 5536 {
wolfSSL 15:117db924cf7c 5537 int ret;
wolfSSL 15:117db924cf7c 5538 int kSz;
wolfSSL 15:117db924cf7c 5539 enum wc_HashType kdfType;
wolfSSL 15:117db924cf7c 5540 byte* secret;
wolfSSL 15:117db924cf7c 5541 word32 secretSz;
wolfSSL 15:117db924cf7c 5542
wolfSSL 15:117db924cf7c 5543 if (kari == NULL || kari->recipKey == NULL ||
wolfSSL 15:117db924cf7c 5544 kari->senderKey == NULL || kari->senderKey->dp == NULL)
wolfSSL 15:117db924cf7c 5545 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 5546
wolfSSL 15:117db924cf7c 5547 /* get KEK size, allocate buff */
wolfSSL 15:117db924cf7c 5548 kSz = wc_PKCS7_GetOIDKeySize(keyWrapOID);
wolfSSL 15:117db924cf7c 5549 if (kSz < 0)
wolfSSL 15:117db924cf7c 5550 return kSz;
wolfSSL 15:117db924cf7c 5551
wolfSSL 15:117db924cf7c 5552 kari->kek = (byte*)XMALLOC(kSz, kari->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 5553 if (kari->kek == NULL)
wolfSSL 15:117db924cf7c 5554 return MEMORY_E;
wolfSSL 15:117db924cf7c 5555
wolfSSL 15:117db924cf7c 5556 kari->kekSz = (word32)kSz;
wolfSSL 15:117db924cf7c 5557
wolfSSL 15:117db924cf7c 5558 /* generate ECC-CMS-SharedInfo */
wolfSSL 15:117db924cf7c 5559 ret = wc_PKCS7_KariGenerateSharedInfo(kari, keyWrapOID);
wolfSSL 15:117db924cf7c 5560 if (ret != 0)
wolfSSL 15:117db924cf7c 5561 return ret;
wolfSSL 15:117db924cf7c 5562
wolfSSL 15:117db924cf7c 5563 /* generate shared secret */
wolfSSL 15:117db924cf7c 5564 secretSz = kari->senderKey->dp->size;
wolfSSL 15:117db924cf7c 5565 secret = (byte*)XMALLOC(secretSz, kari->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 5566 if (secret == NULL)
wolfSSL 15:117db924cf7c 5567 return MEMORY_E;
wolfSSL 15:117db924cf7c 5568
wolfSSL 15:117db924cf7c 5569 if (kari->direction == WC_PKCS7_ENCODE) {
wolfSSL 15:117db924cf7c 5570
wolfSSL 15:117db924cf7c 5571 ret = wc_ecc_shared_secret(kari->senderKey, kari->recipKey,
wolfSSL 15:117db924cf7c 5572 secret, &secretSz);
wolfSSL 15:117db924cf7c 5573
wolfSSL 15:117db924cf7c 5574 } else if (kari->direction == WC_PKCS7_DECODE) {
wolfSSL 15:117db924cf7c 5575
wolfSSL 15:117db924cf7c 5576 ret = wc_ecc_shared_secret(kari->recipKey, kari->senderKey,
wolfSSL 15:117db924cf7c 5577 secret, &secretSz);
wolfSSL 15:117db924cf7c 5578
wolfSSL 15:117db924cf7c 5579 } else {
wolfSSL 15:117db924cf7c 5580 /* bad direction */
wolfSSL 15:117db924cf7c 5581 XFREE(secret, kari->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 5582 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 5583 }
wolfSSL 15:117db924cf7c 5584
wolfSSL 15:117db924cf7c 5585 if (ret != 0) {
wolfSSL 15:117db924cf7c 5586 XFREE(secret, kari->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 5587 return ret;
wolfSSL 15:117db924cf7c 5588 }
wolfSSL 15:117db924cf7c 5589
wolfSSL 15:117db924cf7c 5590 /* run through KDF */
wolfSSL 15:117db924cf7c 5591 switch (keyEncOID) {
wolfSSL 15:117db924cf7c 5592
wolfSSL 15:117db924cf7c 5593 #ifndef NO_SHA
wolfSSL 15:117db924cf7c 5594 case dhSinglePass_stdDH_sha1kdf_scheme:
wolfSSL 15:117db924cf7c 5595 kdfType = WC_HASH_TYPE_SHA;
wolfSSL 15:117db924cf7c 5596 break;
wolfSSL 15:117db924cf7c 5597 #endif
wolfSSL 15:117db924cf7c 5598 #ifndef WOLFSSL_SHA224
wolfSSL 15:117db924cf7c 5599 case dhSinglePass_stdDH_sha224kdf_scheme:
wolfSSL 15:117db924cf7c 5600 kdfType = WC_HASH_TYPE_SHA224;
wolfSSL 15:117db924cf7c 5601 break;
wolfSSL 15:117db924cf7c 5602 #endif
wolfSSL 15:117db924cf7c 5603 #ifndef NO_SHA256
wolfSSL 15:117db924cf7c 5604 case dhSinglePass_stdDH_sha256kdf_scheme:
wolfSSL 15:117db924cf7c 5605 kdfType = WC_HASH_TYPE_SHA256;
wolfSSL 15:117db924cf7c 5606 break;
wolfSSL 15:117db924cf7c 5607 #endif
wolfSSL 15:117db924cf7c 5608 #ifdef WOLFSSL_SHA384
wolfSSL 15:117db924cf7c 5609 case dhSinglePass_stdDH_sha384kdf_scheme:
wolfSSL 15:117db924cf7c 5610 kdfType = WC_HASH_TYPE_SHA384;
wolfSSL 15:117db924cf7c 5611 break;
wolfSSL 15:117db924cf7c 5612 #endif
wolfSSL 15:117db924cf7c 5613 #ifdef WOLFSSL_SHA512
wolfSSL 15:117db924cf7c 5614 case dhSinglePass_stdDH_sha512kdf_scheme:
wolfSSL 15:117db924cf7c 5615 kdfType = WC_HASH_TYPE_SHA512;
wolfSSL 15:117db924cf7c 5616 break;
wolfSSL 15:117db924cf7c 5617 #endif
wolfSSL 15:117db924cf7c 5618 default:
wolfSSL 15:117db924cf7c 5619 WOLFSSL_MSG("Unsupported key agreement algorithm");
wolfSSL 15:117db924cf7c 5620 XFREE(secret, kari->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 5621 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 5622 };
wolfSSL 15:117db924cf7c 5623
wolfSSL 15:117db924cf7c 5624 ret = wc_X963_KDF(kdfType, secret, secretSz, kari->sharedInfo,
wolfSSL 15:117db924cf7c 5625 kari->sharedInfoSz, kari->kek, kari->kekSz);
wolfSSL 15:117db924cf7c 5626 if (ret != 0) {
wolfSSL 15:117db924cf7c 5627 XFREE(secret, kari->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 5628 return ret;
wolfSSL 15:117db924cf7c 5629 }
wolfSSL 15:117db924cf7c 5630
wolfSSL 15:117db924cf7c 5631 XFREE(secret, kari->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 5632
wolfSSL 15:117db924cf7c 5633 return 0;
wolfSSL 15:117db924cf7c 5634 }
wolfSSL 15:117db924cf7c 5635
wolfSSL 15:117db924cf7c 5636
wolfSSL 16:8e0d178b1d1e 5637 /* Encode and add CMS EnvelopedData KARI (KeyAgreeRecipientInfo) RecipientInfo
wolfSSL 16:8e0d178b1d1e 5638 * to CMS/PKCS#7 EnvelopedData structure.
wolfSSL 16:8e0d178b1d1e 5639 *
wolfSSL 16:8e0d178b1d1e 5640 * Returns 0 on success, negative upon error */
wolfSSL 16:8e0d178b1d1e 5641 int wc_PKCS7_AddRecipient_KARI(PKCS7* pkcs7, const byte* cert, word32 certSz,
wolfSSL 16:8e0d178b1d1e 5642 int keyWrapOID, int keyAgreeOID, byte* ukm,
wolfSSL 16:8e0d178b1d1e 5643 word32 ukmSz, int options)
wolfSSL 16:8e0d178b1d1e 5644 {
wolfSSL 16:8e0d178b1d1e 5645 Pkcs7EncodedRecip* recip;
wolfSSL 16:8e0d178b1d1e 5646 Pkcs7EncodedRecip* lastRecip = NULL;
wolfSSL 16:8e0d178b1d1e 5647 WC_PKCS7_KARI* kari = NULL;
wolfSSL 16:8e0d178b1d1e 5648
wolfSSL 16:8e0d178b1d1e 5649 word32 idx = 0;
wolfSSL 16:8e0d178b1d1e 5650 word32 encryptedKeySz = MAX_ENCRYPTED_KEY_SZ;
wolfSSL 16:8e0d178b1d1e 5651
wolfSSL 16:8e0d178b1d1e 5652 int ret = 0;
wolfSSL 15:117db924cf7c 5653 int keySz, direction = 0;
wolfSSL 16:8e0d178b1d1e 5654 int blockKeySz = 0;
wolfSSL 15:117db924cf7c 5655
wolfSSL 15:117db924cf7c 5656 /* ASN.1 layout */
wolfSSL 15:117db924cf7c 5657 int totalSz = 0;
wolfSSL 15:117db924cf7c 5658 int kariSeqSz = 0;
wolfSSL 15:117db924cf7c 5659 byte kariSeq[MAX_SEQ_SZ]; /* IMPLICIT [1] */
wolfSSL 15:117db924cf7c 5660 int verSz = 0;
wolfSSL 15:117db924cf7c 5661 byte ver[MAX_VERSION_SZ];
wolfSSL 15:117db924cf7c 5662
wolfSSL 15:117db924cf7c 5663 int origIdOrKeySeqSz = 0;
wolfSSL 15:117db924cf7c 5664 byte origIdOrKeySeq[MAX_SEQ_SZ]; /* IMPLICIT [0] */
wolfSSL 15:117db924cf7c 5665 int origPubKeySeqSz = 0;
wolfSSL 15:117db924cf7c 5666 byte origPubKeySeq[MAX_SEQ_SZ]; /* IMPLICIT [1] */
wolfSSL 15:117db924cf7c 5667 int origAlgIdSz = 0;
wolfSSL 15:117db924cf7c 5668 byte origAlgId[MAX_ALGO_SZ];
wolfSSL 15:117db924cf7c 5669 int origPubKeyStrSz = 0;
wolfSSL 15:117db924cf7c 5670 byte origPubKeyStr[MAX_OCTET_STR_SZ];
wolfSSL 15:117db924cf7c 5671
wolfSSL 15:117db924cf7c 5672 /* optional user keying material */
wolfSSL 15:117db924cf7c 5673 int ukmOctetSz = 0;
wolfSSL 15:117db924cf7c 5674 byte ukmOctetStr[MAX_OCTET_STR_SZ];
wolfSSL 15:117db924cf7c 5675 int ukmExplicitSz = 0;
wolfSSL 15:117db924cf7c 5676 byte ukmExplicitSeq[MAX_SEQ_SZ];
wolfSSL 15:117db924cf7c 5677
wolfSSL 15:117db924cf7c 5678 int keyEncryptAlgoIdSz = 0;
wolfSSL 15:117db924cf7c 5679 byte keyEncryptAlgoId[MAX_ALGO_SZ];
wolfSSL 15:117db924cf7c 5680 int keyWrapAlgSz = 0;
wolfSSL 15:117db924cf7c 5681 byte keyWrapAlg[MAX_ALGO_SZ];
wolfSSL 15:117db924cf7c 5682
wolfSSL 15:117db924cf7c 5683 int recipEncKeysSeqSz = 0;
wolfSSL 15:117db924cf7c 5684 byte recipEncKeysSeq[MAX_SEQ_SZ];
wolfSSL 15:117db924cf7c 5685 int recipEncKeySeqSz = 0;
wolfSSL 15:117db924cf7c 5686 byte recipEncKeySeq[MAX_SEQ_SZ];
wolfSSL 15:117db924cf7c 5687 int recipKeyIdSeqSz = 0;
wolfSSL 15:117db924cf7c 5688 byte recipKeyIdSeq[MAX_SEQ_SZ]; /* IMPLICIT [0] */
wolfSSL 15:117db924cf7c 5689 int subjKeyIdOctetSz = 0;
wolfSSL 15:117db924cf7c 5690 byte subjKeyIdOctet[MAX_OCTET_STR_SZ];
wolfSSL 15:117db924cf7c 5691 int encryptedKeyOctetSz = 0;
wolfSSL 15:117db924cf7c 5692 byte encryptedKeyOctet[MAX_OCTET_STR_SZ];
wolfSSL 15:117db924cf7c 5693
wolfSSL 16:8e0d178b1d1e 5694 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 5695 byte* encryptedKey;
wolfSSL 16:8e0d178b1d1e 5696
wolfSSL 16:8e0d178b1d1e 5697 encryptedKey = (byte*)XMALLOC(MAX_ENCRYPTED_KEY_SZ, pkcs7->heap,
wolfSSL 16:8e0d178b1d1e 5698 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 5699 if (encryptedKey == NULL) {
wolfSSL 16:8e0d178b1d1e 5700 return MEMORY_E;
wolfSSL 16:8e0d178b1d1e 5701 }
wolfSSL 16:8e0d178b1d1e 5702 #else
wolfSSL 16:8e0d178b1d1e 5703 byte encryptedKey[MAX_ENCRYPTED_KEY_SZ];
wolfSSL 16:8e0d178b1d1e 5704 #endif
wolfSSL 16:8e0d178b1d1e 5705
wolfSSL 16:8e0d178b1d1e 5706 /* allocate and init memory for recipient */
wolfSSL 16:8e0d178b1d1e 5707 recip = (Pkcs7EncodedRecip*)XMALLOC(sizeof(Pkcs7EncodedRecip), pkcs7->heap,
wolfSSL 16:8e0d178b1d1e 5708 DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 5709 if (recip == NULL) {
wolfSSL 16:8e0d178b1d1e 5710 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 5711 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 5712 #endif
wolfSSL 16:8e0d178b1d1e 5713 return MEMORY_E;
wolfSSL 16:8e0d178b1d1e 5714 }
wolfSSL 16:8e0d178b1d1e 5715 XMEMSET(recip, 0, sizeof(Pkcs7EncodedRecip));
wolfSSL 16:8e0d178b1d1e 5716
wolfSSL 16:8e0d178b1d1e 5717 /* get key size for content-encryption key based on algorithm */
wolfSSL 16:8e0d178b1d1e 5718 blockKeySz = wc_PKCS7_GetOIDKeySize(pkcs7->encryptOID);
wolfSSL 16:8e0d178b1d1e 5719 if (blockKeySz < 0) {
wolfSSL 16:8e0d178b1d1e 5720 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 5721 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 5722 #endif
wolfSSL 16:8e0d178b1d1e 5723 XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 5724 return blockKeySz;
wolfSSL 16:8e0d178b1d1e 5725 }
wolfSSL 16:8e0d178b1d1e 5726
wolfSSL 16:8e0d178b1d1e 5727 /* generate random content encryption key, if needed */
wolfSSL 16:8e0d178b1d1e 5728 ret = PKCS7_GenerateContentEncryptionKey(pkcs7, blockKeySz);
wolfSSL 16:8e0d178b1d1e 5729 if (ret < 0) {
wolfSSL 16:8e0d178b1d1e 5730 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 5731 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 5732 #endif
wolfSSL 16:8e0d178b1d1e 5733 XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 5734 return ret;
wolfSSL 16:8e0d178b1d1e 5735 }
wolfSSL 15:117db924cf7c 5736
wolfSSL 15:117db924cf7c 5737 /* set direction based on keyWrapAlgo */
wolfSSL 16:8e0d178b1d1e 5738 switch (keyWrapOID) {
wolfSSL 15:117db924cf7c 5739 #ifndef NO_AES
wolfSSL 15:117db924cf7c 5740 #ifdef WOLFSSL_AES_128
wolfSSL 15:117db924cf7c 5741 case AES128_WRAP:
wolfSSL 15:117db924cf7c 5742 #endif
wolfSSL 15:117db924cf7c 5743 #ifdef WOLFSSL_AES_192
wolfSSL 15:117db924cf7c 5744 case AES192_WRAP:
wolfSSL 15:117db924cf7c 5745 #endif
wolfSSL 15:117db924cf7c 5746 #ifdef WOLFSSL_AES_256
wolfSSL 15:117db924cf7c 5747 case AES256_WRAP:
wolfSSL 15:117db924cf7c 5748 #endif
wolfSSL 15:117db924cf7c 5749 direction = AES_ENCRYPTION;
wolfSSL 15:117db924cf7c 5750 break;
wolfSSL 15:117db924cf7c 5751 #endif
wolfSSL 15:117db924cf7c 5752 default:
wolfSSL 15:117db924cf7c 5753 WOLFSSL_MSG("Unsupported key wrap algorithm");
wolfSSL 16:8e0d178b1d1e 5754 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 5755 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 5756 #endif
wolfSSL 16:8e0d178b1d1e 5757 XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 5758 return BAD_KEYWRAP_ALG_E;
wolfSSL 15:117db924cf7c 5759 }
wolfSSL 15:117db924cf7c 5760
wolfSSL 15:117db924cf7c 5761 kari = wc_PKCS7_KariNew(pkcs7, WC_PKCS7_ENCODE);
wolfSSL 16:8e0d178b1d1e 5762 if (kari == NULL) {
wolfSSL 16:8e0d178b1d1e 5763 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 5764 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 5765 #endif
wolfSSL 16:8e0d178b1d1e 5766 XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 5767 return MEMORY_E;
wolfSSL 16:8e0d178b1d1e 5768 }
wolfSSL 15:117db924cf7c 5769
wolfSSL 15:117db924cf7c 5770 /* set user keying material if available */
wolfSSL 16:8e0d178b1d1e 5771 if (ukmSz > 0 && ukm != NULL) {
wolfSSL 16:8e0d178b1d1e 5772 kari->ukm = ukm;
wolfSSL 16:8e0d178b1d1e 5773 kari->ukmSz = ukmSz;
wolfSSL 15:117db924cf7c 5774 kari->ukmOwner = 0;
wolfSSL 15:117db924cf7c 5775 }
wolfSSL 15:117db924cf7c 5776
wolfSSL 15:117db924cf7c 5777 /* parse recipient cert, get public key */
wolfSSL 15:117db924cf7c 5778 ret = wc_PKCS7_KariParseRecipCert(kari, cert, certSz, NULL, 0);
wolfSSL 15:117db924cf7c 5779 if (ret != 0) {
wolfSSL 15:117db924cf7c 5780 wc_PKCS7_KariFree(kari);
wolfSSL 16:8e0d178b1d1e 5781 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 5782 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 5783 #endif
wolfSSL 16:8e0d178b1d1e 5784 XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 5785 return ret;
wolfSSL 15:117db924cf7c 5786 }
wolfSSL 15:117db924cf7c 5787
wolfSSL 15:117db924cf7c 5788 /* generate sender ephemeral ECC key */
wolfSSL 16:8e0d178b1d1e 5789 ret = wc_PKCS7_KariGenerateEphemeralKey(kari);
wolfSSL 15:117db924cf7c 5790 if (ret != 0) {
wolfSSL 15:117db924cf7c 5791 wc_PKCS7_KariFree(kari);
wolfSSL 16:8e0d178b1d1e 5792 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 5793 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 5794 #endif
wolfSSL 16:8e0d178b1d1e 5795 XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 5796 return ret;
wolfSSL 15:117db924cf7c 5797 }
wolfSSL 15:117db924cf7c 5798
wolfSSL 15:117db924cf7c 5799 /* generate KEK (key encryption key) */
wolfSSL 16:8e0d178b1d1e 5800 ret = wc_PKCS7_KariGenerateKEK(kari, keyWrapOID, keyAgreeOID);
wolfSSL 15:117db924cf7c 5801 if (ret != 0) {
wolfSSL 15:117db924cf7c 5802 wc_PKCS7_KariFree(kari);
wolfSSL 16:8e0d178b1d1e 5803 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 5804 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 5805 #endif
wolfSSL 16:8e0d178b1d1e 5806 XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 5807 return ret;
wolfSSL 15:117db924cf7c 5808 }
wolfSSL 15:117db924cf7c 5809
wolfSSL 15:117db924cf7c 5810 /* encrypt CEK with KEK */
wolfSSL 16:8e0d178b1d1e 5811 keySz = wc_PKCS7_KeyWrap(pkcs7->cek, pkcs7->cekSz, kari->kek,
wolfSSL 16:8e0d178b1d1e 5812 kari->kekSz, encryptedKey, encryptedKeySz,
wolfSSL 16:8e0d178b1d1e 5813 keyWrapOID, direction);
wolfSSL 15:117db924cf7c 5814 if (keySz <= 0) {
wolfSSL 15:117db924cf7c 5815 wc_PKCS7_KariFree(kari);
wolfSSL 16:8e0d178b1d1e 5816 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 5817 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 5818 #endif
wolfSSL 16:8e0d178b1d1e 5819 XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 5820 return keySz;
wolfSSL 16:8e0d178b1d1e 5821 }
wolfSSL 16:8e0d178b1d1e 5822 encryptedKeySz = (word32)keySz;
wolfSSL 15:117db924cf7c 5823
wolfSSL 15:117db924cf7c 5824 /* Start of RecipientEncryptedKeys */
wolfSSL 15:117db924cf7c 5825
wolfSSL 15:117db924cf7c 5826 /* EncryptedKey */
wolfSSL 16:8e0d178b1d1e 5827 encryptedKeyOctetSz = SetOctetString(encryptedKeySz, encryptedKeyOctet);
wolfSSL 16:8e0d178b1d1e 5828 totalSz += (encryptedKeyOctetSz + encryptedKeySz);
wolfSSL 15:117db924cf7c 5829
wolfSSL 15:117db924cf7c 5830 /* SubjectKeyIdentifier */
wolfSSL 15:117db924cf7c 5831 subjKeyIdOctetSz = SetOctetString(KEYID_SIZE, subjKeyIdOctet);
wolfSSL 15:117db924cf7c 5832 totalSz += (subjKeyIdOctetSz + KEYID_SIZE);
wolfSSL 15:117db924cf7c 5833
wolfSSL 15:117db924cf7c 5834 /* RecipientKeyIdentifier IMPLICIT [0] */
wolfSSL 15:117db924cf7c 5835 recipKeyIdSeqSz = SetImplicit(ASN_SEQUENCE, 0, subjKeyIdOctetSz +
wolfSSL 15:117db924cf7c 5836 KEYID_SIZE, recipKeyIdSeq);
wolfSSL 15:117db924cf7c 5837 totalSz += recipKeyIdSeqSz;
wolfSSL 15:117db924cf7c 5838
wolfSSL 15:117db924cf7c 5839 /* RecipientEncryptedKey */
wolfSSL 15:117db924cf7c 5840 recipEncKeySeqSz = SetSequence(totalSz, recipEncKeySeq);
wolfSSL 15:117db924cf7c 5841 totalSz += recipEncKeySeqSz;
wolfSSL 15:117db924cf7c 5842
wolfSSL 15:117db924cf7c 5843 /* RecipientEncryptedKeys */
wolfSSL 15:117db924cf7c 5844 recipEncKeysSeqSz = SetSequence(totalSz, recipEncKeysSeq);
wolfSSL 15:117db924cf7c 5845 totalSz += recipEncKeysSeqSz;
wolfSSL 15:117db924cf7c 5846
wolfSSL 15:117db924cf7c 5847 /* Start of optional UserKeyingMaterial */
wolfSSL 15:117db924cf7c 5848
wolfSSL 15:117db924cf7c 5849 if (kari->ukmSz > 0) {
wolfSSL 15:117db924cf7c 5850 ukmOctetSz = SetOctetString(kari->ukmSz, ukmOctetStr);
wolfSSL 15:117db924cf7c 5851 totalSz += (ukmOctetSz + kari->ukmSz);
wolfSSL 15:117db924cf7c 5852
wolfSSL 15:117db924cf7c 5853 ukmExplicitSz = SetExplicit(1, ukmOctetSz + kari->ukmSz,
wolfSSL 15:117db924cf7c 5854 ukmExplicitSeq);
wolfSSL 15:117db924cf7c 5855 totalSz += ukmExplicitSz;
wolfSSL 15:117db924cf7c 5856 }
wolfSSL 15:117db924cf7c 5857
wolfSSL 15:117db924cf7c 5858 /* Start of KeyEncryptionAlgorithmIdentifier */
wolfSSL 15:117db924cf7c 5859
wolfSSL 15:117db924cf7c 5860 /* KeyWrapAlgorithm */
wolfSSL 16:8e0d178b1d1e 5861 keyWrapAlgSz = SetAlgoID(keyWrapOID, keyWrapAlg, oidKeyWrapType, 0);
wolfSSL 15:117db924cf7c 5862 totalSz += keyWrapAlgSz;
wolfSSL 15:117db924cf7c 5863
wolfSSL 15:117db924cf7c 5864 /* KeyEncryptionAlgorithmIdentifier */
wolfSSL 16:8e0d178b1d1e 5865 keyEncryptAlgoIdSz = SetAlgoID(keyAgreeOID, keyEncryptAlgoId,
wolfSSL 15:117db924cf7c 5866 oidCmsKeyAgreeType, keyWrapAlgSz);
wolfSSL 15:117db924cf7c 5867 totalSz += keyEncryptAlgoIdSz;
wolfSSL 15:117db924cf7c 5868
wolfSSL 15:117db924cf7c 5869 /* Start of OriginatorIdentifierOrKey */
wolfSSL 15:117db924cf7c 5870
wolfSSL 15:117db924cf7c 5871 /* recipient ECPoint, public key */
wolfSSL 15:117db924cf7c 5872 XMEMSET(origPubKeyStr, 0, sizeof(origPubKeyStr)); /* no unused bits */
wolfSSL 15:117db924cf7c 5873 origPubKeyStr[0] = ASN_BIT_STRING;
wolfSSL 15:117db924cf7c 5874 origPubKeyStrSz = SetLength(kari->senderKeyExportSz + 1,
wolfSSL 15:117db924cf7c 5875 origPubKeyStr + 1) + 2;
wolfSSL 15:117db924cf7c 5876 totalSz += (origPubKeyStrSz + kari->senderKeyExportSz);
wolfSSL 15:117db924cf7c 5877
wolfSSL 16:8e0d178b1d1e 5878 /* Originator AlgorithmIdentifier, params set to NULL for interop
wolfSSL 16:8e0d178b1d1e 5879 compatibility */
wolfSSL 16:8e0d178b1d1e 5880 origAlgIdSz = SetAlgoID(ECDSAk, origAlgId, oidKeyType, 2);
wolfSSL 16:8e0d178b1d1e 5881 origAlgId[origAlgIdSz++] = ASN_TAG_NULL;
wolfSSL 16:8e0d178b1d1e 5882 origAlgId[origAlgIdSz++] = 0;
wolfSSL 15:117db924cf7c 5883 totalSz += origAlgIdSz;
wolfSSL 15:117db924cf7c 5884
wolfSSL 15:117db924cf7c 5885 /* outer OriginatorPublicKey IMPLICIT [1] */
wolfSSL 15:117db924cf7c 5886 origPubKeySeqSz = SetImplicit(ASN_SEQUENCE, 1,
wolfSSL 15:117db924cf7c 5887 origAlgIdSz + origPubKeyStrSz +
wolfSSL 15:117db924cf7c 5888 kari->senderKeyExportSz, origPubKeySeq);
wolfSSL 15:117db924cf7c 5889 totalSz += origPubKeySeqSz;
wolfSSL 15:117db924cf7c 5890
wolfSSL 15:117db924cf7c 5891 /* outer OriginatorIdentiferOrKey IMPLICIT [0] */
wolfSSL 15:117db924cf7c 5892 origIdOrKeySeqSz = SetImplicit(ASN_SEQUENCE, 0,
wolfSSL 15:117db924cf7c 5893 origPubKeySeqSz + origAlgIdSz +
wolfSSL 15:117db924cf7c 5894 origPubKeyStrSz + kari->senderKeyExportSz,
wolfSSL 15:117db924cf7c 5895 origIdOrKeySeq);
wolfSSL 15:117db924cf7c 5896 totalSz += origIdOrKeySeqSz;
wolfSSL 15:117db924cf7c 5897
wolfSSL 15:117db924cf7c 5898 /* version, always 3 */
wolfSSL 15:117db924cf7c 5899 verSz = SetMyVersion(3, ver, 0);
wolfSSL 15:117db924cf7c 5900 totalSz += verSz;
wolfSSL 16:8e0d178b1d1e 5901 recip->recipVersion = 3;
wolfSSL 15:117db924cf7c 5902
wolfSSL 15:117db924cf7c 5903 /* outer IMPLICIT [1] kari */
wolfSSL 15:117db924cf7c 5904 kariSeqSz = SetImplicit(ASN_SEQUENCE, 1, totalSz, kariSeq);
wolfSSL 15:117db924cf7c 5905 totalSz += kariSeqSz;
wolfSSL 15:117db924cf7c 5906
wolfSSL 16:8e0d178b1d1e 5907 if (totalSz > MAX_RECIP_SZ) {
wolfSSL 15:117db924cf7c 5908 WOLFSSL_MSG("KeyAgreeRecipientInfo output buffer too small");
wolfSSL 15:117db924cf7c 5909 wc_PKCS7_KariFree(kari);
wolfSSL 16:8e0d178b1d1e 5910 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 5911 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 5912 #endif
wolfSSL 16:8e0d178b1d1e 5913 XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 5914 return BUFFER_E;
wolfSSL 15:117db924cf7c 5915 }
wolfSSL 15:117db924cf7c 5916
wolfSSL 16:8e0d178b1d1e 5917 XMEMCPY(recip->recip + idx, kariSeq, kariSeqSz);
wolfSSL 15:117db924cf7c 5918 idx += kariSeqSz;
wolfSSL 16:8e0d178b1d1e 5919 XMEMCPY(recip->recip + idx, ver, verSz);
wolfSSL 15:117db924cf7c 5920 idx += verSz;
wolfSSL 15:117db924cf7c 5921
wolfSSL 16:8e0d178b1d1e 5922 XMEMCPY(recip->recip + idx, origIdOrKeySeq, origIdOrKeySeqSz);
wolfSSL 15:117db924cf7c 5923 idx += origIdOrKeySeqSz;
wolfSSL 16:8e0d178b1d1e 5924 XMEMCPY(recip->recip + idx, origPubKeySeq, origPubKeySeqSz);
wolfSSL 15:117db924cf7c 5925 idx += origPubKeySeqSz;
wolfSSL 16:8e0d178b1d1e 5926
wolfSSL 16:8e0d178b1d1e 5927 /* AlgorithmIdentifier with NULL parameter */
wolfSSL 16:8e0d178b1d1e 5928 XMEMCPY(recip->recip + idx, origAlgId, origAlgIdSz);
wolfSSL 15:117db924cf7c 5929 idx += origAlgIdSz;
wolfSSL 16:8e0d178b1d1e 5930
wolfSSL 16:8e0d178b1d1e 5931 XMEMCPY(recip->recip + idx, origPubKeyStr, origPubKeyStrSz);
wolfSSL 15:117db924cf7c 5932 idx += origPubKeyStrSz;
wolfSSL 15:117db924cf7c 5933 /* ephemeral public key */
wolfSSL 16:8e0d178b1d1e 5934 XMEMCPY(recip->recip + idx, kari->senderKeyExport, kari->senderKeyExportSz);
wolfSSL 15:117db924cf7c 5935 idx += kari->senderKeyExportSz;
wolfSSL 15:117db924cf7c 5936
wolfSSL 15:117db924cf7c 5937 if (kari->ukmSz > 0) {
wolfSSL 16:8e0d178b1d1e 5938 XMEMCPY(recip->recip + idx, ukmExplicitSeq, ukmExplicitSz);
wolfSSL 15:117db924cf7c 5939 idx += ukmExplicitSz;
wolfSSL 16:8e0d178b1d1e 5940 XMEMCPY(recip->recip + idx, ukmOctetStr, ukmOctetSz);
wolfSSL 15:117db924cf7c 5941 idx += ukmOctetSz;
wolfSSL 16:8e0d178b1d1e 5942 XMEMCPY(recip->recip + idx, kari->ukm, kari->ukmSz);
wolfSSL 15:117db924cf7c 5943 idx += kari->ukmSz;
wolfSSL 15:117db924cf7c 5944 }
wolfSSL 15:117db924cf7c 5945
wolfSSL 16:8e0d178b1d1e 5946 XMEMCPY(recip->recip + idx, keyEncryptAlgoId, keyEncryptAlgoIdSz);
wolfSSL 15:117db924cf7c 5947 idx += keyEncryptAlgoIdSz;
wolfSSL 16:8e0d178b1d1e 5948 XMEMCPY(recip->recip + idx, keyWrapAlg, keyWrapAlgSz);
wolfSSL 15:117db924cf7c 5949 idx += keyWrapAlgSz;
wolfSSL 15:117db924cf7c 5950
wolfSSL 16:8e0d178b1d1e 5951 XMEMCPY(recip->recip + idx, recipEncKeysSeq, recipEncKeysSeqSz);
wolfSSL 15:117db924cf7c 5952 idx += recipEncKeysSeqSz;
wolfSSL 16:8e0d178b1d1e 5953 XMEMCPY(recip->recip + idx, recipEncKeySeq, recipEncKeySeqSz);
wolfSSL 15:117db924cf7c 5954 idx += recipEncKeySeqSz;
wolfSSL 16:8e0d178b1d1e 5955 XMEMCPY(recip->recip + idx, recipKeyIdSeq, recipKeyIdSeqSz);
wolfSSL 15:117db924cf7c 5956 idx += recipKeyIdSeqSz;
wolfSSL 16:8e0d178b1d1e 5957 XMEMCPY(recip->recip + idx, subjKeyIdOctet, subjKeyIdOctetSz);
wolfSSL 15:117db924cf7c 5958 idx += subjKeyIdOctetSz;
wolfSSL 15:117db924cf7c 5959 /* subject key id */
wolfSSL 16:8e0d178b1d1e 5960 XMEMCPY(recip->recip + idx, kari->decoded->extSubjKeyId, KEYID_SIZE);
wolfSSL 15:117db924cf7c 5961 idx += KEYID_SIZE;
wolfSSL 16:8e0d178b1d1e 5962 XMEMCPY(recip->recip + idx, encryptedKeyOctet, encryptedKeyOctetSz);
wolfSSL 15:117db924cf7c 5963 idx += encryptedKeyOctetSz;
wolfSSL 15:117db924cf7c 5964 /* encrypted CEK */
wolfSSL 16:8e0d178b1d1e 5965 XMEMCPY(recip->recip + idx, encryptedKey, encryptedKeySz);
wolfSSL 16:8e0d178b1d1e 5966 idx += encryptedKeySz;
wolfSSL 15:117db924cf7c 5967
wolfSSL 15:117db924cf7c 5968 wc_PKCS7_KariFree(kari);
wolfSSL 16:8e0d178b1d1e 5969 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 5970 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 5971 #endif
wolfSSL 16:8e0d178b1d1e 5972
wolfSSL 16:8e0d178b1d1e 5973 /* store recipient size */
wolfSSL 16:8e0d178b1d1e 5974 recip->recipSz = idx;
wolfSSL 16:8e0d178b1d1e 5975 recip->recipType = PKCS7_KARI;
wolfSSL 16:8e0d178b1d1e 5976
wolfSSL 16:8e0d178b1d1e 5977 /* add recipient to recip list */
wolfSSL 16:8e0d178b1d1e 5978 if (pkcs7->recipList == NULL) {
wolfSSL 16:8e0d178b1d1e 5979 pkcs7->recipList = recip;
wolfSSL 16:8e0d178b1d1e 5980 } else {
wolfSSL 16:8e0d178b1d1e 5981 lastRecip = pkcs7->recipList;
wolfSSL 16:8e0d178b1d1e 5982 while (lastRecip->next != NULL) {
wolfSSL 16:8e0d178b1d1e 5983 lastRecip = lastRecip->next;
wolfSSL 16:8e0d178b1d1e 5984 }
wolfSSL 16:8e0d178b1d1e 5985 lastRecip->next = recip;
wolfSSL 16:8e0d178b1d1e 5986 }
wolfSSL 16:8e0d178b1d1e 5987
wolfSSL 16:8e0d178b1d1e 5988 (void)options;
wolfSSL 15:117db924cf7c 5989
wolfSSL 15:117db924cf7c 5990 return idx;
wolfSSL 15:117db924cf7c 5991 }
wolfSSL 15:117db924cf7c 5992
wolfSSL 15:117db924cf7c 5993 #endif /* HAVE_ECC */
wolfSSL 15:117db924cf7c 5994
wolfSSL 15:117db924cf7c 5995 #ifndef NO_RSA
wolfSSL 15:117db924cf7c 5996
wolfSSL 16:8e0d178b1d1e 5997 /* Encode and add CMS EnvelopedData KTRI (KeyTransRecipientInfo) RecipientInfo
wolfSSL 16:8e0d178b1d1e 5998 * to CMS/PKCS#7 EnvelopedData structure.
wolfSSL 16:8e0d178b1d1e 5999 *
wolfSSL 16:8e0d178b1d1e 6000 * Returns 0 on success, negative upon error */
wolfSSL 16:8e0d178b1d1e 6001 int wc_PKCS7_AddRecipient_KTRI(PKCS7* pkcs7, const byte* cert, word32 certSz,
wolfSSL 16:8e0d178b1d1e 6002 int options)
wolfSSL 16:8e0d178b1d1e 6003 {
wolfSSL 16:8e0d178b1d1e 6004 Pkcs7EncodedRecip* recip = NULL;
wolfSSL 16:8e0d178b1d1e 6005 Pkcs7EncodedRecip* lastRecip = NULL;
wolfSSL 16:8e0d178b1d1e 6006
wolfSSL 16:8e0d178b1d1e 6007 WC_RNG rng;
wolfSSL 15:117db924cf7c 6008 word32 idx = 0;
wolfSSL 16:8e0d178b1d1e 6009 word32 encryptedKeySz = 0;
wolfSSL 16:8e0d178b1d1e 6010
wolfSSL 16:8e0d178b1d1e 6011 int ret = 0, blockKeySz;
wolfSSL 16:8e0d178b1d1e 6012 int verSz = 0, issuerSz = 0, snSz = 0, keyEncAlgSz = 0;
wolfSSL 16:8e0d178b1d1e 6013 int issuerSeqSz = 0, recipSeqSz = 0, issuerSerialSeqSz = 0;
wolfSSL 15:117db924cf7c 6014 int encKeyOctetStrSz;
wolfSSL 16:8e0d178b1d1e 6015 int sidType;
wolfSSL 15:117db924cf7c 6016
wolfSSL 15:117db924cf7c 6017 byte ver[MAX_VERSION_SZ];
wolfSSL 15:117db924cf7c 6018 byte issuerSerialSeq[MAX_SEQ_SZ];
wolfSSL 15:117db924cf7c 6019 byte recipSeq[MAX_SEQ_SZ];
wolfSSL 15:117db924cf7c 6020 byte issuerSeq[MAX_SEQ_SZ];
wolfSSL 15:117db924cf7c 6021 byte encKeyOctetStr[MAX_OCTET_STR_SZ];
wolfSSL 15:117db924cf7c 6022
wolfSSL 16:8e0d178b1d1e 6023 byte issuerSKIDSeq[MAX_SEQ_SZ];
wolfSSL 16:8e0d178b1d1e 6024 byte issuerSKID[MAX_OCTET_STR_SZ];
wolfSSL 16:8e0d178b1d1e 6025 word32 issuerSKIDSeqSz = 0, issuerSKIDSz = 0;
wolfSSL 16:8e0d178b1d1e 6026
wolfSSL 16:8e0d178b1d1e 6027 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 6028 byte* serial;
wolfSSL 16:8e0d178b1d1e 6029 byte* keyAlgArray;
wolfSSL 16:8e0d178b1d1e 6030 byte* encryptedKey;
wolfSSL 15:117db924cf7c 6031 RsaKey* pubKey;
wolfSSL 15:117db924cf7c 6032 DecodedCert* decoded;
wolfSSL 15:117db924cf7c 6033
wolfSSL 16:8e0d178b1d1e 6034 serial = (byte*)XMALLOC(MAX_SN_SZ, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6035 keyAlgArray = (byte*)XMALLOC(MAX_SN_SZ, pkcs7->heap,
wolfSSL 16:8e0d178b1d1e 6036 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6037 encryptedKey = (byte*)XMALLOC(MAX_ENCRYPTED_KEY_SZ, pkcs7->heap,
wolfSSL 16:8e0d178b1d1e 6038 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6039 decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), pkcs7->heap,
wolfSSL 16:8e0d178b1d1e 6040 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6041
wolfSSL 16:8e0d178b1d1e 6042 if (decoded == NULL || serial == NULL ||
wolfSSL 16:8e0d178b1d1e 6043 encryptedKey == NULL || keyAlgArray == NULL) {
wolfSSL 16:8e0d178b1d1e 6044 if (serial)
wolfSSL 16:8e0d178b1d1e 6045 XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6046 if (keyAlgArray)
wolfSSL 16:8e0d178b1d1e 6047 XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6048 if (encryptedKey)
wolfSSL 16:8e0d178b1d1e 6049 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6050 if (decoded)
wolfSSL 16:8e0d178b1d1e 6051 XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 6052 return MEMORY_E;
wolfSSL 15:117db924cf7c 6053 }
wolfSSL 15:117db924cf7c 6054 #else
wolfSSL 15:117db924cf7c 6055 byte serial[MAX_SN_SZ];
wolfSSL 15:117db924cf7c 6056 byte keyAlgArray[MAX_ALGO_SZ];
wolfSSL 16:8e0d178b1d1e 6057 byte encryptedKey[MAX_ENCRYPTED_KEY_SZ];
wolfSSL 16:8e0d178b1d1e 6058
wolfSSL 16:8e0d178b1d1e 6059 RsaKey pubKey[1];
wolfSSL 16:8e0d178b1d1e 6060 DecodedCert decoded[1];
wolfSSL 16:8e0d178b1d1e 6061 #endif
wolfSSL 16:8e0d178b1d1e 6062
wolfSSL 16:8e0d178b1d1e 6063 encryptedKeySz = MAX_ENCRYPTED_KEY_SZ;
wolfSSL 16:8e0d178b1d1e 6064 XMEMSET(encryptedKey, 0, encryptedKeySz);
wolfSSL 16:8e0d178b1d1e 6065
wolfSSL 16:8e0d178b1d1e 6066 /* default to IssuerAndSerialNumber if not set */
wolfSSL 16:8e0d178b1d1e 6067 if (pkcs7->sidType != 0) {
wolfSSL 16:8e0d178b1d1e 6068 sidType = pkcs7->sidType;
wolfSSL 16:8e0d178b1d1e 6069 } else {
wolfSSL 16:8e0d178b1d1e 6070 sidType = CMS_ISSUER_AND_SERIAL_NUMBER;
wolfSSL 16:8e0d178b1d1e 6071 }
wolfSSL 16:8e0d178b1d1e 6072
wolfSSL 16:8e0d178b1d1e 6073 /* allow options to override SubjectIdentifier type if set */
wolfSSL 16:8e0d178b1d1e 6074 if (options & CMS_SKID) {
wolfSSL 16:8e0d178b1d1e 6075 sidType = CMS_SKID;
wolfSSL 16:8e0d178b1d1e 6076 } else if (options & CMS_ISSUER_AND_SERIAL_NUMBER) {
wolfSSL 16:8e0d178b1d1e 6077 sidType = CMS_ISSUER_AND_SERIAL_NUMBER;
wolfSSL 16:8e0d178b1d1e 6078 }
wolfSSL 16:8e0d178b1d1e 6079
wolfSSL 16:8e0d178b1d1e 6080 /* allocate recipient struct */
wolfSSL 16:8e0d178b1d1e 6081 recip = (Pkcs7EncodedRecip*)XMALLOC(sizeof(Pkcs7EncodedRecip), pkcs7->heap,
wolfSSL 16:8e0d178b1d1e 6082 DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 6083 if (recip == NULL) {
wolfSSL 16:8e0d178b1d1e 6084 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 6085 XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6086 XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6087 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6088 XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6089 #endif
wolfSSL 16:8e0d178b1d1e 6090 return MEMORY_E;
wolfSSL 16:8e0d178b1d1e 6091 }
wolfSSL 16:8e0d178b1d1e 6092 XMEMSET(recip, 0, sizeof(Pkcs7EncodedRecip));
wolfSSL 16:8e0d178b1d1e 6093
wolfSSL 16:8e0d178b1d1e 6094 /* get key size for content-encryption key based on algorithm */
wolfSSL 16:8e0d178b1d1e 6095 blockKeySz = wc_PKCS7_GetOIDKeySize(pkcs7->encryptOID);
wolfSSL 16:8e0d178b1d1e 6096 if (blockKeySz < 0) {
wolfSSL 16:8e0d178b1d1e 6097 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 6098 XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6099 XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6100 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6101 XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6102 #endif
wolfSSL 16:8e0d178b1d1e 6103 XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 6104 return blockKeySz;
wolfSSL 16:8e0d178b1d1e 6105 }
wolfSSL 16:8e0d178b1d1e 6106
wolfSSL 16:8e0d178b1d1e 6107 /* generate random content encryption key, if needed */
wolfSSL 16:8e0d178b1d1e 6108 ret = PKCS7_GenerateContentEncryptionKey(pkcs7, blockKeySz);
wolfSSL 16:8e0d178b1d1e 6109 if (ret < 0) {
wolfSSL 16:8e0d178b1d1e 6110 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 6111 XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6112 XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6113 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6114 XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6115 #endif
wolfSSL 16:8e0d178b1d1e 6116 XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 6117 return ret;
wolfSSL 16:8e0d178b1d1e 6118 }
wolfSSL 16:8e0d178b1d1e 6119
wolfSSL 16:8e0d178b1d1e 6120 InitDecodedCert(decoded, (byte*)cert, certSz, pkcs7->heap);
wolfSSL 15:117db924cf7c 6121 ret = ParseCert(decoded, CA_TYPE, NO_VERIFY, 0);
wolfSSL 15:117db924cf7c 6122 if (ret < 0) {
wolfSSL 15:117db924cf7c 6123 FreeDecodedCert(decoded);
wolfSSL 15:117db924cf7c 6124 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 6125 XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6126 XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6127 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6128 XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6129 #endif
wolfSSL 16:8e0d178b1d1e 6130 XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 6131 return ret;
wolfSSL 15:117db924cf7c 6132 }
wolfSSL 15:117db924cf7c 6133
wolfSSL 16:8e0d178b1d1e 6134 if (sidType == CMS_ISSUER_AND_SERIAL_NUMBER) {
wolfSSL 16:8e0d178b1d1e 6135
wolfSSL 16:8e0d178b1d1e 6136 /* version, must be 0 for IssuerAndSerialNumber */
wolfSSL 16:8e0d178b1d1e 6137 verSz = SetMyVersion(0, ver, 0);
wolfSSL 16:8e0d178b1d1e 6138 recip->recipVersion = 0;
wolfSSL 16:8e0d178b1d1e 6139
wolfSSL 16:8e0d178b1d1e 6140 /* IssuerAndSerialNumber */
wolfSSL 16:8e0d178b1d1e 6141 if (decoded->issuerRaw == NULL || decoded->issuerRawLen == 0) {
wolfSSL 16:8e0d178b1d1e 6142 WOLFSSL_MSG("DecodedCert lacks raw issuer pointer and length");
wolfSSL 16:8e0d178b1d1e 6143 FreeDecodedCert(decoded);
wolfSSL 16:8e0d178b1d1e 6144 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 6145 XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6146 XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6147 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6148 XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6149 #endif
wolfSSL 16:8e0d178b1d1e 6150 XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 6151 return -1;
wolfSSL 16:8e0d178b1d1e 6152 }
wolfSSL 16:8e0d178b1d1e 6153 issuerSz = decoded->issuerRawLen;
wolfSSL 16:8e0d178b1d1e 6154 issuerSeqSz = SetSequence(issuerSz, issuerSeq);
wolfSSL 16:8e0d178b1d1e 6155
wolfSSL 16:8e0d178b1d1e 6156 if (decoded->serialSz == 0) {
wolfSSL 16:8e0d178b1d1e 6157 WOLFSSL_MSG("DecodedCert missing serial number");
wolfSSL 16:8e0d178b1d1e 6158 FreeDecodedCert(decoded);
wolfSSL 16:8e0d178b1d1e 6159 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 6160 XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6161 XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6162 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6163 XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6164 #endif
wolfSSL 16:8e0d178b1d1e 6165 XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 6166 return -1;
wolfSSL 16:8e0d178b1d1e 6167 }
wolfSSL 16:8e0d178b1d1e 6168 snSz = SetSerialNumber(decoded->serial, decoded->serialSz, serial,
wolfSSL 16:8e0d178b1d1e 6169 MAX_SN_SZ, MAX_SN_SZ);
wolfSSL 16:8e0d178b1d1e 6170
wolfSSL 16:8e0d178b1d1e 6171 issuerSerialSeqSz = SetSequence(issuerSeqSz + issuerSz + snSz,
wolfSSL 16:8e0d178b1d1e 6172 issuerSerialSeq);
wolfSSL 16:8e0d178b1d1e 6173
wolfSSL 16:8e0d178b1d1e 6174 } else if (sidType == CMS_SKID) {
wolfSSL 16:8e0d178b1d1e 6175
wolfSSL 16:8e0d178b1d1e 6176 /* version, must be 2 for SubjectKeyIdentifier */
wolfSSL 16:8e0d178b1d1e 6177 verSz = SetMyVersion(2, ver, 0);
wolfSSL 16:8e0d178b1d1e 6178 recip->recipVersion = 2;
wolfSSL 16:8e0d178b1d1e 6179
wolfSSL 16:8e0d178b1d1e 6180 issuerSKIDSz = SetOctetString(KEYID_SIZE, issuerSKID);
wolfSSL 16:8e0d178b1d1e 6181 issuerSKIDSeqSz = SetExplicit(0, issuerSKIDSz + KEYID_SIZE,
wolfSSL 16:8e0d178b1d1e 6182 issuerSKIDSeq);
wolfSSL 16:8e0d178b1d1e 6183 } else {
wolfSSL 15:117db924cf7c 6184 FreeDecodedCert(decoded);
wolfSSL 15:117db924cf7c 6185 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 6186 XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6187 XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6188 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6189 XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6190 #endif
wolfSSL 16:8e0d178b1d1e 6191 XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 6192 return PKCS7_RECIP_E;
wolfSSL 16:8e0d178b1d1e 6193 }
wolfSSL 16:8e0d178b1d1e 6194
wolfSSL 16:8e0d178b1d1e 6195 pkcs7->publicKeyOID = decoded->keyOID;
wolfSSL 15:117db924cf7c 6196
wolfSSL 15:117db924cf7c 6197 /* KeyEncryptionAlgorithmIdentifier, only support RSA now */
wolfSSL 16:8e0d178b1d1e 6198 if (pkcs7->publicKeyOID != RSAk) {
wolfSSL 15:117db924cf7c 6199 FreeDecodedCert(decoded);
wolfSSL 15:117db924cf7c 6200 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 6201 XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6202 XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6203 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6204 XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6205 #endif
wolfSSL 16:8e0d178b1d1e 6206 XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 6207 return ALGO_ID_E;
wolfSSL 15:117db924cf7c 6208 }
wolfSSL 15:117db924cf7c 6209
wolfSSL 16:8e0d178b1d1e 6210 keyEncAlgSz = SetAlgoID(pkcs7->publicKeyOID, keyAlgArray, oidKeyType, 0);
wolfSSL 15:117db924cf7c 6211 if (keyEncAlgSz == 0) {
wolfSSL 15:117db924cf7c 6212 FreeDecodedCert(decoded);
wolfSSL 15:117db924cf7c 6213 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 6214 XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6215 XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6216 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6217 XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6218 #endif
wolfSSL 16:8e0d178b1d1e 6219 XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 6220 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 6221 }
wolfSSL 16:8e0d178b1d1e 6222
wolfSSL 16:8e0d178b1d1e 6223 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 6224 pubKey = (RsaKey*)XMALLOC(sizeof(RsaKey), pkcs7->heap,
wolfSSL 16:8e0d178b1d1e 6225 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 6226 if (pubKey == NULL) {
wolfSSL 15:117db924cf7c 6227 FreeDecodedCert(decoded);
wolfSSL 16:8e0d178b1d1e 6228 XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6229 XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6230 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6231 XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6232 XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 6233 return MEMORY_E;
wolfSSL 15:117db924cf7c 6234 }
wolfSSL 15:117db924cf7c 6235 #endif
wolfSSL 15:117db924cf7c 6236
wolfSSL 15:117db924cf7c 6237 /* EncryptedKey */
wolfSSL 16:8e0d178b1d1e 6238 ret = wc_InitRsaKey_ex(pubKey, pkcs7->heap, INVALID_DEVID);
wolfSSL 15:117db924cf7c 6239 if (ret != 0) {
wolfSSL 15:117db924cf7c 6240 FreeDecodedCert(decoded);
wolfSSL 15:117db924cf7c 6241 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 6242 XFREE(pubKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6243 XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6244 XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6245 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6246 XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6247 #endif
wolfSSL 16:8e0d178b1d1e 6248 XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 6249 return ret;
wolfSSL 15:117db924cf7c 6250 }
wolfSSL 15:117db924cf7c 6251
wolfSSL 15:117db924cf7c 6252 if (wc_RsaPublicKeyDecode(decoded->publicKey, &idx, pubKey,
wolfSSL 16:8e0d178b1d1e 6253 decoded->pubKeySize) < 0) {
wolfSSL 15:117db924cf7c 6254 WOLFSSL_MSG("ASN RSA key decode error");
wolfSSL 15:117db924cf7c 6255 wc_FreeRsaKey(pubKey);
wolfSSL 15:117db924cf7c 6256 FreeDecodedCert(decoded);
wolfSSL 15:117db924cf7c 6257 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 6258 XFREE(pubKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6259 XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6260 XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6261 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6262 XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6263 #endif
wolfSSL 16:8e0d178b1d1e 6264 XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 6265 return PUBLIC_KEY_E;
wolfSSL 15:117db924cf7c 6266 }
wolfSSL 15:117db924cf7c 6267
wolfSSL 16:8e0d178b1d1e 6268 ret = wc_InitRng_ex(&rng, pkcs7->heap, pkcs7->devId);
wolfSSL 16:8e0d178b1d1e 6269 if (ret != 0) {
wolfSSL 16:8e0d178b1d1e 6270 wc_FreeRsaKey(pubKey);
wolfSSL 16:8e0d178b1d1e 6271 FreeDecodedCert(decoded);
wolfSSL 16:8e0d178b1d1e 6272 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 6273 XFREE(pubKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6274 XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6275 XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6276 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6277 XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6278 #endif
wolfSSL 16:8e0d178b1d1e 6279 XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 6280 return MEMORY_E;
wolfSSL 16:8e0d178b1d1e 6281 }
wolfSSL 16:8e0d178b1d1e 6282
wolfSSL 16:8e0d178b1d1e 6283
wolfSSL 16:8e0d178b1d1e 6284 ret = wc_RsaPublicEncrypt(pkcs7->cek, pkcs7->cekSz, encryptedKey,
wolfSSL 16:8e0d178b1d1e 6285 encryptedKeySz, pubKey, &rng);
wolfSSL 15:117db924cf7c 6286 wc_FreeRsaKey(pubKey);
wolfSSL 16:8e0d178b1d1e 6287 wc_FreeRng(&rng);
wolfSSL 16:8e0d178b1d1e 6288
wolfSSL 16:8e0d178b1d1e 6289 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 6290 XFREE(pubKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6291 #endif
wolfSSL 16:8e0d178b1d1e 6292
wolfSSL 16:8e0d178b1d1e 6293 if (ret < 0) {
wolfSSL 15:117db924cf7c 6294 WOLFSSL_MSG("RSA Public Encrypt failed");
wolfSSL 15:117db924cf7c 6295 FreeDecodedCert(decoded);
wolfSSL 15:117db924cf7c 6296 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 6297 XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6298 XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6299 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6300 XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6301 #endif
wolfSSL 16:8e0d178b1d1e 6302 XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 6303 return ret;
wolfSSL 16:8e0d178b1d1e 6304 }
wolfSSL 16:8e0d178b1d1e 6305 encryptedKeySz = ret;
wolfSSL 16:8e0d178b1d1e 6306
wolfSSL 16:8e0d178b1d1e 6307 encKeyOctetStrSz = SetOctetString(encryptedKeySz, encKeyOctetStr);
wolfSSL 15:117db924cf7c 6308
wolfSSL 15:117db924cf7c 6309 /* RecipientInfo */
wolfSSL 16:8e0d178b1d1e 6310 if (sidType == CMS_ISSUER_AND_SERIAL_NUMBER) {
wolfSSL 16:8e0d178b1d1e 6311 recipSeqSz = SetSequence(verSz + issuerSerialSeqSz + issuerSeqSz +
wolfSSL 16:8e0d178b1d1e 6312 issuerSz + snSz + keyEncAlgSz +
wolfSSL 16:8e0d178b1d1e 6313 encKeyOctetStrSz + encryptedKeySz, recipSeq);
wolfSSL 16:8e0d178b1d1e 6314
wolfSSL 16:8e0d178b1d1e 6315 if (recipSeqSz + verSz + issuerSerialSeqSz + issuerSeqSz + snSz +
wolfSSL 16:8e0d178b1d1e 6316 keyEncAlgSz + encKeyOctetStrSz + encryptedKeySz > MAX_RECIP_SZ) {
wolfSSL 16:8e0d178b1d1e 6317 WOLFSSL_MSG("RecipientInfo output buffer too small");
wolfSSL 16:8e0d178b1d1e 6318 FreeDecodedCert(decoded);
wolfSSL 16:8e0d178b1d1e 6319 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 6320 XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6321 XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6322 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6323 XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6324 #endif
wolfSSL 16:8e0d178b1d1e 6325 XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 6326 return BUFFER_E;
wolfSSL 16:8e0d178b1d1e 6327 }
wolfSSL 16:8e0d178b1d1e 6328
wolfSSL 16:8e0d178b1d1e 6329 } else {
wolfSSL 16:8e0d178b1d1e 6330 recipSeqSz = SetSequence(verSz + issuerSKIDSeqSz + issuerSKIDSz +
wolfSSL 16:8e0d178b1d1e 6331 KEYID_SIZE + keyEncAlgSz + encKeyOctetStrSz +
wolfSSL 16:8e0d178b1d1e 6332 encryptedKeySz, recipSeq);
wolfSSL 16:8e0d178b1d1e 6333
wolfSSL 16:8e0d178b1d1e 6334 if (recipSeqSz + verSz + issuerSKIDSeqSz + issuerSKIDSz + KEYID_SIZE +
wolfSSL 16:8e0d178b1d1e 6335 keyEncAlgSz + encKeyOctetStrSz + encryptedKeySz > MAX_RECIP_SZ) {
wolfSSL 16:8e0d178b1d1e 6336 WOLFSSL_MSG("RecipientInfo output buffer too small");
wolfSSL 16:8e0d178b1d1e 6337 FreeDecodedCert(decoded);
wolfSSL 16:8e0d178b1d1e 6338 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 6339 XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6340 XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6341 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6342 XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6343 #endif
wolfSSL 16:8e0d178b1d1e 6344 XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 6345 return BUFFER_E;
wolfSSL 16:8e0d178b1d1e 6346 }
wolfSSL 16:8e0d178b1d1e 6347 }
wolfSSL 16:8e0d178b1d1e 6348
wolfSSL 16:8e0d178b1d1e 6349 idx = 0;
wolfSSL 16:8e0d178b1d1e 6350 XMEMCPY(recip->recip + idx, recipSeq, recipSeqSz);
wolfSSL 16:8e0d178b1d1e 6351 idx += recipSeqSz;
wolfSSL 16:8e0d178b1d1e 6352 XMEMCPY(recip->recip + idx, ver, verSz);
wolfSSL 16:8e0d178b1d1e 6353 idx += verSz;
wolfSSL 16:8e0d178b1d1e 6354 if (sidType == CMS_ISSUER_AND_SERIAL_NUMBER) {
wolfSSL 16:8e0d178b1d1e 6355 XMEMCPY(recip->recip + idx, issuerSerialSeq, issuerSerialSeqSz);
wolfSSL 16:8e0d178b1d1e 6356 idx += issuerSerialSeqSz;
wolfSSL 16:8e0d178b1d1e 6357 XMEMCPY(recip->recip + idx, issuerSeq, issuerSeqSz);
wolfSSL 16:8e0d178b1d1e 6358 idx += issuerSeqSz;
wolfSSL 16:8e0d178b1d1e 6359 XMEMCPY(recip->recip + idx, decoded->issuerRaw, issuerSz);
wolfSSL 16:8e0d178b1d1e 6360 idx += issuerSz;
wolfSSL 16:8e0d178b1d1e 6361 XMEMCPY(recip->recip + idx, serial, snSz);
wolfSSL 16:8e0d178b1d1e 6362 idx += snSz;
wolfSSL 16:8e0d178b1d1e 6363 } else {
wolfSSL 16:8e0d178b1d1e 6364 XMEMCPY(recip->recip + idx, issuerSKIDSeq, issuerSKIDSeqSz);
wolfSSL 16:8e0d178b1d1e 6365 idx += issuerSKIDSeqSz;
wolfSSL 16:8e0d178b1d1e 6366 XMEMCPY(recip->recip + idx, issuerSKID, issuerSKIDSz);
wolfSSL 16:8e0d178b1d1e 6367 idx += issuerSKIDSz;
wolfSSL 16:8e0d178b1d1e 6368 XMEMCPY(recip->recip + idx, pkcs7->issuerSubjKeyId, KEYID_SIZE);
wolfSSL 16:8e0d178b1d1e 6369 idx += KEYID_SIZE;
wolfSSL 16:8e0d178b1d1e 6370 }
wolfSSL 16:8e0d178b1d1e 6371 XMEMCPY(recip->recip + idx, keyAlgArray, keyEncAlgSz);
wolfSSL 16:8e0d178b1d1e 6372 idx += keyEncAlgSz;
wolfSSL 16:8e0d178b1d1e 6373 XMEMCPY(recip->recip + idx, encKeyOctetStr, encKeyOctetStrSz);
wolfSSL 16:8e0d178b1d1e 6374 idx += encKeyOctetStrSz;
wolfSSL 16:8e0d178b1d1e 6375 XMEMCPY(recip->recip + idx, encryptedKey, encryptedKeySz);
wolfSSL 16:8e0d178b1d1e 6376 idx += encryptedKeySz;
wolfSSL 15:117db924cf7c 6377
wolfSSL 15:117db924cf7c 6378 FreeDecodedCert(decoded);
wolfSSL 15:117db924cf7c 6379
wolfSSL 15:117db924cf7c 6380 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 6381 XFREE(serial, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6382 XFREE(keyAlgArray, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6383 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6384 XFREE(decoded, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 6385 #endif
wolfSSL 16:8e0d178b1d1e 6386
wolfSSL 16:8e0d178b1d1e 6387 /* store recipient size */
wolfSSL 16:8e0d178b1d1e 6388 recip->recipSz = idx;
wolfSSL 16:8e0d178b1d1e 6389 recip->recipType = PKCS7_KTRI;
wolfSSL 16:8e0d178b1d1e 6390
wolfSSL 16:8e0d178b1d1e 6391 /* add recipient to recip list */
wolfSSL 16:8e0d178b1d1e 6392 if (pkcs7->recipList == NULL) {
wolfSSL 16:8e0d178b1d1e 6393 pkcs7->recipList = recip;
wolfSSL 16:8e0d178b1d1e 6394 } else {
wolfSSL 16:8e0d178b1d1e 6395 lastRecip = pkcs7->recipList;
wolfSSL 16:8e0d178b1d1e 6396 while (lastRecip->next != NULL) {
wolfSSL 16:8e0d178b1d1e 6397 lastRecip = lastRecip->next;
wolfSSL 16:8e0d178b1d1e 6398 }
wolfSSL 16:8e0d178b1d1e 6399 lastRecip->next = recip;
wolfSSL 16:8e0d178b1d1e 6400 }
wolfSSL 16:8e0d178b1d1e 6401
wolfSSL 16:8e0d178b1d1e 6402 return idx;
wolfSSL 16:8e0d178b1d1e 6403 }
wolfSSL 16:8e0d178b1d1e 6404
wolfSSL 15:117db924cf7c 6405 #endif /* !NO_RSA */
wolfSSL 15:117db924cf7c 6406
wolfSSL 15:117db924cf7c 6407
wolfSSL 15:117db924cf7c 6408 /* encrypt content using encryptOID algo */
wolfSSL 15:117db924cf7c 6409 static int wc_PKCS7_EncryptContent(int encryptOID, byte* key, int keySz,
wolfSSL 16:8e0d178b1d1e 6410 byte* iv, int ivSz, byte* aad, word32 aadSz,
wolfSSL 16:8e0d178b1d1e 6411 byte* authTag, word32 authTagSz, byte* in,
wolfSSL 16:8e0d178b1d1e 6412 int inSz, byte* out)
wolfSSL 15:117db924cf7c 6413 {
wolfSSL 15:117db924cf7c 6414 int ret;
wolfSSL 15:117db924cf7c 6415 #ifndef NO_AES
wolfSSL 15:117db924cf7c 6416 Aes aes;
wolfSSL 15:117db924cf7c 6417 #endif
wolfSSL 15:117db924cf7c 6418 #ifndef NO_DES3
wolfSSL 15:117db924cf7c 6419 Des des;
wolfSSL 15:117db924cf7c 6420 Des3 des3;
wolfSSL 15:117db924cf7c 6421 #endif
wolfSSL 15:117db924cf7c 6422
wolfSSL 15:117db924cf7c 6423 if (key == NULL || iv == NULL || in == NULL || out == NULL)
wolfSSL 15:117db924cf7c 6424 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 6425
wolfSSL 15:117db924cf7c 6426 switch (encryptOID) {
wolfSSL 15:117db924cf7c 6427 #ifndef NO_AES
wolfSSL 15:117db924cf7c 6428 #ifdef WOLFSSL_AES_128
wolfSSL 15:117db924cf7c 6429 case AES128CBCb:
wolfSSL 15:117db924cf7c 6430 #endif
wolfSSL 15:117db924cf7c 6431 #ifdef WOLFSSL_AES_192
wolfSSL 15:117db924cf7c 6432 case AES192CBCb:
wolfSSL 15:117db924cf7c 6433 #endif
wolfSSL 15:117db924cf7c 6434 #ifdef WOLFSSL_AES_256
wolfSSL 15:117db924cf7c 6435 case AES256CBCb:
wolfSSL 15:117db924cf7c 6436 #endif
wolfSSL 15:117db924cf7c 6437 if (
wolfSSL 15:117db924cf7c 6438 #ifdef WOLFSSL_AES_128
wolfSSL 15:117db924cf7c 6439 (encryptOID == AES128CBCb && keySz != 16 ) ||
wolfSSL 15:117db924cf7c 6440 #endif
wolfSSL 15:117db924cf7c 6441 #ifdef WOLFSSL_AES_192
wolfSSL 15:117db924cf7c 6442 (encryptOID == AES192CBCb && keySz != 24 ) ||
wolfSSL 15:117db924cf7c 6443 #endif
wolfSSL 15:117db924cf7c 6444 #ifdef WOLFSSL_AES_256
wolfSSL 15:117db924cf7c 6445 (encryptOID == AES256CBCb && keySz != 32 ) ||
wolfSSL 15:117db924cf7c 6446 #endif
wolfSSL 15:117db924cf7c 6447 (ivSz != AES_BLOCK_SIZE) )
wolfSSL 15:117db924cf7c 6448 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 6449
wolfSSL 16:8e0d178b1d1e 6450 ret = wc_AesInit(&aes, NULL, INVALID_DEVID);
wolfSSL 16:8e0d178b1d1e 6451 if (ret == 0) {
wolfSSL 16:8e0d178b1d1e 6452 ret = wc_AesSetKey(&aes, key, keySz, iv, AES_ENCRYPTION);
wolfSSL 16:8e0d178b1d1e 6453 if (ret == 0)
wolfSSL 16:8e0d178b1d1e 6454 ret = wc_AesCbcEncrypt(&aes, out, in, inSz);
wolfSSL 16:8e0d178b1d1e 6455 wc_AesFree(&aes);
wolfSSL 16:8e0d178b1d1e 6456 }
wolfSSL 15:117db924cf7c 6457 break;
wolfSSL 16:8e0d178b1d1e 6458 #ifdef HAVE_AESGCM
wolfSSL 16:8e0d178b1d1e 6459 #ifdef WOLFSSL_AES_128
wolfSSL 16:8e0d178b1d1e 6460 case AES128GCMb:
wolfSSL 16:8e0d178b1d1e 6461 #endif
wolfSSL 16:8e0d178b1d1e 6462 #ifdef WOLFSSL_AES_192
wolfSSL 16:8e0d178b1d1e 6463 case AES192GCMb:
wolfSSL 16:8e0d178b1d1e 6464 #endif
wolfSSL 16:8e0d178b1d1e 6465 #ifdef WOLFSSL_AES_256
wolfSSL 16:8e0d178b1d1e 6466 case AES256GCMb:
wolfSSL 16:8e0d178b1d1e 6467 #endif
wolfSSL 16:8e0d178b1d1e 6468 #if defined(WOLFSSL_AES_128) || defined(WOLFSSL_AES_192) || \
wolfSSL 16:8e0d178b1d1e 6469 defined(WOLFSSL_AES_256)
wolfSSL 16:8e0d178b1d1e 6470 if (authTag == NULL)
wolfSSL 16:8e0d178b1d1e 6471 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 6472
wolfSSL 16:8e0d178b1d1e 6473 ret = wc_AesInit(&aes, NULL, INVALID_DEVID);
wolfSSL 16:8e0d178b1d1e 6474 if (ret == 0) {
wolfSSL 16:8e0d178b1d1e 6475 ret = wc_AesGcmSetKey(&aes, key, keySz);
wolfSSL 16:8e0d178b1d1e 6476 if (ret == 0)
wolfSSL 16:8e0d178b1d1e 6477 ret = wc_AesGcmEncrypt(&aes, out, in, inSz, iv, ivSz,
wolfSSL 16:8e0d178b1d1e 6478 authTag, authTagSz, aad, aadSz);
wolfSSL 16:8e0d178b1d1e 6479 wc_AesFree(&aes);
wolfSSL 16:8e0d178b1d1e 6480 }
wolfSSL 16:8e0d178b1d1e 6481 break;
wolfSSL 16:8e0d178b1d1e 6482 #endif
wolfSSL 16:8e0d178b1d1e 6483 #endif /* HAVE_AESGCM */
wolfSSL 16:8e0d178b1d1e 6484 #ifdef HAVE_AESCCM
wolfSSL 16:8e0d178b1d1e 6485 #ifdef WOLFSSL_AES_128
wolfSSL 16:8e0d178b1d1e 6486 case AES128CCMb:
wolfSSL 16:8e0d178b1d1e 6487 #endif
wolfSSL 16:8e0d178b1d1e 6488 #ifdef WOLFSSL_AES_192
wolfSSL 16:8e0d178b1d1e 6489 case AES192CCMb:
wolfSSL 16:8e0d178b1d1e 6490 #endif
wolfSSL 16:8e0d178b1d1e 6491 #ifdef WOLFSSL_AES_256
wolfSSL 16:8e0d178b1d1e 6492 case AES256CCMb:
wolfSSL 16:8e0d178b1d1e 6493 #endif
wolfSSL 16:8e0d178b1d1e 6494 #if defined(WOLFSSL_AES_128) || defined(WOLFSSL_AES_192) || \
wolfSSL 16:8e0d178b1d1e 6495 defined(WOLFSSL_AES_256)
wolfSSL 16:8e0d178b1d1e 6496 if (authTag == NULL)
wolfSSL 16:8e0d178b1d1e 6497 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 6498
wolfSSL 16:8e0d178b1d1e 6499 ret = wc_AesInit(&aes, NULL, INVALID_DEVID);
wolfSSL 16:8e0d178b1d1e 6500 if (ret == 0) {
wolfSSL 16:8e0d178b1d1e 6501 ret = wc_AesCcmSetKey(&aes, key, keySz);
wolfSSL 16:8e0d178b1d1e 6502 if (ret == 0)
wolfSSL 16:8e0d178b1d1e 6503 ret = wc_AesCcmEncrypt(&aes, out, in, inSz, iv, ivSz,
wolfSSL 16:8e0d178b1d1e 6504 authTag, authTagSz, aad, aadSz);
wolfSSL 16:8e0d178b1d1e 6505 wc_AesFree(&aes);
wolfSSL 16:8e0d178b1d1e 6506 }
wolfSSL 16:8e0d178b1d1e 6507 break;
wolfSSL 16:8e0d178b1d1e 6508 #endif
wolfSSL 16:8e0d178b1d1e 6509 #endif /* HAVE_AESCCM */
wolfSSL 16:8e0d178b1d1e 6510 #endif /* NO_AES */
wolfSSL 15:117db924cf7c 6511 #ifndef NO_DES3
wolfSSL 15:117db924cf7c 6512 case DESb:
wolfSSL 15:117db924cf7c 6513 if (keySz != DES_KEYLEN || ivSz != DES_BLOCK_SIZE)
wolfSSL 15:117db924cf7c 6514 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 6515
wolfSSL 15:117db924cf7c 6516 ret = wc_Des_SetKey(&des, key, iv, DES_ENCRYPTION);
wolfSSL 15:117db924cf7c 6517 if (ret == 0)
wolfSSL 15:117db924cf7c 6518 ret = wc_Des_CbcEncrypt(&des, out, in, inSz);
wolfSSL 15:117db924cf7c 6519
wolfSSL 15:117db924cf7c 6520 break;
wolfSSL 15:117db924cf7c 6521
wolfSSL 15:117db924cf7c 6522 case DES3b:
wolfSSL 15:117db924cf7c 6523 if (keySz != DES3_KEYLEN || ivSz != DES_BLOCK_SIZE)
wolfSSL 15:117db924cf7c 6524 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 6525
wolfSSL 16:8e0d178b1d1e 6526 ret = wc_Des3Init(&des3, NULL, INVALID_DEVID);
wolfSSL 16:8e0d178b1d1e 6527 if (ret == 0) {
wolfSSL 16:8e0d178b1d1e 6528 ret = wc_Des3_SetKey(&des3, key, iv, DES_ENCRYPTION);
wolfSSL 16:8e0d178b1d1e 6529 if (ret == 0)
wolfSSL 16:8e0d178b1d1e 6530 ret = wc_Des3_CbcEncrypt(&des3, out, in, inSz);
wolfSSL 16:8e0d178b1d1e 6531 wc_Des3Free(&des3);
wolfSSL 16:8e0d178b1d1e 6532 }
wolfSSL 15:117db924cf7c 6533 break;
wolfSSL 15:117db924cf7c 6534 #endif
wolfSSL 15:117db924cf7c 6535 default:
wolfSSL 15:117db924cf7c 6536 WOLFSSL_MSG("Unsupported content cipher type");
wolfSSL 15:117db924cf7c 6537 return ALGO_ID_E;
wolfSSL 15:117db924cf7c 6538 };
wolfSSL 15:117db924cf7c 6539
wolfSSL 16:8e0d178b1d1e 6540 #if defined(NO_AES) || (!defined(HAVE_AESGCM) && !defined(HAVE_AESCCM))
wolfSSL 16:8e0d178b1d1e 6541 (void)authTag;
wolfSSL 16:8e0d178b1d1e 6542 (void)authTagSz;
wolfSSL 16:8e0d178b1d1e 6543 (void)aad;
wolfSSL 16:8e0d178b1d1e 6544 (void)aadSz;
wolfSSL 16:8e0d178b1d1e 6545 #endif
wolfSSL 15:117db924cf7c 6546 return ret;
wolfSSL 15:117db924cf7c 6547 }
wolfSSL 15:117db924cf7c 6548
wolfSSL 15:117db924cf7c 6549
wolfSSL 16:8e0d178b1d1e 6550 /* decrypt content using encryptOID algo
wolfSSL 16:8e0d178b1d1e 6551 * returns 0 on success */
wolfSSL 16:8e0d178b1d1e 6552 static int wc_PKCS7_DecryptContent(PKCS7* pkcs7, int encryptOID, byte* key,
wolfSSL 16:8e0d178b1d1e 6553 int keySz, byte* iv, int ivSz, byte* aad, word32 aadSz, byte* authTag,
wolfSSL 16:8e0d178b1d1e 6554 word32 authTagSz, byte* in, int inSz, byte* out)
wolfSSL 15:117db924cf7c 6555 {
wolfSSL 15:117db924cf7c 6556 int ret;
wolfSSL 15:117db924cf7c 6557 #ifndef NO_AES
wolfSSL 15:117db924cf7c 6558 Aes aes;
wolfSSL 15:117db924cf7c 6559 #endif
wolfSSL 15:117db924cf7c 6560 #ifndef NO_DES3
wolfSSL 15:117db924cf7c 6561 Des des;
wolfSSL 15:117db924cf7c 6562 Des3 des3;
wolfSSL 15:117db924cf7c 6563 #endif
wolfSSL 15:117db924cf7c 6564
wolfSSL 16:8e0d178b1d1e 6565 if (iv == NULL || in == NULL || out == NULL)
wolfSSL 16:8e0d178b1d1e 6566 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 6567
wolfSSL 16:8e0d178b1d1e 6568 if (pkcs7->decryptionCb != NULL) {
wolfSSL 16:8e0d178b1d1e 6569 return pkcs7->decryptionCb(pkcs7, encryptOID, iv, ivSz,
wolfSSL 16:8e0d178b1d1e 6570 aad, aadSz, authTag, authTagSz, in,
wolfSSL 16:8e0d178b1d1e 6571 inSz, out, pkcs7->decryptionCtx);
wolfSSL 16:8e0d178b1d1e 6572 }
wolfSSL 16:8e0d178b1d1e 6573
wolfSSL 16:8e0d178b1d1e 6574 if (key == NULL)
wolfSSL 15:117db924cf7c 6575 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 6576
wolfSSL 15:117db924cf7c 6577 switch (encryptOID) {
wolfSSL 15:117db924cf7c 6578 #ifndef NO_AES
wolfSSL 15:117db924cf7c 6579 #ifdef WOLFSSL_AES_128
wolfSSL 15:117db924cf7c 6580 case AES128CBCb:
wolfSSL 15:117db924cf7c 6581 #endif
wolfSSL 15:117db924cf7c 6582 #ifdef WOLFSSL_AES_192
wolfSSL 15:117db924cf7c 6583 case AES192CBCb:
wolfSSL 15:117db924cf7c 6584 #endif
wolfSSL 15:117db924cf7c 6585 #ifdef WOLFSSL_AES_256
wolfSSL 15:117db924cf7c 6586 case AES256CBCb:
wolfSSL 15:117db924cf7c 6587 #endif
wolfSSL 15:117db924cf7c 6588 if (
wolfSSL 15:117db924cf7c 6589 #ifdef WOLFSSL_AES_128
wolfSSL 15:117db924cf7c 6590 (encryptOID == AES128CBCb && keySz != 16 ) ||
wolfSSL 15:117db924cf7c 6591 #endif
wolfSSL 15:117db924cf7c 6592 #ifdef WOLFSSL_AES_192
wolfSSL 15:117db924cf7c 6593 (encryptOID == AES192CBCb && keySz != 24 ) ||
wolfSSL 15:117db924cf7c 6594 #endif
wolfSSL 15:117db924cf7c 6595 #ifdef WOLFSSL_AES_256
wolfSSL 15:117db924cf7c 6596 (encryptOID == AES256CBCb && keySz != 32 ) ||
wolfSSL 15:117db924cf7c 6597 #endif
wolfSSL 15:117db924cf7c 6598 (ivSz != AES_BLOCK_SIZE) )
wolfSSL 15:117db924cf7c 6599 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 6600 ret = wc_AesInit(&aes, NULL, INVALID_DEVID);
wolfSSL 16:8e0d178b1d1e 6601 if (ret == 0) {
wolfSSL 16:8e0d178b1d1e 6602 ret = wc_AesSetKey(&aes, key, keySz, iv, AES_DECRYPTION);
wolfSSL 16:8e0d178b1d1e 6603 if (ret == 0)
wolfSSL 16:8e0d178b1d1e 6604 ret = wc_AesCbcDecrypt(&aes, out, in, inSz);
wolfSSL 16:8e0d178b1d1e 6605 wc_AesFree(&aes);
wolfSSL 16:8e0d178b1d1e 6606 }
wolfSSL 15:117db924cf7c 6607 break;
wolfSSL 16:8e0d178b1d1e 6608 #ifdef HAVE_AESGCM
wolfSSL 16:8e0d178b1d1e 6609 #ifdef WOLFSSL_AES_128
wolfSSL 16:8e0d178b1d1e 6610 case AES128GCMb:
wolfSSL 16:8e0d178b1d1e 6611 #endif
wolfSSL 16:8e0d178b1d1e 6612 #ifdef WOLFSSL_AES_192
wolfSSL 16:8e0d178b1d1e 6613 case AES192GCMb:
wolfSSL 16:8e0d178b1d1e 6614 #endif
wolfSSL 16:8e0d178b1d1e 6615 #ifdef WOLFSSL_AES_256
wolfSSL 16:8e0d178b1d1e 6616 case AES256GCMb:
wolfSSL 16:8e0d178b1d1e 6617 #endif
wolfSSL 16:8e0d178b1d1e 6618 #if defined(WOLFSSL_AES_128) || defined(WOLFSSL_AES_192) || \
wolfSSL 16:8e0d178b1d1e 6619 defined(WOLFSSL_AES_256)
wolfSSL 16:8e0d178b1d1e 6620 if (authTag == NULL)
wolfSSL 16:8e0d178b1d1e 6621 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 6622
wolfSSL 16:8e0d178b1d1e 6623 ret = wc_AesInit(&aes, NULL, INVALID_DEVID);
wolfSSL 16:8e0d178b1d1e 6624 if (ret == 0) {
wolfSSL 16:8e0d178b1d1e 6625 ret = wc_AesGcmSetKey(&aes, key, keySz);
wolfSSL 16:8e0d178b1d1e 6626 if (ret == 0)
wolfSSL 16:8e0d178b1d1e 6627 ret = wc_AesGcmDecrypt(&aes, out, in, inSz, iv, ivSz,
wolfSSL 16:8e0d178b1d1e 6628 authTag, authTagSz, aad, aadSz);
wolfSSL 16:8e0d178b1d1e 6629 wc_AesFree(&aes);
wolfSSL 16:8e0d178b1d1e 6630 }
wolfSSL 16:8e0d178b1d1e 6631 break;
wolfSSL 16:8e0d178b1d1e 6632 #endif
wolfSSL 16:8e0d178b1d1e 6633 #endif /* HAVE_AESGCM */
wolfSSL 16:8e0d178b1d1e 6634 #ifdef HAVE_AESCCM
wolfSSL 16:8e0d178b1d1e 6635 #ifdef WOLFSSL_AES_128
wolfSSL 16:8e0d178b1d1e 6636 case AES128CCMb:
wolfSSL 16:8e0d178b1d1e 6637 #endif
wolfSSL 16:8e0d178b1d1e 6638 #ifdef WOLFSSL_AES_192
wolfSSL 16:8e0d178b1d1e 6639 case AES192CCMb:
wolfSSL 16:8e0d178b1d1e 6640 #endif
wolfSSL 16:8e0d178b1d1e 6641 #ifdef WOLFSSL_AES_256
wolfSSL 16:8e0d178b1d1e 6642 case AES256CCMb:
wolfSSL 16:8e0d178b1d1e 6643 #endif
wolfSSL 16:8e0d178b1d1e 6644 #if defined(WOLFSSL_AES_128) || defined(WOLFSSL_AES_192) || \
wolfSSL 16:8e0d178b1d1e 6645 defined(WOLFSSL_AES_256)
wolfSSL 16:8e0d178b1d1e 6646 if (authTag == NULL)
wolfSSL 16:8e0d178b1d1e 6647 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 6648
wolfSSL 16:8e0d178b1d1e 6649 ret = wc_AesInit(&aes, NULL, INVALID_DEVID);
wolfSSL 16:8e0d178b1d1e 6650 if (ret == 0) {
wolfSSL 16:8e0d178b1d1e 6651 ret = wc_AesCcmSetKey(&aes, key, keySz);
wolfSSL 16:8e0d178b1d1e 6652 if (ret == 0)
wolfSSL 16:8e0d178b1d1e 6653 ret = wc_AesCcmDecrypt(&aes, out, in, inSz, iv, ivSz,
wolfSSL 16:8e0d178b1d1e 6654 authTag, authTagSz, aad, aadSz);
wolfSSL 16:8e0d178b1d1e 6655 wc_AesFree(&aes);
wolfSSL 16:8e0d178b1d1e 6656 }
wolfSSL 16:8e0d178b1d1e 6657 break;
wolfSSL 16:8e0d178b1d1e 6658 #endif
wolfSSL 16:8e0d178b1d1e 6659 #endif /* HAVE_AESCCM */
wolfSSL 16:8e0d178b1d1e 6660 #endif /* NO_AES */
wolfSSL 15:117db924cf7c 6661 #ifndef NO_DES3
wolfSSL 15:117db924cf7c 6662 case DESb:
wolfSSL 15:117db924cf7c 6663 if (keySz != DES_KEYLEN || ivSz != DES_BLOCK_SIZE)
wolfSSL 15:117db924cf7c 6664 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 6665
wolfSSL 15:117db924cf7c 6666 ret = wc_Des_SetKey(&des, key, iv, DES_DECRYPTION);
wolfSSL 15:117db924cf7c 6667 if (ret == 0)
wolfSSL 15:117db924cf7c 6668 ret = wc_Des_CbcDecrypt(&des, out, in, inSz);
wolfSSL 15:117db924cf7c 6669
wolfSSL 15:117db924cf7c 6670 break;
wolfSSL 15:117db924cf7c 6671 case DES3b:
wolfSSL 15:117db924cf7c 6672 if (keySz != DES3_KEYLEN || ivSz != DES_BLOCK_SIZE)
wolfSSL 15:117db924cf7c 6673 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 6674
wolfSSL 16:8e0d178b1d1e 6675 ret = wc_Des3Init(&des3, NULL, INVALID_DEVID);
wolfSSL 16:8e0d178b1d1e 6676 if (ret == 0) {
wolfSSL 16:8e0d178b1d1e 6677 ret = wc_Des3_SetKey(&des3, key, iv, DES_DECRYPTION);
wolfSSL 16:8e0d178b1d1e 6678 if (ret == 0)
wolfSSL 16:8e0d178b1d1e 6679 ret = wc_Des3_CbcDecrypt(&des3, out, in, inSz);
wolfSSL 16:8e0d178b1d1e 6680 wc_Des3Free(&des3);
wolfSSL 16:8e0d178b1d1e 6681 }
wolfSSL 15:117db924cf7c 6682
wolfSSL 15:117db924cf7c 6683 break;
wolfSSL 15:117db924cf7c 6684 #endif
wolfSSL 15:117db924cf7c 6685 default:
wolfSSL 15:117db924cf7c 6686 WOLFSSL_MSG("Unsupported content cipher type");
wolfSSL 15:117db924cf7c 6687 return ALGO_ID_E;
wolfSSL 15:117db924cf7c 6688 };
wolfSSL 15:117db924cf7c 6689
wolfSSL 16:8e0d178b1d1e 6690 #if defined(NO_AES) || (!defined(HAVE_AESGCM) && !defined(HAVE_AESCCM))
wolfSSL 16:8e0d178b1d1e 6691 (void)authTag;
wolfSSL 16:8e0d178b1d1e 6692 (void)authTagSz;
wolfSSL 16:8e0d178b1d1e 6693 (void)aad;
wolfSSL 16:8e0d178b1d1e 6694 (void)aadSz;
wolfSSL 16:8e0d178b1d1e 6695 #endif
wolfSSL 16:8e0d178b1d1e 6696
wolfSSL 15:117db924cf7c 6697 return ret;
wolfSSL 15:117db924cf7c 6698 }
wolfSSL 15:117db924cf7c 6699
wolfSSL 15:117db924cf7c 6700
wolfSSL 16:8e0d178b1d1e 6701 /* Generate random block, place in out, return 0 on success negative on error.
wolfSSL 16:8e0d178b1d1e 6702 * Used for generation of IV, nonce, etc */
wolfSSL 16:8e0d178b1d1e 6703 static int wc_PKCS7_GenerateBlock(PKCS7* pkcs7, WC_RNG* rng, byte* out,
wolfSSL 16:8e0d178b1d1e 6704 word32 outSz)
wolfSSL 15:117db924cf7c 6705 {
wolfSSL 15:117db924cf7c 6706 int ret;
wolfSSL 15:117db924cf7c 6707 WC_RNG* rnd = NULL;
wolfSSL 15:117db924cf7c 6708
wolfSSL 16:8e0d178b1d1e 6709 if (out == NULL || outSz == 0)
wolfSSL 15:117db924cf7c 6710 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 6711
wolfSSL 15:117db924cf7c 6712 /* input RNG is optional, init local one if input rng is NULL */
wolfSSL 15:117db924cf7c 6713 if (rng == NULL) {
wolfSSL 15:117db924cf7c 6714 rnd = (WC_RNG*)XMALLOC(sizeof(WC_RNG), pkcs7->heap, DYNAMIC_TYPE_RNG);
wolfSSL 15:117db924cf7c 6715 if (rnd == NULL)
wolfSSL 15:117db924cf7c 6716 return MEMORY_E;
wolfSSL 15:117db924cf7c 6717
wolfSSL 15:117db924cf7c 6718 ret = wc_InitRng_ex(rnd, pkcs7->heap, pkcs7->devId);
wolfSSL 15:117db924cf7c 6719 if (ret != 0) {
wolfSSL 15:117db924cf7c 6720 XFREE(rnd, pkcs7->heap, DYNAMIC_TYPE_RNG);
wolfSSL 15:117db924cf7c 6721 return ret;
wolfSSL 15:117db924cf7c 6722 }
wolfSSL 15:117db924cf7c 6723
wolfSSL 15:117db924cf7c 6724 } else {
wolfSSL 15:117db924cf7c 6725 rnd = rng;
wolfSSL 15:117db924cf7c 6726 }
wolfSSL 15:117db924cf7c 6727
wolfSSL 16:8e0d178b1d1e 6728 ret = wc_RNG_GenerateBlock(rnd, out, outSz);
wolfSSL 15:117db924cf7c 6729
wolfSSL 15:117db924cf7c 6730 if (rng == NULL) {
wolfSSL 15:117db924cf7c 6731 wc_FreeRng(rnd);
wolfSSL 15:117db924cf7c 6732 XFREE(rnd, pkcs7->heap, DYNAMIC_TYPE_RNG);
wolfSSL 15:117db924cf7c 6733 }
wolfSSL 15:117db924cf7c 6734
wolfSSL 15:117db924cf7c 6735 return ret;
wolfSSL 15:117db924cf7c 6736 }
wolfSSL 15:117db924cf7c 6737
wolfSSL 15:117db924cf7c 6738
wolfSSL 16:8e0d178b1d1e 6739 /* Set default SignerIdentifier type to be used. Is either
wolfSSL 16:8e0d178b1d1e 6740 * IssuerAndSerialNumber or SubjectKeyIdentifier. Encoding defaults to using
wolfSSL 16:8e0d178b1d1e 6741 * IssuerAndSerialNumber unless set with this function or explicitly
wolfSSL 16:8e0d178b1d1e 6742 * overridden via options when adding RecipientInfo type.
wolfSSL 16:8e0d178b1d1e 6743 *
wolfSSL 16:8e0d178b1d1e 6744 * Using the type DEGENERATE_SID skips over signer information. In degenerate
wolfSSL 16:8e0d178b1d1e 6745 * cases there are no signers.
wolfSSL 16:8e0d178b1d1e 6746 *
wolfSSL 16:8e0d178b1d1e 6747 * pkcs7 - pointer to initialized PKCS7 structure
wolfSSL 16:8e0d178b1d1e 6748 * type - either CMS_ISSUER_AND_SERIAL_NUMBER, CMS_SKID or DEGENERATE_SID
wolfSSL 16:8e0d178b1d1e 6749 *
wolfSSL 16:8e0d178b1d1e 6750 * return 0 on success, negative upon error */
wolfSSL 16:8e0d178b1d1e 6751 int wc_PKCS7_SetSignerIdentifierType(PKCS7* pkcs7, int type)
wolfSSL 16:8e0d178b1d1e 6752 {
wolfSSL 16:8e0d178b1d1e 6753 if (pkcs7 == NULL)
wolfSSL 16:8e0d178b1d1e 6754 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 6755
wolfSSL 16:8e0d178b1d1e 6756 if (type != CMS_ISSUER_AND_SERIAL_NUMBER &&
wolfSSL 16:8e0d178b1d1e 6757 type != CMS_SKID &&
wolfSSL 16:8e0d178b1d1e 6758 type != DEGENERATE_SID) {
wolfSSL 16:8e0d178b1d1e 6759 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 6760 }
wolfSSL 16:8e0d178b1d1e 6761
wolfSSL 16:8e0d178b1d1e 6762 pkcs7->sidType = type;
wolfSSL 16:8e0d178b1d1e 6763
wolfSSL 16:8e0d178b1d1e 6764 return 0;
wolfSSL 16:8e0d178b1d1e 6765 }
wolfSSL 16:8e0d178b1d1e 6766
wolfSSL 16:8e0d178b1d1e 6767
wolfSSL 16:8e0d178b1d1e 6768 /* Set custom contentType, currently supported with SignedData type
wolfSSL 16:8e0d178b1d1e 6769 *
wolfSSL 16:8e0d178b1d1e 6770 * pkcs7 - pointer to initialized PKCS7 structure
wolfSSL 16:8e0d178b1d1e 6771 * contentType - pointer to array with ASN.1 encoded OID value
wolfSSL 16:8e0d178b1d1e 6772 * sz - length of contentType array, octets
wolfSSL 16:8e0d178b1d1e 6773 *
wolfSSL 16:8e0d178b1d1e 6774 * return 0 on success, negative upon error */
wolfSSL 16:8e0d178b1d1e 6775 int wc_PKCS7_SetContentType(PKCS7* pkcs7, byte* contentType, word32 sz)
wolfSSL 16:8e0d178b1d1e 6776 {
wolfSSL 16:8e0d178b1d1e 6777 if (pkcs7 == NULL || contentType == NULL || sz == 0)
wolfSSL 16:8e0d178b1d1e 6778 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 6779
wolfSSL 16:8e0d178b1d1e 6780 if (sz > MAX_OID_SZ) {
wolfSSL 16:8e0d178b1d1e 6781 WOLFSSL_MSG("input array too large, bounded by MAX_OID_SZ");
wolfSSL 16:8e0d178b1d1e 6782 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 6783 }
wolfSSL 16:8e0d178b1d1e 6784
wolfSSL 16:8e0d178b1d1e 6785 XMEMCPY(pkcs7->contentType, contentType, sz);
wolfSSL 16:8e0d178b1d1e 6786 pkcs7->contentTypeSz = sz;
wolfSSL 16:8e0d178b1d1e 6787
wolfSSL 16:8e0d178b1d1e 6788 return 0;
wolfSSL 16:8e0d178b1d1e 6789 }
wolfSSL 16:8e0d178b1d1e 6790
wolfSSL 16:8e0d178b1d1e 6791
wolfSSL 15:117db924cf7c 6792 /* return size of padded data, padded to blockSz chunks, or negative on error */
wolfSSL 15:117db924cf7c 6793 int wc_PKCS7_GetPadSize(word32 inputSz, word32 blockSz)
wolfSSL 15:117db924cf7c 6794 {
wolfSSL 15:117db924cf7c 6795 int padSz;
wolfSSL 15:117db924cf7c 6796
wolfSSL 15:117db924cf7c 6797 if (blockSz == 0)
wolfSSL 15:117db924cf7c 6798 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 6799
wolfSSL 15:117db924cf7c 6800 padSz = blockSz - (inputSz % blockSz);
wolfSSL 15:117db924cf7c 6801
wolfSSL 15:117db924cf7c 6802 return padSz;
wolfSSL 15:117db924cf7c 6803 }
wolfSSL 15:117db924cf7c 6804
wolfSSL 15:117db924cf7c 6805
wolfSSL 15:117db924cf7c 6806 /* pad input data to blockSz chunk, place in outSz. out must be big enough
wolfSSL 15:117db924cf7c 6807 * for input + pad bytes. See wc_PKCS7_GetPadSize() helper. */
wolfSSL 15:117db924cf7c 6808 int wc_PKCS7_PadData(byte* in, word32 inSz, byte* out, word32 outSz,
wolfSSL 15:117db924cf7c 6809 word32 blockSz)
wolfSSL 15:117db924cf7c 6810 {
wolfSSL 15:117db924cf7c 6811 int i, padSz;
wolfSSL 15:117db924cf7c 6812
wolfSSL 15:117db924cf7c 6813 if (in == NULL || inSz == 0 ||
wolfSSL 15:117db924cf7c 6814 out == NULL || outSz == 0)
wolfSSL 15:117db924cf7c 6815 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 6816
wolfSSL 15:117db924cf7c 6817 padSz = wc_PKCS7_GetPadSize(inSz, blockSz);
wolfSSL 15:117db924cf7c 6818
wolfSSL 15:117db924cf7c 6819 if (outSz < (inSz + padSz))
wolfSSL 15:117db924cf7c 6820 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 6821
wolfSSL 15:117db924cf7c 6822 XMEMCPY(out, in, inSz);
wolfSSL 15:117db924cf7c 6823
wolfSSL 15:117db924cf7c 6824 for (i = 0; i < padSz; i++) {
wolfSSL 15:117db924cf7c 6825 out[inSz + i] = (byte)padSz;
wolfSSL 15:117db924cf7c 6826 }
wolfSSL 15:117db924cf7c 6827
wolfSSL 15:117db924cf7c 6828 return inSz + padSz;
wolfSSL 15:117db924cf7c 6829 }
wolfSSL 15:117db924cf7c 6830
wolfSSL 15:117db924cf7c 6831
wolfSSL 16:8e0d178b1d1e 6832 /* Encode and add CMS EnvelopedData ORI (OtherRecipientInfo) RecipientInfo
wolfSSL 16:8e0d178b1d1e 6833 * to CMS/PKCS#7 EnvelopedData structure.
wolfSSL 16:8e0d178b1d1e 6834 *
wolfSSL 16:8e0d178b1d1e 6835 * Return 0 on success, negative upon error */
wolfSSL 16:8e0d178b1d1e 6836 int wc_PKCS7_AddRecipient_ORI(PKCS7* pkcs7, CallbackOriEncrypt oriEncryptCb,
wolfSSL 16:8e0d178b1d1e 6837 int options)
wolfSSL 16:8e0d178b1d1e 6838 {
wolfSSL 16:8e0d178b1d1e 6839 int oriTypeLenSz, blockKeySz, ret;
wolfSSL 16:8e0d178b1d1e 6840 word32 idx, recipSeqSz;
wolfSSL 16:8e0d178b1d1e 6841
wolfSSL 16:8e0d178b1d1e 6842 Pkcs7EncodedRecip* recip = NULL;
wolfSSL 16:8e0d178b1d1e 6843 Pkcs7EncodedRecip* lastRecip = NULL;
wolfSSL 16:8e0d178b1d1e 6844
wolfSSL 16:8e0d178b1d1e 6845 byte recipSeq[MAX_SEQ_SZ];
wolfSSL 16:8e0d178b1d1e 6846 byte oriTypeLen[MAX_LENGTH_SZ];
wolfSSL 16:8e0d178b1d1e 6847
wolfSSL 16:8e0d178b1d1e 6848 byte oriType[MAX_ORI_TYPE_SZ];
wolfSSL 16:8e0d178b1d1e 6849 byte oriValue[MAX_ORI_VALUE_SZ];
wolfSSL 16:8e0d178b1d1e 6850 word32 oriTypeSz = MAX_ORI_TYPE_SZ;
wolfSSL 16:8e0d178b1d1e 6851 word32 oriValueSz = MAX_ORI_VALUE_SZ;
wolfSSL 16:8e0d178b1d1e 6852
wolfSSL 16:8e0d178b1d1e 6853 if (pkcs7 == NULL || oriEncryptCb == NULL) {
wolfSSL 16:8e0d178b1d1e 6854 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 6855 }
wolfSSL 16:8e0d178b1d1e 6856
wolfSSL 16:8e0d178b1d1e 6857 /* allocate memory for RecipientInfo, KEK, encrypted key */
wolfSSL 16:8e0d178b1d1e 6858 recip = (Pkcs7EncodedRecip*)XMALLOC(sizeof(Pkcs7EncodedRecip),
wolfSSL 16:8e0d178b1d1e 6859 pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 6860 if (recip == NULL)
wolfSSL 16:8e0d178b1d1e 6861 return MEMORY_E;
wolfSSL 16:8e0d178b1d1e 6862 XMEMSET(recip, 0, sizeof(Pkcs7EncodedRecip));
wolfSSL 16:8e0d178b1d1e 6863
wolfSSL 16:8e0d178b1d1e 6864 /* get key size for content-encryption key based on algorithm */
wolfSSL 16:8e0d178b1d1e 6865 blockKeySz = wc_PKCS7_GetOIDKeySize(pkcs7->encryptOID);
wolfSSL 16:8e0d178b1d1e 6866 if (blockKeySz < 0) {
wolfSSL 16:8e0d178b1d1e 6867 XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 6868 return blockKeySz;
wolfSSL 16:8e0d178b1d1e 6869 }
wolfSSL 16:8e0d178b1d1e 6870
wolfSSL 16:8e0d178b1d1e 6871 /* generate random content encryption key, if needed */
wolfSSL 16:8e0d178b1d1e 6872 ret = PKCS7_GenerateContentEncryptionKey(pkcs7, blockKeySz);
wolfSSL 16:8e0d178b1d1e 6873 if (ret < 0) {
wolfSSL 16:8e0d178b1d1e 6874 XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 6875 return ret;
wolfSSL 16:8e0d178b1d1e 6876 }
wolfSSL 16:8e0d178b1d1e 6877
wolfSSL 16:8e0d178b1d1e 6878 /* call user callback to encrypt CEK and get oriType and oriValue
wolfSSL 16:8e0d178b1d1e 6879 values back */
wolfSSL 16:8e0d178b1d1e 6880 ret = oriEncryptCb(pkcs7, pkcs7->cek, pkcs7->cekSz, oriType, &oriTypeSz,
wolfSSL 16:8e0d178b1d1e 6881 oriValue, &oriValueSz, pkcs7->oriEncryptCtx);
wolfSSL 16:8e0d178b1d1e 6882 if (ret != 0) {
wolfSSL 16:8e0d178b1d1e 6883 XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 6884 return ret;
wolfSSL 16:8e0d178b1d1e 6885 }
wolfSSL 16:8e0d178b1d1e 6886
wolfSSL 16:8e0d178b1d1e 6887 oriTypeLenSz = SetLength(oriTypeSz, oriTypeLen);
wolfSSL 16:8e0d178b1d1e 6888
wolfSSL 16:8e0d178b1d1e 6889 recipSeqSz = SetImplicit(ASN_SEQUENCE, 4, 1 + oriTypeLenSz + oriTypeSz +
wolfSSL 16:8e0d178b1d1e 6890 oriValueSz, recipSeq);
wolfSSL 16:8e0d178b1d1e 6891
wolfSSL 16:8e0d178b1d1e 6892 idx = 0;
wolfSSL 16:8e0d178b1d1e 6893 XMEMCPY(recip->recip + idx, recipSeq, recipSeqSz);
wolfSSL 16:8e0d178b1d1e 6894 idx += recipSeqSz;
wolfSSL 16:8e0d178b1d1e 6895 /* oriType */
wolfSSL 16:8e0d178b1d1e 6896 recip->recip[idx] = ASN_OBJECT_ID;
wolfSSL 16:8e0d178b1d1e 6897 idx += 1;
wolfSSL 16:8e0d178b1d1e 6898 XMEMCPY(recip->recip + idx, oriTypeLen, oriTypeLenSz);
wolfSSL 16:8e0d178b1d1e 6899 idx += oriTypeLenSz;
wolfSSL 16:8e0d178b1d1e 6900 XMEMCPY(recip->recip + idx, oriType, oriTypeSz);
wolfSSL 16:8e0d178b1d1e 6901 idx += oriTypeSz;
wolfSSL 16:8e0d178b1d1e 6902 /* oriValue, input MUST already be ASN.1 encoded */
wolfSSL 16:8e0d178b1d1e 6903 XMEMCPY(recip->recip + idx, oriValue, oriValueSz);
wolfSSL 16:8e0d178b1d1e 6904 idx += oriValueSz;
wolfSSL 16:8e0d178b1d1e 6905
wolfSSL 16:8e0d178b1d1e 6906 /* store recipient size */
wolfSSL 16:8e0d178b1d1e 6907 recip->recipSz = idx;
wolfSSL 16:8e0d178b1d1e 6908 recip->recipType = PKCS7_ORI;
wolfSSL 16:8e0d178b1d1e 6909 recip->recipVersion = 4;
wolfSSL 16:8e0d178b1d1e 6910
wolfSSL 16:8e0d178b1d1e 6911 /* add recipient to recip list */
wolfSSL 16:8e0d178b1d1e 6912 if (pkcs7->recipList == NULL) {
wolfSSL 16:8e0d178b1d1e 6913 pkcs7->recipList = recip;
wolfSSL 16:8e0d178b1d1e 6914 } else {
wolfSSL 16:8e0d178b1d1e 6915 lastRecip = pkcs7->recipList;
wolfSSL 16:8e0d178b1d1e 6916 while (lastRecip->next != NULL) {
wolfSSL 16:8e0d178b1d1e 6917 lastRecip = lastRecip->next;
wolfSSL 16:8e0d178b1d1e 6918 }
wolfSSL 16:8e0d178b1d1e 6919 lastRecip->next = recip;
wolfSSL 16:8e0d178b1d1e 6920 }
wolfSSL 16:8e0d178b1d1e 6921
wolfSSL 16:8e0d178b1d1e 6922 (void)options;
wolfSSL 16:8e0d178b1d1e 6923
wolfSSL 16:8e0d178b1d1e 6924 return idx;
wolfSSL 16:8e0d178b1d1e 6925 }
wolfSSL 16:8e0d178b1d1e 6926
wolfSSL 16:8e0d178b1d1e 6927 #if !defined(NO_PWDBASED) && !defined(NO_SHA)
wolfSSL 16:8e0d178b1d1e 6928
wolfSSL 16:8e0d178b1d1e 6929
wolfSSL 16:8e0d178b1d1e 6930 static int wc_PKCS7_GenerateKEK_PWRI(PKCS7* pkcs7, byte* passwd, word32 pLen,
wolfSSL 16:8e0d178b1d1e 6931 byte* salt, word32 saltSz, int kdfOID,
wolfSSL 16:8e0d178b1d1e 6932 int prfOID, int iterations, byte* out,
wolfSSL 16:8e0d178b1d1e 6933 word32 outSz)
wolfSSL 16:8e0d178b1d1e 6934 {
wolfSSL 16:8e0d178b1d1e 6935 int ret;
wolfSSL 16:8e0d178b1d1e 6936
wolfSSL 16:8e0d178b1d1e 6937 if (pkcs7 == NULL || passwd == NULL || salt == NULL || out == NULL)
wolfSSL 16:8e0d178b1d1e 6938 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 6939
wolfSSL 16:8e0d178b1d1e 6940 switch (kdfOID) {
wolfSSL 16:8e0d178b1d1e 6941
wolfSSL 16:8e0d178b1d1e 6942 case PBKDF2_OID:
wolfSSL 16:8e0d178b1d1e 6943
wolfSSL 16:8e0d178b1d1e 6944 ret = wc_PBKDF2(out, passwd, pLen, salt, saltSz, iterations,
wolfSSL 16:8e0d178b1d1e 6945 outSz, prfOID);
wolfSSL 16:8e0d178b1d1e 6946 if (ret != 0) {
wolfSSL 16:8e0d178b1d1e 6947 return ret;
wolfSSL 16:8e0d178b1d1e 6948 }
wolfSSL 16:8e0d178b1d1e 6949
wolfSSL 16:8e0d178b1d1e 6950 break;
wolfSSL 16:8e0d178b1d1e 6951
wolfSSL 16:8e0d178b1d1e 6952 default:
wolfSSL 16:8e0d178b1d1e 6953 WOLFSSL_MSG("Unsupported KDF OID");
wolfSSL 16:8e0d178b1d1e 6954 return PKCS7_OID_E;
wolfSSL 16:8e0d178b1d1e 6955 }
wolfSSL 16:8e0d178b1d1e 6956
wolfSSL 16:8e0d178b1d1e 6957 return 0;
wolfSSL 16:8e0d178b1d1e 6958 }
wolfSSL 16:8e0d178b1d1e 6959
wolfSSL 16:8e0d178b1d1e 6960
wolfSSL 16:8e0d178b1d1e 6961 /* RFC3211 (Section 2.3.1) key wrap algorithm (id-alg-PWRI-KEK).
wolfSSL 16:8e0d178b1d1e 6962 *
wolfSSL 16:8e0d178b1d1e 6963 * Returns output size on success, negative upon error */
wolfSSL 16:8e0d178b1d1e 6964 static int wc_PKCS7_PwriKek_KeyWrap(PKCS7* pkcs7, const byte* kek, word32 kekSz,
wolfSSL 16:8e0d178b1d1e 6965 const byte* cek, word32 cekSz,
wolfSSL 16:8e0d178b1d1e 6966 byte* out, word32 *outSz,
wolfSSL 16:8e0d178b1d1e 6967 const byte* iv, word32 ivSz, int algID)
wolfSSL 16:8e0d178b1d1e 6968 {
wolfSSL 16:8e0d178b1d1e 6969 WC_RNG rng;
wolfSSL 16:8e0d178b1d1e 6970 int blockSz, outLen, ret;
wolfSSL 16:8e0d178b1d1e 6971 word32 padSz;
wolfSSL 16:8e0d178b1d1e 6972 byte* lastBlock;
wolfSSL 16:8e0d178b1d1e 6973
wolfSSL 16:8e0d178b1d1e 6974 if (kek == NULL || cek == NULL || iv == NULL || outSz == NULL)
wolfSSL 16:8e0d178b1d1e 6975 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 6976
wolfSSL 16:8e0d178b1d1e 6977 /* get encryption algorithm block size */
wolfSSL 16:8e0d178b1d1e 6978 blockSz = wc_PKCS7_GetOIDBlockSize(algID);
wolfSSL 16:8e0d178b1d1e 6979 if (blockSz < 0)
wolfSSL 16:8e0d178b1d1e 6980 return blockSz;
wolfSSL 16:8e0d178b1d1e 6981
wolfSSL 16:8e0d178b1d1e 6982 /* get pad bytes needed to block boundary */
wolfSSL 16:8e0d178b1d1e 6983 padSz = blockSz - ((4 + cekSz) % blockSz);
wolfSSL 16:8e0d178b1d1e 6984 outLen = 4 + cekSz + padSz;
wolfSSL 16:8e0d178b1d1e 6985
wolfSSL 16:8e0d178b1d1e 6986 /* must be at least two blocks long */
wolfSSL 16:8e0d178b1d1e 6987 if (outLen < 2 * blockSz)
wolfSSL 16:8e0d178b1d1e 6988 padSz += blockSz;
wolfSSL 16:8e0d178b1d1e 6989
wolfSSL 16:8e0d178b1d1e 6990 /* if user set out to NULL, give back required length */
wolfSSL 16:8e0d178b1d1e 6991 if (out == NULL) {
wolfSSL 16:8e0d178b1d1e 6992 *outSz = outLen;
wolfSSL 16:8e0d178b1d1e 6993 return LENGTH_ONLY_E;
wolfSSL 16:8e0d178b1d1e 6994 }
wolfSSL 16:8e0d178b1d1e 6995
wolfSSL 16:8e0d178b1d1e 6996 /* verify output buffer is large enough */
wolfSSL 16:8e0d178b1d1e 6997 if (*outSz < (word32)outLen)
wolfSSL 16:8e0d178b1d1e 6998 return BUFFER_E;
wolfSSL 16:8e0d178b1d1e 6999
wolfSSL 16:8e0d178b1d1e 7000 out[0] = cekSz;
wolfSSL 16:8e0d178b1d1e 7001 out[1] = ~cek[0];
wolfSSL 16:8e0d178b1d1e 7002 out[2] = ~cek[1];
wolfSSL 16:8e0d178b1d1e 7003 out[3] = ~cek[2];
wolfSSL 16:8e0d178b1d1e 7004 XMEMCPY(out + 4, cek, cekSz);
wolfSSL 16:8e0d178b1d1e 7005
wolfSSL 16:8e0d178b1d1e 7006 /* random padding of size padSz */
wolfSSL 16:8e0d178b1d1e 7007 ret = wc_InitRng_ex(&rng, pkcs7->heap, pkcs7->devId);
wolfSSL 16:8e0d178b1d1e 7008 if (ret != 0)
wolfSSL 16:8e0d178b1d1e 7009 return ret;
wolfSSL 16:8e0d178b1d1e 7010
wolfSSL 16:8e0d178b1d1e 7011 ret = wc_RNG_GenerateBlock(&rng, out + 4 + cekSz, padSz);
wolfSSL 16:8e0d178b1d1e 7012
wolfSSL 16:8e0d178b1d1e 7013 if (ret == 0) {
wolfSSL 16:8e0d178b1d1e 7014 /* encrypt, normal */
wolfSSL 16:8e0d178b1d1e 7015 ret = wc_PKCS7_EncryptContent(algID, (byte*)kek, kekSz, (byte*)iv,
wolfSSL 16:8e0d178b1d1e 7016 ivSz, NULL, 0, NULL, 0, out, outLen, out);
wolfSSL 16:8e0d178b1d1e 7017 }
wolfSSL 16:8e0d178b1d1e 7018
wolfSSL 16:8e0d178b1d1e 7019 if (ret == 0) {
wolfSSL 16:8e0d178b1d1e 7020 /* encrypt again, using last ciphertext block as IV */
wolfSSL 16:8e0d178b1d1e 7021 lastBlock = out + (((outLen / blockSz) - 1) * blockSz);
wolfSSL 16:8e0d178b1d1e 7022 ret = wc_PKCS7_EncryptContent(algID, (byte*)kek, kekSz, lastBlock,
wolfSSL 16:8e0d178b1d1e 7023 blockSz, NULL, 0, NULL, 0, out,
wolfSSL 16:8e0d178b1d1e 7024 outLen, out);
wolfSSL 16:8e0d178b1d1e 7025 }
wolfSSL 16:8e0d178b1d1e 7026
wolfSSL 16:8e0d178b1d1e 7027 if (ret == 0) {
wolfSSL 16:8e0d178b1d1e 7028 *outSz = outLen;
wolfSSL 16:8e0d178b1d1e 7029 } else {
wolfSSL 16:8e0d178b1d1e 7030 outLen = ret;
wolfSSL 16:8e0d178b1d1e 7031 }
wolfSSL 16:8e0d178b1d1e 7032
wolfSSL 16:8e0d178b1d1e 7033 wc_FreeRng(&rng);
wolfSSL 16:8e0d178b1d1e 7034
wolfSSL 16:8e0d178b1d1e 7035 return outLen;
wolfSSL 16:8e0d178b1d1e 7036 }
wolfSSL 16:8e0d178b1d1e 7037
wolfSSL 16:8e0d178b1d1e 7038
wolfSSL 16:8e0d178b1d1e 7039 /* RFC3211 (Section 2.3.2) key unwrap algorithm (id-alg-PWRI-KEK).
wolfSSL 16:8e0d178b1d1e 7040 *
wolfSSL 16:8e0d178b1d1e 7041 * Returns cek size on success, negative upon error */
wolfSSL 16:8e0d178b1d1e 7042 static int wc_PKCS7_PwriKek_KeyUnWrap(PKCS7* pkcs7, const byte* kek,
wolfSSL 16:8e0d178b1d1e 7043 word32 kekSz, const byte* in, word32 inSz,
wolfSSL 16:8e0d178b1d1e 7044 byte* out, word32 outSz, const byte* iv,
wolfSSL 16:8e0d178b1d1e 7045 word32 ivSz, int algID)
wolfSSL 16:8e0d178b1d1e 7046 {
wolfSSL 16:8e0d178b1d1e 7047 int blockSz, cekLen, ret;
wolfSSL 16:8e0d178b1d1e 7048 byte* tmpIv = NULL;
wolfSSL 16:8e0d178b1d1e 7049 byte* lastBlock = NULL;
wolfSSL 16:8e0d178b1d1e 7050 byte* outTmp = NULL;
wolfSSL 16:8e0d178b1d1e 7051
wolfSSL 16:8e0d178b1d1e 7052 if (pkcs7 == NULL || kek == NULL || in == NULL ||
wolfSSL 16:8e0d178b1d1e 7053 out == NULL || iv == NULL) {
wolfSSL 16:8e0d178b1d1e 7054 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 7055 }
wolfSSL 16:8e0d178b1d1e 7056
wolfSSL 16:8e0d178b1d1e 7057 outTmp = (byte*)XMALLOC(inSz, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 7058 if (outTmp == NULL)
wolfSSL 16:8e0d178b1d1e 7059 return MEMORY_E;
wolfSSL 16:8e0d178b1d1e 7060
wolfSSL 16:8e0d178b1d1e 7061 /* get encryption algorithm block size */
wolfSSL 16:8e0d178b1d1e 7062 blockSz = wc_PKCS7_GetOIDBlockSize(algID);
wolfSSL 16:8e0d178b1d1e 7063 if (blockSz < 0) {
wolfSSL 16:8e0d178b1d1e 7064 XFREE(outTmp, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 7065 return blockSz;
wolfSSL 16:8e0d178b1d1e 7066 }
wolfSSL 16:8e0d178b1d1e 7067
wolfSSL 16:8e0d178b1d1e 7068 /* input needs to be blockSz multiple and at least 2 * blockSz */
wolfSSL 16:8e0d178b1d1e 7069 if (((inSz % blockSz) != 0) || (inSz < (2 * (word32)blockSz))) {
wolfSSL 16:8e0d178b1d1e 7070 WOLFSSL_MSG("PWRI-KEK unwrap input must of block size and >= 2 "
wolfSSL 16:8e0d178b1d1e 7071 "times block size");
wolfSSL 16:8e0d178b1d1e 7072 XFREE(outTmp, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 7073 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 7074 }
wolfSSL 16:8e0d178b1d1e 7075
wolfSSL 16:8e0d178b1d1e 7076 /* use block out[n-1] as IV to decrypt block out[n] */
wolfSSL 16:8e0d178b1d1e 7077 lastBlock = (byte*)in + inSz - blockSz;
wolfSSL 16:8e0d178b1d1e 7078 tmpIv = lastBlock - blockSz;
wolfSSL 16:8e0d178b1d1e 7079
wolfSSL 16:8e0d178b1d1e 7080 /* decrypt last block */
wolfSSL 16:8e0d178b1d1e 7081 ret = wc_PKCS7_DecryptContent(pkcs7, algID, (byte*)kek, kekSz, tmpIv,
wolfSSL 16:8e0d178b1d1e 7082 blockSz, NULL, 0, NULL, 0, lastBlock, blockSz,
wolfSSL 16:8e0d178b1d1e 7083 outTmp + inSz - blockSz);
wolfSSL 16:8e0d178b1d1e 7084
wolfSSL 16:8e0d178b1d1e 7085 if (ret == 0) {
wolfSSL 16:8e0d178b1d1e 7086 /* using last decrypted block as IV, decrypt [0 ... n-1] blocks */
wolfSSL 16:8e0d178b1d1e 7087 lastBlock = outTmp + inSz - blockSz;
wolfSSL 16:8e0d178b1d1e 7088 ret = wc_PKCS7_DecryptContent(pkcs7, algID, (byte*)kek, kekSz,
wolfSSL 16:8e0d178b1d1e 7089 lastBlock, blockSz, NULL, 0, NULL, 0, (byte*)in, inSz - blockSz,
wolfSSL 16:8e0d178b1d1e 7090 outTmp);
wolfSSL 16:8e0d178b1d1e 7091 }
wolfSSL 16:8e0d178b1d1e 7092
wolfSSL 16:8e0d178b1d1e 7093 if (ret == 0) {
wolfSSL 16:8e0d178b1d1e 7094 /* decrypt using original kek and iv */
wolfSSL 16:8e0d178b1d1e 7095 ret = wc_PKCS7_DecryptContent(pkcs7, algID, (byte*)kek, kekSz,
wolfSSL 16:8e0d178b1d1e 7096 (byte*)iv, ivSz, NULL, 0, NULL, 0, outTmp, inSz, outTmp);
wolfSSL 16:8e0d178b1d1e 7097 }
wolfSSL 16:8e0d178b1d1e 7098
wolfSSL 16:8e0d178b1d1e 7099 if (ret != 0) {
wolfSSL 16:8e0d178b1d1e 7100 ForceZero(outTmp, inSz);
wolfSSL 16:8e0d178b1d1e 7101 XFREE(outTmp, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 7102 return ret;
wolfSSL 16:8e0d178b1d1e 7103 }
wolfSSL 16:8e0d178b1d1e 7104
wolfSSL 16:8e0d178b1d1e 7105 cekLen = outTmp[0];
wolfSSL 16:8e0d178b1d1e 7106
wolfSSL 16:8e0d178b1d1e 7107 /* verify length */
wolfSSL 16:8e0d178b1d1e 7108 if ((word32)cekLen > inSz) {
wolfSSL 16:8e0d178b1d1e 7109 ForceZero(outTmp, inSz);
wolfSSL 16:8e0d178b1d1e 7110 XFREE(outTmp, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 7111 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 7112 }
wolfSSL 16:8e0d178b1d1e 7113
wolfSSL 16:8e0d178b1d1e 7114 /* verify check bytes */
wolfSSL 16:8e0d178b1d1e 7115 if ((outTmp[1] ^ outTmp[4]) != 0xFF ||
wolfSSL 16:8e0d178b1d1e 7116 (outTmp[2] ^ outTmp[5]) != 0xFF ||
wolfSSL 16:8e0d178b1d1e 7117 (outTmp[3] ^ outTmp[6]) != 0xFF) {
wolfSSL 16:8e0d178b1d1e 7118 ForceZero(outTmp, inSz);
wolfSSL 16:8e0d178b1d1e 7119 XFREE(outTmp, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 7120 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 7121 }
wolfSSL 16:8e0d178b1d1e 7122
wolfSSL 16:8e0d178b1d1e 7123 if (outSz < (word32)cekLen) {
wolfSSL 16:8e0d178b1d1e 7124 ForceZero(outTmp, inSz);
wolfSSL 16:8e0d178b1d1e 7125 XFREE(outTmp, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 7126 return BUFFER_E;
wolfSSL 16:8e0d178b1d1e 7127 }
wolfSSL 16:8e0d178b1d1e 7128
wolfSSL 16:8e0d178b1d1e 7129 XMEMCPY(out, outTmp + 4, outTmp[0]);
wolfSSL 16:8e0d178b1d1e 7130 ForceZero(outTmp, inSz);
wolfSSL 16:8e0d178b1d1e 7131 XFREE(outTmp, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 7132
wolfSSL 16:8e0d178b1d1e 7133 return cekLen;
wolfSSL 16:8e0d178b1d1e 7134 }
wolfSSL 16:8e0d178b1d1e 7135
wolfSSL 16:8e0d178b1d1e 7136
wolfSSL 16:8e0d178b1d1e 7137 /* Encode and add CMS EnvelopedData PWRI (PasswordRecipientInfo) RecipientInfo
wolfSSL 16:8e0d178b1d1e 7138 * to CMS/PKCS#7 EnvelopedData structure.
wolfSSL 16:8e0d178b1d1e 7139 *
wolfSSL 16:8e0d178b1d1e 7140 * Return 0 on success, negative upon error */
wolfSSL 16:8e0d178b1d1e 7141 int wc_PKCS7_AddRecipient_PWRI(PKCS7* pkcs7, byte* passwd, word32 pLen,
wolfSSL 16:8e0d178b1d1e 7142 byte* salt, word32 saltSz, int kdfOID,
wolfSSL 16:8e0d178b1d1e 7143 int hashOID, int iterations, int kekEncryptOID,
wolfSSL 16:8e0d178b1d1e 7144 int options)
wolfSSL 16:8e0d178b1d1e 7145 {
wolfSSL 16:8e0d178b1d1e 7146 Pkcs7EncodedRecip* recip = NULL;
wolfSSL 16:8e0d178b1d1e 7147 Pkcs7EncodedRecip* lastRecip = NULL;
wolfSSL 16:8e0d178b1d1e 7148
wolfSSL 16:8e0d178b1d1e 7149 /* PasswordRecipientInfo */
wolfSSL 16:8e0d178b1d1e 7150 byte recipSeq[MAX_SEQ_SZ];
wolfSSL 16:8e0d178b1d1e 7151 byte ver[MAX_VERSION_SZ];
wolfSSL 16:8e0d178b1d1e 7152 word32 recipSeqSz, verSz;
wolfSSL 16:8e0d178b1d1e 7153
wolfSSL 16:8e0d178b1d1e 7154 /* KeyDerivationAlgorithmIdentifier */
wolfSSL 16:8e0d178b1d1e 7155 byte kdfAlgoIdSeq[MAX_SEQ_SZ];
wolfSSL 16:8e0d178b1d1e 7156 byte kdfAlgoId[MAX_OID_SZ];
wolfSSL 16:8e0d178b1d1e 7157 byte kdfParamsSeq[MAX_SEQ_SZ]; /* PBKDF2-params */
wolfSSL 16:8e0d178b1d1e 7158 byte kdfSaltOctetStr[MAX_OCTET_STR_SZ]; /* salt OCTET STRING */
wolfSSL 16:8e0d178b1d1e 7159 byte kdfIterations[MAX_VERSION_SZ];
wolfSSL 16:8e0d178b1d1e 7160 word32 kdfAlgoIdSeqSz, kdfAlgoIdSz;
wolfSSL 16:8e0d178b1d1e 7161 word32 kdfParamsSeqSz, kdfSaltOctetStrSz, kdfIterationsSz;
wolfSSL 16:8e0d178b1d1e 7162 /* OPTIONAL: keyLength, not supported yet */
wolfSSL 16:8e0d178b1d1e 7163 /* OPTIONAL: prf AlgorithIdentifier, not supported yet */
wolfSSL 16:8e0d178b1d1e 7164
wolfSSL 16:8e0d178b1d1e 7165 /* KeyEncryptionAlgorithmIdentifier */
wolfSSL 16:8e0d178b1d1e 7166 byte keyEncAlgoIdSeq[MAX_SEQ_SZ];
wolfSSL 16:8e0d178b1d1e 7167 byte keyEncAlgoId[MAX_OID_SZ]; /* id-alg-PWRI-KEK */
wolfSSL 16:8e0d178b1d1e 7168 byte pwriEncAlgoId[MAX_ALGO_SZ];
wolfSSL 16:8e0d178b1d1e 7169 byte ivOctetString[MAX_OCTET_STR_SZ];
wolfSSL 16:8e0d178b1d1e 7170 word32 keyEncAlgoIdSeqSz, keyEncAlgoIdSz;
wolfSSL 16:8e0d178b1d1e 7171 word32 pwriEncAlgoIdSz, ivOctetStringSz;
wolfSSL 16:8e0d178b1d1e 7172
wolfSSL 16:8e0d178b1d1e 7173 /* EncryptedKey */
wolfSSL 16:8e0d178b1d1e 7174 byte encKeyOctetStr[MAX_OCTET_STR_SZ];
wolfSSL 16:8e0d178b1d1e 7175 word32 encKeyOctetStrSz;
wolfSSL 16:8e0d178b1d1e 7176
wolfSSL 16:8e0d178b1d1e 7177 byte tmpIv[MAX_CONTENT_IV_SIZE];
wolfSSL 16:8e0d178b1d1e 7178 byte* encryptedKey = NULL;
wolfSSL 16:8e0d178b1d1e 7179 byte* kek = NULL;
wolfSSL 16:8e0d178b1d1e 7180
wolfSSL 16:8e0d178b1d1e 7181 int cekKeySz = 0, kekKeySz = 0, kekBlockSz = 0, ret = 0;
wolfSSL 16:8e0d178b1d1e 7182 int encryptOID;
wolfSSL 16:8e0d178b1d1e 7183 word32 idx, totalSz = 0, encryptedKeySz;
wolfSSL 16:8e0d178b1d1e 7184
wolfSSL 16:8e0d178b1d1e 7185 if (pkcs7 == NULL || passwd == NULL || pLen == 0 ||
wolfSSL 16:8e0d178b1d1e 7186 salt == NULL || saltSz == 0) {
wolfSSL 16:8e0d178b1d1e 7187 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 7188 }
wolfSSL 16:8e0d178b1d1e 7189
wolfSSL 16:8e0d178b1d1e 7190 /* allow user to use different KEK encryption algorithm than used for
wolfSSL 16:8e0d178b1d1e 7191 * main content encryption algorithm, if passed in */
wolfSSL 16:8e0d178b1d1e 7192 if (kekEncryptOID != 0) {
wolfSSL 16:8e0d178b1d1e 7193 encryptOID = kekEncryptOID;
wolfSSL 16:8e0d178b1d1e 7194 } else {
wolfSSL 16:8e0d178b1d1e 7195 encryptOID = pkcs7->encryptOID;
wolfSSL 16:8e0d178b1d1e 7196 }
wolfSSL 16:8e0d178b1d1e 7197
wolfSSL 16:8e0d178b1d1e 7198 /* get content-encryption key size, based on algorithm */
wolfSSL 16:8e0d178b1d1e 7199 cekKeySz = wc_PKCS7_GetOIDKeySize(pkcs7->encryptOID);
wolfSSL 16:8e0d178b1d1e 7200 if (cekKeySz < 0)
wolfSSL 16:8e0d178b1d1e 7201 return cekKeySz;
wolfSSL 16:8e0d178b1d1e 7202
wolfSSL 16:8e0d178b1d1e 7203 /* get KEK encryption key size, based on algorithm */
wolfSSL 16:8e0d178b1d1e 7204 if (encryptOID != pkcs7->encryptOID) {
wolfSSL 16:8e0d178b1d1e 7205 kekKeySz = wc_PKCS7_GetOIDKeySize(encryptOID);
wolfSSL 16:8e0d178b1d1e 7206 } else {
wolfSSL 16:8e0d178b1d1e 7207 kekKeySz = cekKeySz;
wolfSSL 16:8e0d178b1d1e 7208 }
wolfSSL 16:8e0d178b1d1e 7209
wolfSSL 16:8e0d178b1d1e 7210 /* get KEK encryption block size */
wolfSSL 16:8e0d178b1d1e 7211 kekBlockSz = wc_PKCS7_GetOIDBlockSize(encryptOID);
wolfSSL 16:8e0d178b1d1e 7212 if (kekBlockSz < 0)
wolfSSL 16:8e0d178b1d1e 7213 return kekBlockSz;
wolfSSL 16:8e0d178b1d1e 7214
wolfSSL 16:8e0d178b1d1e 7215 /* generate random CEK */
wolfSSL 16:8e0d178b1d1e 7216 ret = PKCS7_GenerateContentEncryptionKey(pkcs7, cekKeySz);
wolfSSL 16:8e0d178b1d1e 7217 if (ret < 0)
wolfSSL 16:8e0d178b1d1e 7218 return ret;
wolfSSL 16:8e0d178b1d1e 7219
wolfSSL 16:8e0d178b1d1e 7220 /* generate random IV */
wolfSSL 16:8e0d178b1d1e 7221 ret = wc_PKCS7_GenerateBlock(pkcs7, NULL, tmpIv, kekBlockSz);
wolfSSL 16:8e0d178b1d1e 7222 if (ret != 0)
wolfSSL 16:8e0d178b1d1e 7223 return ret;
wolfSSL 16:8e0d178b1d1e 7224
wolfSSL 16:8e0d178b1d1e 7225 /* allocate memory for RecipientInfo, KEK, encrypted key */
wolfSSL 16:8e0d178b1d1e 7226 recip = (Pkcs7EncodedRecip*)XMALLOC(sizeof(Pkcs7EncodedRecip),
wolfSSL 16:8e0d178b1d1e 7227 pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 7228 if (recip == NULL)
wolfSSL 16:8e0d178b1d1e 7229 return MEMORY_E;
wolfSSL 16:8e0d178b1d1e 7230
wolfSSL 16:8e0d178b1d1e 7231 kek = (byte*)XMALLOC(kekKeySz, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 7232 if (kek == NULL) {
wolfSSL 16:8e0d178b1d1e 7233 XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 7234 return MEMORY_E;
wolfSSL 16:8e0d178b1d1e 7235 }
wolfSSL 16:8e0d178b1d1e 7236
wolfSSL 16:8e0d178b1d1e 7237 encryptedKey = (byte*)XMALLOC(MAX_ENCRYPTED_KEY_SZ,
wolfSSL 16:8e0d178b1d1e 7238 pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 7239 if (encryptedKey == NULL) {
wolfSSL 16:8e0d178b1d1e 7240 XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 7241 XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 7242 return MEMORY_E;
wolfSSL 16:8e0d178b1d1e 7243 }
wolfSSL 16:8e0d178b1d1e 7244
wolfSSL 16:8e0d178b1d1e 7245 encryptedKeySz = MAX_ENCRYPTED_KEY_SZ;
wolfSSL 16:8e0d178b1d1e 7246 XMEMSET(recip, 0, sizeof(Pkcs7EncodedRecip));
wolfSSL 16:8e0d178b1d1e 7247 XMEMSET(kek, 0, kekKeySz);
wolfSSL 16:8e0d178b1d1e 7248 XMEMSET(encryptedKey, 0, encryptedKeySz);
wolfSSL 16:8e0d178b1d1e 7249
wolfSSL 16:8e0d178b1d1e 7250 /* generate KEK: expand password into KEK */
wolfSSL 16:8e0d178b1d1e 7251 ret = wc_PKCS7_GenerateKEK_PWRI(pkcs7, passwd, pLen, salt, saltSz,
wolfSSL 16:8e0d178b1d1e 7252 kdfOID, hashOID, iterations, kek,
wolfSSL 16:8e0d178b1d1e 7253 kekKeySz);
wolfSSL 16:8e0d178b1d1e 7254 if (ret < 0) {
wolfSSL 16:8e0d178b1d1e 7255 XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 7256 XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 7257 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 7258 return ret;
wolfSSL 16:8e0d178b1d1e 7259 }
wolfSSL 16:8e0d178b1d1e 7260
wolfSSL 16:8e0d178b1d1e 7261 /* generate encrypted key: encrypt CEK with KEK */
wolfSSL 16:8e0d178b1d1e 7262 ret = wc_PKCS7_PwriKek_KeyWrap(pkcs7, kek, kekKeySz, pkcs7->cek,
wolfSSL 16:8e0d178b1d1e 7263 pkcs7->cekSz, encryptedKey, &encryptedKeySz,
wolfSSL 16:8e0d178b1d1e 7264 tmpIv, kekBlockSz, encryptOID);
wolfSSL 16:8e0d178b1d1e 7265 if (ret < 0) {
wolfSSL 16:8e0d178b1d1e 7266 XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 7267 XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 7268 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 7269 return ret;
wolfSSL 16:8e0d178b1d1e 7270 }
wolfSSL 16:8e0d178b1d1e 7271 encryptedKeySz = ret;
wolfSSL 16:8e0d178b1d1e 7272
wolfSSL 16:8e0d178b1d1e 7273 /* put together encrypted key OCTET STRING */
wolfSSL 16:8e0d178b1d1e 7274 encKeyOctetStrSz = SetOctetString(encryptedKeySz, encKeyOctetStr);
wolfSSL 16:8e0d178b1d1e 7275 totalSz += (encKeyOctetStrSz + encryptedKeySz);
wolfSSL 16:8e0d178b1d1e 7276
wolfSSL 16:8e0d178b1d1e 7277 /* put together IV OCTET STRING */
wolfSSL 16:8e0d178b1d1e 7278 ivOctetStringSz = SetOctetString(kekBlockSz, ivOctetString);
wolfSSL 16:8e0d178b1d1e 7279 totalSz += (ivOctetStringSz + kekBlockSz);
wolfSSL 16:8e0d178b1d1e 7280
wolfSSL 16:8e0d178b1d1e 7281 /* set PWRIAlgorithms AlgorithmIdentifier, adding (ivOctetStringSz +
wolfSSL 16:8e0d178b1d1e 7282 blockKeySz) for IV OCTET STRING */
wolfSSL 16:8e0d178b1d1e 7283 pwriEncAlgoIdSz = SetAlgoID(encryptOID, pwriEncAlgoId,
wolfSSL 16:8e0d178b1d1e 7284 oidBlkType, ivOctetStringSz + kekBlockSz);
wolfSSL 16:8e0d178b1d1e 7285 totalSz += pwriEncAlgoIdSz;
wolfSSL 16:8e0d178b1d1e 7286
wolfSSL 16:8e0d178b1d1e 7287 /* set KeyEncryptionAlgorithms OID */
wolfSSL 16:8e0d178b1d1e 7288 ret = wc_SetContentType(PWRI_KEK_WRAP, keyEncAlgoId, sizeof(keyEncAlgoId));
wolfSSL 16:8e0d178b1d1e 7289 if (ret <= 0) {
wolfSSL 16:8e0d178b1d1e 7290 XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 7291 XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 7292 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 7293 return ret;
wolfSSL 16:8e0d178b1d1e 7294 }
wolfSSL 16:8e0d178b1d1e 7295 keyEncAlgoIdSz = ret;
wolfSSL 16:8e0d178b1d1e 7296 totalSz += keyEncAlgoIdSz;
wolfSSL 16:8e0d178b1d1e 7297
wolfSSL 16:8e0d178b1d1e 7298 /* KeyEncryptionAlgorithm SEQ */
wolfSSL 16:8e0d178b1d1e 7299 keyEncAlgoIdSeqSz = SetSequence(keyEncAlgoIdSz + pwriEncAlgoIdSz +
wolfSSL 16:8e0d178b1d1e 7300 ivOctetStringSz + kekBlockSz,
wolfSSL 16:8e0d178b1d1e 7301 keyEncAlgoIdSeq);
wolfSSL 16:8e0d178b1d1e 7302 totalSz += keyEncAlgoIdSeqSz;
wolfSSL 16:8e0d178b1d1e 7303
wolfSSL 16:8e0d178b1d1e 7304 /* set KDF salt */
wolfSSL 16:8e0d178b1d1e 7305 kdfSaltOctetStrSz = SetOctetString(saltSz, kdfSaltOctetStr);
wolfSSL 16:8e0d178b1d1e 7306 totalSz += (kdfSaltOctetStrSz + saltSz);
wolfSSL 16:8e0d178b1d1e 7307
wolfSSL 16:8e0d178b1d1e 7308 /* set KDF iteration count */
wolfSSL 16:8e0d178b1d1e 7309 kdfIterationsSz = SetMyVersion(iterations, kdfIterations, 0);
wolfSSL 16:8e0d178b1d1e 7310 totalSz += kdfIterationsSz;
wolfSSL 16:8e0d178b1d1e 7311
wolfSSL 16:8e0d178b1d1e 7312 /* set KDF params SEQ */
wolfSSL 16:8e0d178b1d1e 7313 kdfParamsSeqSz = SetSequence(kdfSaltOctetStrSz + saltSz + kdfIterationsSz,
wolfSSL 16:8e0d178b1d1e 7314 kdfParamsSeq);
wolfSSL 16:8e0d178b1d1e 7315 totalSz += kdfParamsSeqSz;
wolfSSL 16:8e0d178b1d1e 7316
wolfSSL 16:8e0d178b1d1e 7317 /* set KDF algo OID */
wolfSSL 16:8e0d178b1d1e 7318 ret = wc_SetContentType(kdfOID, kdfAlgoId, sizeof(kdfAlgoId));
wolfSSL 16:8e0d178b1d1e 7319 if (ret <= 0) {
wolfSSL 16:8e0d178b1d1e 7320 XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 7321 XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 7322 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 7323 return ret;
wolfSSL 16:8e0d178b1d1e 7324 }
wolfSSL 16:8e0d178b1d1e 7325 kdfAlgoIdSz = ret;
wolfSSL 16:8e0d178b1d1e 7326 totalSz += kdfAlgoIdSz;
wolfSSL 16:8e0d178b1d1e 7327
wolfSSL 16:8e0d178b1d1e 7328 /* set KeyDerivationAlgorithmIdentifier EXPLICIT [0] SEQ */
wolfSSL 16:8e0d178b1d1e 7329 kdfAlgoIdSeqSz = SetExplicit(0, kdfAlgoIdSz + kdfParamsSeqSz +
wolfSSL 16:8e0d178b1d1e 7330 kdfSaltOctetStrSz + saltSz + kdfIterationsSz,
wolfSSL 16:8e0d178b1d1e 7331 kdfAlgoIdSeq);
wolfSSL 16:8e0d178b1d1e 7332 totalSz += kdfAlgoIdSeqSz;
wolfSSL 16:8e0d178b1d1e 7333
wolfSSL 16:8e0d178b1d1e 7334 /* set PasswordRecipientInfo CMSVersion, MUST be 0 */
wolfSSL 16:8e0d178b1d1e 7335 verSz = SetMyVersion(0, ver, 0);
wolfSSL 16:8e0d178b1d1e 7336 totalSz += verSz;
wolfSSL 16:8e0d178b1d1e 7337 recip->recipVersion = 0;
wolfSSL 16:8e0d178b1d1e 7338
wolfSSL 16:8e0d178b1d1e 7339 /* set PasswordRecipientInfo SEQ */
wolfSSL 16:8e0d178b1d1e 7340 recipSeqSz = SetImplicit(ASN_SEQUENCE, 3, totalSz, recipSeq);
wolfSSL 16:8e0d178b1d1e 7341 totalSz += recipSeqSz;
wolfSSL 16:8e0d178b1d1e 7342
wolfSSL 16:8e0d178b1d1e 7343 if (totalSz > MAX_RECIP_SZ) {
wolfSSL 16:8e0d178b1d1e 7344 WOLFSSL_MSG("CMS Recipient output buffer too small");
wolfSSL 16:8e0d178b1d1e 7345 XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 7346 XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 7347 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 7348 return BUFFER_E;
wolfSSL 16:8e0d178b1d1e 7349 }
wolfSSL 16:8e0d178b1d1e 7350
wolfSSL 16:8e0d178b1d1e 7351 idx = 0;
wolfSSL 16:8e0d178b1d1e 7352 XMEMCPY(recip->recip + idx, recipSeq, recipSeqSz);
wolfSSL 16:8e0d178b1d1e 7353 idx += recipSeqSz;
wolfSSL 16:8e0d178b1d1e 7354 XMEMCPY(recip->recip + idx, ver, verSz);
wolfSSL 16:8e0d178b1d1e 7355 idx += verSz;
wolfSSL 16:8e0d178b1d1e 7356 XMEMCPY(recip->recip + idx, kdfAlgoIdSeq, kdfAlgoIdSeqSz);
wolfSSL 16:8e0d178b1d1e 7357 idx += kdfAlgoIdSeqSz;
wolfSSL 16:8e0d178b1d1e 7358 XMEMCPY(recip->recip + idx, kdfAlgoId, kdfAlgoIdSz);
wolfSSL 16:8e0d178b1d1e 7359 idx += kdfAlgoIdSz;
wolfSSL 16:8e0d178b1d1e 7360 XMEMCPY(recip->recip + idx, kdfParamsSeq, kdfParamsSeqSz);
wolfSSL 16:8e0d178b1d1e 7361 idx += kdfParamsSeqSz;
wolfSSL 16:8e0d178b1d1e 7362 XMEMCPY(recip->recip + idx, kdfSaltOctetStr, kdfSaltOctetStrSz);
wolfSSL 16:8e0d178b1d1e 7363 idx += kdfSaltOctetStrSz;
wolfSSL 16:8e0d178b1d1e 7364 XMEMCPY(recip->recip + idx, salt, saltSz);
wolfSSL 16:8e0d178b1d1e 7365 idx += saltSz;
wolfSSL 16:8e0d178b1d1e 7366 XMEMCPY(recip->recip + idx, kdfIterations, kdfIterationsSz);
wolfSSL 16:8e0d178b1d1e 7367 idx += kdfIterationsSz;
wolfSSL 16:8e0d178b1d1e 7368 XMEMCPY(recip->recip + idx, keyEncAlgoIdSeq, keyEncAlgoIdSeqSz);
wolfSSL 16:8e0d178b1d1e 7369 idx += keyEncAlgoIdSeqSz;
wolfSSL 16:8e0d178b1d1e 7370 XMEMCPY(recip->recip + idx, keyEncAlgoId, keyEncAlgoIdSz);
wolfSSL 16:8e0d178b1d1e 7371 idx += keyEncAlgoIdSz;
wolfSSL 16:8e0d178b1d1e 7372 XMEMCPY(recip->recip + idx, pwriEncAlgoId, pwriEncAlgoIdSz);
wolfSSL 16:8e0d178b1d1e 7373 idx += pwriEncAlgoIdSz;
wolfSSL 16:8e0d178b1d1e 7374 XMEMCPY(recip->recip + idx, ivOctetString, ivOctetStringSz);
wolfSSL 16:8e0d178b1d1e 7375 idx += ivOctetStringSz;
wolfSSL 16:8e0d178b1d1e 7376 XMEMCPY(recip->recip + idx, tmpIv, kekBlockSz);
wolfSSL 16:8e0d178b1d1e 7377 idx += kekBlockSz;
wolfSSL 16:8e0d178b1d1e 7378 XMEMCPY(recip->recip + idx, encKeyOctetStr, encKeyOctetStrSz);
wolfSSL 16:8e0d178b1d1e 7379 idx += encKeyOctetStrSz;
wolfSSL 16:8e0d178b1d1e 7380 XMEMCPY(recip->recip + idx, encryptedKey, encryptedKeySz);
wolfSSL 16:8e0d178b1d1e 7381 idx += encryptedKeySz;
wolfSSL 16:8e0d178b1d1e 7382
wolfSSL 16:8e0d178b1d1e 7383 ForceZero(kek, kekBlockSz);
wolfSSL 16:8e0d178b1d1e 7384 ForceZero(encryptedKey, encryptedKeySz);
wolfSSL 16:8e0d178b1d1e 7385 XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 7386 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 7387
wolfSSL 16:8e0d178b1d1e 7388 /* store recipient size */
wolfSSL 16:8e0d178b1d1e 7389 recip->recipSz = idx;
wolfSSL 16:8e0d178b1d1e 7390 recip->recipType = PKCS7_PWRI;
wolfSSL 16:8e0d178b1d1e 7391
wolfSSL 16:8e0d178b1d1e 7392 /* add recipient to recip list */
wolfSSL 16:8e0d178b1d1e 7393 if (pkcs7->recipList == NULL) {
wolfSSL 16:8e0d178b1d1e 7394 pkcs7->recipList = recip;
wolfSSL 16:8e0d178b1d1e 7395 } else {
wolfSSL 16:8e0d178b1d1e 7396 lastRecip = pkcs7->recipList;
wolfSSL 16:8e0d178b1d1e 7397 while (lastRecip->next != NULL) {
wolfSSL 16:8e0d178b1d1e 7398 lastRecip = lastRecip->next;
wolfSSL 16:8e0d178b1d1e 7399 }
wolfSSL 16:8e0d178b1d1e 7400 lastRecip->next = recip;
wolfSSL 16:8e0d178b1d1e 7401 }
wolfSSL 16:8e0d178b1d1e 7402
wolfSSL 16:8e0d178b1d1e 7403 (void)options;
wolfSSL 16:8e0d178b1d1e 7404
wolfSSL 16:8e0d178b1d1e 7405 return idx;
wolfSSL 16:8e0d178b1d1e 7406 }
wolfSSL 16:8e0d178b1d1e 7407
wolfSSL 16:8e0d178b1d1e 7408 /* Import password and KDF settings into a PKCS7 structure. Used for setting
wolfSSL 16:8e0d178b1d1e 7409 * the password info for decryption a EnvelopedData PWRI RecipientInfo.
wolfSSL 16:8e0d178b1d1e 7410 *
wolfSSL 16:8e0d178b1d1e 7411 * Returns 0 on success, negative upon error */
wolfSSL 16:8e0d178b1d1e 7412 int wc_PKCS7_SetPassword(PKCS7* pkcs7, byte* passwd, word32 pLen)
wolfSSL 16:8e0d178b1d1e 7413 {
wolfSSL 16:8e0d178b1d1e 7414 if (pkcs7 == NULL || passwd == NULL || pLen == 0)
wolfSSL 16:8e0d178b1d1e 7415 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 7416
wolfSSL 16:8e0d178b1d1e 7417 pkcs7->pass = passwd;
wolfSSL 16:8e0d178b1d1e 7418 pkcs7->passSz = pLen;
wolfSSL 16:8e0d178b1d1e 7419
wolfSSL 16:8e0d178b1d1e 7420 return 0;
wolfSSL 16:8e0d178b1d1e 7421 }
wolfSSL 16:8e0d178b1d1e 7422
wolfSSL 16:8e0d178b1d1e 7423 #endif /* NO_PWDBASED */
wolfSSL 16:8e0d178b1d1e 7424
wolfSSL 16:8e0d178b1d1e 7425
wolfSSL 16:8e0d178b1d1e 7426 /* Encode and add CMS EnvelopedData KEKRI (KEKRecipientInfo) RecipientInfo
wolfSSL 16:8e0d178b1d1e 7427 * to CMS/PKCS#7 EnvelopedData structure.
wolfSSL 16:8e0d178b1d1e 7428 *
wolfSSL 16:8e0d178b1d1e 7429 * pkcs7 - pointer to initialized PKCS7 structure
wolfSSL 16:8e0d178b1d1e 7430 * keyWrapOID - OID sum of key wrap algorithm identifier
wolfSSL 16:8e0d178b1d1e 7431 * kek - key encryption key
wolfSSL 16:8e0d178b1d1e 7432 * kekSz - size of kek, bytes
wolfSSL 16:8e0d178b1d1e 7433 * keyID - key-encryption key identifier, pre-distributed to endpoints
wolfSSL 16:8e0d178b1d1e 7434 * keyIDSz - size of keyID, bytes
wolfSSL 16:8e0d178b1d1e 7435 * timePtr - pointer to "time_t", which is typically "long" (OPTIONAL)
wolfSSL 16:8e0d178b1d1e 7436 * otherOID - ASN.1 encoded OID of other attribute (OPTIONAL)
wolfSSL 16:8e0d178b1d1e 7437 * otherOIDSz - size of otherOID, bytes (OPTIONAL)
wolfSSL 16:8e0d178b1d1e 7438 * other - other attribute (OPTIONAL)
wolfSSL 16:8e0d178b1d1e 7439 * otherSz - size of other (OPTIONAL)
wolfSSL 16:8e0d178b1d1e 7440 *
wolfSSL 16:8e0d178b1d1e 7441 * Returns 0 on success, negative upon error */
wolfSSL 16:8e0d178b1d1e 7442 int wc_PKCS7_AddRecipient_KEKRI(PKCS7* pkcs7, int keyWrapOID, byte* kek,
wolfSSL 16:8e0d178b1d1e 7443 word32 kekSz, byte* keyId, word32 keyIdSz,
wolfSSL 16:8e0d178b1d1e 7444 void* timePtr, byte* otherOID,
wolfSSL 16:8e0d178b1d1e 7445 word32 otherOIDSz, byte* other, word32 otherSz,
wolfSSL 16:8e0d178b1d1e 7446 int options)
wolfSSL 16:8e0d178b1d1e 7447 {
wolfSSL 16:8e0d178b1d1e 7448 Pkcs7EncodedRecip* recip = NULL;
wolfSSL 16:8e0d178b1d1e 7449 Pkcs7EncodedRecip* lastRecip = NULL;
wolfSSL 16:8e0d178b1d1e 7450
wolfSSL 16:8e0d178b1d1e 7451 byte recipSeq[MAX_SEQ_SZ];
wolfSSL 16:8e0d178b1d1e 7452 byte ver[MAX_VERSION_SZ];
wolfSSL 16:8e0d178b1d1e 7453 byte kekIdSeq[MAX_SEQ_SZ];
wolfSSL 16:8e0d178b1d1e 7454 byte kekIdOctetStr[MAX_OCTET_STR_SZ];
wolfSSL 16:8e0d178b1d1e 7455 byte genTime[ASN_GENERALIZED_TIME_SIZE];
wolfSSL 16:8e0d178b1d1e 7456 byte otherAttSeq[MAX_SEQ_SZ];
wolfSSL 16:8e0d178b1d1e 7457 byte encAlgoId[MAX_ALGO_SZ];
wolfSSL 16:8e0d178b1d1e 7458 byte encKeyOctetStr[MAX_OCTET_STR_SZ];
wolfSSL 16:8e0d178b1d1e 7459 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 7460 byte* encryptedKey;
wolfSSL 16:8e0d178b1d1e 7461 #else
wolfSSL 16:8e0d178b1d1e 7462 byte encryptedKey[MAX_ENCRYPTED_KEY_SZ];
wolfSSL 16:8e0d178b1d1e 7463 #endif
wolfSSL 16:8e0d178b1d1e 7464
wolfSSL 16:8e0d178b1d1e 7465 int blockKeySz = 0, ret = 0, direction;
wolfSSL 16:8e0d178b1d1e 7466 word32 idx = 0;
wolfSSL 16:8e0d178b1d1e 7467 word32 totalSz = 0;
wolfSSL 16:8e0d178b1d1e 7468 word32 recipSeqSz = 0, verSz = 0;
wolfSSL 16:8e0d178b1d1e 7469 word32 kekIdSeqSz = 0, kekIdOctetStrSz = 0;
wolfSSL 16:8e0d178b1d1e 7470 word32 otherAttSeqSz = 0, encAlgoIdSz = 0, encKeyOctetStrSz = 0;
wolfSSL 16:8e0d178b1d1e 7471 int encryptedKeySz;
wolfSSL 16:8e0d178b1d1e 7472
wolfSSL 16:8e0d178b1d1e 7473 int timeSz = 0;
wolfSSL 16:8e0d178b1d1e 7474 #ifndef NO_ASN_TIME
wolfSSL 16:8e0d178b1d1e 7475 time_t* tm = NULL;
wolfSSL 16:8e0d178b1d1e 7476 #endif
wolfSSL 16:8e0d178b1d1e 7477
wolfSSL 16:8e0d178b1d1e 7478 if (pkcs7 == NULL || kek == NULL || keyId == NULL)
wolfSSL 16:8e0d178b1d1e 7479 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 7480
wolfSSL 16:8e0d178b1d1e 7481 recip = (Pkcs7EncodedRecip*)XMALLOC(sizeof(Pkcs7EncodedRecip), pkcs7->heap,
wolfSSL 16:8e0d178b1d1e 7482 DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 7483 if (recip == NULL)
wolfSSL 16:8e0d178b1d1e 7484 return MEMORY_E;
wolfSSL 16:8e0d178b1d1e 7485
wolfSSL 16:8e0d178b1d1e 7486 XMEMSET(recip, 0, sizeof(Pkcs7EncodedRecip));
wolfSSL 16:8e0d178b1d1e 7487
wolfSSL 16:8e0d178b1d1e 7488 /* get key size for content-encryption key based on algorithm */
wolfSSL 16:8e0d178b1d1e 7489 blockKeySz = wc_PKCS7_GetOIDKeySize(pkcs7->encryptOID);
wolfSSL 16:8e0d178b1d1e 7490 if (blockKeySz < 0) {
wolfSSL 16:8e0d178b1d1e 7491 XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 7492 return blockKeySz;
wolfSSL 16:8e0d178b1d1e 7493 }
wolfSSL 16:8e0d178b1d1e 7494
wolfSSL 16:8e0d178b1d1e 7495 /* generate random content encryption key, if needed */
wolfSSL 16:8e0d178b1d1e 7496 ret = PKCS7_GenerateContentEncryptionKey(pkcs7, blockKeySz);
wolfSSL 16:8e0d178b1d1e 7497 if (ret < 0) {
wolfSSL 16:8e0d178b1d1e 7498 XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 7499 return ret;
wolfSSL 16:8e0d178b1d1e 7500 }
wolfSSL 16:8e0d178b1d1e 7501
wolfSSL 16:8e0d178b1d1e 7502 /* EncryptedKey */
wolfSSL 16:8e0d178b1d1e 7503 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 7504 encryptedKey = (byte*)XMALLOC(MAX_ENCRYPTED_KEY_SZ, pkcs7->heap,
wolfSSL 16:8e0d178b1d1e 7505 DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 7506 if (encryptedKey == NULL) {
wolfSSL 16:8e0d178b1d1e 7507 XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 7508 return MEMORY_E;
wolfSSL 16:8e0d178b1d1e 7509 }
wolfSSL 16:8e0d178b1d1e 7510 #endif
wolfSSL 16:8e0d178b1d1e 7511 encryptedKeySz = MAX_ENCRYPTED_KEY_SZ;
wolfSSL 16:8e0d178b1d1e 7512 XMEMSET(encryptedKey, 0, encryptedKeySz);
wolfSSL 16:8e0d178b1d1e 7513
wolfSSL 16:8e0d178b1d1e 7514 #ifndef NO_AES
wolfSSL 16:8e0d178b1d1e 7515 direction = AES_ENCRYPTION;
wolfSSL 16:8e0d178b1d1e 7516 #else
wolfSSL 16:8e0d178b1d1e 7517 direction = DES_ENCRYPTION;
wolfSSL 16:8e0d178b1d1e 7518 #endif
wolfSSL 16:8e0d178b1d1e 7519
wolfSSL 16:8e0d178b1d1e 7520 encryptedKeySz = wc_PKCS7_KeyWrap(pkcs7->cek, pkcs7->cekSz, kek, kekSz,
wolfSSL 16:8e0d178b1d1e 7521 encryptedKey, encryptedKeySz, keyWrapOID,
wolfSSL 16:8e0d178b1d1e 7522 direction);
wolfSSL 16:8e0d178b1d1e 7523 if (encryptedKeySz < 0) {
wolfSSL 16:8e0d178b1d1e 7524 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 7525 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 7526 #endif
wolfSSL 16:8e0d178b1d1e 7527 XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 7528 return encryptedKeySz;
wolfSSL 16:8e0d178b1d1e 7529 }
wolfSSL 16:8e0d178b1d1e 7530 /* handle a zero size encKey case as WC_KEY_SIZE_E */
wolfSSL 16:8e0d178b1d1e 7531 if (encryptedKeySz == 0 || encryptedKeySz > MAX_ENCRYPTED_KEY_SZ) {
wolfSSL 16:8e0d178b1d1e 7532 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 7533 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 7534 #endif
wolfSSL 16:8e0d178b1d1e 7535 XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 7536 return WC_KEY_SIZE_E;
wolfSSL 16:8e0d178b1d1e 7537 }
wolfSSL 16:8e0d178b1d1e 7538
wolfSSL 16:8e0d178b1d1e 7539 encKeyOctetStrSz = SetOctetString(encryptedKeySz, encKeyOctetStr);
wolfSSL 16:8e0d178b1d1e 7540 totalSz += (encKeyOctetStrSz + encryptedKeySz);
wolfSSL 16:8e0d178b1d1e 7541
wolfSSL 16:8e0d178b1d1e 7542 /* KeyEncryptionAlgorithmIdentifier */
wolfSSL 16:8e0d178b1d1e 7543 encAlgoIdSz = SetAlgoID(keyWrapOID, encAlgoId, oidKeyWrapType, 0);
wolfSSL 16:8e0d178b1d1e 7544 totalSz += encAlgoIdSz;
wolfSSL 16:8e0d178b1d1e 7545
wolfSSL 16:8e0d178b1d1e 7546 /* KEKIdentifier: keyIdentifier */
wolfSSL 16:8e0d178b1d1e 7547 kekIdOctetStrSz = SetOctetString(keyIdSz, kekIdOctetStr);
wolfSSL 16:8e0d178b1d1e 7548 totalSz += (kekIdOctetStrSz + keyIdSz);
wolfSSL 16:8e0d178b1d1e 7549
wolfSSL 16:8e0d178b1d1e 7550 /* KEKIdentifier: GeneralizedTime (OPTIONAL) */
wolfSSL 16:8e0d178b1d1e 7551 #ifndef NO_ASN_TIME
wolfSSL 16:8e0d178b1d1e 7552 if (timePtr != NULL) {
wolfSSL 16:8e0d178b1d1e 7553 tm = (time_t*)timePtr;
wolfSSL 16:8e0d178b1d1e 7554 timeSz = GetAsnTimeString(tm, genTime, sizeof(genTime));
wolfSSL 16:8e0d178b1d1e 7555 if (timeSz < 0) {
wolfSSL 16:8e0d178b1d1e 7556 XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 7557 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 7558 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 7559 #endif
wolfSSL 16:8e0d178b1d1e 7560 return timeSz;
wolfSSL 16:8e0d178b1d1e 7561 }
wolfSSL 16:8e0d178b1d1e 7562 totalSz += timeSz;
wolfSSL 16:8e0d178b1d1e 7563 }
wolfSSL 16:8e0d178b1d1e 7564 #endif
wolfSSL 16:8e0d178b1d1e 7565
wolfSSL 16:8e0d178b1d1e 7566 /* KEKIdentifier: OtherKeyAttribute SEQ (OPTIONAL) */
wolfSSL 16:8e0d178b1d1e 7567 if (other != NULL && otherSz > 0) {
wolfSSL 16:8e0d178b1d1e 7568 otherAttSeqSz = SetSequence(otherOIDSz + otherSz, otherAttSeq);
wolfSSL 16:8e0d178b1d1e 7569 totalSz += otherAttSeqSz + otherOIDSz + otherSz;
wolfSSL 16:8e0d178b1d1e 7570 }
wolfSSL 16:8e0d178b1d1e 7571
wolfSSL 16:8e0d178b1d1e 7572 /* KEKIdentifier SEQ */
wolfSSL 16:8e0d178b1d1e 7573 kekIdSeqSz = SetSequence(kekIdOctetStrSz + keyIdSz + timeSz +
wolfSSL 16:8e0d178b1d1e 7574 otherAttSeqSz + otherOIDSz + otherSz, kekIdSeq);
wolfSSL 16:8e0d178b1d1e 7575 totalSz += kekIdSeqSz;
wolfSSL 16:8e0d178b1d1e 7576
wolfSSL 16:8e0d178b1d1e 7577 /* version */
wolfSSL 16:8e0d178b1d1e 7578 verSz = SetMyVersion(4, ver, 0);
wolfSSL 16:8e0d178b1d1e 7579 totalSz += verSz;
wolfSSL 16:8e0d178b1d1e 7580 recip->recipVersion = 4;
wolfSSL 16:8e0d178b1d1e 7581
wolfSSL 16:8e0d178b1d1e 7582 /* KEKRecipientInfo SEQ */
wolfSSL 16:8e0d178b1d1e 7583 recipSeqSz = SetImplicit(ASN_SEQUENCE, 2, totalSz, recipSeq);
wolfSSL 16:8e0d178b1d1e 7584 totalSz += recipSeqSz;
wolfSSL 16:8e0d178b1d1e 7585
wolfSSL 16:8e0d178b1d1e 7586 if (totalSz > MAX_RECIP_SZ) {
wolfSSL 16:8e0d178b1d1e 7587 WOLFSSL_MSG("CMS Recipient output buffer too small");
wolfSSL 16:8e0d178b1d1e 7588 XFREE(recip, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 7589 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 7590 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 7591 #endif
wolfSSL 16:8e0d178b1d1e 7592 return BUFFER_E;
wolfSSL 16:8e0d178b1d1e 7593 }
wolfSSL 16:8e0d178b1d1e 7594
wolfSSL 16:8e0d178b1d1e 7595 XMEMCPY(recip->recip + idx, recipSeq, recipSeqSz);
wolfSSL 16:8e0d178b1d1e 7596 idx += recipSeqSz;
wolfSSL 16:8e0d178b1d1e 7597 XMEMCPY(recip->recip + idx, ver, verSz);
wolfSSL 16:8e0d178b1d1e 7598 idx += verSz;
wolfSSL 16:8e0d178b1d1e 7599 XMEMCPY(recip->recip + idx, kekIdSeq, kekIdSeqSz);
wolfSSL 16:8e0d178b1d1e 7600 idx += kekIdSeqSz;
wolfSSL 16:8e0d178b1d1e 7601 XMEMCPY(recip->recip + idx, kekIdOctetStr, kekIdOctetStrSz);
wolfSSL 16:8e0d178b1d1e 7602 idx += kekIdOctetStrSz;
wolfSSL 16:8e0d178b1d1e 7603 XMEMCPY(recip->recip + idx, keyId, keyIdSz);
wolfSSL 16:8e0d178b1d1e 7604 idx += keyIdSz;
wolfSSL 16:8e0d178b1d1e 7605 if (timePtr != NULL) {
wolfSSL 16:8e0d178b1d1e 7606 XMEMCPY(recip->recip + idx, genTime, timeSz);
wolfSSL 16:8e0d178b1d1e 7607 idx += timeSz;
wolfSSL 16:8e0d178b1d1e 7608 }
wolfSSL 16:8e0d178b1d1e 7609 if (other != NULL && otherSz > 0) {
wolfSSL 16:8e0d178b1d1e 7610 XMEMCPY(recip->recip + idx, otherAttSeq, otherAttSeqSz);
wolfSSL 16:8e0d178b1d1e 7611 idx += otherAttSeqSz;
wolfSSL 16:8e0d178b1d1e 7612 XMEMCPY(recip->recip + idx, otherOID, otherOIDSz);
wolfSSL 16:8e0d178b1d1e 7613 idx += otherOIDSz;
wolfSSL 16:8e0d178b1d1e 7614 XMEMCPY(recip->recip + idx, other, otherSz);
wolfSSL 16:8e0d178b1d1e 7615 idx += otherSz;
wolfSSL 16:8e0d178b1d1e 7616 }
wolfSSL 16:8e0d178b1d1e 7617 XMEMCPY(recip->recip + idx, encAlgoId, encAlgoIdSz);
wolfSSL 16:8e0d178b1d1e 7618 idx += encAlgoIdSz;
wolfSSL 16:8e0d178b1d1e 7619 XMEMCPY(recip->recip + idx, encKeyOctetStr, encKeyOctetStrSz);
wolfSSL 16:8e0d178b1d1e 7620 idx += encKeyOctetStrSz;
wolfSSL 16:8e0d178b1d1e 7621 XMEMCPY(recip->recip + idx, encryptedKey, encryptedKeySz);
wolfSSL 16:8e0d178b1d1e 7622 idx += encryptedKeySz;
wolfSSL 16:8e0d178b1d1e 7623
wolfSSL 16:8e0d178b1d1e 7624 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 7625 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 7626 #endif
wolfSSL 16:8e0d178b1d1e 7627
wolfSSL 16:8e0d178b1d1e 7628 /* store recipient size */
wolfSSL 16:8e0d178b1d1e 7629 recip->recipSz = idx;
wolfSSL 16:8e0d178b1d1e 7630 recip->recipType = PKCS7_KEKRI;
wolfSSL 16:8e0d178b1d1e 7631
wolfSSL 16:8e0d178b1d1e 7632 /* add recipient to recip list */
wolfSSL 16:8e0d178b1d1e 7633 if (pkcs7->recipList == NULL) {
wolfSSL 16:8e0d178b1d1e 7634 pkcs7->recipList = recip;
wolfSSL 16:8e0d178b1d1e 7635 } else {
wolfSSL 16:8e0d178b1d1e 7636 lastRecip = pkcs7->recipList;
wolfSSL 16:8e0d178b1d1e 7637 while(lastRecip->next != NULL) {
wolfSSL 16:8e0d178b1d1e 7638 lastRecip = lastRecip->next;
wolfSSL 16:8e0d178b1d1e 7639 }
wolfSSL 16:8e0d178b1d1e 7640 lastRecip->next = recip;
wolfSSL 16:8e0d178b1d1e 7641 }
wolfSSL 16:8e0d178b1d1e 7642
wolfSSL 16:8e0d178b1d1e 7643 (void)options;
wolfSSL 16:8e0d178b1d1e 7644
wolfSSL 16:8e0d178b1d1e 7645 return idx;
wolfSSL 16:8e0d178b1d1e 7646 }
wolfSSL 16:8e0d178b1d1e 7647
wolfSSL 16:8e0d178b1d1e 7648
wolfSSL 16:8e0d178b1d1e 7649 static int wc_PKCS7_GetCMSVersion(PKCS7* pkcs7, int cmsContentType)
wolfSSL 16:8e0d178b1d1e 7650 {
wolfSSL 16:8e0d178b1d1e 7651 int version = -1;
wolfSSL 16:8e0d178b1d1e 7652
wolfSSL 16:8e0d178b1d1e 7653 if (pkcs7 == NULL)
wolfSSL 16:8e0d178b1d1e 7654 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 7655
wolfSSL 16:8e0d178b1d1e 7656 switch (cmsContentType) {
wolfSSL 16:8e0d178b1d1e 7657 case ENVELOPED_DATA:
wolfSSL 16:8e0d178b1d1e 7658
wolfSSL 16:8e0d178b1d1e 7659 /* NOTE: EnvelopedData does not currently support
wolfSSL 16:8e0d178b1d1e 7660 originatorInfo or unprotectedAttributes. When either of these
wolfSSL 16:8e0d178b1d1e 7661 are added, version checking below needs to be updated to match
wolfSSL 16:8e0d178b1d1e 7662 Section 6.1 of RFC 5652 */
wolfSSL 16:8e0d178b1d1e 7663
wolfSSL 16:8e0d178b1d1e 7664 /* if RecipientInfos include pwri or ori, version is 3 */
wolfSSL 16:8e0d178b1d1e 7665 if (wc_PKCS7_RecipientListIncludesType(pkcs7, PKCS7_PWRI) ||
wolfSSL 16:8e0d178b1d1e 7666 wc_PKCS7_RecipientListIncludesType(pkcs7, PKCS7_ORI)) {
wolfSSL 16:8e0d178b1d1e 7667 version = 3;
wolfSSL 16:8e0d178b1d1e 7668 break;
wolfSSL 16:8e0d178b1d1e 7669 }
wolfSSL 16:8e0d178b1d1e 7670
wolfSSL 16:8e0d178b1d1e 7671 /* if unprotectedAttrs is absent AND all RecipientInfo structs
wolfSSL 16:8e0d178b1d1e 7672 are version 0, version is 0 */
wolfSSL 16:8e0d178b1d1e 7673 if (wc_PKCS7_RecipientListVersionsAllZero(pkcs7)) {
wolfSSL 16:8e0d178b1d1e 7674 version = 0;
wolfSSL 16:8e0d178b1d1e 7675 break;
wolfSSL 16:8e0d178b1d1e 7676 }
wolfSSL 16:8e0d178b1d1e 7677
wolfSSL 16:8e0d178b1d1e 7678 /* otherwise, version is 2 */
wolfSSL 16:8e0d178b1d1e 7679 version = 2;
wolfSSL 16:8e0d178b1d1e 7680 break;
wolfSSL 16:8e0d178b1d1e 7681
wolfSSL 16:8e0d178b1d1e 7682 default:
wolfSSL 16:8e0d178b1d1e 7683 break;
wolfSSL 16:8e0d178b1d1e 7684 }
wolfSSL 16:8e0d178b1d1e 7685
wolfSSL 16:8e0d178b1d1e 7686 return version;
wolfSSL 16:8e0d178b1d1e 7687 }
wolfSSL 16:8e0d178b1d1e 7688
wolfSSL 16:8e0d178b1d1e 7689
wolfSSL 15:117db924cf7c 7690 /* build PKCS#7 envelopedData content type, return enveloped size */
wolfSSL 15:117db924cf7c 7691 int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz)
wolfSSL 15:117db924cf7c 7692 {
wolfSSL 15:117db924cf7c 7693 int ret, idx = 0;
wolfSSL 15:117db924cf7c 7694 int totalSz, padSz, encryptedOutSz;
wolfSSL 15:117db924cf7c 7695
wolfSSL 16:8e0d178b1d1e 7696 int contentInfoSeqSz = 0, outerContentTypeSz = 0, outerContentSz;
wolfSSL 15:117db924cf7c 7697 byte contentInfoSeq[MAX_SEQ_SZ];
wolfSSL 15:117db924cf7c 7698 byte outerContentType[MAX_ALGO_SZ];
wolfSSL 15:117db924cf7c 7699 byte outerContent[MAX_SEQ_SZ];
wolfSSL 15:117db924cf7c 7700
wolfSSL 16:8e0d178b1d1e 7701 int kariVersion;
wolfSSL 15:117db924cf7c 7702 int envDataSeqSz, verSz;
wolfSSL 15:117db924cf7c 7703 byte envDataSeq[MAX_SEQ_SZ];
wolfSSL 15:117db924cf7c 7704 byte ver[MAX_VERSION_SZ];
wolfSSL 15:117db924cf7c 7705
wolfSSL 15:117db924cf7c 7706 WC_RNG rng;
wolfSSL 16:8e0d178b1d1e 7707 int blockSz, blockKeySz;
wolfSSL 15:117db924cf7c 7708 byte* plain;
wolfSSL 15:117db924cf7c 7709 byte* encryptedContent;
wolfSSL 15:117db924cf7c 7710
wolfSSL 16:8e0d178b1d1e 7711 Pkcs7EncodedRecip* tmpRecip = NULL;
wolfSSL 15:117db924cf7c 7712 int recipSz, recipSetSz;
wolfSSL 15:117db924cf7c 7713 byte recipSet[MAX_SET_SZ];
wolfSSL 15:117db924cf7c 7714
wolfSSL 15:117db924cf7c 7715 int encContentOctetSz, encContentSeqSz, contentTypeSz;
wolfSSL 15:117db924cf7c 7716 int contentEncAlgoSz, ivOctetStringSz;
wolfSSL 15:117db924cf7c 7717 byte encContentSeq[MAX_SEQ_SZ];
wolfSSL 15:117db924cf7c 7718 byte contentType[MAX_ALGO_SZ];
wolfSSL 15:117db924cf7c 7719 byte contentEncAlgo[MAX_ALGO_SZ];
wolfSSL 15:117db924cf7c 7720 byte tmpIv[MAX_CONTENT_IV_SIZE];
wolfSSL 15:117db924cf7c 7721 byte ivOctetString[MAX_OCTET_STR_SZ];
wolfSSL 15:117db924cf7c 7722 byte encContentOctet[MAX_OCTET_STR_SZ];
wolfSSL 15:117db924cf7c 7723
wolfSSL 16:8e0d178b1d1e 7724 if (pkcs7 == NULL || pkcs7->content == NULL || pkcs7->contentSz == 0)
wolfSSL 15:117db924cf7c 7725 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 7726
wolfSSL 15:117db924cf7c 7727 if (output == NULL || outputSz == 0)
wolfSSL 15:117db924cf7c 7728 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 7729
wolfSSL 15:117db924cf7c 7730 blockKeySz = wc_PKCS7_GetOIDKeySize(pkcs7->encryptOID);
wolfSSL 15:117db924cf7c 7731 if (blockKeySz < 0)
wolfSSL 15:117db924cf7c 7732 return blockKeySz;
wolfSSL 15:117db924cf7c 7733
wolfSSL 15:117db924cf7c 7734 blockSz = wc_PKCS7_GetOIDBlockSize(pkcs7->encryptOID);
wolfSSL 15:117db924cf7c 7735 if (blockSz < 0)
wolfSSL 15:117db924cf7c 7736 return blockSz;
wolfSSL 15:117db924cf7c 7737
wolfSSL 16:8e0d178b1d1e 7738 if (pkcs7->contentOID != FIRMWARE_PKG_DATA) {
wolfSSL 16:8e0d178b1d1e 7739 /* outer content type */
wolfSSL 16:8e0d178b1d1e 7740 ret = wc_SetContentType(ENVELOPED_DATA, outerContentType,
wolfSSL 16:8e0d178b1d1e 7741 sizeof(outerContentType));
wolfSSL 16:8e0d178b1d1e 7742 if (ret < 0)
wolfSSL 16:8e0d178b1d1e 7743 return ret;
wolfSSL 16:8e0d178b1d1e 7744
wolfSSL 16:8e0d178b1d1e 7745 outerContentTypeSz = ret;
wolfSSL 15:117db924cf7c 7746 }
wolfSSL 15:117db924cf7c 7747
wolfSSL 15:117db924cf7c 7748 /* generate random content encryption key */
wolfSSL 16:8e0d178b1d1e 7749 ret = PKCS7_GenerateContentEncryptionKey(pkcs7, blockKeySz);
wolfSSL 16:8e0d178b1d1e 7750 if (ret != 0) {
wolfSSL 16:8e0d178b1d1e 7751 return ret;
wolfSSL 16:8e0d178b1d1e 7752 }
wolfSSL 16:8e0d178b1d1e 7753
wolfSSL 16:8e0d178b1d1e 7754 /* build RecipientInfo, only if user manually set singleCert and size */
wolfSSL 16:8e0d178b1d1e 7755 if (pkcs7->singleCert != NULL && pkcs7->singleCertSz > 0) {
wolfSSL 16:8e0d178b1d1e 7756 switch (pkcs7->publicKeyOID) {
wolfSSL 16:8e0d178b1d1e 7757 #ifndef NO_RSA
wolfSSL 16:8e0d178b1d1e 7758 case RSAk:
wolfSSL 16:8e0d178b1d1e 7759 ret = wc_PKCS7_AddRecipient_KTRI(pkcs7, pkcs7->singleCert,
wolfSSL 16:8e0d178b1d1e 7760 pkcs7->singleCertSz, 0);
wolfSSL 16:8e0d178b1d1e 7761 break;
wolfSSL 16:8e0d178b1d1e 7762 #endif
wolfSSL 16:8e0d178b1d1e 7763 #ifdef HAVE_ECC
wolfSSL 16:8e0d178b1d1e 7764 case ECDSAk:
wolfSSL 16:8e0d178b1d1e 7765 ret = wc_PKCS7_AddRecipient_KARI(pkcs7, pkcs7->singleCert,
wolfSSL 16:8e0d178b1d1e 7766 pkcs7->singleCertSz,
wolfSSL 16:8e0d178b1d1e 7767 pkcs7->keyWrapOID,
wolfSSL 16:8e0d178b1d1e 7768 pkcs7->keyAgreeOID, pkcs7->ukm,
wolfSSL 16:8e0d178b1d1e 7769 pkcs7->ukmSz, 0);
wolfSSL 16:8e0d178b1d1e 7770 break;
wolfSSL 16:8e0d178b1d1e 7771 #endif
wolfSSL 16:8e0d178b1d1e 7772
wolfSSL 16:8e0d178b1d1e 7773 default:
wolfSSL 16:8e0d178b1d1e 7774 WOLFSSL_MSG("Unsupported RecipientInfo public key type");
wolfSSL 16:8e0d178b1d1e 7775 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 7776 };
wolfSSL 16:8e0d178b1d1e 7777
wolfSSL 16:8e0d178b1d1e 7778 if (ret < 0) {
wolfSSL 16:8e0d178b1d1e 7779 WOLFSSL_MSG("Failed to create RecipientInfo");
wolfSSL 16:8e0d178b1d1e 7780 return ret;
wolfSSL 16:8e0d178b1d1e 7781 }
wolfSSL 16:8e0d178b1d1e 7782 }
wolfSSL 16:8e0d178b1d1e 7783
wolfSSL 16:8e0d178b1d1e 7784 recipSz = wc_PKCS7_GetRecipientListSize(pkcs7);
wolfSSL 16:8e0d178b1d1e 7785 if (recipSz < 0) {
wolfSSL 16:8e0d178b1d1e 7786 return ret;
wolfSSL 16:8e0d178b1d1e 7787
wolfSSL 16:8e0d178b1d1e 7788 } else if (recipSz == 0) {
wolfSSL 16:8e0d178b1d1e 7789 WOLFSSL_MSG("You must add at least one CMS recipient");
wolfSSL 16:8e0d178b1d1e 7790 return PKCS7_RECIP_E;
wolfSSL 16:8e0d178b1d1e 7791 }
wolfSSL 16:8e0d178b1d1e 7792 recipSetSz = SetSet(recipSz, recipSet);
wolfSSL 16:8e0d178b1d1e 7793
wolfSSL 16:8e0d178b1d1e 7794 /* version, defined in Section 6.1 of RFC 5652 */
wolfSSL 16:8e0d178b1d1e 7795 kariVersion = wc_PKCS7_GetCMSVersion(pkcs7, ENVELOPED_DATA);
wolfSSL 16:8e0d178b1d1e 7796 if (kariVersion < 0) {
wolfSSL 16:8e0d178b1d1e 7797 WOLFSSL_MSG("Failed to set CMS EnvelopedData version");
wolfSSL 16:8e0d178b1d1e 7798 return PKCS7_RECIP_E;
wolfSSL 16:8e0d178b1d1e 7799 }
wolfSSL 16:8e0d178b1d1e 7800
wolfSSL 16:8e0d178b1d1e 7801 verSz = SetMyVersion(kariVersion, ver, 0);
wolfSSL 16:8e0d178b1d1e 7802
wolfSSL 15:117db924cf7c 7803 ret = wc_InitRng_ex(&rng, pkcs7->heap, pkcs7->devId);
wolfSSL 15:117db924cf7c 7804 if (ret != 0)
wolfSSL 15:117db924cf7c 7805 return ret;
wolfSSL 15:117db924cf7c 7806
wolfSSL 16:8e0d178b1d1e 7807 /* generate IV for block cipher */
wolfSSL 16:8e0d178b1d1e 7808 ret = wc_PKCS7_GenerateBlock(pkcs7, &rng, tmpIv, blockSz);
wolfSSL 16:8e0d178b1d1e 7809 wc_FreeRng(&rng);
wolfSSL 16:8e0d178b1d1e 7810 if (ret != 0)
wolfSSL 15:117db924cf7c 7811 return ret;
wolfSSL 15:117db924cf7c 7812
wolfSSL 15:117db924cf7c 7813 /* EncryptedContentInfo */
wolfSSL 16:8e0d178b1d1e 7814 ret = wc_SetContentType(pkcs7->contentOID, contentType,
wolfSSL 16:8e0d178b1d1e 7815 sizeof(contentType));
wolfSSL 16:8e0d178b1d1e 7816 if (ret < 0)
wolfSSL 16:8e0d178b1d1e 7817 return ret;
wolfSSL 16:8e0d178b1d1e 7818
wolfSSL 16:8e0d178b1d1e 7819 contentTypeSz = ret;
wolfSSL 15:117db924cf7c 7820
wolfSSL 15:117db924cf7c 7821 /* allocate encrypted content buffer and PKCS#7 padding */
wolfSSL 15:117db924cf7c 7822 padSz = wc_PKCS7_GetPadSize(pkcs7->contentSz, blockSz);
wolfSSL 15:117db924cf7c 7823 if (padSz < 0)
wolfSSL 15:117db924cf7c 7824 return padSz;
wolfSSL 15:117db924cf7c 7825
wolfSSL 15:117db924cf7c 7826 encryptedOutSz = pkcs7->contentSz + padSz;
wolfSSL 15:117db924cf7c 7827
wolfSSL 16:8e0d178b1d1e 7828 plain = (byte*)XMALLOC(encryptedOutSz, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 7829 if (plain == NULL)
wolfSSL 15:117db924cf7c 7830 return MEMORY_E;
wolfSSL 15:117db924cf7c 7831
wolfSSL 15:117db924cf7c 7832 ret = wc_PKCS7_PadData(pkcs7->content, pkcs7->contentSz, plain,
wolfSSL 15:117db924cf7c 7833 encryptedOutSz, blockSz);
wolfSSL 15:117db924cf7c 7834 if (ret < 0) {
wolfSSL 15:117db924cf7c 7835 XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 7836 return ret;
wolfSSL 15:117db924cf7c 7837 }
wolfSSL 15:117db924cf7c 7838
wolfSSL 15:117db924cf7c 7839 encryptedContent = (byte*)XMALLOC(encryptedOutSz, pkcs7->heap,
wolfSSL 15:117db924cf7c 7840 DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 7841 if (encryptedContent == NULL) {
wolfSSL 15:117db924cf7c 7842 XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 7843 return MEMORY_E;
wolfSSL 15:117db924cf7c 7844 }
wolfSSL 15:117db924cf7c 7845
wolfSSL 15:117db924cf7c 7846 /* put together IV OCTET STRING */
wolfSSL 15:117db924cf7c 7847 ivOctetStringSz = SetOctetString(blockSz, ivOctetString);
wolfSSL 15:117db924cf7c 7848
wolfSSL 15:117db924cf7c 7849 /* build up our ContentEncryptionAlgorithmIdentifier sequence,
wolfSSL 15:117db924cf7c 7850 * adding (ivOctetStringSz + blockSz) for IV OCTET STRING */
wolfSSL 15:117db924cf7c 7851 contentEncAlgoSz = SetAlgoID(pkcs7->encryptOID, contentEncAlgo,
wolfSSL 15:117db924cf7c 7852 oidBlkType, ivOctetStringSz + blockSz);
wolfSSL 15:117db924cf7c 7853
wolfSSL 15:117db924cf7c 7854 if (contentEncAlgoSz == 0) {
wolfSSL 15:117db924cf7c 7855 XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 7856 XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 7857 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 7858 }
wolfSSL 15:117db924cf7c 7859
wolfSSL 15:117db924cf7c 7860 /* encrypt content */
wolfSSL 16:8e0d178b1d1e 7861 ret = wc_PKCS7_EncryptContent(pkcs7->encryptOID, pkcs7->cek,
wolfSSL 16:8e0d178b1d1e 7862 pkcs7->cekSz, tmpIv, blockSz, NULL, 0, NULL, 0, plain,
wolfSSL 16:8e0d178b1d1e 7863 encryptedOutSz, encryptedContent);
wolfSSL 15:117db924cf7c 7864
wolfSSL 15:117db924cf7c 7865 if (ret != 0) {
wolfSSL 15:117db924cf7c 7866 XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 7867 XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 7868 return ret;
wolfSSL 15:117db924cf7c 7869 }
wolfSSL 15:117db924cf7c 7870
wolfSSL 15:117db924cf7c 7871 encContentOctetSz = SetImplicit(ASN_OCTET_STRING, 0, encryptedOutSz,
wolfSSL 15:117db924cf7c 7872 encContentOctet);
wolfSSL 15:117db924cf7c 7873
wolfSSL 15:117db924cf7c 7874 encContentSeqSz = SetSequence(contentTypeSz + contentEncAlgoSz +
wolfSSL 15:117db924cf7c 7875 ivOctetStringSz + blockSz +
wolfSSL 15:117db924cf7c 7876 encContentOctetSz + encryptedOutSz,
wolfSSL 15:117db924cf7c 7877 encContentSeq);
wolfSSL 15:117db924cf7c 7878
wolfSSL 15:117db924cf7c 7879 /* keep track of sizes for outer wrapper layering */
wolfSSL 15:117db924cf7c 7880 totalSz = verSz + recipSetSz + recipSz + encContentSeqSz + contentTypeSz +
wolfSSL 15:117db924cf7c 7881 contentEncAlgoSz + ivOctetStringSz + blockSz +
wolfSSL 15:117db924cf7c 7882 encContentOctetSz + encryptedOutSz;
wolfSSL 15:117db924cf7c 7883
wolfSSL 15:117db924cf7c 7884 /* EnvelopedData */
wolfSSL 15:117db924cf7c 7885 envDataSeqSz = SetSequence(totalSz, envDataSeq);
wolfSSL 15:117db924cf7c 7886 totalSz += envDataSeqSz;
wolfSSL 15:117db924cf7c 7887
wolfSSL 15:117db924cf7c 7888 /* outer content */
wolfSSL 15:117db924cf7c 7889 outerContentSz = SetExplicit(0, totalSz, outerContent);
wolfSSL 15:117db924cf7c 7890 totalSz += outerContentTypeSz;
wolfSSL 15:117db924cf7c 7891 totalSz += outerContentSz;
wolfSSL 15:117db924cf7c 7892
wolfSSL 16:8e0d178b1d1e 7893 if (pkcs7->contentOID != FIRMWARE_PKG_DATA) {
wolfSSL 16:8e0d178b1d1e 7894 /* ContentInfo */
wolfSSL 16:8e0d178b1d1e 7895 contentInfoSeqSz = SetSequence(totalSz, contentInfoSeq);
wolfSSL 16:8e0d178b1d1e 7896 totalSz += contentInfoSeqSz;
wolfSSL 16:8e0d178b1d1e 7897 }
wolfSSL 15:117db924cf7c 7898
wolfSSL 15:117db924cf7c 7899 if (totalSz > (int)outputSz) {
wolfSSL 15:117db924cf7c 7900 WOLFSSL_MSG("Pkcs7_encrypt output buffer too small");
wolfSSL 15:117db924cf7c 7901 XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 7902 XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 7903 return BUFFER_E;
wolfSSL 15:117db924cf7c 7904 }
wolfSSL 15:117db924cf7c 7905
wolfSSL 16:8e0d178b1d1e 7906 if (pkcs7->contentOID != FIRMWARE_PKG_DATA) {
wolfSSL 16:8e0d178b1d1e 7907 XMEMCPY(output + idx, contentInfoSeq, contentInfoSeqSz);
wolfSSL 16:8e0d178b1d1e 7908 idx += contentInfoSeqSz;
wolfSSL 16:8e0d178b1d1e 7909 XMEMCPY(output + idx, outerContentType, outerContentTypeSz);
wolfSSL 16:8e0d178b1d1e 7910 idx += outerContentTypeSz;
wolfSSL 16:8e0d178b1d1e 7911 XMEMCPY(output + idx, outerContent, outerContentSz);
wolfSSL 16:8e0d178b1d1e 7912 idx += outerContentSz;
wolfSSL 16:8e0d178b1d1e 7913 }
wolfSSL 15:117db924cf7c 7914 XMEMCPY(output + idx, envDataSeq, envDataSeqSz);
wolfSSL 15:117db924cf7c 7915 idx += envDataSeqSz;
wolfSSL 15:117db924cf7c 7916 XMEMCPY(output + idx, ver, verSz);
wolfSSL 15:117db924cf7c 7917 idx += verSz;
wolfSSL 15:117db924cf7c 7918 XMEMCPY(output + idx, recipSet, recipSetSz);
wolfSSL 15:117db924cf7c 7919 idx += recipSetSz;
wolfSSL 16:8e0d178b1d1e 7920 /* copy in recipients from list */
wolfSSL 16:8e0d178b1d1e 7921 tmpRecip = pkcs7->recipList;
wolfSSL 16:8e0d178b1d1e 7922 while (tmpRecip != NULL) {
wolfSSL 16:8e0d178b1d1e 7923 XMEMCPY(output + idx, tmpRecip->recip, tmpRecip->recipSz);
wolfSSL 16:8e0d178b1d1e 7924 idx += tmpRecip->recipSz;
wolfSSL 16:8e0d178b1d1e 7925 tmpRecip = tmpRecip->next;
wolfSSL 16:8e0d178b1d1e 7926 }
wolfSSL 16:8e0d178b1d1e 7927 wc_PKCS7_FreeEncodedRecipientSet(pkcs7);
wolfSSL 15:117db924cf7c 7928 XMEMCPY(output + idx, encContentSeq, encContentSeqSz);
wolfSSL 15:117db924cf7c 7929 idx += encContentSeqSz;
wolfSSL 15:117db924cf7c 7930 XMEMCPY(output + idx, contentType, contentTypeSz);
wolfSSL 15:117db924cf7c 7931 idx += contentTypeSz;
wolfSSL 15:117db924cf7c 7932 XMEMCPY(output + idx, contentEncAlgo, contentEncAlgoSz);
wolfSSL 15:117db924cf7c 7933 idx += contentEncAlgoSz;
wolfSSL 15:117db924cf7c 7934 XMEMCPY(output + idx, ivOctetString, ivOctetStringSz);
wolfSSL 15:117db924cf7c 7935 idx += ivOctetStringSz;
wolfSSL 15:117db924cf7c 7936 XMEMCPY(output + idx, tmpIv, blockSz);
wolfSSL 15:117db924cf7c 7937 idx += blockSz;
wolfSSL 15:117db924cf7c 7938 XMEMCPY(output + idx, encContentOctet, encContentOctetSz);
wolfSSL 15:117db924cf7c 7939 idx += encContentOctetSz;
wolfSSL 15:117db924cf7c 7940 XMEMCPY(output + idx, encryptedContent, encryptedOutSz);
wolfSSL 15:117db924cf7c 7941 idx += encryptedOutSz;
wolfSSL 15:117db924cf7c 7942
wolfSSL 15:117db924cf7c 7943 XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 7944 XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 7945
wolfSSL 15:117db924cf7c 7946 return idx;
wolfSSL 15:117db924cf7c 7947 }
wolfSSL 15:117db924cf7c 7948
wolfSSL 15:117db924cf7c 7949 #ifndef NO_RSA
wolfSSL 15:117db924cf7c 7950 /* decode KeyTransRecipientInfo (ktri), return 0 on success, <0 on error */
wolfSSL 16:8e0d178b1d1e 7951 static int wc_PKCS7_DecryptKtri(PKCS7* pkcs7, byte* in, word32 inSz,
wolfSSL 15:117db924cf7c 7952 word32* idx, byte* decryptedKey,
wolfSSL 15:117db924cf7c 7953 word32* decryptedKeySz, int* recipFound)
wolfSSL 15:117db924cf7c 7954 {
wolfSSL 16:8e0d178b1d1e 7955 int length, encryptedKeySz = 0, ret = 0;
wolfSSL 16:8e0d178b1d1e 7956 int keySz, version, sidType = 0;
wolfSSL 15:117db924cf7c 7957 word32 encOID;
wolfSSL 15:117db924cf7c 7958 word32 keyIdx;
wolfSSL 15:117db924cf7c 7959 byte issuerHash[KEYID_SIZE];
wolfSSL 16:8e0d178b1d1e 7960 byte* outKey = NULL;
wolfSSL 16:8e0d178b1d1e 7961 byte* pkiMsg = in;
wolfSSL 16:8e0d178b1d1e 7962 word32 pkiMsgSz = inSz;
wolfSSL 16:8e0d178b1d1e 7963 byte tag;
wolfSSL 16:8e0d178b1d1e 7964
wolfSSL 16:8e0d178b1d1e 7965
wolfSSL 16:8e0d178b1d1e 7966 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 7967 word32 tmpIdx = *idx;
wolfSSL 16:8e0d178b1d1e 7968 long rc;
wolfSSL 16:8e0d178b1d1e 7969 #endif
wolfSSL 15:117db924cf7c 7970 #ifdef WC_RSA_BLINDING
wolfSSL 15:117db924cf7c 7971 WC_RNG rng;
wolfSSL 15:117db924cf7c 7972 #endif
wolfSSL 15:117db924cf7c 7973
wolfSSL 15:117db924cf7c 7974 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 7975 mp_int* serialNum = NULL;
wolfSSL 16:8e0d178b1d1e 7976 byte* encryptedKey = NULL;
wolfSSL 16:8e0d178b1d1e 7977 RsaKey* privKey = NULL;
wolfSSL 15:117db924cf7c 7978 #else
wolfSSL 16:8e0d178b1d1e 7979 mp_int serialNum[1];
wolfSSL 15:117db924cf7c 7980 byte encryptedKey[MAX_ENCRYPTED_KEY_SZ];
wolfSSL 16:8e0d178b1d1e 7981 RsaKey privKey[1];
wolfSSL 16:8e0d178b1d1e 7982 #endif
wolfSSL 16:8e0d178b1d1e 7983
wolfSSL 16:8e0d178b1d1e 7984 switch (pkcs7->state) {
wolfSSL 16:8e0d178b1d1e 7985 case WC_PKCS7_DECRYPT_KTRI:
wolfSSL 16:8e0d178b1d1e 7986 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 7987 if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_VERSION_SZ,
wolfSSL 16:8e0d178b1d1e 7988 &pkiMsg, idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 7989 return ret;
wolfSSL 16:8e0d178b1d1e 7990 }
wolfSSL 16:8e0d178b1d1e 7991
wolfSSL 16:8e0d178b1d1e 7992 rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK,
wolfSSL 16:8e0d178b1d1e 7993 in, inSz);
wolfSSL 16:8e0d178b1d1e 7994 if (rc < 0) {
wolfSSL 16:8e0d178b1d1e 7995 ret = (int)rc;
wolfSSL 16:8e0d178b1d1e 7996 break;
wolfSSL 16:8e0d178b1d1e 7997 }
wolfSSL 16:8e0d178b1d1e 7998 pkiMsgSz = (word32)rc;
wolfSSL 16:8e0d178b1d1e 7999
wolfSSL 16:8e0d178b1d1e 8000 #endif
wolfSSL 16:8e0d178b1d1e 8001 if (GetMyVersion(pkiMsg, idx, &version, pkiMsgSz) < 0)
wolfSSL 16:8e0d178b1d1e 8002 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 8003
wolfSSL 16:8e0d178b1d1e 8004 if (version == 0) {
wolfSSL 16:8e0d178b1d1e 8005 sidType = CMS_ISSUER_AND_SERIAL_NUMBER;
wolfSSL 16:8e0d178b1d1e 8006 } else if (version == 2) {
wolfSSL 16:8e0d178b1d1e 8007 sidType = CMS_SKID;
wolfSSL 16:8e0d178b1d1e 8008 } else {
wolfSSL 16:8e0d178b1d1e 8009 return ASN_VERSION_E;
wolfSSL 16:8e0d178b1d1e 8010 }
wolfSSL 16:8e0d178b1d1e 8011
wolfSSL 16:8e0d178b1d1e 8012 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 8013 if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 8014 break;
wolfSSL 16:8e0d178b1d1e 8015 }
wolfSSL 16:8e0d178b1d1e 8016 wc_PKCS7_StreamStoreVar(pkcs7, 0, sidType, version);
wolfSSL 16:8e0d178b1d1e 8017
wolfSSL 16:8e0d178b1d1e 8018 /* @TODO getting total amount left because of GetInt call later on
wolfSSL 16:8e0d178b1d1e 8019 * this could be optimized to stream better */
wolfSSL 16:8e0d178b1d1e 8020 pkcs7->stream->expected = (pkcs7->stream->maxLen -
wolfSSL 16:8e0d178b1d1e 8021 pkcs7->stream->totalRd) + pkcs7->stream->length;
wolfSSL 16:8e0d178b1d1e 8022 #endif
wolfSSL 16:8e0d178b1d1e 8023 wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_DECRYPT_KTRI_2);
wolfSSL 16:8e0d178b1d1e 8024 FALL_THROUGH;
wolfSSL 16:8e0d178b1d1e 8025
wolfSSL 16:8e0d178b1d1e 8026 case WC_PKCS7_DECRYPT_KTRI_2:
wolfSSL 16:8e0d178b1d1e 8027 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 8028
wolfSSL 16:8e0d178b1d1e 8029 if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, pkcs7->stream->expected,
wolfSSL 16:8e0d178b1d1e 8030 &pkiMsg, idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 8031 return ret;
wolfSSL 16:8e0d178b1d1e 8032 }
wolfSSL 16:8e0d178b1d1e 8033
wolfSSL 16:8e0d178b1d1e 8034 rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK,
wolfSSL 16:8e0d178b1d1e 8035 in, inSz);
wolfSSL 16:8e0d178b1d1e 8036 if (rc < 0) {
wolfSSL 16:8e0d178b1d1e 8037 ret = (int)rc;
wolfSSL 16:8e0d178b1d1e 8038 break;
wolfSSL 16:8e0d178b1d1e 8039 }
wolfSSL 16:8e0d178b1d1e 8040 pkiMsgSz = (word32)rc;
wolfSSL 16:8e0d178b1d1e 8041
wolfSSL 16:8e0d178b1d1e 8042 wc_PKCS7_StreamGetVar(pkcs7, NULL, &sidType, &version);
wolfSSL 16:8e0d178b1d1e 8043
wolfSSL 16:8e0d178b1d1e 8044 /* @TODO get expected size for next part, does not account for
wolfSSL 16:8e0d178b1d1e 8045 * GetInt call well */
wolfSSL 16:8e0d178b1d1e 8046 if (pkcs7->stream->expected == MAX_SEQ_SZ) {
wolfSSL 16:8e0d178b1d1e 8047 int sz;
wolfSSL 16:8e0d178b1d1e 8048 word32 lidx;
wolfSSL 16:8e0d178b1d1e 8049
wolfSSL 16:8e0d178b1d1e 8050 if (sidType == CMS_ISSUER_AND_SERIAL_NUMBER) {
wolfSSL 16:8e0d178b1d1e 8051 lidx = *idx;
wolfSSL 16:8e0d178b1d1e 8052 ret = GetSequence(pkiMsg, &lidx, &sz, pkiMsgSz);
wolfSSL 16:8e0d178b1d1e 8053 if (ret < 0)
wolfSSL 16:8e0d178b1d1e 8054 return ret;
wolfSSL 16:8e0d178b1d1e 8055 }
wolfSSL 16:8e0d178b1d1e 8056 else {
wolfSSL 16:8e0d178b1d1e 8057 lidx = *idx + ASN_TAG_SZ;
wolfSSL 16:8e0d178b1d1e 8058 ret = GetLength(pkiMsg, &lidx, &sz, pkiMsgSz);
wolfSSL 16:8e0d178b1d1e 8059 if (ret < 0)
wolfSSL 16:8e0d178b1d1e 8060 return ret;
wolfSSL 16:8e0d178b1d1e 8061 }
wolfSSL 16:8e0d178b1d1e 8062
wolfSSL 16:8e0d178b1d1e 8063 pkcs7->stream->expected = sz + MAX_ALGO_SZ + ASN_TAG_SZ +
wolfSSL 16:8e0d178b1d1e 8064 MAX_LENGTH_SZ;
wolfSSL 16:8e0d178b1d1e 8065 if (pkcs7->stream->length > 0 &&
wolfSSL 16:8e0d178b1d1e 8066 pkcs7->stream->length < pkcs7->stream->expected) {
wolfSSL 16:8e0d178b1d1e 8067 return WC_PKCS7_WANT_READ_E;
wolfSSL 16:8e0d178b1d1e 8068 }
wolfSSL 16:8e0d178b1d1e 8069 }
wolfSSL 16:8e0d178b1d1e 8070 #endif /* !NO_PKCS7_STREAM */
wolfSSL 16:8e0d178b1d1e 8071
wolfSSL 16:8e0d178b1d1e 8072 if (sidType == CMS_ISSUER_AND_SERIAL_NUMBER) {
wolfSSL 16:8e0d178b1d1e 8073
wolfSSL 16:8e0d178b1d1e 8074 /* remove IssuerAndSerialNumber */
wolfSSL 16:8e0d178b1d1e 8075 if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0)
wolfSSL 16:8e0d178b1d1e 8076 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 8077
wolfSSL 16:8e0d178b1d1e 8078 if (GetNameHash(pkiMsg, idx, issuerHash, pkiMsgSz) < 0)
wolfSSL 16:8e0d178b1d1e 8079 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 8080
wolfSSL 16:8e0d178b1d1e 8081 /* if we found correct recipient, issuer hashes will match */
wolfSSL 16:8e0d178b1d1e 8082 if (XMEMCMP(issuerHash, pkcs7->issuerHash, KEYID_SIZE) == 0) {
wolfSSL 16:8e0d178b1d1e 8083 *recipFound = 1;
wolfSSL 16:8e0d178b1d1e 8084 }
wolfSSL 16:8e0d178b1d1e 8085
wolfSSL 16:8e0d178b1d1e 8086 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 8087 serialNum = (mp_int*)XMALLOC(sizeof(mp_int), pkcs7->heap,
wolfSSL 16:8e0d178b1d1e 8088 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 8089 if (serialNum == NULL)
wolfSSL 16:8e0d178b1d1e 8090 return MEMORY_E;
wolfSSL 16:8e0d178b1d1e 8091 #endif
wolfSSL 16:8e0d178b1d1e 8092
wolfSSL 16:8e0d178b1d1e 8093 if (GetInt(serialNum, pkiMsg, idx, pkiMsgSz) < 0) {
wolfSSL 16:8e0d178b1d1e 8094 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 8095 XFREE(serialNum, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 8096 #endif
wolfSSL 16:8e0d178b1d1e 8097 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 8098 }
wolfSSL 16:8e0d178b1d1e 8099
wolfSSL 16:8e0d178b1d1e 8100 mp_clear(serialNum);
wolfSSL 16:8e0d178b1d1e 8101
wolfSSL 16:8e0d178b1d1e 8102 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 8103 XFREE(serialNum, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 8104 #endif
wolfSSL 16:8e0d178b1d1e 8105
wolfSSL 16:8e0d178b1d1e 8106 } else {
wolfSSL 16:8e0d178b1d1e 8107 /* remove SubjectKeyIdentifier */
wolfSSL 16:8e0d178b1d1e 8108 if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0)
wolfSSL 16:8e0d178b1d1e 8109 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 8110
wolfSSL 16:8e0d178b1d1e 8111 if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC))
wolfSSL 16:8e0d178b1d1e 8112 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 8113
wolfSSL 16:8e0d178b1d1e 8114 if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)
wolfSSL 16:8e0d178b1d1e 8115 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 8116
wolfSSL 16:8e0d178b1d1e 8117 if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0)
wolfSSL 16:8e0d178b1d1e 8118 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 8119
wolfSSL 16:8e0d178b1d1e 8120 if (tag != ASN_OCTET_STRING)
wolfSSL 16:8e0d178b1d1e 8121 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 8122
wolfSSL 16:8e0d178b1d1e 8123 if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)
wolfSSL 16:8e0d178b1d1e 8124 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 8125
wolfSSL 16:8e0d178b1d1e 8126 /* if we found correct recipient, SKID will match */
wolfSSL 16:8e0d178b1d1e 8127 if (XMEMCMP(pkiMsg + (*idx), pkcs7->issuerSubjKeyId,
wolfSSL 16:8e0d178b1d1e 8128 KEYID_SIZE) == 0) {
wolfSSL 16:8e0d178b1d1e 8129 *recipFound = 1;
wolfSSL 16:8e0d178b1d1e 8130 }
wolfSSL 16:8e0d178b1d1e 8131 (*idx) += KEYID_SIZE;
wolfSSL 16:8e0d178b1d1e 8132 }
wolfSSL 16:8e0d178b1d1e 8133
wolfSSL 16:8e0d178b1d1e 8134 if (GetAlgoId(pkiMsg, idx, &encOID, oidKeyType, pkiMsgSz) < 0)
wolfSSL 16:8e0d178b1d1e 8135 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 8136
wolfSSL 16:8e0d178b1d1e 8137 /* key encryption algorithm must be RSA for now */
wolfSSL 16:8e0d178b1d1e 8138 if (encOID != RSAk)
wolfSSL 16:8e0d178b1d1e 8139 return ALGO_ID_E;
wolfSSL 16:8e0d178b1d1e 8140
wolfSSL 16:8e0d178b1d1e 8141 /* read encryptedKey */
wolfSSL 16:8e0d178b1d1e 8142 if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0)
wolfSSL 16:8e0d178b1d1e 8143 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 8144
wolfSSL 16:8e0d178b1d1e 8145 if (tag != ASN_OCTET_STRING)
wolfSSL 16:8e0d178b1d1e 8146 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 8147
wolfSSL 16:8e0d178b1d1e 8148 if (GetLength(pkiMsg, idx, &encryptedKeySz, pkiMsgSz) < 0) {
wolfSSL 16:8e0d178b1d1e 8149 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 8150 }
wolfSSL 16:8e0d178b1d1e 8151 if (encryptedKeySz > MAX_ENCRYPTED_KEY_SZ) {
wolfSSL 16:8e0d178b1d1e 8152 return BUFFER_E;
wolfSSL 16:8e0d178b1d1e 8153 }
wolfSSL 16:8e0d178b1d1e 8154
wolfSSL 16:8e0d178b1d1e 8155 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 8156 if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 8157 break;
wolfSSL 16:8e0d178b1d1e 8158 }
wolfSSL 16:8e0d178b1d1e 8159 wc_PKCS7_StreamStoreVar(pkcs7, encryptedKeySz, sidType, version);
wolfSSL 16:8e0d178b1d1e 8160 pkcs7->stream->expected = encryptedKeySz;
wolfSSL 16:8e0d178b1d1e 8161 #endif
wolfSSL 16:8e0d178b1d1e 8162 wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_DECRYPT_KTRI_3);
wolfSSL 16:8e0d178b1d1e 8163 FALL_THROUGH;
wolfSSL 16:8e0d178b1d1e 8164
wolfSSL 16:8e0d178b1d1e 8165 case WC_PKCS7_DECRYPT_KTRI_3:
wolfSSL 16:8e0d178b1d1e 8166 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 8167 if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
wolfSSL 16:8e0d178b1d1e 8168 pkcs7->stream->expected, &pkiMsg, idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 8169 return ret;
wolfSSL 16:8e0d178b1d1e 8170 }
wolfSSL 16:8e0d178b1d1e 8171 encryptedKeySz = pkcs7->stream->expected;
wolfSSL 16:8e0d178b1d1e 8172 #endif
wolfSSL 16:8e0d178b1d1e 8173
wolfSSL 16:8e0d178b1d1e 8174 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 8175 encryptedKey = (byte*)XMALLOC(encryptedKeySz, pkcs7->heap,
wolfSSL 16:8e0d178b1d1e 8176 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 8177 if (encryptedKey == NULL)
wolfSSL 16:8e0d178b1d1e 8178 return MEMORY_E;
wolfSSL 16:8e0d178b1d1e 8179 #endif
wolfSSL 16:8e0d178b1d1e 8180
wolfSSL 16:8e0d178b1d1e 8181 if (*recipFound == 1)
wolfSSL 16:8e0d178b1d1e 8182 XMEMCPY(encryptedKey, &pkiMsg[*idx], encryptedKeySz);
wolfSSL 16:8e0d178b1d1e 8183 *idx += encryptedKeySz;
wolfSSL 16:8e0d178b1d1e 8184
wolfSSL 16:8e0d178b1d1e 8185 /* load private key */
wolfSSL 16:8e0d178b1d1e 8186 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 8187 privKey = (RsaKey*)XMALLOC(sizeof(RsaKey), pkcs7->heap,
wolfSSL 16:8e0d178b1d1e 8188 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 8189 if (privKey == NULL) {
wolfSSL 16:8e0d178b1d1e 8190 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 8191 return MEMORY_E;
wolfSSL 16:8e0d178b1d1e 8192 }
wolfSSL 16:8e0d178b1d1e 8193 #endif
wolfSSL 16:8e0d178b1d1e 8194
wolfSSL 16:8e0d178b1d1e 8195 ret = wc_InitRsaKey_ex(privKey, pkcs7->heap, INVALID_DEVID);
wolfSSL 16:8e0d178b1d1e 8196 if (ret != 0) {
wolfSSL 16:8e0d178b1d1e 8197 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 8198 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 8199 XFREE(privKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 8200 #endif
wolfSSL 16:8e0d178b1d1e 8201 return ret;
wolfSSL 16:8e0d178b1d1e 8202 }
wolfSSL 16:8e0d178b1d1e 8203
wolfSSL 16:8e0d178b1d1e 8204 if (pkcs7->privateKey != NULL && pkcs7->privateKeySz > 0) {
wolfSSL 16:8e0d178b1d1e 8205 keyIdx = 0;
wolfSSL 16:8e0d178b1d1e 8206 ret = wc_RsaPrivateKeyDecode(pkcs7->privateKey, &keyIdx,
wolfSSL 16:8e0d178b1d1e 8207 privKey, pkcs7->privateKeySz);
wolfSSL 16:8e0d178b1d1e 8208 }
wolfSSL 16:8e0d178b1d1e 8209 else if (pkcs7->devId == INVALID_DEVID) {
wolfSSL 16:8e0d178b1d1e 8210 ret = BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 8211 }
wolfSSL 16:8e0d178b1d1e 8212 if (ret != 0) {
wolfSSL 16:8e0d178b1d1e 8213 WOLFSSL_MSG("Failed to decode RSA private key");
wolfSSL 16:8e0d178b1d1e 8214 wc_FreeRsaKey(privKey);
wolfSSL 16:8e0d178b1d1e 8215 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 8216 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 8217 XFREE(privKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 8218 #endif
wolfSSL 16:8e0d178b1d1e 8219 return ret;
wolfSSL 16:8e0d178b1d1e 8220 }
wolfSSL 16:8e0d178b1d1e 8221
wolfSSL 16:8e0d178b1d1e 8222 /* decrypt encryptedKey */
wolfSSL 16:8e0d178b1d1e 8223 #ifdef WC_RSA_BLINDING
wolfSSL 16:8e0d178b1d1e 8224 ret = wc_InitRng_ex(&rng, pkcs7->heap, pkcs7->devId);
wolfSSL 16:8e0d178b1d1e 8225 if (ret == 0) {
wolfSSL 16:8e0d178b1d1e 8226 ret = wc_RsaSetRNG(privKey, &rng);
wolfSSL 16:8e0d178b1d1e 8227 }
wolfSSL 16:8e0d178b1d1e 8228 #endif
wolfSSL 16:8e0d178b1d1e 8229 if (ret == 0) {
wolfSSL 16:8e0d178b1d1e 8230 keySz = wc_RsaPrivateDecryptInline(encryptedKey, encryptedKeySz,
wolfSSL 16:8e0d178b1d1e 8231 &outKey, privKey);
wolfSSL 16:8e0d178b1d1e 8232 #ifdef WC_RSA_BLINDING
wolfSSL 16:8e0d178b1d1e 8233 wc_FreeRng(&rng);
wolfSSL 16:8e0d178b1d1e 8234 #endif
wolfSSL 16:8e0d178b1d1e 8235 } else {
wolfSSL 16:8e0d178b1d1e 8236 keySz = ret;
wolfSSL 16:8e0d178b1d1e 8237 }
wolfSSL 16:8e0d178b1d1e 8238 wc_FreeRsaKey(privKey);
wolfSSL 16:8e0d178b1d1e 8239
wolfSSL 16:8e0d178b1d1e 8240 if (keySz <= 0 || outKey == NULL) {
wolfSSL 16:8e0d178b1d1e 8241 ForceZero(encryptedKey, encryptedKeySz);
wolfSSL 16:8e0d178b1d1e 8242 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 8243 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 8244 XFREE(privKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 8245 #endif
wolfSSL 16:8e0d178b1d1e 8246 return keySz;
wolfSSL 16:8e0d178b1d1e 8247 } else {
wolfSSL 16:8e0d178b1d1e 8248 *decryptedKeySz = keySz;
wolfSSL 16:8e0d178b1d1e 8249 XMEMCPY(decryptedKey, outKey, keySz);
wolfSSL 16:8e0d178b1d1e 8250 ForceZero(encryptedKey, encryptedKeySz);
wolfSSL 16:8e0d178b1d1e 8251 }
wolfSSL 16:8e0d178b1d1e 8252
wolfSSL 16:8e0d178b1d1e 8253 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 8254 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 8255 XFREE(privKey, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 8256 #endif
wolfSSL 16:8e0d178b1d1e 8257
wolfSSL 16:8e0d178b1d1e 8258 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 8259 if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 8260 break;
wolfSSL 16:8e0d178b1d1e 8261 }
wolfSSL 16:8e0d178b1d1e 8262 #endif
wolfSSL 16:8e0d178b1d1e 8263 ret = 0; /* success */
wolfSSL 16:8e0d178b1d1e 8264 break;
wolfSSL 16:8e0d178b1d1e 8265
wolfSSL 16:8e0d178b1d1e 8266 default:
wolfSSL 16:8e0d178b1d1e 8267 WOLFSSL_MSG("PKCS7 Unknown KTRI decrypt state");
wolfSSL 16:8e0d178b1d1e 8268 ret = BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 8269 }
wolfSSL 16:8e0d178b1d1e 8270
wolfSSL 16:8e0d178b1d1e 8271 return ret;
wolfSSL 15:117db924cf7c 8272 }
wolfSSL 15:117db924cf7c 8273 #endif /* !NO_RSA */
wolfSSL 15:117db924cf7c 8274
wolfSSL 15:117db924cf7c 8275 #ifdef HAVE_ECC
wolfSSL 15:117db924cf7c 8276
wolfSSL 15:117db924cf7c 8277 /* remove ASN.1 OriginatorIdentifierOrKey, return 0 on success, <0 on error */
wolfSSL 15:117db924cf7c 8278 static int wc_PKCS7_KariGetOriginatorIdentifierOrKey(WC_PKCS7_KARI* kari,
wolfSSL 15:117db924cf7c 8279 byte* pkiMsg, word32 pkiMsgSz, word32* idx)
wolfSSL 15:117db924cf7c 8280 {
wolfSSL 15:117db924cf7c 8281 int ret, length;
wolfSSL 16:8e0d178b1d1e 8282 word32 keyOID, oidSum = 0;
wolfSSL 16:8e0d178b1d1e 8283 int curve_id = ECC_CURVE_DEF;
wolfSSL 16:8e0d178b1d1e 8284 byte tag;
wolfSSL 15:117db924cf7c 8285
wolfSSL 15:117db924cf7c 8286 if (kari == NULL || pkiMsg == NULL || idx == NULL)
wolfSSL 15:117db924cf7c 8287 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 8288
wolfSSL 15:117db924cf7c 8289 /* remove OriginatorIdentifierOrKey */
wolfSSL 16:8e0d178b1d1e 8290 if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) == 0 &&
wolfSSL 16:8e0d178b1d1e 8291 tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) {
wolfSSL 15:117db924cf7c 8292 if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 8293 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 8294
wolfSSL 15:117db924cf7c 8295 } else {
wolfSSL 15:117db924cf7c 8296 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 8297 }
wolfSSL 15:117db924cf7c 8298
wolfSSL 15:117db924cf7c 8299 /* remove OriginatorPublicKey */
wolfSSL 16:8e0d178b1d1e 8300 if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) == 0 &&
wolfSSL 16:8e0d178b1d1e 8301 tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) {
wolfSSL 15:117db924cf7c 8302 if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 8303 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 8304
wolfSSL 15:117db924cf7c 8305 } else {
wolfSSL 15:117db924cf7c 8306 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 8307 }
wolfSSL 15:117db924cf7c 8308
wolfSSL 15:117db924cf7c 8309 /* remove AlgorithmIdentifier */
wolfSSL 15:117db924cf7c 8310 if (GetAlgoId(pkiMsg, idx, &keyOID, oidKeyType, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 8311 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 8312
wolfSSL 15:117db924cf7c 8313 if (keyOID != ECDSAk)
wolfSSL 15:117db924cf7c 8314 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 8315
wolfSSL 16:8e0d178b1d1e 8316 /* optional algorithm parameters */
wolfSSL 16:8e0d178b1d1e 8317 ret = GetObjectId(pkiMsg, idx, &oidSum, oidIgnoreType, pkiMsgSz);
wolfSSL 16:8e0d178b1d1e 8318 if (ret == 0) {
wolfSSL 16:8e0d178b1d1e 8319 /* get curve id */
wolfSSL 16:8e0d178b1d1e 8320 curve_id = wc_ecc_get_oid(oidSum, NULL, 0);
wolfSSL 16:8e0d178b1d1e 8321 if (curve_id < 0)
wolfSSL 16:8e0d178b1d1e 8322 return ECC_CURVE_OID_E;
wolfSSL 16:8e0d178b1d1e 8323 }
wolfSSL 16:8e0d178b1d1e 8324
wolfSSL 15:117db924cf7c 8325 /* remove ECPoint BIT STRING */
wolfSSL 16:8e0d178b1d1e 8326 if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0)
wolfSSL 16:8e0d178b1d1e 8327 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 8328
wolfSSL 16:8e0d178b1d1e 8329 if (tag != ASN_BIT_STRING)
wolfSSL 15:117db924cf7c 8330 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 8331
wolfSSL 15:117db924cf7c 8332 if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 8333 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 8334
wolfSSL 16:8e0d178b1d1e 8335 if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0)
wolfSSL 16:8e0d178b1d1e 8336 return ASN_EXPECT_0_E;
wolfSSL 16:8e0d178b1d1e 8337
wolfSSL 16:8e0d178b1d1e 8338 if (tag != ASN_OTHER_TYPE)
wolfSSL 15:117db924cf7c 8339 return ASN_EXPECT_0_E;
wolfSSL 15:117db924cf7c 8340
wolfSSL 15:117db924cf7c 8341 /* get sender ephemeral public ECDSA key */
wolfSSL 15:117db924cf7c 8342 ret = wc_ecc_init_ex(kari->senderKey, kari->heap, kari->devId);
wolfSSL 15:117db924cf7c 8343 if (ret != 0)
wolfSSL 15:117db924cf7c 8344 return ret;
wolfSSL 15:117db924cf7c 8345
wolfSSL 15:117db924cf7c 8346 kari->senderKeyInit = 1;
wolfSSL 15:117db924cf7c 8347
wolfSSL 15:117db924cf7c 8348 /* length-1 for unused bits counter */
wolfSSL 16:8e0d178b1d1e 8349 ret = wc_ecc_import_x963_ex(pkiMsg + (*idx), length - 1, kari->senderKey,
wolfSSL 16:8e0d178b1d1e 8350 curve_id);
wolfSSL 16:8e0d178b1d1e 8351 if (ret != 0) {
wolfSSL 16:8e0d178b1d1e 8352 ret = wc_EccPublicKeyDecode(pkiMsg, idx, kari->senderKey, *idx + length - 1);
wolfSSL 16:8e0d178b1d1e 8353 if (ret != 0)
wolfSSL 16:8e0d178b1d1e 8354 return ret;
wolfSSL 16:8e0d178b1d1e 8355 }
wolfSSL 16:8e0d178b1d1e 8356 else {
wolfSSL 16:8e0d178b1d1e 8357 (*idx) += length - 1;
wolfSSL 16:8e0d178b1d1e 8358 }
wolfSSL 15:117db924cf7c 8359
wolfSSL 15:117db924cf7c 8360 return 0;
wolfSSL 15:117db924cf7c 8361 }
wolfSSL 15:117db924cf7c 8362
wolfSSL 15:117db924cf7c 8363
wolfSSL 15:117db924cf7c 8364 /* remove optional UserKeyingMaterial if available, return 0 on success,
wolfSSL 15:117db924cf7c 8365 * < 0 on error */
wolfSSL 15:117db924cf7c 8366 static int wc_PKCS7_KariGetUserKeyingMaterial(WC_PKCS7_KARI* kari,
wolfSSL 15:117db924cf7c 8367 byte* pkiMsg, word32 pkiMsgSz, word32* idx)
wolfSSL 15:117db924cf7c 8368 {
wolfSSL 15:117db924cf7c 8369 int length;
wolfSSL 15:117db924cf7c 8370 word32 savedIdx;
wolfSSL 16:8e0d178b1d1e 8371 byte tag;
wolfSSL 15:117db924cf7c 8372
wolfSSL 15:117db924cf7c 8373 if (kari == NULL || pkiMsg == NULL || idx == NULL)
wolfSSL 15:117db924cf7c 8374 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 8375
wolfSSL 15:117db924cf7c 8376 savedIdx = *idx;
wolfSSL 15:117db924cf7c 8377
wolfSSL 15:117db924cf7c 8378 /* starts with EXPLICIT [1] */
wolfSSL 16:8e0d178b1d1e 8379 if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0) {
wolfSSL 16:8e0d178b1d1e 8380 *idx = savedIdx;
wolfSSL 16:8e0d178b1d1e 8381 return 0;
wolfSSL 16:8e0d178b1d1e 8382 }
wolfSSL 16:8e0d178b1d1e 8383 if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) {
wolfSSL 15:117db924cf7c 8384 *idx = savedIdx;
wolfSSL 15:117db924cf7c 8385 return 0;
wolfSSL 15:117db924cf7c 8386 }
wolfSSL 15:117db924cf7c 8387
wolfSSL 15:117db924cf7c 8388 if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0) {
wolfSSL 15:117db924cf7c 8389 *idx = savedIdx;
wolfSSL 15:117db924cf7c 8390 return 0;
wolfSSL 15:117db924cf7c 8391 }
wolfSSL 15:117db924cf7c 8392
wolfSSL 15:117db924cf7c 8393 /* get OCTET STRING */
wolfSSL 16:8e0d178b1d1e 8394 if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0) {
wolfSSL 16:8e0d178b1d1e 8395 *idx = savedIdx;
wolfSSL 16:8e0d178b1d1e 8396 return 0;
wolfSSL 16:8e0d178b1d1e 8397 }
wolfSSL 16:8e0d178b1d1e 8398 if (tag != ASN_OCTET_STRING) {
wolfSSL 15:117db924cf7c 8399 *idx = savedIdx;
wolfSSL 15:117db924cf7c 8400 return 0;
wolfSSL 15:117db924cf7c 8401 }
wolfSSL 15:117db924cf7c 8402
wolfSSL 15:117db924cf7c 8403 if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0) {
wolfSSL 15:117db924cf7c 8404 *idx = savedIdx;
wolfSSL 15:117db924cf7c 8405 return 0;
wolfSSL 15:117db924cf7c 8406 }
wolfSSL 15:117db924cf7c 8407
wolfSSL 15:117db924cf7c 8408 kari->ukm = NULL;
wolfSSL 15:117db924cf7c 8409 if (length > 0) {
wolfSSL 15:117db924cf7c 8410 kari->ukm = (byte*)XMALLOC(length, kari->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 8411 if (kari->ukm == NULL)
wolfSSL 15:117db924cf7c 8412 return MEMORY_E;
wolfSSL 15:117db924cf7c 8413
wolfSSL 15:117db924cf7c 8414 XMEMCPY(kari->ukm, pkiMsg + (*idx), length);
wolfSSL 15:117db924cf7c 8415 kari->ukmOwner = 1;
wolfSSL 15:117db924cf7c 8416 }
wolfSSL 15:117db924cf7c 8417
wolfSSL 15:117db924cf7c 8418 (*idx) += length;
wolfSSL 15:117db924cf7c 8419 kari->ukmSz = length;
wolfSSL 15:117db924cf7c 8420
wolfSSL 15:117db924cf7c 8421 return 0;
wolfSSL 15:117db924cf7c 8422 }
wolfSSL 15:117db924cf7c 8423
wolfSSL 15:117db924cf7c 8424
wolfSSL 15:117db924cf7c 8425 /* remove ASN.1 KeyEncryptionAlgorithmIdentifier, return 0 on success,
wolfSSL 15:117db924cf7c 8426 * < 0 on error */
wolfSSL 15:117db924cf7c 8427 static int wc_PKCS7_KariGetKeyEncryptionAlgorithmId(WC_PKCS7_KARI* kari,
wolfSSL 16:8e0d178b1d1e 8428 byte* pkiMsg, word32 pkiMsgSz, word32* idx,
wolfSSL 16:8e0d178b1d1e 8429 word32* keyAgreeOID, word32* keyWrapOID)
wolfSSL 16:8e0d178b1d1e 8430 {
wolfSSL 16:8e0d178b1d1e 8431 int length = 0;
wolfSSL 16:8e0d178b1d1e 8432 word32 localIdx;
wolfSSL 16:8e0d178b1d1e 8433
wolfSSL 15:117db924cf7c 8434 if (kari == NULL || pkiMsg == NULL || idx == NULL ||
wolfSSL 15:117db924cf7c 8435 keyAgreeOID == NULL || keyWrapOID == NULL)
wolfSSL 15:117db924cf7c 8436 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 8437
wolfSSL 16:8e0d178b1d1e 8438 localIdx = *idx;
wolfSSL 16:8e0d178b1d1e 8439
wolfSSL 15:117db924cf7c 8440 /* remove KeyEncryptionAlgorithmIdentifier */
wolfSSL 16:8e0d178b1d1e 8441 if (GetSequence(pkiMsg, &localIdx, &length, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 8442 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 8443
wolfSSL 16:8e0d178b1d1e 8444 localIdx = *idx;
wolfSSL 16:8e0d178b1d1e 8445 if (GetAlgoId(pkiMsg, &localIdx, keyAgreeOID, oidCmsKeyAgreeType,
wolfSSL 16:8e0d178b1d1e 8446 pkiMsgSz) < 0) {
wolfSSL 16:8e0d178b1d1e 8447 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 8448 }
wolfSSL 16:8e0d178b1d1e 8449
wolfSSL 16:8e0d178b1d1e 8450 if (localIdx < *idx + length) {
wolfSSL 16:8e0d178b1d1e 8451 *idx = localIdx;
wolfSSL 16:8e0d178b1d1e 8452 }
wolfSSL 15:117db924cf7c 8453 /* remove KeyWrapAlgorithm, stored in parameter of KeyEncAlgoId */
wolfSSL 15:117db924cf7c 8454 if (GetAlgoId(pkiMsg, idx, keyWrapOID, oidKeyWrapType, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 8455 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 8456
wolfSSL 15:117db924cf7c 8457 return 0;
wolfSSL 15:117db924cf7c 8458 }
wolfSSL 15:117db924cf7c 8459
wolfSSL 15:117db924cf7c 8460
wolfSSL 15:117db924cf7c 8461 /* remove ASN.1 SubjectKeyIdentifier, return 0 on success, < 0 on error
wolfSSL 15:117db924cf7c 8462 * if subject key ID matches, recipFound is set to 1 */
wolfSSL 15:117db924cf7c 8463 static int wc_PKCS7_KariGetSubjectKeyIdentifier(WC_PKCS7_KARI* kari,
wolfSSL 15:117db924cf7c 8464 byte* pkiMsg, word32 pkiMsgSz, word32* idx,
wolfSSL 16:8e0d178b1d1e 8465 int* recipFound, byte* rid)
wolfSSL 15:117db924cf7c 8466 {
wolfSSL 15:117db924cf7c 8467 int length;
wolfSSL 16:8e0d178b1d1e 8468 byte tag;
wolfSSL 16:8e0d178b1d1e 8469
wolfSSL 16:8e0d178b1d1e 8470 if (kari == NULL || pkiMsg == NULL || idx == NULL || recipFound == NULL ||
wolfSSL 16:8e0d178b1d1e 8471 rid == NULL)
wolfSSL 15:117db924cf7c 8472 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 8473
wolfSSL 15:117db924cf7c 8474 /* remove RecipientKeyIdentifier IMPLICIT [0] */
wolfSSL 16:8e0d178b1d1e 8475 if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0) {
wolfSSL 16:8e0d178b1d1e 8476 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 8477 }
wolfSSL 16:8e0d178b1d1e 8478
wolfSSL 16:8e0d178b1d1e 8479 if (tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) {
wolfSSL 15:117db924cf7c 8480 if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 8481 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 8482
wolfSSL 15:117db924cf7c 8483 } else {
wolfSSL 15:117db924cf7c 8484 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 8485 }
wolfSSL 15:117db924cf7c 8486
wolfSSL 15:117db924cf7c 8487 /* remove SubjectKeyIdentifier */
wolfSSL 16:8e0d178b1d1e 8488 if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0) {
wolfSSL 16:8e0d178b1d1e 8489 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 8490 }
wolfSSL 16:8e0d178b1d1e 8491
wolfSSL 16:8e0d178b1d1e 8492 if (tag != ASN_OCTET_STRING)
wolfSSL 15:117db924cf7c 8493 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 8494
wolfSSL 15:117db924cf7c 8495 if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 8496 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 8497
wolfSSL 15:117db924cf7c 8498 if (length != KEYID_SIZE)
wolfSSL 15:117db924cf7c 8499 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 8500
wolfSSL 16:8e0d178b1d1e 8501 XMEMCPY(rid, pkiMsg + (*idx), KEYID_SIZE);
wolfSSL 15:117db924cf7c 8502 (*idx) += length;
wolfSSL 15:117db924cf7c 8503
wolfSSL 15:117db924cf7c 8504 /* subject key id should match if recipient found */
wolfSSL 16:8e0d178b1d1e 8505 if (XMEMCMP(rid, kari->decoded->extSubjKeyId, KEYID_SIZE) == 0) {
wolfSSL 15:117db924cf7c 8506 *recipFound = 1;
wolfSSL 15:117db924cf7c 8507 }
wolfSSL 15:117db924cf7c 8508
wolfSSL 15:117db924cf7c 8509 return 0;
wolfSSL 15:117db924cf7c 8510 }
wolfSSL 15:117db924cf7c 8511
wolfSSL 15:117db924cf7c 8512
wolfSSL 15:117db924cf7c 8513 /* remove ASN.1 IssuerAndSerialNumber, return 0 on success, < 0 on error
wolfSSL 15:117db924cf7c 8514 * if issuer and serial number match, recipFound is set to 1 */
wolfSSL 15:117db924cf7c 8515 static int wc_PKCS7_KariGetIssuerAndSerialNumber(WC_PKCS7_KARI* kari,
wolfSSL 15:117db924cf7c 8516 byte* pkiMsg, word32 pkiMsgSz, word32* idx,
wolfSSL 16:8e0d178b1d1e 8517 int* recipFound, byte* rid)
wolfSSL 15:117db924cf7c 8518 {
wolfSSL 15:117db924cf7c 8519 int length, ret;
wolfSSL 15:117db924cf7c 8520 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 8521 mp_int* serial;
wolfSSL 15:117db924cf7c 8522 mp_int* recipSerial;
wolfSSL 15:117db924cf7c 8523 #else
wolfSSL 16:8e0d178b1d1e 8524 mp_int serial[1];
wolfSSL 16:8e0d178b1d1e 8525 mp_int recipSerial[1];
wolfSSL 16:8e0d178b1d1e 8526 #endif
wolfSSL 16:8e0d178b1d1e 8527
wolfSSL 16:8e0d178b1d1e 8528 if (rid == NULL) {
wolfSSL 16:8e0d178b1d1e 8529 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 8530 }
wolfSSL 15:117db924cf7c 8531
wolfSSL 15:117db924cf7c 8532 /* remove IssuerAndSerialNumber */
wolfSSL 15:117db924cf7c 8533 if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 8534 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 8535
wolfSSL 16:8e0d178b1d1e 8536 if (GetNameHash(pkiMsg, idx, rid, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 8537 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 8538
wolfSSL 15:117db924cf7c 8539 /* if we found correct recipient, issuer hashes will match */
wolfSSL 16:8e0d178b1d1e 8540 if (XMEMCMP(rid, kari->decoded->issuerHash, KEYID_SIZE) == 0) {
wolfSSL 15:117db924cf7c 8541 *recipFound = 1;
wolfSSL 15:117db924cf7c 8542 }
wolfSSL 15:117db924cf7c 8543
wolfSSL 15:117db924cf7c 8544 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 8545 serial = (mp_int*)XMALLOC(sizeof(mp_int), kari->heap,
wolfSSL 15:117db924cf7c 8546 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 8547 if (serial == NULL)
wolfSSL 15:117db924cf7c 8548 return MEMORY_E;
wolfSSL 15:117db924cf7c 8549
wolfSSL 15:117db924cf7c 8550 recipSerial = (mp_int*)XMALLOC(sizeof(mp_int), kari->heap,
wolfSSL 15:117db924cf7c 8551 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 8552 if (recipSerial == NULL) {
wolfSSL 15:117db924cf7c 8553 XFREE(serial, kari->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 8554 return MEMORY_E;
wolfSSL 15:117db924cf7c 8555 }
wolfSSL 15:117db924cf7c 8556 #endif
wolfSSL 15:117db924cf7c 8557
wolfSSL 15:117db924cf7c 8558 if (GetInt(serial, pkiMsg, idx, pkiMsgSz) < 0) {
wolfSSL 15:117db924cf7c 8559 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 8560 XFREE(serial, kari->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 8561 XFREE(recipSerial, kari->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 8562 #endif
wolfSSL 15:117db924cf7c 8563 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 8564 }
wolfSSL 15:117db924cf7c 8565
wolfSSL 15:117db924cf7c 8566 ret = mp_read_unsigned_bin(recipSerial, kari->decoded->serial,
wolfSSL 15:117db924cf7c 8567 kari->decoded->serialSz);
wolfSSL 15:117db924cf7c 8568 if (ret != MP_OKAY) {
wolfSSL 15:117db924cf7c 8569 mp_clear(serial);
wolfSSL 15:117db924cf7c 8570 WOLFSSL_MSG("Failed to parse CMS recipient serial number");
wolfSSL 15:117db924cf7c 8571 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 8572 XFREE(serial, kari->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 8573 XFREE(recipSerial, kari->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 8574 #endif
wolfSSL 15:117db924cf7c 8575 return ret;
wolfSSL 15:117db924cf7c 8576 }
wolfSSL 15:117db924cf7c 8577
wolfSSL 15:117db924cf7c 8578 if (mp_cmp(recipSerial, serial) != MP_EQ) {
wolfSSL 15:117db924cf7c 8579 mp_clear(serial);
wolfSSL 15:117db924cf7c 8580 mp_clear(recipSerial);
wolfSSL 15:117db924cf7c 8581 WOLFSSL_MSG("CMS serial number does not match recipient");
wolfSSL 15:117db924cf7c 8582 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 8583 XFREE(serial, kari->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 8584 XFREE(recipSerial, kari->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 8585 #endif
wolfSSL 15:117db924cf7c 8586 return PKCS7_RECIP_E;
wolfSSL 15:117db924cf7c 8587 }
wolfSSL 15:117db924cf7c 8588
wolfSSL 15:117db924cf7c 8589 mp_clear(serial);
wolfSSL 15:117db924cf7c 8590 mp_clear(recipSerial);
wolfSSL 15:117db924cf7c 8591
wolfSSL 15:117db924cf7c 8592 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 8593 XFREE(serial, kari->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 8594 XFREE(recipSerial, kari->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 8595 #endif
wolfSSL 15:117db924cf7c 8596
wolfSSL 15:117db924cf7c 8597 return 0;
wolfSSL 15:117db924cf7c 8598 }
wolfSSL 15:117db924cf7c 8599
wolfSSL 15:117db924cf7c 8600
wolfSSL 15:117db924cf7c 8601 /* remove ASN.1 RecipientEncryptedKeys, return 0 on success, < 0 on error */
wolfSSL 15:117db924cf7c 8602 static int wc_PKCS7_KariGetRecipientEncryptedKeys(WC_PKCS7_KARI* kari,
wolfSSL 15:117db924cf7c 8603 byte* pkiMsg, word32 pkiMsgSz, word32* idx,
wolfSSL 15:117db924cf7c 8604 int* recipFound, byte* encryptedKey,
wolfSSL 16:8e0d178b1d1e 8605 int* encryptedKeySz, byte* rid)
wolfSSL 15:117db924cf7c 8606 {
wolfSSL 15:117db924cf7c 8607 int length;
wolfSSL 15:117db924cf7c 8608 int ret = 0;
wolfSSL 16:8e0d178b1d1e 8609 byte tag;
wolfSSL 16:8e0d178b1d1e 8610 word32 localIdx;
wolfSSL 15:117db924cf7c 8611
wolfSSL 15:117db924cf7c 8612 if (kari == NULL || pkiMsg == NULL || idx == NULL ||
wolfSSL 15:117db924cf7c 8613 recipFound == NULL || encryptedKey == NULL)
wolfSSL 15:117db924cf7c 8614 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 8615
wolfSSL 15:117db924cf7c 8616 /* remove RecipientEncryptedKeys */
wolfSSL 15:117db924cf7c 8617 if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 8618 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 8619
wolfSSL 15:117db924cf7c 8620 /* remove RecipientEncryptedKeys */
wolfSSL 15:117db924cf7c 8621 if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 8622 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 8623
wolfSSL 15:117db924cf7c 8624 /* KeyAgreeRecipientIdentifier is CHOICE of IssuerAndSerialNumber
wolfSSL 15:117db924cf7c 8625 * or [0] IMMPLICIT RecipientKeyIdentifier */
wolfSSL 16:8e0d178b1d1e 8626 localIdx = *idx;
wolfSSL 16:8e0d178b1d1e 8627 if (GetASNTag(pkiMsg, &localIdx, &tag, pkiMsgSz) < 0)
wolfSSL 16:8e0d178b1d1e 8628 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 8629
wolfSSL 16:8e0d178b1d1e 8630 if (tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) {
wolfSSL 15:117db924cf7c 8631 /* try to get RecipientKeyIdentifier */
wolfSSL 15:117db924cf7c 8632 ret = wc_PKCS7_KariGetSubjectKeyIdentifier(kari, pkiMsg, pkiMsgSz,
wolfSSL 16:8e0d178b1d1e 8633 idx, recipFound, rid);
wolfSSL 15:117db924cf7c 8634 } else {
wolfSSL 15:117db924cf7c 8635 /* try to get IssuerAndSerialNumber */
wolfSSL 15:117db924cf7c 8636 ret = wc_PKCS7_KariGetIssuerAndSerialNumber(kari, pkiMsg, pkiMsgSz,
wolfSSL 16:8e0d178b1d1e 8637 idx, recipFound, rid);
wolfSSL 15:117db924cf7c 8638 }
wolfSSL 15:117db924cf7c 8639
wolfSSL 15:117db924cf7c 8640 /* if we don't have either option, malformed CMS */
wolfSSL 15:117db924cf7c 8641 if (ret != 0)
wolfSSL 15:117db924cf7c 8642 return ret;
wolfSSL 15:117db924cf7c 8643
wolfSSL 15:117db924cf7c 8644 /* remove EncryptedKey */
wolfSSL 16:8e0d178b1d1e 8645 if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0)
wolfSSL 16:8e0d178b1d1e 8646 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 8647
wolfSSL 16:8e0d178b1d1e 8648 if (tag != ASN_OCTET_STRING)
wolfSSL 15:117db924cf7c 8649 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 8650
wolfSSL 15:117db924cf7c 8651 if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 8652 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 8653
wolfSSL 15:117db924cf7c 8654 /* put encrypted CEK in decryptedKey buffer for now, decrypt later */
wolfSSL 15:117db924cf7c 8655 if (length > *encryptedKeySz)
wolfSSL 15:117db924cf7c 8656 return BUFFER_E;
wolfSSL 15:117db924cf7c 8657
wolfSSL 15:117db924cf7c 8658 XMEMCPY(encryptedKey, pkiMsg + (*idx), length);
wolfSSL 15:117db924cf7c 8659 *encryptedKeySz = length;
wolfSSL 15:117db924cf7c 8660 (*idx) += length;
wolfSSL 15:117db924cf7c 8661
wolfSSL 15:117db924cf7c 8662 return 0;
wolfSSL 15:117db924cf7c 8663 }
wolfSSL 15:117db924cf7c 8664
wolfSSL 15:117db924cf7c 8665 #endif /* HAVE_ECC */
wolfSSL 15:117db924cf7c 8666
wolfSSL 15:117db924cf7c 8667
wolfSSL 16:8e0d178b1d1e 8668 int wc_PKCS7_SetOriEncryptCtx(PKCS7* pkcs7, void* ctx)
wolfSSL 16:8e0d178b1d1e 8669 {
wolfSSL 16:8e0d178b1d1e 8670 if (pkcs7 == NULL)
wolfSSL 16:8e0d178b1d1e 8671 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 8672
wolfSSL 16:8e0d178b1d1e 8673 pkcs7->oriEncryptCtx = ctx;
wolfSSL 16:8e0d178b1d1e 8674
wolfSSL 16:8e0d178b1d1e 8675 return 0;
wolfSSL 16:8e0d178b1d1e 8676 }
wolfSSL 16:8e0d178b1d1e 8677
wolfSSL 16:8e0d178b1d1e 8678
wolfSSL 16:8e0d178b1d1e 8679 int wc_PKCS7_SetOriDecryptCtx(PKCS7* pkcs7, void* ctx)
wolfSSL 16:8e0d178b1d1e 8680 {
wolfSSL 16:8e0d178b1d1e 8681
wolfSSL 16:8e0d178b1d1e 8682 if (pkcs7 == NULL)
wolfSSL 16:8e0d178b1d1e 8683 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 8684
wolfSSL 16:8e0d178b1d1e 8685 pkcs7->oriDecryptCtx = ctx;
wolfSSL 16:8e0d178b1d1e 8686
wolfSSL 16:8e0d178b1d1e 8687 return 0;
wolfSSL 16:8e0d178b1d1e 8688 }
wolfSSL 16:8e0d178b1d1e 8689
wolfSSL 16:8e0d178b1d1e 8690
wolfSSL 16:8e0d178b1d1e 8691 int wc_PKCS7_SetOriDecryptCb(PKCS7* pkcs7, CallbackOriDecrypt cb)
wolfSSL 16:8e0d178b1d1e 8692 {
wolfSSL 16:8e0d178b1d1e 8693 if (pkcs7 == NULL)
wolfSSL 16:8e0d178b1d1e 8694 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 8695
wolfSSL 16:8e0d178b1d1e 8696 pkcs7->oriDecryptCb = cb;
wolfSSL 16:8e0d178b1d1e 8697
wolfSSL 16:8e0d178b1d1e 8698 return 0;
wolfSSL 16:8e0d178b1d1e 8699 }
wolfSSL 16:8e0d178b1d1e 8700
wolfSSL 16:8e0d178b1d1e 8701
wolfSSL 16:8e0d178b1d1e 8702 /* return 0 on success */
wolfSSL 16:8e0d178b1d1e 8703 int wc_PKCS7_SetWrapCEKCb(PKCS7* pkcs7, CallbackWrapCEK cb)
wolfSSL 16:8e0d178b1d1e 8704 {
wolfSSL 16:8e0d178b1d1e 8705 if (pkcs7 == NULL)
wolfSSL 16:8e0d178b1d1e 8706 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 8707
wolfSSL 16:8e0d178b1d1e 8708 pkcs7->wrapCEKCb = cb;
wolfSSL 16:8e0d178b1d1e 8709
wolfSSL 16:8e0d178b1d1e 8710 return 0;
wolfSSL 16:8e0d178b1d1e 8711 }
wolfSSL 16:8e0d178b1d1e 8712
wolfSSL 16:8e0d178b1d1e 8713 /* Decrypt ASN.1 OtherRecipientInfo (ori), as defined by:
wolfSSL 16:8e0d178b1d1e 8714 *
wolfSSL 16:8e0d178b1d1e 8715 * OtherRecipientInfo ::= SEQUENCE {
wolfSSL 16:8e0d178b1d1e 8716 * oriType OBJECT IDENTIFIER,
wolfSSL 16:8e0d178b1d1e 8717 * oriValue ANY DEFINED BY oriType }
wolfSSL 16:8e0d178b1d1e 8718 *
wolfSSL 16:8e0d178b1d1e 8719 * pkcs7 - pointer to initialized PKCS7 structure
wolfSSL 16:8e0d178b1d1e 8720 * pkiMsg - pointer to encoded CMS bundle
wolfSSL 16:8e0d178b1d1e 8721 * pkiMsgSz - size of pkiMsg, bytes
wolfSSL 16:8e0d178b1d1e 8722 * idx - [IN/OUT] pointer to index into pkiMsg
wolfSSL 16:8e0d178b1d1e 8723 * decryptedKey - [OUT] output buf for decrypted content encryption key
wolfSSL 16:8e0d178b1d1e 8724 * decryptedKeySz - [IN/OUT] size of buffer, size of decrypted key
wolfSSL 16:8e0d178b1d1e 8725 * recipFound - [OUT] 1 if recipient has been found, 0 if not
wolfSSL 16:8e0d178b1d1e 8726 *
wolfSSL 16:8e0d178b1d1e 8727 * Return 0 on success, negative upon error.
wolfSSL 16:8e0d178b1d1e 8728 */
wolfSSL 16:8e0d178b1d1e 8729 static int wc_PKCS7_DecryptOri(PKCS7* pkcs7, byte* in, word32 inSz,
wolfSSL 16:8e0d178b1d1e 8730 word32* idx, byte* decryptedKey,
wolfSSL 16:8e0d178b1d1e 8731 word32* decryptedKeySz, int* recipFound)
wolfSSL 16:8e0d178b1d1e 8732 {
wolfSSL 16:8e0d178b1d1e 8733 int ret, seqSz, oriOIDSz;
wolfSSL 16:8e0d178b1d1e 8734 word32 oriValueSz, tmpIdx;
wolfSSL 16:8e0d178b1d1e 8735 byte* oriValue;
wolfSSL 16:8e0d178b1d1e 8736 byte oriOID[MAX_OID_SZ];
wolfSSL 16:8e0d178b1d1e 8737
wolfSSL 16:8e0d178b1d1e 8738 byte* pkiMsg = in;
wolfSSL 16:8e0d178b1d1e 8739 word32 pkiMsgSz = inSz;
wolfSSL 16:8e0d178b1d1e 8740 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 8741 word32 stateIdx = *idx;
wolfSSL 16:8e0d178b1d1e 8742 long rc;
wolfSSL 16:8e0d178b1d1e 8743 #endif
wolfSSL 16:8e0d178b1d1e 8744
wolfSSL 16:8e0d178b1d1e 8745 if (pkcs7->oriDecryptCb == NULL) {
wolfSSL 16:8e0d178b1d1e 8746 WOLFSSL_MSG("You must register an ORI Decrypt callback");
wolfSSL 16:8e0d178b1d1e 8747 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 8748 }
wolfSSL 16:8e0d178b1d1e 8749
wolfSSL 16:8e0d178b1d1e 8750 switch (pkcs7->state) {
wolfSSL 16:8e0d178b1d1e 8751
wolfSSL 16:8e0d178b1d1e 8752 case WC_PKCS7_DECRYPT_ORI:
wolfSSL 16:8e0d178b1d1e 8753 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 8754 /* @TODO for now just get full buffer, needs divided up */
wolfSSL 16:8e0d178b1d1e 8755 if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
wolfSSL 16:8e0d178b1d1e 8756 (pkcs7->stream->maxLen - pkcs7->stream->totalRd) +
wolfSSL 16:8e0d178b1d1e 8757 pkcs7->stream->length, &pkiMsg, idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 8758 return ret;
wolfSSL 16:8e0d178b1d1e 8759 }
wolfSSL 16:8e0d178b1d1e 8760
wolfSSL 16:8e0d178b1d1e 8761 rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK, in,
wolfSSL 16:8e0d178b1d1e 8762 inSz);
wolfSSL 16:8e0d178b1d1e 8763 if (rc < 0) {
wolfSSL 16:8e0d178b1d1e 8764 ret = (int)rc;
wolfSSL 16:8e0d178b1d1e 8765 break;
wolfSSL 16:8e0d178b1d1e 8766 }
wolfSSL 16:8e0d178b1d1e 8767 pkiMsgSz = (word32)rc;
wolfSSL 16:8e0d178b1d1e 8768 #endif
wolfSSL 16:8e0d178b1d1e 8769 /* get OtherRecipientInfo sequence length */
wolfSSL 16:8e0d178b1d1e 8770 if (GetLength(pkiMsg, idx, &seqSz, pkiMsgSz) < 0)
wolfSSL 16:8e0d178b1d1e 8771 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 8772
wolfSSL 16:8e0d178b1d1e 8773 tmpIdx = *idx;
wolfSSL 16:8e0d178b1d1e 8774
wolfSSL 16:8e0d178b1d1e 8775 /* remove and store oriType OBJECT IDENTIFIER */
wolfSSL 16:8e0d178b1d1e 8776 if (GetASNObjectId(pkiMsg, idx, &oriOIDSz, pkiMsgSz) != 0)
wolfSSL 16:8e0d178b1d1e 8777 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 8778
wolfSSL 16:8e0d178b1d1e 8779 XMEMCPY(oriOID, pkiMsg + *idx, oriOIDSz);
wolfSSL 16:8e0d178b1d1e 8780 *idx += oriOIDSz;
wolfSSL 16:8e0d178b1d1e 8781
wolfSSL 16:8e0d178b1d1e 8782 /* get oriValue, increment idx */
wolfSSL 16:8e0d178b1d1e 8783 oriValue = pkiMsg + *idx;
wolfSSL 16:8e0d178b1d1e 8784 oriValueSz = seqSz - (*idx - tmpIdx);
wolfSSL 16:8e0d178b1d1e 8785 *idx += oriValueSz;
wolfSSL 16:8e0d178b1d1e 8786
wolfSSL 16:8e0d178b1d1e 8787 /* pass oriOID and oriValue to user callback, expect back
wolfSSL 16:8e0d178b1d1e 8788 decryptedKey and size */
wolfSSL 16:8e0d178b1d1e 8789 ret = pkcs7->oriDecryptCb(pkcs7, oriOID, (word32)oriOIDSz, oriValue,
wolfSSL 16:8e0d178b1d1e 8790 oriValueSz, decryptedKey, decryptedKeySz,
wolfSSL 16:8e0d178b1d1e 8791 pkcs7->oriDecryptCtx);
wolfSSL 16:8e0d178b1d1e 8792
wolfSSL 16:8e0d178b1d1e 8793 if (ret != 0 || decryptedKey == NULL || *decryptedKeySz == 0) {
wolfSSL 16:8e0d178b1d1e 8794 /* decrypt operation failed */
wolfSSL 16:8e0d178b1d1e 8795 *recipFound = 0;
wolfSSL 16:8e0d178b1d1e 8796 return PKCS7_RECIP_E;
wolfSSL 16:8e0d178b1d1e 8797 }
wolfSSL 16:8e0d178b1d1e 8798
wolfSSL 16:8e0d178b1d1e 8799 /* mark recipFound, since we only support one RecipientInfo for now */
wolfSSL 16:8e0d178b1d1e 8800 *recipFound = 1;
wolfSSL 16:8e0d178b1d1e 8801
wolfSSL 16:8e0d178b1d1e 8802 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 8803 if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &stateIdx, idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 8804 break;
wolfSSL 16:8e0d178b1d1e 8805 }
wolfSSL 16:8e0d178b1d1e 8806 #endif
wolfSSL 16:8e0d178b1d1e 8807 ret = 0; /* success */
wolfSSL 16:8e0d178b1d1e 8808 break;
wolfSSL 16:8e0d178b1d1e 8809
wolfSSL 16:8e0d178b1d1e 8810 default:
wolfSSL 16:8e0d178b1d1e 8811 WOLFSSL_MSG("PKCS7 ORI unknown state");
wolfSSL 16:8e0d178b1d1e 8812 ret = BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 8813
wolfSSL 16:8e0d178b1d1e 8814 }
wolfSSL 16:8e0d178b1d1e 8815
wolfSSL 16:8e0d178b1d1e 8816 return ret;
wolfSSL 16:8e0d178b1d1e 8817 }
wolfSSL 16:8e0d178b1d1e 8818
wolfSSL 16:8e0d178b1d1e 8819 #if !defined(NO_PWDBASED) && !defined(NO_SHA)
wolfSSL 16:8e0d178b1d1e 8820
wolfSSL 16:8e0d178b1d1e 8821 /* decode ASN.1 PasswordRecipientInfo (pwri), return 0 on success,
wolfSSL 16:8e0d178b1d1e 8822 * < 0 on error */
wolfSSL 16:8e0d178b1d1e 8823 static int wc_PKCS7_DecryptPwri(PKCS7* pkcs7, byte* in, word32 inSz,
wolfSSL 16:8e0d178b1d1e 8824 word32* idx, byte* decryptedKey,
wolfSSL 16:8e0d178b1d1e 8825 word32* decryptedKeySz, int* recipFound)
wolfSSL 16:8e0d178b1d1e 8826 {
wolfSSL 16:8e0d178b1d1e 8827 byte* salt;
wolfSSL 16:8e0d178b1d1e 8828 byte* cek;
wolfSSL 16:8e0d178b1d1e 8829 byte* kek;
wolfSSL 16:8e0d178b1d1e 8830
wolfSSL 16:8e0d178b1d1e 8831 byte tmpIv[MAX_CONTENT_IV_SIZE];
wolfSSL 16:8e0d178b1d1e 8832
wolfSSL 16:8e0d178b1d1e 8833 int ret = 0, length, saltSz, iterations, blockSz, kekKeySz;
wolfSSL 16:8e0d178b1d1e 8834 int hashOID = WC_SHA; /* default to SHA1 */
wolfSSL 16:8e0d178b1d1e 8835 word32 kdfAlgoId, pwriEncAlgoId, keyEncAlgoId, cekSz;
wolfSSL 16:8e0d178b1d1e 8836 byte* pkiMsg = in;
wolfSSL 16:8e0d178b1d1e 8837 word32 pkiMsgSz = inSz;
wolfSSL 16:8e0d178b1d1e 8838 byte tag;
wolfSSL 16:8e0d178b1d1e 8839 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 8840 word32 tmpIdx = *idx;
wolfSSL 16:8e0d178b1d1e 8841 long rc;
wolfSSL 16:8e0d178b1d1e 8842 #endif
wolfSSL 16:8e0d178b1d1e 8843
wolfSSL 16:8e0d178b1d1e 8844 switch (pkcs7->state) {
wolfSSL 16:8e0d178b1d1e 8845 case WC_PKCS7_DECRYPT_PWRI:
wolfSSL 16:8e0d178b1d1e 8846 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 8847 /*@TODO for now just get full buffer, needs divided up */
wolfSSL 16:8e0d178b1d1e 8848 if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
wolfSSL 16:8e0d178b1d1e 8849 (pkcs7->stream->maxLen - pkcs7->stream->totalRd) +
wolfSSL 16:8e0d178b1d1e 8850 pkcs7->stream->length, &pkiMsg, idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 8851 return ret;
wolfSSL 16:8e0d178b1d1e 8852 }
wolfSSL 16:8e0d178b1d1e 8853
wolfSSL 16:8e0d178b1d1e 8854 rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK, in,
wolfSSL 16:8e0d178b1d1e 8855 inSz);
wolfSSL 16:8e0d178b1d1e 8856 if (rc < 0) {
wolfSSL 16:8e0d178b1d1e 8857 ret = (int)rc;
wolfSSL 16:8e0d178b1d1e 8858 break;
wolfSSL 16:8e0d178b1d1e 8859 }
wolfSSL 16:8e0d178b1d1e 8860 pkiMsgSz = (word32)rc;
wolfSSL 16:8e0d178b1d1e 8861 #endif
wolfSSL 16:8e0d178b1d1e 8862 /* remove KeyDerivationAlgorithmIdentifier */
wolfSSL 16:8e0d178b1d1e 8863 if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0)
wolfSSL 16:8e0d178b1d1e 8864 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 8865
wolfSSL 16:8e0d178b1d1e 8866 if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
wolfSSL 16:8e0d178b1d1e 8867 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 8868
wolfSSL 16:8e0d178b1d1e 8869 if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)
wolfSSL 16:8e0d178b1d1e 8870 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 8871
wolfSSL 16:8e0d178b1d1e 8872 /* get KeyDerivationAlgorithmIdentifier */
wolfSSL 16:8e0d178b1d1e 8873 if (wc_GetContentType(pkiMsg, idx, &kdfAlgoId, pkiMsgSz) < 0)
wolfSSL 16:8e0d178b1d1e 8874 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 8875
wolfSSL 16:8e0d178b1d1e 8876 /* get KDF params SEQ */
wolfSSL 16:8e0d178b1d1e 8877 if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0)
wolfSSL 16:8e0d178b1d1e 8878 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 8879
wolfSSL 16:8e0d178b1d1e 8880 /* get KDF salt OCTET STRING */
wolfSSL 16:8e0d178b1d1e 8881 if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0)
wolfSSL 16:8e0d178b1d1e 8882 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 8883
wolfSSL 16:8e0d178b1d1e 8884 if (tag != ASN_OCTET_STRING)
wolfSSL 16:8e0d178b1d1e 8885 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 8886
wolfSSL 16:8e0d178b1d1e 8887 if (GetLength(pkiMsg, idx, &saltSz, pkiMsgSz) < 0)
wolfSSL 16:8e0d178b1d1e 8888 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 8889
wolfSSL 16:8e0d178b1d1e 8890 salt = (byte*)XMALLOC(saltSz, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 8891 if (salt == NULL)
wolfSSL 16:8e0d178b1d1e 8892 return MEMORY_E;
wolfSSL 16:8e0d178b1d1e 8893
wolfSSL 16:8e0d178b1d1e 8894 XMEMCPY(salt, pkiMsg + (*idx), saltSz);
wolfSSL 16:8e0d178b1d1e 8895 *idx += saltSz;
wolfSSL 16:8e0d178b1d1e 8896
wolfSSL 16:8e0d178b1d1e 8897 /* get KDF iterations */
wolfSSL 16:8e0d178b1d1e 8898 if (GetMyVersion(pkiMsg, idx, &iterations, pkiMsgSz) < 0) {
wolfSSL 16:8e0d178b1d1e 8899 XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 8900 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 8901 }
wolfSSL 16:8e0d178b1d1e 8902
wolfSSL 16:8e0d178b1d1e 8903 /* get KeyEncAlgoId SEQ */
wolfSSL 16:8e0d178b1d1e 8904 if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0) {
wolfSSL 16:8e0d178b1d1e 8905 XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 8906 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 8907 }
wolfSSL 16:8e0d178b1d1e 8908
wolfSSL 16:8e0d178b1d1e 8909 /* get KeyEncAlgoId */
wolfSSL 16:8e0d178b1d1e 8910 if (wc_GetContentType(pkiMsg, idx, &keyEncAlgoId, pkiMsgSz) < 0) {
wolfSSL 16:8e0d178b1d1e 8911 XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 8912 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 8913 }
wolfSSL 16:8e0d178b1d1e 8914
wolfSSL 16:8e0d178b1d1e 8915 /* get pwriEncAlgoId */
wolfSSL 16:8e0d178b1d1e 8916 if (GetAlgoId(pkiMsg, idx, &pwriEncAlgoId, oidBlkType, pkiMsgSz) < 0) {
wolfSSL 16:8e0d178b1d1e 8917 XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 8918 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 8919 }
wolfSSL 16:8e0d178b1d1e 8920
wolfSSL 16:8e0d178b1d1e 8921 blockSz = wc_PKCS7_GetOIDBlockSize(pwriEncAlgoId);
wolfSSL 16:8e0d178b1d1e 8922 if (blockSz < 0) {
wolfSSL 16:8e0d178b1d1e 8923 XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 8924 return blockSz;
wolfSSL 16:8e0d178b1d1e 8925 }
wolfSSL 16:8e0d178b1d1e 8926
wolfSSL 16:8e0d178b1d1e 8927 /* get content-encryption key size, based on algorithm */
wolfSSL 16:8e0d178b1d1e 8928 kekKeySz = wc_PKCS7_GetOIDKeySize(pwriEncAlgoId);
wolfSSL 16:8e0d178b1d1e 8929 if (kekKeySz < 0) {
wolfSSL 16:8e0d178b1d1e 8930 XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 8931 return kekKeySz;
wolfSSL 16:8e0d178b1d1e 8932 }
wolfSSL 16:8e0d178b1d1e 8933
wolfSSL 16:8e0d178b1d1e 8934 /* get block cipher IV, stored in OPTIONAL parameter of AlgoID */
wolfSSL 16:8e0d178b1d1e 8935 if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0) {
wolfSSL 16:8e0d178b1d1e 8936 XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 8937 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 8938 }
wolfSSL 16:8e0d178b1d1e 8939
wolfSSL 16:8e0d178b1d1e 8940 if (tag != ASN_OCTET_STRING) {
wolfSSL 16:8e0d178b1d1e 8941 XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 8942 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 8943 }
wolfSSL 16:8e0d178b1d1e 8944
wolfSSL 16:8e0d178b1d1e 8945 if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0) {
wolfSSL 16:8e0d178b1d1e 8946 XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 8947 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 8948 }
wolfSSL 16:8e0d178b1d1e 8949
wolfSSL 16:8e0d178b1d1e 8950 if (length != blockSz) {
wolfSSL 16:8e0d178b1d1e 8951 WOLFSSL_MSG("Incorrect IV length, must be of content alg block size");
wolfSSL 16:8e0d178b1d1e 8952 XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 8953 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 8954 }
wolfSSL 16:8e0d178b1d1e 8955
wolfSSL 16:8e0d178b1d1e 8956 XMEMCPY(tmpIv, pkiMsg + (*idx), length);
wolfSSL 16:8e0d178b1d1e 8957 *idx += length;
wolfSSL 16:8e0d178b1d1e 8958
wolfSSL 16:8e0d178b1d1e 8959 /* get EncryptedKey */
wolfSSL 16:8e0d178b1d1e 8960 if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0) {
wolfSSL 16:8e0d178b1d1e 8961 XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 8962 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 8963 }
wolfSSL 16:8e0d178b1d1e 8964
wolfSSL 16:8e0d178b1d1e 8965 if (tag != ASN_OCTET_STRING) {
wolfSSL 16:8e0d178b1d1e 8966 XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 8967 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 8968 }
wolfSSL 16:8e0d178b1d1e 8969
wolfSSL 16:8e0d178b1d1e 8970 if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0) {
wolfSSL 16:8e0d178b1d1e 8971 XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 8972 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 8973 }
wolfSSL 16:8e0d178b1d1e 8974
wolfSSL 16:8e0d178b1d1e 8975 /* allocate temporary space for decrypted key */
wolfSSL 16:8e0d178b1d1e 8976 cekSz = length;
wolfSSL 16:8e0d178b1d1e 8977 cek = (byte*)XMALLOC(cekSz, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 8978 if (cek == NULL) {
wolfSSL 16:8e0d178b1d1e 8979 XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 8980 return MEMORY_E;
wolfSSL 16:8e0d178b1d1e 8981 }
wolfSSL 16:8e0d178b1d1e 8982
wolfSSL 16:8e0d178b1d1e 8983 /* generate KEK */
wolfSSL 16:8e0d178b1d1e 8984 kek = (byte*)XMALLOC(kekKeySz, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 8985 if (kek == NULL) {
wolfSSL 16:8e0d178b1d1e 8986 XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 8987 XFREE(cek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 8988 return MEMORY_E;
wolfSSL 16:8e0d178b1d1e 8989 }
wolfSSL 16:8e0d178b1d1e 8990
wolfSSL 16:8e0d178b1d1e 8991 ret = wc_PKCS7_GenerateKEK_PWRI(pkcs7, pkcs7->pass, pkcs7->passSz,
wolfSSL 16:8e0d178b1d1e 8992 salt, saltSz, kdfAlgoId, hashOID,
wolfSSL 16:8e0d178b1d1e 8993 iterations, kek, kekKeySz);
wolfSSL 16:8e0d178b1d1e 8994 if (ret < 0) {
wolfSSL 16:8e0d178b1d1e 8995 XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 8996 XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 8997 XFREE(cek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 8998 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 8999 }
wolfSSL 16:8e0d178b1d1e 9000
wolfSSL 16:8e0d178b1d1e 9001 /* decrypt CEK with KEK */
wolfSSL 16:8e0d178b1d1e 9002 ret = wc_PKCS7_PwriKek_KeyUnWrap(pkcs7, kek, kekKeySz,
wolfSSL 16:8e0d178b1d1e 9003 pkiMsg + (*idx), length, cek,
wolfSSL 16:8e0d178b1d1e 9004 cekSz, tmpIv, blockSz,
wolfSSL 16:8e0d178b1d1e 9005 pwriEncAlgoId);
wolfSSL 16:8e0d178b1d1e 9006 if (ret < 0) {
wolfSSL 16:8e0d178b1d1e 9007 XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 9008 XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 9009 XFREE(cek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 9010 return ret;
wolfSSL 16:8e0d178b1d1e 9011 }
wolfSSL 16:8e0d178b1d1e 9012 cekSz = ret;
wolfSSL 16:8e0d178b1d1e 9013
wolfSSL 16:8e0d178b1d1e 9014 if (*decryptedKeySz < cekSz) {
wolfSSL 16:8e0d178b1d1e 9015 WOLFSSL_MSG("Decrypted key buffer too small for CEK");
wolfSSL 16:8e0d178b1d1e 9016 XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 9017 XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 9018 XFREE(cek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 9019 return BUFFER_E;
wolfSSL 16:8e0d178b1d1e 9020 }
wolfSSL 16:8e0d178b1d1e 9021
wolfSSL 16:8e0d178b1d1e 9022 XMEMCPY(decryptedKey, cek, cekSz);
wolfSSL 16:8e0d178b1d1e 9023 *decryptedKeySz = cekSz;
wolfSSL 16:8e0d178b1d1e 9024
wolfSSL 16:8e0d178b1d1e 9025 XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 9026 XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 9027 XFREE(cek, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 9028
wolfSSL 16:8e0d178b1d1e 9029 /* mark recipFound, since we only support one RecipientInfo for now */
wolfSSL 16:8e0d178b1d1e 9030 *recipFound = 1;
wolfSSL 16:8e0d178b1d1e 9031 *idx += length;
wolfSSL 16:8e0d178b1d1e 9032 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 9033 if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 9034 break;
wolfSSL 16:8e0d178b1d1e 9035 }
wolfSSL 16:8e0d178b1d1e 9036 #endif
wolfSSL 16:8e0d178b1d1e 9037 ret = 0; /* success */
wolfSSL 16:8e0d178b1d1e 9038 break;
wolfSSL 16:8e0d178b1d1e 9039
wolfSSL 16:8e0d178b1d1e 9040 default:
wolfSSL 16:8e0d178b1d1e 9041 WOLFSSL_MSG("PKCS7 PWRI unknown state");
wolfSSL 16:8e0d178b1d1e 9042 ret = BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 9043 }
wolfSSL 16:8e0d178b1d1e 9044
wolfSSL 16:8e0d178b1d1e 9045 return ret;
wolfSSL 16:8e0d178b1d1e 9046 }
wolfSSL 16:8e0d178b1d1e 9047
wolfSSL 16:8e0d178b1d1e 9048 #endif /* NO_PWDBASED | NO_SHA */
wolfSSL 16:8e0d178b1d1e 9049
wolfSSL 16:8e0d178b1d1e 9050 /* decode ASN.1 KEKRecipientInfo (kekri), return 0 on success,
wolfSSL 16:8e0d178b1d1e 9051 * < 0 on error */
wolfSSL 16:8e0d178b1d1e 9052 static int wc_PKCS7_DecryptKekri(PKCS7* pkcs7, byte* in, word32 inSz,
wolfSSL 16:8e0d178b1d1e 9053 word32* idx, byte* decryptedKey,
wolfSSL 16:8e0d178b1d1e 9054 word32* decryptedKeySz, int* recipFound)
wolfSSL 16:8e0d178b1d1e 9055 {
wolfSSL 16:8e0d178b1d1e 9056 int length, keySz, dateLen, direction;
wolfSSL 16:8e0d178b1d1e 9057 byte* keyId = NULL;
wolfSSL 16:8e0d178b1d1e 9058 const byte* datePtr = NULL;
wolfSSL 16:8e0d178b1d1e 9059 byte dateFormat, tag;
wolfSSL 16:8e0d178b1d1e 9060 word32 keyIdSz, kekIdSz, keyWrapOID, localIdx;
wolfSSL 16:8e0d178b1d1e 9061
wolfSSL 16:8e0d178b1d1e 9062 int ret = 0;
wolfSSL 16:8e0d178b1d1e 9063 byte* pkiMsg = in;
wolfSSL 16:8e0d178b1d1e 9064 word32 pkiMsgSz = inSz;
wolfSSL 16:8e0d178b1d1e 9065 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 9066 word32 tmpIdx = *idx;
wolfSSL 16:8e0d178b1d1e 9067 long rc;
wolfSSL 16:8e0d178b1d1e 9068 #endif
wolfSSL 16:8e0d178b1d1e 9069
wolfSSL 16:8e0d178b1d1e 9070 WOLFSSL_ENTER("wc_PKCS7_DecryptKekri");
wolfSSL 16:8e0d178b1d1e 9071 switch (pkcs7->state) {
wolfSSL 16:8e0d178b1d1e 9072 case WC_PKCS7_DECRYPT_KEKRI:
wolfSSL 16:8e0d178b1d1e 9073 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 9074 /* @TODO for now just get full buffer, needs divided up */
wolfSSL 16:8e0d178b1d1e 9075 if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
wolfSSL 16:8e0d178b1d1e 9076 (pkcs7->stream->maxLen - pkcs7->stream->totalRd) +
wolfSSL 16:8e0d178b1d1e 9077 pkcs7->stream->length, &pkiMsg, idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 9078 return ret;
wolfSSL 16:8e0d178b1d1e 9079 }
wolfSSL 16:8e0d178b1d1e 9080
wolfSSL 16:8e0d178b1d1e 9081 rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK, in,
wolfSSL 16:8e0d178b1d1e 9082 inSz);
wolfSSL 16:8e0d178b1d1e 9083 if (rc < 0) {
wolfSSL 16:8e0d178b1d1e 9084 ret = (int)rc;
wolfSSL 16:8e0d178b1d1e 9085 break;
wolfSSL 16:8e0d178b1d1e 9086 }
wolfSSL 16:8e0d178b1d1e 9087 pkiMsgSz = (word32)rc;
wolfSSL 16:8e0d178b1d1e 9088 #endif
wolfSSL 16:8e0d178b1d1e 9089 /* remove KEKIdentifier */
wolfSSL 16:8e0d178b1d1e 9090 if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0)
wolfSSL 16:8e0d178b1d1e 9091 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 9092
wolfSSL 16:8e0d178b1d1e 9093 kekIdSz = length;
wolfSSL 16:8e0d178b1d1e 9094
wolfSSL 16:8e0d178b1d1e 9095 if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0)
wolfSSL 16:8e0d178b1d1e 9096 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 9097
wolfSSL 16:8e0d178b1d1e 9098 if (tag != ASN_OCTET_STRING)
wolfSSL 16:8e0d178b1d1e 9099 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 9100
wolfSSL 16:8e0d178b1d1e 9101 if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)
wolfSSL 16:8e0d178b1d1e 9102 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 9103
wolfSSL 16:8e0d178b1d1e 9104 /* save keyIdentifier and length */
wolfSSL 16:8e0d178b1d1e 9105 keyId = pkiMsg + *idx;
wolfSSL 16:8e0d178b1d1e 9106 keyIdSz = length;
wolfSSL 16:8e0d178b1d1e 9107 *idx += keyIdSz;
wolfSSL 16:8e0d178b1d1e 9108
wolfSSL 16:8e0d178b1d1e 9109 /* may have OPTIONAL GeneralizedTime */
wolfSSL 16:8e0d178b1d1e 9110 localIdx = *idx;
wolfSSL 16:8e0d178b1d1e 9111 if ((*idx < kekIdSz) && GetASNTag(pkiMsg, &localIdx, &tag,
wolfSSL 16:8e0d178b1d1e 9112 pkiMsgSz) == 0 && tag == ASN_GENERALIZED_TIME) {
wolfSSL 16:8e0d178b1d1e 9113 if (wc_GetDateInfo(pkiMsg + *idx, pkiMsgSz, &datePtr, &dateFormat,
wolfSSL 16:8e0d178b1d1e 9114 &dateLen) != 0) {
wolfSSL 16:8e0d178b1d1e 9115 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 9116 }
wolfSSL 16:8e0d178b1d1e 9117 *idx += (dateLen + 1);
wolfSSL 16:8e0d178b1d1e 9118 }
wolfSSL 16:8e0d178b1d1e 9119
wolfSSL 16:8e0d178b1d1e 9120 /* may have OPTIONAL OtherKeyAttribute */
wolfSSL 16:8e0d178b1d1e 9121 localIdx = *idx;
wolfSSL 16:8e0d178b1d1e 9122 if ((*idx < kekIdSz) && GetASNTag(pkiMsg, &localIdx, &tag,
wolfSSL 16:8e0d178b1d1e 9123 pkiMsgSz) == 0 && tag == (ASN_SEQUENCE |
wolfSSL 16:8e0d178b1d1e 9124 ASN_CONSTRUCTED)) {
wolfSSL 16:8e0d178b1d1e 9125 if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0)
wolfSSL 16:8e0d178b1d1e 9126 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 9127
wolfSSL 16:8e0d178b1d1e 9128 /* skip it */
wolfSSL 16:8e0d178b1d1e 9129 *idx += length;
wolfSSL 16:8e0d178b1d1e 9130 }
wolfSSL 16:8e0d178b1d1e 9131
wolfSSL 16:8e0d178b1d1e 9132 /* get KeyEncryptionAlgorithmIdentifier */
wolfSSL 16:8e0d178b1d1e 9133 if (GetAlgoId(pkiMsg, idx, &keyWrapOID, oidKeyWrapType, pkiMsgSz) < 0)
wolfSSL 16:8e0d178b1d1e 9134 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 9135
wolfSSL 16:8e0d178b1d1e 9136 /* get EncryptedKey */
wolfSSL 16:8e0d178b1d1e 9137 if (GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) < 0)
wolfSSL 16:8e0d178b1d1e 9138 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 9139
wolfSSL 16:8e0d178b1d1e 9140 if (tag != ASN_OCTET_STRING)
wolfSSL 16:8e0d178b1d1e 9141 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 9142
wolfSSL 16:8e0d178b1d1e 9143 if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)
wolfSSL 16:8e0d178b1d1e 9144 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 9145
wolfSSL 16:8e0d178b1d1e 9146 #ifndef NO_AES
wolfSSL 16:8e0d178b1d1e 9147 direction = AES_DECRYPTION;
wolfSSL 16:8e0d178b1d1e 9148 #else
wolfSSL 16:8e0d178b1d1e 9149 direction = DES_DECRYPTION;
wolfSSL 16:8e0d178b1d1e 9150 #endif
wolfSSL 16:8e0d178b1d1e 9151
wolfSSL 16:8e0d178b1d1e 9152 /* decrypt CEK with KEK */
wolfSSL 16:8e0d178b1d1e 9153 if (pkcs7->wrapCEKCb) {
wolfSSL 16:8e0d178b1d1e 9154 keySz = pkcs7->wrapCEKCb(pkcs7, pkiMsg + *idx, length, keyId,
wolfSSL 16:8e0d178b1d1e 9155 keyIdSz, NULL, 0, decryptedKey,
wolfSSL 16:8e0d178b1d1e 9156 *decryptedKeySz, keyWrapOID,
wolfSSL 16:8e0d178b1d1e 9157 (int)PKCS7_KEKRI, direction);
wolfSSL 16:8e0d178b1d1e 9158 }
wolfSSL 16:8e0d178b1d1e 9159 else {
wolfSSL 16:8e0d178b1d1e 9160 keySz = wc_PKCS7_KeyWrap(pkiMsg + *idx, length, pkcs7->privateKey,
wolfSSL 16:8e0d178b1d1e 9161 pkcs7->privateKeySz, decryptedKey, *decryptedKeySz,
wolfSSL 16:8e0d178b1d1e 9162 keyWrapOID, direction);
wolfSSL 16:8e0d178b1d1e 9163 }
wolfSSL 16:8e0d178b1d1e 9164 if (keySz <= 0)
wolfSSL 16:8e0d178b1d1e 9165 return keySz;
wolfSSL 16:8e0d178b1d1e 9166
wolfSSL 16:8e0d178b1d1e 9167 *decryptedKeySz = (word32)keySz;
wolfSSL 16:8e0d178b1d1e 9168
wolfSSL 16:8e0d178b1d1e 9169 /* mark recipFound, since we only support one RecipientInfo for now */
wolfSSL 16:8e0d178b1d1e 9170 *recipFound = 1;
wolfSSL 16:8e0d178b1d1e 9171 *idx += length;
wolfSSL 16:8e0d178b1d1e 9172
wolfSSL 16:8e0d178b1d1e 9173 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 9174 if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 9175 break;
wolfSSL 16:8e0d178b1d1e 9176 }
wolfSSL 16:8e0d178b1d1e 9177 #endif
wolfSSL 16:8e0d178b1d1e 9178 ret = 0; /* success */
wolfSSL 16:8e0d178b1d1e 9179 break;
wolfSSL 16:8e0d178b1d1e 9180
wolfSSL 16:8e0d178b1d1e 9181 default:
wolfSSL 16:8e0d178b1d1e 9182 WOLFSSL_MSG("PKCS7 KEKRI unknown state");
wolfSSL 16:8e0d178b1d1e 9183 ret = BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 9184
wolfSSL 16:8e0d178b1d1e 9185 }
wolfSSL 16:8e0d178b1d1e 9186
wolfSSL 16:8e0d178b1d1e 9187 (void)keyId;
wolfSSL 16:8e0d178b1d1e 9188 return ret;
wolfSSL 16:8e0d178b1d1e 9189 }
wolfSSL 16:8e0d178b1d1e 9190
wolfSSL 16:8e0d178b1d1e 9191
wolfSSL 15:117db924cf7c 9192 /* decode ASN.1 KeyAgreeRecipientInfo (kari), return 0 on success,
wolfSSL 15:117db924cf7c 9193 * < 0 on error */
wolfSSL 16:8e0d178b1d1e 9194 static int wc_PKCS7_DecryptKari(PKCS7* pkcs7, byte* in, word32 inSz,
wolfSSL 15:117db924cf7c 9195 word32* idx, byte* decryptedKey,
wolfSSL 15:117db924cf7c 9196 word32* decryptedKeySz, int* recipFound)
wolfSSL 15:117db924cf7c 9197 {
wolfSSL 15:117db924cf7c 9198 #ifdef HAVE_ECC
wolfSSL 15:117db924cf7c 9199 int ret, keySz;
wolfSSL 15:117db924cf7c 9200 int encryptedKeySz;
wolfSSL 15:117db924cf7c 9201 int direction = 0;
wolfSSL 15:117db924cf7c 9202 word32 keyAgreeOID, keyWrapOID;
wolfSSL 16:8e0d178b1d1e 9203 byte rid[KEYID_SIZE];
wolfSSL 15:117db924cf7c 9204
wolfSSL 15:117db924cf7c 9205 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 9206 byte* encryptedKey;
wolfSSL 15:117db924cf7c 9207 #else
wolfSSL 16:8e0d178b1d1e 9208 byte encryptedKey[MAX_ENCRYPTED_KEY_SZ];
wolfSSL 16:8e0d178b1d1e 9209 #endif
wolfSSL 16:8e0d178b1d1e 9210
wolfSSL 16:8e0d178b1d1e 9211 byte* pkiMsg = in;
wolfSSL 16:8e0d178b1d1e 9212 word32 pkiMsgSz = inSz;
wolfSSL 16:8e0d178b1d1e 9213 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 9214 word32 tmpIdx = (idx) ? *idx : 0;
wolfSSL 16:8e0d178b1d1e 9215 long rc;
wolfSSL 16:8e0d178b1d1e 9216 #endif
wolfSSL 16:8e0d178b1d1e 9217
wolfSSL 16:8e0d178b1d1e 9218 WOLFSSL_ENTER("wc_PKCS7_DecryptKari");
wolfSSL 16:8e0d178b1d1e 9219 if (pkcs7 == NULL || pkiMsg == NULL ||
wolfSSL 16:8e0d178b1d1e 9220 ((pkcs7->singleCert == NULL || pkcs7->singleCertSz == 0) &&
wolfSSL 16:8e0d178b1d1e 9221 pkcs7->wrapCEKCb == NULL) ||
wolfSSL 15:117db924cf7c 9222 idx == NULL || decryptedKey == NULL || decryptedKeySz == NULL) {
wolfSSL 15:117db924cf7c 9223 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 9224 }
wolfSSL 15:117db924cf7c 9225
wolfSSL 16:8e0d178b1d1e 9226 switch (pkcs7->state) {
wolfSSL 16:8e0d178b1d1e 9227 case WC_PKCS7_DECRYPT_KARI: {
wolfSSL 16:8e0d178b1d1e 9228 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 9229 /* @TODO for now just get full buffer, needs divided up */
wolfSSL 16:8e0d178b1d1e 9230 if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
wolfSSL 16:8e0d178b1d1e 9231 (pkcs7->stream->maxLen - pkcs7->stream->totalRd) +
wolfSSL 16:8e0d178b1d1e 9232 pkcs7->stream->length, &pkiMsg, idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 9233 return ret;
wolfSSL 16:8e0d178b1d1e 9234 }
wolfSSL 16:8e0d178b1d1e 9235
wolfSSL 16:8e0d178b1d1e 9236 rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK, in,
wolfSSL 16:8e0d178b1d1e 9237 inSz);
wolfSSL 16:8e0d178b1d1e 9238 if (rc < 0) {
wolfSSL 16:8e0d178b1d1e 9239 ret = (int)rc;
wolfSSL 16:8e0d178b1d1e 9240 break;
wolfSSL 16:8e0d178b1d1e 9241 }
wolfSSL 16:8e0d178b1d1e 9242 pkiMsgSz = (word32)rc;
wolfSSL 16:8e0d178b1d1e 9243 #endif
wolfSSL 16:8e0d178b1d1e 9244 WC_PKCS7_KARI* kari;
wolfSSL 16:8e0d178b1d1e 9245
wolfSSL 16:8e0d178b1d1e 9246 kari = wc_PKCS7_KariNew(pkcs7, WC_PKCS7_DECODE);
wolfSSL 16:8e0d178b1d1e 9247 if (kari == NULL)
wolfSSL 16:8e0d178b1d1e 9248 return MEMORY_E;
wolfSSL 16:8e0d178b1d1e 9249
wolfSSL 15:117db924cf7c 9250 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 9251 encryptedKey = (byte*)XMALLOC(MAX_ENCRYPTED_KEY_SZ, pkcs7->heap,
wolfSSL 16:8e0d178b1d1e 9252 DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 9253 if (encryptedKey == NULL) {
wolfSSL 16:8e0d178b1d1e 9254 wc_PKCS7_KariFree(kari);
wolfSSL 16:8e0d178b1d1e 9255 return MEMORY_E;
wolfSSL 16:8e0d178b1d1e 9256 }
wolfSSL 16:8e0d178b1d1e 9257 #endif
wolfSSL 16:8e0d178b1d1e 9258 encryptedKeySz = MAX_ENCRYPTED_KEY_SZ;
wolfSSL 16:8e0d178b1d1e 9259
wolfSSL 16:8e0d178b1d1e 9260 /* parse cert and key */
wolfSSL 16:8e0d178b1d1e 9261 if (pkcs7->singleCert != NULL) {
wolfSSL 16:8e0d178b1d1e 9262 ret = wc_PKCS7_KariParseRecipCert(kari, (byte*)pkcs7->singleCert,
wolfSSL 16:8e0d178b1d1e 9263 pkcs7->singleCertSz, pkcs7->privateKey,
wolfSSL 16:8e0d178b1d1e 9264 pkcs7->privateKeySz);
wolfSSL 16:8e0d178b1d1e 9265 if (ret != 0) {
wolfSSL 16:8e0d178b1d1e 9266 wc_PKCS7_KariFree(kari);
wolfSSL 16:8e0d178b1d1e 9267 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 9268 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 9269 #endif
wolfSSL 16:8e0d178b1d1e 9270 return ret;
wolfSSL 16:8e0d178b1d1e 9271 }
wolfSSL 16:8e0d178b1d1e 9272 }
wolfSSL 16:8e0d178b1d1e 9273
wolfSSL 16:8e0d178b1d1e 9274 /* remove OriginatorIdentifierOrKey */
wolfSSL 16:8e0d178b1d1e 9275 ret = wc_PKCS7_KariGetOriginatorIdentifierOrKey(kari, pkiMsg,
wolfSSL 16:8e0d178b1d1e 9276 pkiMsgSz, idx);
wolfSSL 16:8e0d178b1d1e 9277 if (ret != 0) {
wolfSSL 16:8e0d178b1d1e 9278 wc_PKCS7_KariFree(kari);
wolfSSL 16:8e0d178b1d1e 9279 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 9280 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 9281 #endif
wolfSSL 16:8e0d178b1d1e 9282 return ret;
wolfSSL 16:8e0d178b1d1e 9283 }
wolfSSL 16:8e0d178b1d1e 9284
wolfSSL 16:8e0d178b1d1e 9285 /* try and remove optional UserKeyingMaterial */
wolfSSL 16:8e0d178b1d1e 9286 ret = wc_PKCS7_KariGetUserKeyingMaterial(kari, pkiMsg, pkiMsgSz, idx);
wolfSSL 16:8e0d178b1d1e 9287 if (ret != 0) {
wolfSSL 16:8e0d178b1d1e 9288 wc_PKCS7_KariFree(kari);
wolfSSL 16:8e0d178b1d1e 9289 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 9290 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 9291 #endif
wolfSSL 16:8e0d178b1d1e 9292 return ret;
wolfSSL 16:8e0d178b1d1e 9293 }
wolfSSL 16:8e0d178b1d1e 9294
wolfSSL 16:8e0d178b1d1e 9295 /* remove KeyEncryptionAlgorithmIdentifier */
wolfSSL 16:8e0d178b1d1e 9296 ret = wc_PKCS7_KariGetKeyEncryptionAlgorithmId(kari, pkiMsg,
wolfSSL 16:8e0d178b1d1e 9297 pkiMsgSz, idx, &keyAgreeOID, &keyWrapOID);
wolfSSL 16:8e0d178b1d1e 9298 if (ret != 0) {
wolfSSL 16:8e0d178b1d1e 9299 wc_PKCS7_KariFree(kari);
wolfSSL 16:8e0d178b1d1e 9300 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 9301 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 9302 #endif
wolfSSL 16:8e0d178b1d1e 9303 return ret;
wolfSSL 16:8e0d178b1d1e 9304 }
wolfSSL 16:8e0d178b1d1e 9305
wolfSSL 16:8e0d178b1d1e 9306 /* if user has not explicitly set keyAgreeOID, set from one in bundle */
wolfSSL 16:8e0d178b1d1e 9307 if (pkcs7->keyAgreeOID == 0)
wolfSSL 16:8e0d178b1d1e 9308 pkcs7->keyAgreeOID = keyAgreeOID;
wolfSSL 16:8e0d178b1d1e 9309
wolfSSL 16:8e0d178b1d1e 9310 /* set direction based on key wrap algorithm */
wolfSSL 16:8e0d178b1d1e 9311 switch (keyWrapOID) {
wolfSSL 16:8e0d178b1d1e 9312 #ifndef NO_AES
wolfSSL 16:8e0d178b1d1e 9313 #ifdef WOLFSSL_AES_128
wolfSSL 16:8e0d178b1d1e 9314 case AES128_WRAP:
wolfSSL 16:8e0d178b1d1e 9315 #endif
wolfSSL 16:8e0d178b1d1e 9316 #ifdef WOLFSSL_AES_192
wolfSSL 16:8e0d178b1d1e 9317 case AES192_WRAP:
wolfSSL 16:8e0d178b1d1e 9318 #endif
wolfSSL 16:8e0d178b1d1e 9319 #ifdef WOLFSSL_AES_256
wolfSSL 16:8e0d178b1d1e 9320 case AES256_WRAP:
wolfSSL 16:8e0d178b1d1e 9321 #endif
wolfSSL 16:8e0d178b1d1e 9322 direction = AES_DECRYPTION;
wolfSSL 16:8e0d178b1d1e 9323 break;
wolfSSL 16:8e0d178b1d1e 9324 #endif
wolfSSL 16:8e0d178b1d1e 9325 default:
wolfSSL 16:8e0d178b1d1e 9326 WOLFSSL_MSG("AES key wrap algorithm unsupported");
wolfSSL 16:8e0d178b1d1e 9327 if (pkcs7->wrapCEKCb) {
wolfSSL 16:8e0d178b1d1e 9328 WOLFSSL_MSG("Direction not set!");
wolfSSL 16:8e0d178b1d1e 9329 break; /* if unwrapping callback is set then do not
wolfSSL 16:8e0d178b1d1e 9330 * force restriction of supported wrap
wolfSSL 16:8e0d178b1d1e 9331 * algorithms */
wolfSSL 16:8e0d178b1d1e 9332 }
wolfSSL 16:8e0d178b1d1e 9333
wolfSSL 16:8e0d178b1d1e 9334 wc_PKCS7_KariFree(kari);
wolfSSL 16:8e0d178b1d1e 9335 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 9336 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 9337 #endif
wolfSSL 16:8e0d178b1d1e 9338 return BAD_KEYWRAP_ALG_E;
wolfSSL 16:8e0d178b1d1e 9339 }
wolfSSL 16:8e0d178b1d1e 9340
wolfSSL 16:8e0d178b1d1e 9341 /* remove RecipientEncryptedKeys */
wolfSSL 16:8e0d178b1d1e 9342 ret = wc_PKCS7_KariGetRecipientEncryptedKeys(kari, pkiMsg, pkiMsgSz,
wolfSSL 16:8e0d178b1d1e 9343 idx, recipFound, encryptedKey, &encryptedKeySz, rid);
wolfSSL 16:8e0d178b1d1e 9344 if (ret != 0) {
wolfSSL 16:8e0d178b1d1e 9345 wc_PKCS7_KariFree(kari);
wolfSSL 16:8e0d178b1d1e 9346 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 9347 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 9348 #endif
wolfSSL 16:8e0d178b1d1e 9349 return ret;
wolfSSL 16:8e0d178b1d1e 9350 }
wolfSSL 16:8e0d178b1d1e 9351
wolfSSL 16:8e0d178b1d1e 9352 /* decrypt CEK with KEK */
wolfSSL 16:8e0d178b1d1e 9353 if (pkcs7->wrapCEKCb) {
wolfSSL 16:8e0d178b1d1e 9354 word32 tmpKeySz = 0;
wolfSSL 16:8e0d178b1d1e 9355 byte* tmpKeyDer = NULL;
wolfSSL 16:8e0d178b1d1e 9356
wolfSSL 16:8e0d178b1d1e 9357 ret = wc_ecc_export_x963(kari->senderKey, NULL, &tmpKeySz);
wolfSSL 16:8e0d178b1d1e 9358 if (ret != LENGTH_ONLY_E) {
wolfSSL 16:8e0d178b1d1e 9359 return ret;
wolfSSL 16:8e0d178b1d1e 9360 }
wolfSSL 16:8e0d178b1d1e 9361
wolfSSL 16:8e0d178b1d1e 9362 /* buffer space for algorithm/curve */
wolfSSL 16:8e0d178b1d1e 9363 tmpKeySz += MAX_SEQ_SZ;
wolfSSL 16:8e0d178b1d1e 9364 tmpKeySz += 2 * MAX_ALGO_SZ;
wolfSSL 16:8e0d178b1d1e 9365
wolfSSL 16:8e0d178b1d1e 9366 /* buffer space for public key sequence */
wolfSSL 16:8e0d178b1d1e 9367 tmpKeySz += MAX_SEQ_SZ;
wolfSSL 16:8e0d178b1d1e 9368 tmpKeySz += TRAILING_ZERO;
wolfSSL 16:8e0d178b1d1e 9369
wolfSSL 16:8e0d178b1d1e 9370 tmpKeyDer = (byte*)XMALLOC(tmpKeySz, pkcs7->heap,
wolfSSL 16:8e0d178b1d1e 9371 DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 9372 if (tmpKeyDer == NULL) {
wolfSSL 16:8e0d178b1d1e 9373 return MEMORY_E;
wolfSSL 16:8e0d178b1d1e 9374 }
wolfSSL 16:8e0d178b1d1e 9375
wolfSSL 16:8e0d178b1d1e 9376 ret = wc_EccPublicKeyToDer(kari->senderKey, tmpKeyDer,
wolfSSL 16:8e0d178b1d1e 9377 tmpKeySz, 1);
wolfSSL 16:8e0d178b1d1e 9378 if (ret < 0) {
wolfSSL 16:8e0d178b1d1e 9379 XFREE(tmpKeyDer, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 9380 return ret;
wolfSSL 16:8e0d178b1d1e 9381 }
wolfSSL 16:8e0d178b1d1e 9382 tmpKeySz = (word32)ret;
wolfSSL 16:8e0d178b1d1e 9383
wolfSSL 16:8e0d178b1d1e 9384 keySz = pkcs7->wrapCEKCb(pkcs7, encryptedKey, encryptedKeySz,
wolfSSL 16:8e0d178b1d1e 9385 rid, KEYID_SIZE, tmpKeyDer, tmpKeySz,
wolfSSL 16:8e0d178b1d1e 9386 decryptedKey, *decryptedKeySz,
wolfSSL 16:8e0d178b1d1e 9387 keyWrapOID, (int)PKCS7_KARI, direction);
wolfSSL 16:8e0d178b1d1e 9388 XFREE(tmpKeyDer, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 9389
wolfSSL 16:8e0d178b1d1e 9390 if (keySz > 0) {
wolfSSL 16:8e0d178b1d1e 9391 /* If unwrapping was successful then consider recipient
wolfSSL 16:8e0d178b1d1e 9392 * found. Checking for NULL singleCert to confirm previous
wolfSSL 16:8e0d178b1d1e 9393 * SID check was not done */
wolfSSL 16:8e0d178b1d1e 9394 if (pkcs7->singleCert == NULL)
wolfSSL 16:8e0d178b1d1e 9395 *recipFound = 1;
wolfSSL 16:8e0d178b1d1e 9396 }
wolfSSL 16:8e0d178b1d1e 9397 }
wolfSSL 16:8e0d178b1d1e 9398 else {
wolfSSL 16:8e0d178b1d1e 9399 /* create KEK */
wolfSSL 16:8e0d178b1d1e 9400 ret = wc_PKCS7_KariGenerateKEK(kari, keyWrapOID, pkcs7->keyAgreeOID);
wolfSSL 16:8e0d178b1d1e 9401 if (ret != 0) {
wolfSSL 16:8e0d178b1d1e 9402 wc_PKCS7_KariFree(kari);
wolfSSL 16:8e0d178b1d1e 9403 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 9404 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 9405 #endif
wolfSSL 16:8e0d178b1d1e 9406 return ret;
wolfSSL 16:8e0d178b1d1e 9407 }
wolfSSL 16:8e0d178b1d1e 9408
wolfSSL 16:8e0d178b1d1e 9409 /* decrypt CEK with KEK */
wolfSSL 16:8e0d178b1d1e 9410 keySz = wc_PKCS7_KeyWrap(encryptedKey, encryptedKeySz, kari->kek,
wolfSSL 16:8e0d178b1d1e 9411 kari->kekSz, decryptedKey, *decryptedKeySz,
wolfSSL 16:8e0d178b1d1e 9412 keyWrapOID, direction);
wolfSSL 16:8e0d178b1d1e 9413 }
wolfSSL 16:8e0d178b1d1e 9414 if (keySz <= 0) {
wolfSSL 16:8e0d178b1d1e 9415 wc_PKCS7_KariFree(kari);
wolfSSL 16:8e0d178b1d1e 9416 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 9417 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 9418 #endif
wolfSSL 16:8e0d178b1d1e 9419 return keySz;
wolfSSL 16:8e0d178b1d1e 9420 }
wolfSSL 16:8e0d178b1d1e 9421 *decryptedKeySz = (word32)keySz;
wolfSSL 16:8e0d178b1d1e 9422
wolfSSL 15:117db924cf7c 9423 wc_PKCS7_KariFree(kari);
wolfSSL 15:117db924cf7c 9424 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 9425 XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 9426 #endif
wolfSSL 16:8e0d178b1d1e 9427 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 9428 if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 9429 break;
wolfSSL 16:8e0d178b1d1e 9430 }
wolfSSL 16:8e0d178b1d1e 9431 #endif
wolfSSL 16:8e0d178b1d1e 9432 ret = 0; /* success */
wolfSSL 16:8e0d178b1d1e 9433 }
wolfSSL 16:8e0d178b1d1e 9434 break;
wolfSSL 16:8e0d178b1d1e 9435
wolfSSL 16:8e0d178b1d1e 9436 default:
wolfSSL 16:8e0d178b1d1e 9437 WOLFSSL_MSG("PKCS7 kari unknown state");
wolfSSL 16:8e0d178b1d1e 9438 ret = BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 9439
wolfSSL 16:8e0d178b1d1e 9440 }
wolfSSL 16:8e0d178b1d1e 9441
wolfSSL 15:117db924cf7c 9442 (void)pkiMsg;
wolfSSL 15:117db924cf7c 9443 (void)pkiMsgSz;
wolfSSL 16:8e0d178b1d1e 9444
wolfSSL 16:8e0d178b1d1e 9445 return ret;
wolfSSL 16:8e0d178b1d1e 9446 #else
wolfSSL 16:8e0d178b1d1e 9447 (void)in;
wolfSSL 16:8e0d178b1d1e 9448 (void)inSz;
wolfSSL 16:8e0d178b1d1e 9449 (void)pkcs7;
wolfSSL 15:117db924cf7c 9450 (void)idx;
wolfSSL 15:117db924cf7c 9451 (void)decryptedKey;
wolfSSL 15:117db924cf7c 9452 (void)decryptedKeySz;
wolfSSL 15:117db924cf7c 9453 (void)recipFound;
wolfSSL 15:117db924cf7c 9454
wolfSSL 15:117db924cf7c 9455 return NOT_COMPILED_IN;
wolfSSL 15:117db924cf7c 9456 #endif /* HAVE_ECC */
wolfSSL 15:117db924cf7c 9457 }
wolfSSL 15:117db924cf7c 9458
wolfSSL 15:117db924cf7c 9459
wolfSSL 15:117db924cf7c 9460 /* decode ASN.1 RecipientInfos SET, return 0 on success, < 0 on error */
wolfSSL 16:8e0d178b1d1e 9461 static int wc_PKCS7_DecryptRecipientInfos(PKCS7* pkcs7, byte* in,
wolfSSL 16:8e0d178b1d1e 9462 word32 inSz, word32* idx, byte* decryptedKey,
wolfSSL 15:117db924cf7c 9463 word32* decryptedKeySz, int* recipFound)
wolfSSL 15:117db924cf7c 9464 {
wolfSSL 15:117db924cf7c 9465 word32 savedIdx;
wolfSSL 16:8e0d178b1d1e 9466 int version, ret = 0, length;
wolfSSL 16:8e0d178b1d1e 9467 byte* pkiMsg = in;
wolfSSL 16:8e0d178b1d1e 9468 word32 pkiMsgSz = inSz;
wolfSSL 16:8e0d178b1d1e 9469 byte tag;
wolfSSL 16:8e0d178b1d1e 9470 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 9471 word32 tmpIdx;
wolfSSL 16:8e0d178b1d1e 9472 long rc;
wolfSSL 16:8e0d178b1d1e 9473 #endif
wolfSSL 15:117db924cf7c 9474
wolfSSL 15:117db924cf7c 9475 if (pkcs7 == NULL || pkiMsg == NULL || idx == NULL ||
wolfSSL 15:117db924cf7c 9476 decryptedKey == NULL || decryptedKeySz == NULL ||
wolfSSL 15:117db924cf7c 9477 recipFound == NULL) {
wolfSSL 15:117db924cf7c 9478 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 9479 }
wolfSSL 15:117db924cf7c 9480
wolfSSL 16:8e0d178b1d1e 9481 WOLFSSL_ENTER("wc_PKCS7_DecryptRecipientInfos");
wolfSSL 16:8e0d178b1d1e 9482 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 9483 tmpIdx = *idx;
wolfSSL 16:8e0d178b1d1e 9484 #endif
wolfSSL 16:8e0d178b1d1e 9485
wolfSSL 16:8e0d178b1d1e 9486 /* check if in the process of decrypting */
wolfSSL 16:8e0d178b1d1e 9487 switch (pkcs7->state) {
wolfSSL 16:8e0d178b1d1e 9488 case WC_PKCS7_DECRYPT_KTRI:
wolfSSL 16:8e0d178b1d1e 9489 case WC_PKCS7_DECRYPT_KTRI_2:
wolfSSL 16:8e0d178b1d1e 9490 case WC_PKCS7_DECRYPT_KTRI_3:
wolfSSL 16:8e0d178b1d1e 9491 #ifndef NO_RSA
wolfSSL 16:8e0d178b1d1e 9492 ret = wc_PKCS7_DecryptKtri(pkcs7, in, inSz, idx,
wolfSSL 16:8e0d178b1d1e 9493 decryptedKey, decryptedKeySz, recipFound);
wolfSSL 16:8e0d178b1d1e 9494 #else
wolfSSL 16:8e0d178b1d1e 9495 return NOT_COMPILED_IN;
wolfSSL 16:8e0d178b1d1e 9496 #endif
wolfSSL 16:8e0d178b1d1e 9497 break;
wolfSSL 16:8e0d178b1d1e 9498
wolfSSL 16:8e0d178b1d1e 9499 case WC_PKCS7_DECRYPT_KARI:
wolfSSL 16:8e0d178b1d1e 9500 ret = wc_PKCS7_DecryptKari(pkcs7, in, inSz, idx,
wolfSSL 16:8e0d178b1d1e 9501 decryptedKey, decryptedKeySz, recipFound);
wolfSSL 16:8e0d178b1d1e 9502 break;
wolfSSL 16:8e0d178b1d1e 9503
wolfSSL 16:8e0d178b1d1e 9504 case WC_PKCS7_DECRYPT_KEKRI:
wolfSSL 16:8e0d178b1d1e 9505 ret = wc_PKCS7_DecryptKekri(pkcs7, in, inSz, idx,
wolfSSL 16:8e0d178b1d1e 9506 decryptedKey, decryptedKeySz, recipFound);
wolfSSL 16:8e0d178b1d1e 9507 break;
wolfSSL 16:8e0d178b1d1e 9508
wolfSSL 16:8e0d178b1d1e 9509 case WC_PKCS7_DECRYPT_PWRI:
wolfSSL 16:8e0d178b1d1e 9510 #if !defined(NO_PWDBASED) && !defined(NO_SHA)
wolfSSL 16:8e0d178b1d1e 9511 ret = wc_PKCS7_DecryptPwri(pkcs7, in, inSz, idx,
wolfSSL 16:8e0d178b1d1e 9512 decryptedKey, decryptedKeySz, recipFound);
wolfSSL 16:8e0d178b1d1e 9513 #else
wolfSSL 16:8e0d178b1d1e 9514 return NOT_COMPILED_IN;
wolfSSL 16:8e0d178b1d1e 9515 #endif
wolfSSL 16:8e0d178b1d1e 9516 break;
wolfSSL 16:8e0d178b1d1e 9517
wolfSSL 16:8e0d178b1d1e 9518 case WC_PKCS7_DECRYPT_ORI:
wolfSSL 16:8e0d178b1d1e 9519 ret = wc_PKCS7_DecryptOri(pkcs7, in, inSz, idx,
wolfSSL 16:8e0d178b1d1e 9520 decryptedKey, decryptedKeySz, recipFound);
wolfSSL 16:8e0d178b1d1e 9521 break;
wolfSSL 16:8e0d178b1d1e 9522
wolfSSL 16:8e0d178b1d1e 9523 default:
wolfSSL 16:8e0d178b1d1e 9524 /* not in decrypting state */
wolfSSL 16:8e0d178b1d1e 9525 break;
wolfSSL 16:8e0d178b1d1e 9526 }
wolfSSL 16:8e0d178b1d1e 9527
wolfSSL 16:8e0d178b1d1e 9528 if (ret < 0) {
wolfSSL 16:8e0d178b1d1e 9529 return ret;
wolfSSL 16:8e0d178b1d1e 9530 }
wolfSSL 16:8e0d178b1d1e 9531
wolfSSL 15:117db924cf7c 9532 savedIdx = *idx;
wolfSSL 16:8e0d178b1d1e 9533 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 9534 rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK, in, inSz);
wolfSSL 16:8e0d178b1d1e 9535 if (rc < 0) {
wolfSSL 16:8e0d178b1d1e 9536 return (int)rc;
wolfSSL 16:8e0d178b1d1e 9537 }
wolfSSL 16:8e0d178b1d1e 9538 pkiMsgSz = (word32)rc;
wolfSSL 16:8e0d178b1d1e 9539 if (pkcs7->stream->length > 0)
wolfSSL 16:8e0d178b1d1e 9540 pkiMsg = pkcs7->stream->buffer;
wolfSSL 16:8e0d178b1d1e 9541 #endif
wolfSSL 15:117db924cf7c 9542
wolfSSL 15:117db924cf7c 9543 /* when looking for next recipient, use first sequence and version to
wolfSSL 15:117db924cf7c 9544 * indicate there is another, if not, move on */
wolfSSL 15:117db924cf7c 9545 while(*recipFound == 0) {
wolfSSL 15:117db924cf7c 9546
wolfSSL 15:117db924cf7c 9547 /* remove RecipientInfo, if we don't have a SEQUENCE, back up idx to
wolfSSL 15:117db924cf7c 9548 * last good saved one */
wolfSSL 15:117db924cf7c 9549 if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) > 0) {
wolfSSL 15:117db924cf7c 9550
wolfSSL 15:117db924cf7c 9551 #ifndef NO_RSA
wolfSSL 15:117db924cf7c 9552 /* found ktri */
wolfSSL 16:8e0d178b1d1e 9553 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 9554 if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 9555 break;
wolfSSL 16:8e0d178b1d1e 9556 }
wolfSSL 16:8e0d178b1d1e 9557 #endif
wolfSSL 16:8e0d178b1d1e 9558 wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_DECRYPT_KTRI);
wolfSSL 16:8e0d178b1d1e 9559 ret = wc_PKCS7_DecryptKtri(pkcs7, in, inSz, idx,
wolfSSL 15:117db924cf7c 9560 decryptedKey, decryptedKeySz,
wolfSSL 15:117db924cf7c 9561 recipFound);
wolfSSL 15:117db924cf7c 9562 if (ret != 0)
wolfSSL 15:117db924cf7c 9563 return ret;
wolfSSL 15:117db924cf7c 9564 #else
wolfSSL 15:117db924cf7c 9565 return NOT_COMPILED_IN;
wolfSSL 15:117db924cf7c 9566 #endif
wolfSSL 15:117db924cf7c 9567 }
wolfSSL 15:117db924cf7c 9568 else {
wolfSSL 16:8e0d178b1d1e 9569 word32 localIdx;
wolfSSL 15:117db924cf7c 9570 /* kari is IMPLICIT[1] */
wolfSSL 15:117db924cf7c 9571 *idx = savedIdx;
wolfSSL 16:8e0d178b1d1e 9572 localIdx = *idx;
wolfSSL 16:8e0d178b1d1e 9573
wolfSSL 16:8e0d178b1d1e 9574 if (GetASNTag(pkiMsg, &localIdx, &tag, pkiMsgSz) != 0) {
wolfSSL 16:8e0d178b1d1e 9575 /* no room for recipient info */
wolfSSL 16:8e0d178b1d1e 9576 break;
wolfSSL 16:8e0d178b1d1e 9577 }
wolfSSL 16:8e0d178b1d1e 9578
wolfSSL 16:8e0d178b1d1e 9579 if (tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) {
wolfSSL 15:117db924cf7c 9580 (*idx)++;
wolfSSL 15:117db924cf7c 9581 if (GetLength(pkiMsg, idx, &length, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 9582 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 9583
wolfSSL 15:117db924cf7c 9584 if (GetMyVersion(pkiMsg, idx, &version, pkiMsgSz) < 0) {
wolfSSL 15:117db924cf7c 9585 *idx = savedIdx;
wolfSSL 15:117db924cf7c 9586 break;
wolfSSL 15:117db924cf7c 9587 }
wolfSSL 15:117db924cf7c 9588
wolfSSL 15:117db924cf7c 9589 if (version != 3)
wolfSSL 15:117db924cf7c 9590 return ASN_VERSION_E;
wolfSSL 15:117db924cf7c 9591
wolfSSL 15:117db924cf7c 9592 /* found kari */
wolfSSL 16:8e0d178b1d1e 9593 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 9594 if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 9595 break;
wolfSSL 16:8e0d178b1d1e 9596 }
wolfSSL 16:8e0d178b1d1e 9597 #endif
wolfSSL 16:8e0d178b1d1e 9598 wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_DECRYPT_KARI);
wolfSSL 16:8e0d178b1d1e 9599 ret = wc_PKCS7_DecryptKari(pkcs7, in, inSz, idx,
wolfSSL 15:117db924cf7c 9600 decryptedKey, decryptedKeySz,
wolfSSL 15:117db924cf7c 9601 recipFound);
wolfSSL 15:117db924cf7c 9602 if (ret != 0)
wolfSSL 15:117db924cf7c 9603 return ret;
wolfSSL 16:8e0d178b1d1e 9604
wolfSSL 16:8e0d178b1d1e 9605 /* kekri is IMPLICIT[2] */
wolfSSL 16:8e0d178b1d1e 9606 } else if (tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 2)) {
wolfSSL 16:8e0d178b1d1e 9607 (*idx)++;
wolfSSL 16:8e0d178b1d1e 9608
wolfSSL 16:8e0d178b1d1e 9609 if (GetLength(pkiMsg, idx, &version, pkiMsgSz) < 0)
wolfSSL 16:8e0d178b1d1e 9610 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 9611
wolfSSL 16:8e0d178b1d1e 9612 if (GetMyVersion(pkiMsg, idx, &version, pkiMsgSz) < 0) {
wolfSSL 16:8e0d178b1d1e 9613 *idx = savedIdx;
wolfSSL 16:8e0d178b1d1e 9614 break;
wolfSSL 16:8e0d178b1d1e 9615 }
wolfSSL 16:8e0d178b1d1e 9616
wolfSSL 16:8e0d178b1d1e 9617 if (version != 4)
wolfSSL 16:8e0d178b1d1e 9618 return ASN_VERSION_E;
wolfSSL 16:8e0d178b1d1e 9619
wolfSSL 16:8e0d178b1d1e 9620 /* found kekri */
wolfSSL 16:8e0d178b1d1e 9621 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 9622 if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 9623 break;
wolfSSL 16:8e0d178b1d1e 9624 }
wolfSSL 16:8e0d178b1d1e 9625 #endif
wolfSSL 16:8e0d178b1d1e 9626 wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_DECRYPT_KEKRI);
wolfSSL 16:8e0d178b1d1e 9627 ret = wc_PKCS7_DecryptKekri(pkcs7, in, inSz, idx,
wolfSSL 16:8e0d178b1d1e 9628 decryptedKey, decryptedKeySz,
wolfSSL 16:8e0d178b1d1e 9629 recipFound);
wolfSSL 16:8e0d178b1d1e 9630 if (ret != 0)
wolfSSL 16:8e0d178b1d1e 9631 return ret;
wolfSSL 16:8e0d178b1d1e 9632
wolfSSL 16:8e0d178b1d1e 9633 /* pwri is IMPLICIT[3] */
wolfSSL 16:8e0d178b1d1e 9634 } else if (tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 3)) {
wolfSSL 16:8e0d178b1d1e 9635 #if !defined(NO_PWDBASED) && !defined(NO_SHA)
wolfSSL 16:8e0d178b1d1e 9636 (*idx)++;
wolfSSL 16:8e0d178b1d1e 9637
wolfSSL 16:8e0d178b1d1e 9638 if (GetLength(pkiMsg, idx, &version, pkiMsgSz) < 0)
wolfSSL 16:8e0d178b1d1e 9639 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 9640
wolfSSL 16:8e0d178b1d1e 9641 if (GetMyVersion(pkiMsg, idx, &version, pkiMsgSz) < 0) {
wolfSSL 16:8e0d178b1d1e 9642 *idx = savedIdx;
wolfSSL 16:8e0d178b1d1e 9643 break;
wolfSSL 16:8e0d178b1d1e 9644 }
wolfSSL 16:8e0d178b1d1e 9645
wolfSSL 16:8e0d178b1d1e 9646 if (version != 0)
wolfSSL 16:8e0d178b1d1e 9647 return ASN_VERSION_E;
wolfSSL 16:8e0d178b1d1e 9648
wolfSSL 16:8e0d178b1d1e 9649 /* found pwri */
wolfSSL 16:8e0d178b1d1e 9650 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 9651 if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 9652 break;
wolfSSL 16:8e0d178b1d1e 9653 }
wolfSSL 16:8e0d178b1d1e 9654 #endif
wolfSSL 16:8e0d178b1d1e 9655 wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_DECRYPT_PWRI);
wolfSSL 16:8e0d178b1d1e 9656 ret = wc_PKCS7_DecryptPwri(pkcs7, in, inSz, idx,
wolfSSL 16:8e0d178b1d1e 9657 decryptedKey, decryptedKeySz,
wolfSSL 16:8e0d178b1d1e 9658 recipFound);
wolfSSL 16:8e0d178b1d1e 9659 if (ret != 0)
wolfSSL 16:8e0d178b1d1e 9660 return ret;
wolfSSL 16:8e0d178b1d1e 9661 #else
wolfSSL 16:8e0d178b1d1e 9662 return NOT_COMPILED_IN;
wolfSSL 16:8e0d178b1d1e 9663 #endif
wolfSSL 16:8e0d178b1d1e 9664
wolfSSL 16:8e0d178b1d1e 9665 /* ori is IMPLICIT[4] */
wolfSSL 16:8e0d178b1d1e 9666 } else if (tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 4)) {
wolfSSL 16:8e0d178b1d1e 9667 (*idx)++;
wolfSSL 16:8e0d178b1d1e 9668
wolfSSL 16:8e0d178b1d1e 9669 /* found ori */
wolfSSL 16:8e0d178b1d1e 9670 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 9671 if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 9672 break;
wolfSSL 16:8e0d178b1d1e 9673 }
wolfSSL 16:8e0d178b1d1e 9674 #endif
wolfSSL 16:8e0d178b1d1e 9675 wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_DECRYPT_ORI);
wolfSSL 16:8e0d178b1d1e 9676 ret = wc_PKCS7_DecryptOri(pkcs7, in, inSz, idx,
wolfSSL 16:8e0d178b1d1e 9677 decryptedKey, decryptedKeySz,
wolfSSL 16:8e0d178b1d1e 9678 recipFound);
wolfSSL 16:8e0d178b1d1e 9679 if (ret != 0)
wolfSSL 16:8e0d178b1d1e 9680 return ret;
wolfSSL 16:8e0d178b1d1e 9681
wolfSSL 16:8e0d178b1d1e 9682 } else {
wolfSSL 15:117db924cf7c 9683 /* failed to find RecipientInfo, restore idx and continue */
wolfSSL 15:117db924cf7c 9684 *idx = savedIdx;
wolfSSL 15:117db924cf7c 9685 break;
wolfSSL 15:117db924cf7c 9686 }
wolfSSL 15:117db924cf7c 9687 }
wolfSSL 15:117db924cf7c 9688
wolfSSL 15:117db924cf7c 9689 /* update good idx */
wolfSSL 15:117db924cf7c 9690 savedIdx = *idx;
wolfSSL 15:117db924cf7c 9691 }
wolfSSL 15:117db924cf7c 9692
wolfSSL 16:8e0d178b1d1e 9693 return ret;
wolfSSL 16:8e0d178b1d1e 9694 }
wolfSSL 16:8e0d178b1d1e 9695
wolfSSL 16:8e0d178b1d1e 9696
wolfSSL 16:8e0d178b1d1e 9697 /* Parse encoded EnvelopedData bundle up to RecipientInfo set.
wolfSSL 16:8e0d178b1d1e 9698 *
wolfSSL 16:8e0d178b1d1e 9699 * return size of RecipientInfo SET on success, negative upon error */
wolfSSL 16:8e0d178b1d1e 9700 static int wc_PKCS7_ParseToRecipientInfoSet(PKCS7* pkcs7, byte* in,
wolfSSL 16:8e0d178b1d1e 9701 word32 inSz, word32* idx,
wolfSSL 16:8e0d178b1d1e 9702 int type)
wolfSSL 16:8e0d178b1d1e 9703 {
wolfSSL 16:8e0d178b1d1e 9704 int version = 0, length, ret = 0;
wolfSSL 16:8e0d178b1d1e 9705 word32 contentType;
wolfSSL 16:8e0d178b1d1e 9706 byte* pkiMsg = in;
wolfSSL 16:8e0d178b1d1e 9707 word32 pkiMsgSz = inSz;
wolfSSL 16:8e0d178b1d1e 9708 byte tag;
wolfSSL 16:8e0d178b1d1e 9709 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 9710 word32 tmpIdx = 0;
wolfSSL 16:8e0d178b1d1e 9711 long rc;
wolfSSL 16:8e0d178b1d1e 9712 #endif
wolfSSL 16:8e0d178b1d1e 9713
wolfSSL 16:8e0d178b1d1e 9714 if (pkcs7 == NULL || pkiMsg == NULL || pkiMsgSz == 0 || idx == NULL)
wolfSSL 16:8e0d178b1d1e 9715 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 9716
wolfSSL 16:8e0d178b1d1e 9717 if ((type != ENVELOPED_DATA) && (type != AUTH_ENVELOPED_DATA) &&
wolfSSL 16:8e0d178b1d1e 9718 pkcs7->contentOID != FIRMWARE_PKG_DATA)
wolfSSL 16:8e0d178b1d1e 9719 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 9720
wolfSSL 16:8e0d178b1d1e 9721 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 9722 if (pkcs7->stream == NULL) {
wolfSSL 16:8e0d178b1d1e 9723 if ((ret = wc_PKCS7_CreateStream(pkcs7)) != 0) {
wolfSSL 16:8e0d178b1d1e 9724 return ret;
wolfSSL 16:8e0d178b1d1e 9725 }
wolfSSL 16:8e0d178b1d1e 9726 }
wolfSSL 16:8e0d178b1d1e 9727 #endif
wolfSSL 16:8e0d178b1d1e 9728
wolfSSL 16:8e0d178b1d1e 9729 switch (pkcs7->state) {
wolfSSL 16:8e0d178b1d1e 9730 case WC_PKCS7_INFOSET_START:
wolfSSL 16:8e0d178b1d1e 9731 case WC_PKCS7_INFOSET_BER:
wolfSSL 16:8e0d178b1d1e 9732 case WC_PKCS7_INFOSET_STAGE1:
wolfSSL 16:8e0d178b1d1e 9733 case WC_PKCS7_INFOSET_STAGE2:
wolfSSL 16:8e0d178b1d1e 9734 case WC_PKCS7_INFOSET_END:
wolfSSL 16:8e0d178b1d1e 9735 break;
wolfSSL 16:8e0d178b1d1e 9736
wolfSSL 16:8e0d178b1d1e 9737 default:
wolfSSL 16:8e0d178b1d1e 9738 WOLFSSL_MSG("Warning, setting PKCS7 info state to start");
wolfSSL 16:8e0d178b1d1e 9739 wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_INFOSET_START);
wolfSSL 16:8e0d178b1d1e 9740 }
wolfSSL 16:8e0d178b1d1e 9741
wolfSSL 16:8e0d178b1d1e 9742 switch (pkcs7->state) {
wolfSSL 16:8e0d178b1d1e 9743 case WC_PKCS7_INFOSET_START:
wolfSSL 16:8e0d178b1d1e 9744 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 9745 if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_SEQ_SZ +
wolfSSL 16:8e0d178b1d1e 9746 ASN_TAG_SZ, &pkiMsg, idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 9747 return ret;
wolfSSL 16:8e0d178b1d1e 9748 }
wolfSSL 16:8e0d178b1d1e 9749
wolfSSL 16:8e0d178b1d1e 9750 rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_SEQ_PEEK, in, inSz);
wolfSSL 16:8e0d178b1d1e 9751 if (rc < 0) {
wolfSSL 16:8e0d178b1d1e 9752 ret = (int)rc;
wolfSSL 16:8e0d178b1d1e 9753 break;
wolfSSL 16:8e0d178b1d1e 9754 }
wolfSSL 16:8e0d178b1d1e 9755 pkiMsgSz = (word32)rc;
wolfSSL 16:8e0d178b1d1e 9756 #endif
wolfSSL 16:8e0d178b1d1e 9757 /* read past ContentInfo, verify type is envelopedData */
wolfSSL 16:8e0d178b1d1e 9758 if (ret == 0 && GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0)
wolfSSL 16:8e0d178b1d1e 9759 {
wolfSSL 16:8e0d178b1d1e 9760 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 9761 }
wolfSSL 16:8e0d178b1d1e 9762
wolfSSL 16:8e0d178b1d1e 9763 if (ret == 0 && length == 0 && pkiMsg[(*idx)-1] == 0x80) {
wolfSSL 16:8e0d178b1d1e 9764 #ifdef ASN_BER_TO_DER
wolfSSL 16:8e0d178b1d1e 9765 word32 len;
wolfSSL 16:8e0d178b1d1e 9766
wolfSSL 16:8e0d178b1d1e 9767 wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_INFOSET_BER);
wolfSSL 16:8e0d178b1d1e 9768 FALL_THROUGH;
wolfSSL 16:8e0d178b1d1e 9769
wolfSSL 16:8e0d178b1d1e 9770 /* full buffer is needed for conversion */
wolfSSL 16:8e0d178b1d1e 9771 case WC_PKCS7_INFOSET_BER:
wolfSSL 16:8e0d178b1d1e 9772 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 9773 if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
wolfSSL 16:8e0d178b1d1e 9774 pkcs7->stream->maxLen - pkcs7->stream->length,
wolfSSL 16:8e0d178b1d1e 9775 &pkiMsg, idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 9776 return ret;
wolfSSL 16:8e0d178b1d1e 9777 }
wolfSSL 16:8e0d178b1d1e 9778
wolfSSL 16:8e0d178b1d1e 9779 rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK,
wolfSSL 16:8e0d178b1d1e 9780 in, inSz);
wolfSSL 16:8e0d178b1d1e 9781 if (rc < 0) {
wolfSSL 16:8e0d178b1d1e 9782 ret = (int)rc;
wolfSSL 16:8e0d178b1d1e 9783 break;
wolfSSL 16:8e0d178b1d1e 9784 }
wolfSSL 16:8e0d178b1d1e 9785 pkiMsgSz = (word32)rc;
wolfSSL 16:8e0d178b1d1e 9786 #endif
wolfSSL 16:8e0d178b1d1e 9787
wolfSSL 16:8e0d178b1d1e 9788 len = 0;
wolfSSL 16:8e0d178b1d1e 9789
wolfSSL 16:8e0d178b1d1e 9790 ret = wc_BerToDer(pkiMsg, pkiMsgSz, NULL, &len);
wolfSSL 16:8e0d178b1d1e 9791 if (ret != LENGTH_ONLY_E)
wolfSSL 16:8e0d178b1d1e 9792 return ret;
wolfSSL 16:8e0d178b1d1e 9793 pkcs7->der = (byte*)XMALLOC(len, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 9794 if (pkcs7->der == NULL)
wolfSSL 16:8e0d178b1d1e 9795 return MEMORY_E;
wolfSSL 16:8e0d178b1d1e 9796 ret = wc_BerToDer(pkiMsg, pkiMsgSz, pkcs7->der, &len);
wolfSSL 16:8e0d178b1d1e 9797 if (ret < 0)
wolfSSL 16:8e0d178b1d1e 9798 return ret;
wolfSSL 16:8e0d178b1d1e 9799
wolfSSL 16:8e0d178b1d1e 9800 pkiMsg = in = pkcs7->der;
wolfSSL 16:8e0d178b1d1e 9801 pkiMsgSz = pkcs7->derSz = len;
wolfSSL 16:8e0d178b1d1e 9802 *idx = 0;
wolfSSL 16:8e0d178b1d1e 9803
wolfSSL 16:8e0d178b1d1e 9804 if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0)
wolfSSL 16:8e0d178b1d1e 9805 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 9806 #else
wolfSSL 16:8e0d178b1d1e 9807 return BER_INDEF_E;
wolfSSL 16:8e0d178b1d1e 9808 #endif
wolfSSL 16:8e0d178b1d1e 9809 }
wolfSSL 16:8e0d178b1d1e 9810 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 9811 if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 9812 break;
wolfSSL 16:8e0d178b1d1e 9813 }
wolfSSL 16:8e0d178b1d1e 9814 #endif
wolfSSL 16:8e0d178b1d1e 9815 wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_INFOSET_STAGE1);
wolfSSL 16:8e0d178b1d1e 9816 FALL_THROUGH;
wolfSSL 16:8e0d178b1d1e 9817
wolfSSL 16:8e0d178b1d1e 9818 case WC_PKCS7_INFOSET_STAGE1:
wolfSSL 16:8e0d178b1d1e 9819 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 9820 if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_OID_SZ +
wolfSSL 16:8e0d178b1d1e 9821 MAX_LENGTH_SZ + ASN_TAG_SZ, &pkiMsg, idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 9822 return ret;
wolfSSL 16:8e0d178b1d1e 9823 }
wolfSSL 16:8e0d178b1d1e 9824
wolfSSL 16:8e0d178b1d1e 9825 pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length :inSz;
wolfSSL 16:8e0d178b1d1e 9826 #endif
wolfSSL 16:8e0d178b1d1e 9827 if (pkcs7->contentOID != FIRMWARE_PKG_DATA ||
wolfSSL 16:8e0d178b1d1e 9828 type == AUTH_ENVELOPED_DATA) {
wolfSSL 16:8e0d178b1d1e 9829 if (ret == 0 && wc_GetContentType(pkiMsg, idx, &contentType,
wolfSSL 16:8e0d178b1d1e 9830 pkiMsgSz) < 0)
wolfSSL 16:8e0d178b1d1e 9831 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 9832
wolfSSL 16:8e0d178b1d1e 9833 if (ret == 0) {
wolfSSL 16:8e0d178b1d1e 9834 if (type == ENVELOPED_DATA && contentType != ENVELOPED_DATA) {
wolfSSL 16:8e0d178b1d1e 9835 WOLFSSL_MSG("PKCS#7 input not of type EnvelopedData");
wolfSSL 16:8e0d178b1d1e 9836 ret = PKCS7_OID_E;
wolfSSL 16:8e0d178b1d1e 9837 } else if (type == AUTH_ENVELOPED_DATA &&
wolfSSL 16:8e0d178b1d1e 9838 contentType != AUTH_ENVELOPED_DATA) {
wolfSSL 16:8e0d178b1d1e 9839 WOLFSSL_MSG("PKCS#7 input not of type AuthEnvelopedData");
wolfSSL 16:8e0d178b1d1e 9840 ret = PKCS7_OID_E;
wolfSSL 16:8e0d178b1d1e 9841 }
wolfSSL 16:8e0d178b1d1e 9842 }
wolfSSL 16:8e0d178b1d1e 9843
wolfSSL 16:8e0d178b1d1e 9844 if (ret == 0 && GetASNTag(pkiMsg, idx, &tag, pkiMsgSz) != 0)
wolfSSL 16:8e0d178b1d1e 9845 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 9846
wolfSSL 16:8e0d178b1d1e 9847 if (ret == 0 && tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC
wolfSSL 16:8e0d178b1d1e 9848 | 0))
wolfSSL 16:8e0d178b1d1e 9849 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 9850
wolfSSL 16:8e0d178b1d1e 9851 if (ret == 0 && GetLength_ex(pkiMsg, idx, &length, pkiMsgSz,
wolfSSL 16:8e0d178b1d1e 9852 NO_USER_CHECK) < 0)
wolfSSL 16:8e0d178b1d1e 9853 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 9854 }
wolfSSL 16:8e0d178b1d1e 9855
wolfSSL 16:8e0d178b1d1e 9856 if (ret < 0)
wolfSSL 16:8e0d178b1d1e 9857 break;
wolfSSL 16:8e0d178b1d1e 9858
wolfSSL 16:8e0d178b1d1e 9859 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 9860 if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 9861 break;
wolfSSL 16:8e0d178b1d1e 9862 }
wolfSSL 16:8e0d178b1d1e 9863 #endif
wolfSSL 16:8e0d178b1d1e 9864 wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_INFOSET_STAGE2);
wolfSSL 16:8e0d178b1d1e 9865 FALL_THROUGH;
wolfSSL 16:8e0d178b1d1e 9866
wolfSSL 16:8e0d178b1d1e 9867 case WC_PKCS7_INFOSET_STAGE2:
wolfSSL 16:8e0d178b1d1e 9868 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 9869 if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_SEQ_SZ +
wolfSSL 16:8e0d178b1d1e 9870 MAX_VERSION_SZ, &pkiMsg, idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 9871 return ret;
wolfSSL 16:8e0d178b1d1e 9872 }
wolfSSL 16:8e0d178b1d1e 9873
wolfSSL 16:8e0d178b1d1e 9874 rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK, in,
wolfSSL 16:8e0d178b1d1e 9875 inSz);
wolfSSL 16:8e0d178b1d1e 9876 if (rc < 0) {
wolfSSL 16:8e0d178b1d1e 9877 ret = (int)rc;
wolfSSL 16:8e0d178b1d1e 9878 break;
wolfSSL 16:8e0d178b1d1e 9879 }
wolfSSL 16:8e0d178b1d1e 9880 pkiMsgSz = (word32)rc;
wolfSSL 16:8e0d178b1d1e 9881 #endif
wolfSSL 16:8e0d178b1d1e 9882 /* remove EnvelopedData and version */
wolfSSL 16:8e0d178b1d1e 9883 if (pkcs7->contentOID != FIRMWARE_PKG_DATA ||
wolfSSL 16:8e0d178b1d1e 9884 type == AUTH_ENVELOPED_DATA) {
wolfSSL 16:8e0d178b1d1e 9885 if (ret == 0 && GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0)
wolfSSL 16:8e0d178b1d1e 9886 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 9887 }
wolfSSL 16:8e0d178b1d1e 9888
wolfSSL 16:8e0d178b1d1e 9889 if (ret == 0 && GetMyVersion(pkiMsg, idx, &version, pkiMsgSz) < 0)
wolfSSL 16:8e0d178b1d1e 9890 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 9891
wolfSSL 16:8e0d178b1d1e 9892 if (ret < 0)
wolfSSL 16:8e0d178b1d1e 9893 break;
wolfSSL 16:8e0d178b1d1e 9894
wolfSSL 16:8e0d178b1d1e 9895 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 9896 if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 9897 break;
wolfSSL 16:8e0d178b1d1e 9898 }
wolfSSL 16:8e0d178b1d1e 9899
wolfSSL 16:8e0d178b1d1e 9900 pkcs7->stream->varOne = version;
wolfSSL 16:8e0d178b1d1e 9901 #endif
wolfSSL 16:8e0d178b1d1e 9902 wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_INFOSET_END);
wolfSSL 16:8e0d178b1d1e 9903 FALL_THROUGH;
wolfSSL 16:8e0d178b1d1e 9904
wolfSSL 16:8e0d178b1d1e 9905 case WC_PKCS7_INFOSET_END:
wolfSSL 16:8e0d178b1d1e 9906 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 9907 if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
wolfSSL 16:8e0d178b1d1e 9908 MAX_SET_SZ, &pkiMsg, idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 9909 return ret;
wolfSSL 16:8e0d178b1d1e 9910 }
wolfSSL 16:8e0d178b1d1e 9911
wolfSSL 16:8e0d178b1d1e 9912 rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK, in,
wolfSSL 16:8e0d178b1d1e 9913 inSz);
wolfSSL 16:8e0d178b1d1e 9914 if (rc < 0) {
wolfSSL 16:8e0d178b1d1e 9915 ret = (int)rc;
wolfSSL 16:8e0d178b1d1e 9916 break;
wolfSSL 16:8e0d178b1d1e 9917 }
wolfSSL 16:8e0d178b1d1e 9918 pkiMsgSz = (word32)rc;
wolfSSL 16:8e0d178b1d1e 9919 version = pkcs7->stream->varOne;
wolfSSL 16:8e0d178b1d1e 9920 #endif
wolfSSL 16:8e0d178b1d1e 9921
wolfSSL 16:8e0d178b1d1e 9922 if (type == ENVELOPED_DATA) {
wolfSSL 16:8e0d178b1d1e 9923 /* TODO :: make this more accurate */
wolfSSL 16:8e0d178b1d1e 9924 if ((pkcs7->publicKeyOID == RSAk &&
wolfSSL 16:8e0d178b1d1e 9925 (version != 0 && version != 2))
wolfSSL 16:8e0d178b1d1e 9926 #ifdef HAVE_ECC
wolfSSL 16:8e0d178b1d1e 9927 || (pkcs7->publicKeyOID == ECDSAk &&
wolfSSL 16:8e0d178b1d1e 9928 (version != 0 && version != 2 && version != 3))
wolfSSL 16:8e0d178b1d1e 9929 #endif
wolfSSL 16:8e0d178b1d1e 9930 ) {
wolfSSL 16:8e0d178b1d1e 9931 WOLFSSL_MSG("PKCS#7 envelopedData version incorrect");
wolfSSL 16:8e0d178b1d1e 9932 ret = ASN_VERSION_E;
wolfSSL 16:8e0d178b1d1e 9933 }
wolfSSL 16:8e0d178b1d1e 9934 } else {
wolfSSL 16:8e0d178b1d1e 9935 /* AuthEnvelopedData version MUST be 0 */
wolfSSL 16:8e0d178b1d1e 9936 if (version != 0) {
wolfSSL 16:8e0d178b1d1e 9937 WOLFSSL_MSG("PKCS#7 AuthEnvelopedData needs to be of version 0");
wolfSSL 16:8e0d178b1d1e 9938 ret = ASN_VERSION_E;
wolfSSL 16:8e0d178b1d1e 9939 }
wolfSSL 16:8e0d178b1d1e 9940 }
wolfSSL 16:8e0d178b1d1e 9941
wolfSSL 16:8e0d178b1d1e 9942 /* remove RecipientInfo set, get length of set */
wolfSSL 16:8e0d178b1d1e 9943 if (ret == 0 && GetSet(pkiMsg, idx, &length, pkiMsgSz) < 0)
wolfSSL 16:8e0d178b1d1e 9944 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 9945
wolfSSL 16:8e0d178b1d1e 9946 if (ret < 0)
wolfSSL 16:8e0d178b1d1e 9947 break;
wolfSSL 16:8e0d178b1d1e 9948
wolfSSL 16:8e0d178b1d1e 9949 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 9950 if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 9951 break;
wolfSSL 16:8e0d178b1d1e 9952 }
wolfSSL 16:8e0d178b1d1e 9953 #endif
wolfSSL 16:8e0d178b1d1e 9954
wolfSSL 16:8e0d178b1d1e 9955 if (ret == 0)
wolfSSL 16:8e0d178b1d1e 9956 ret = length;
wolfSSL 16:8e0d178b1d1e 9957
wolfSSL 16:8e0d178b1d1e 9958 break;
wolfSSL 16:8e0d178b1d1e 9959
wolfSSL 16:8e0d178b1d1e 9960 default:
wolfSSL 16:8e0d178b1d1e 9961 WOLFSSL_MSG("Bad PKCS7 info set state");
wolfSSL 16:8e0d178b1d1e 9962 ret = BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 9963 break;
wolfSSL 16:8e0d178b1d1e 9964 }
wolfSSL 16:8e0d178b1d1e 9965
wolfSSL 16:8e0d178b1d1e 9966 return ret;
wolfSSL 16:8e0d178b1d1e 9967 }
wolfSSL 16:8e0d178b1d1e 9968
wolfSSL 16:8e0d178b1d1e 9969
wolfSSL 16:8e0d178b1d1e 9970 /* Import secret/private key into a PKCS7 structure. Used for setting
wolfSSL 16:8e0d178b1d1e 9971 * the secret key for decryption a EnvelopedData KEKRI RecipientInfo.
wolfSSL 16:8e0d178b1d1e 9972 *
wolfSSL 16:8e0d178b1d1e 9973 * Returns 0 on success, negative upon error */
wolfSSL 16:8e0d178b1d1e 9974 WOLFSSL_API int wc_PKCS7_SetKey(PKCS7* pkcs7, byte* key, word32 keySz)
wolfSSL 16:8e0d178b1d1e 9975 {
wolfSSL 16:8e0d178b1d1e 9976 if (pkcs7 == NULL || key == NULL || keySz == 0)
wolfSSL 16:8e0d178b1d1e 9977 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 9978
wolfSSL 16:8e0d178b1d1e 9979 pkcs7->privateKey = key;
wolfSSL 16:8e0d178b1d1e 9980 pkcs7->privateKeySz = keySz;
wolfSSL 16:8e0d178b1d1e 9981
wolfSSL 16:8e0d178b1d1e 9982 return 0;
wolfSSL 16:8e0d178b1d1e 9983 }
wolfSSL 16:8e0d178b1d1e 9984
wolfSSL 16:8e0d178b1d1e 9985
wolfSSL 16:8e0d178b1d1e 9986 /* append data to encrypted content cache in PKCS7 structure
wolfSSL 16:8e0d178b1d1e 9987 * return 0 on success, negative on error */
wolfSSL 16:8e0d178b1d1e 9988 static int PKCS7_CacheEncryptedContent(PKCS7* pkcs7, byte* in, word32 inSz)
wolfSSL 16:8e0d178b1d1e 9989 {
wolfSSL 16:8e0d178b1d1e 9990 byte* oldCache;
wolfSSL 16:8e0d178b1d1e 9991 word32 oldCacheSz;
wolfSSL 16:8e0d178b1d1e 9992
wolfSSL 16:8e0d178b1d1e 9993 if (pkcs7 == NULL || in == NULL)
wolfSSL 16:8e0d178b1d1e 9994 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 9995
wolfSSL 16:8e0d178b1d1e 9996 /* save pointer to old cache */
wolfSSL 16:8e0d178b1d1e 9997 oldCache = pkcs7->cachedEncryptedContent;
wolfSSL 16:8e0d178b1d1e 9998 oldCacheSz = pkcs7->cachedEncryptedContentSz;
wolfSSL 16:8e0d178b1d1e 9999
wolfSSL 16:8e0d178b1d1e 10000 /* re-allocate new buffer to fit appended data */
wolfSSL 16:8e0d178b1d1e 10001 pkcs7->cachedEncryptedContent = (byte*)XMALLOC(oldCacheSz + inSz,
wolfSSL 16:8e0d178b1d1e 10002 pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 10003 if (pkcs7->cachedEncryptedContent == NULL) {
wolfSSL 16:8e0d178b1d1e 10004 pkcs7->cachedEncryptedContentSz = 0;
wolfSSL 16:8e0d178b1d1e 10005 XFREE(oldCache, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 10006 return MEMORY_E;
wolfSSL 16:8e0d178b1d1e 10007 }
wolfSSL 16:8e0d178b1d1e 10008
wolfSSL 16:8e0d178b1d1e 10009 if (oldCache != NULL) {
wolfSSL 16:8e0d178b1d1e 10010 XMEMCPY(pkcs7->cachedEncryptedContent, oldCache, oldCacheSz);
wolfSSL 16:8e0d178b1d1e 10011 }
wolfSSL 16:8e0d178b1d1e 10012 XMEMCPY(pkcs7->cachedEncryptedContent + oldCacheSz, in, inSz);
wolfSSL 16:8e0d178b1d1e 10013 pkcs7->cachedEncryptedContentSz += inSz;
wolfSSL 16:8e0d178b1d1e 10014
wolfSSL 16:8e0d178b1d1e 10015 XFREE(oldCache, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 10016
wolfSSL 15:117db924cf7c 10017 return 0;
wolfSSL 15:117db924cf7c 10018 }
wolfSSL 15:117db924cf7c 10019
wolfSSL 15:117db924cf7c 10020
wolfSSL 15:117db924cf7c 10021 /* unwrap and decrypt PKCS#7 envelopedData object, return decoded size */
wolfSSL 16:8e0d178b1d1e 10022 WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* in,
wolfSSL 16:8e0d178b1d1e 10023 word32 inSz, byte* output,
wolfSSL 15:117db924cf7c 10024 word32 outputSz)
wolfSSL 15:117db924cf7c 10025 {
wolfSSL 15:117db924cf7c 10026 int recipFound = 0;
wolfSSL 16:8e0d178b1d1e 10027 int ret, length = 0;
wolfSSL 15:117db924cf7c 10028 word32 idx = 0;
wolfSSL 16:8e0d178b1d1e 10029 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 10030 word32 tmpIdx = 0;
wolfSSL 16:8e0d178b1d1e 10031 long rc;
wolfSSL 16:8e0d178b1d1e 10032 #endif
wolfSSL 16:8e0d178b1d1e 10033 word32 contentType, encOID = 0;
wolfSSL 16:8e0d178b1d1e 10034 word32 decryptedKeySz = MAX_ENCRYPTED_KEY_SZ;
wolfSSL 16:8e0d178b1d1e 10035
wolfSSL 16:8e0d178b1d1e 10036 int expBlockSz = 0, blockKeySz = 0;
wolfSSL 16:8e0d178b1d1e 10037 byte tmpIvBuf[MAX_CONTENT_IV_SIZE];
wolfSSL 16:8e0d178b1d1e 10038 byte* tmpIv = tmpIvBuf;
wolfSSL 16:8e0d178b1d1e 10039
wolfSSL 16:8e0d178b1d1e 10040 byte* pkiMsg = in;
wolfSSL 16:8e0d178b1d1e 10041 word32 pkiMsgSz = inSz;
wolfSSL 16:8e0d178b1d1e 10042 byte* decryptedKey = NULL;
wolfSSL 16:8e0d178b1d1e 10043 int encryptedContentTotalSz = 0;
wolfSSL 16:8e0d178b1d1e 10044 int encryptedContentSz = 0;
wolfSSL 15:117db924cf7c 10045 byte padLen;
wolfSSL 15:117db924cf7c 10046 byte* encryptedContent = NULL;
wolfSSL 16:8e0d178b1d1e 10047 int explicitOctet = 0;
wolfSSL 16:8e0d178b1d1e 10048 word32 localIdx;
wolfSSL 16:8e0d178b1d1e 10049 byte tag;
wolfSSL 16:8e0d178b1d1e 10050
wolfSSL 16:8e0d178b1d1e 10051 if (pkcs7 == NULL)
wolfSSL 15:117db924cf7c 10052 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 10053
wolfSSL 15:117db924cf7c 10054 if (pkiMsg == NULL || pkiMsgSz == 0 ||
wolfSSL 15:117db924cf7c 10055 output == NULL || outputSz == 0)
wolfSSL 15:117db924cf7c 10056 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 10057
wolfSSL 16:8e0d178b1d1e 10058 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 10059 (void)tmpIv; /* help out static analysis */
wolfSSL 16:8e0d178b1d1e 10060 if (pkcs7->stream == NULL) {
wolfSSL 16:8e0d178b1d1e 10061 if ((ret = wc_PKCS7_CreateStream(pkcs7)) != 0) {
wolfSSL 15:117db924cf7c 10062 return ret;
wolfSSL 16:8e0d178b1d1e 10063 }
wolfSSL 16:8e0d178b1d1e 10064 }
wolfSSL 16:8e0d178b1d1e 10065 #endif
wolfSSL 16:8e0d178b1d1e 10066
wolfSSL 16:8e0d178b1d1e 10067 switch (pkcs7->state) {
wolfSSL 16:8e0d178b1d1e 10068 case WC_PKCS7_START:
wolfSSL 16:8e0d178b1d1e 10069 case WC_PKCS7_INFOSET_START:
wolfSSL 16:8e0d178b1d1e 10070 case WC_PKCS7_INFOSET_BER:
wolfSSL 16:8e0d178b1d1e 10071 case WC_PKCS7_INFOSET_STAGE1:
wolfSSL 16:8e0d178b1d1e 10072 case WC_PKCS7_INFOSET_STAGE2:
wolfSSL 16:8e0d178b1d1e 10073 case WC_PKCS7_INFOSET_END:
wolfSSL 16:8e0d178b1d1e 10074 ret = wc_PKCS7_ParseToRecipientInfoSet(pkcs7, pkiMsg, pkiMsgSz,
wolfSSL 16:8e0d178b1d1e 10075 &idx, ENVELOPED_DATA);
wolfSSL 16:8e0d178b1d1e 10076 if (ret < 0) {
wolfSSL 16:8e0d178b1d1e 10077 break;
wolfSSL 16:8e0d178b1d1e 10078 }
wolfSSL 16:8e0d178b1d1e 10079
wolfSSL 16:8e0d178b1d1e 10080 #ifdef ASN_BER_TO_DER
wolfSSL 16:8e0d178b1d1e 10081 /* check if content was BER and has been converted to DER */
wolfSSL 16:8e0d178b1d1e 10082 if (pkcs7->derSz > 0)
wolfSSL 16:8e0d178b1d1e 10083 pkiMsg = in = pkcs7->der;
wolfSSL 16:8e0d178b1d1e 10084 #endif
wolfSSL 16:8e0d178b1d1e 10085
wolfSSL 16:8e0d178b1d1e 10086 decryptedKey = (byte*)XMALLOC(MAX_ENCRYPTED_KEY_SZ, pkcs7->heap,
wolfSSL 15:117db924cf7c 10087 DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 10088 if (decryptedKey == NULL)
wolfSSL 16:8e0d178b1d1e 10089 return MEMORY_E;
wolfSSL 16:8e0d178b1d1e 10090 wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_ENV_2);
wolfSSL 16:8e0d178b1d1e 10091 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 10092 tmpIdx = idx;
wolfSSL 16:8e0d178b1d1e 10093 pkcs7->stream->aad = decryptedKey;
wolfSSL 16:8e0d178b1d1e 10094 #endif
wolfSSL 16:8e0d178b1d1e 10095 FALL_THROUGH;
wolfSSL 16:8e0d178b1d1e 10096
wolfSSL 16:8e0d178b1d1e 10097 case WC_PKCS7_ENV_2:
wolfSSL 16:8e0d178b1d1e 10098 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 10099 /* store up enough buffer for initial info set decode */
wolfSSL 16:8e0d178b1d1e 10100 if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_LENGTH_SZ +
wolfSSL 16:8e0d178b1d1e 10101 MAX_VERSION_SZ + ASN_TAG_SZ, &pkiMsg, &idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 10102 return ret;
wolfSSL 16:8e0d178b1d1e 10103 }
wolfSSL 16:8e0d178b1d1e 10104 #endif
wolfSSL 16:8e0d178b1d1e 10105 FALL_THROUGH;
wolfSSL 16:8e0d178b1d1e 10106
wolfSSL 16:8e0d178b1d1e 10107 case WC_PKCS7_DECRYPT_KTRI:
wolfSSL 16:8e0d178b1d1e 10108 case WC_PKCS7_DECRYPT_KTRI_2:
wolfSSL 16:8e0d178b1d1e 10109 case WC_PKCS7_DECRYPT_KTRI_3:
wolfSSL 16:8e0d178b1d1e 10110 case WC_PKCS7_DECRYPT_KARI:
wolfSSL 16:8e0d178b1d1e 10111 case WC_PKCS7_DECRYPT_KEKRI:
wolfSSL 16:8e0d178b1d1e 10112 case WC_PKCS7_DECRYPT_PWRI:
wolfSSL 16:8e0d178b1d1e 10113 case WC_PKCS7_DECRYPT_ORI:
wolfSSL 16:8e0d178b1d1e 10114 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 10115 decryptedKey = pkcs7->stream->aad;
wolfSSL 16:8e0d178b1d1e 10116 decryptedKeySz = MAX_ENCRYPTED_KEY_SZ;
wolfSSL 16:8e0d178b1d1e 10117 #endif
wolfSSL 16:8e0d178b1d1e 10118
wolfSSL 16:8e0d178b1d1e 10119 ret = wc_PKCS7_DecryptRecipientInfos(pkcs7, in, inSz, &idx,
wolfSSL 15:117db924cf7c 10120 decryptedKey, &decryptedKeySz,
wolfSSL 15:117db924cf7c 10121 &recipFound);
wolfSSL 16:8e0d178b1d1e 10122 if (ret == 0 && recipFound == 0) {
wolfSSL 16:8e0d178b1d1e 10123 WOLFSSL_MSG("No recipient found in envelopedData that matches input");
wolfSSL 16:8e0d178b1d1e 10124 ret = PKCS7_RECIP_E;
wolfSSL 16:8e0d178b1d1e 10125 }
wolfSSL 16:8e0d178b1d1e 10126
wolfSSL 16:8e0d178b1d1e 10127 if (ret != 0)
wolfSSL 16:8e0d178b1d1e 10128 break;
wolfSSL 16:8e0d178b1d1e 10129 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 10130 tmpIdx = idx;
wolfSSL 16:8e0d178b1d1e 10131 pkcs7->stream->aadSz = decryptedKeySz;
wolfSSL 16:8e0d178b1d1e 10132 #endif
wolfSSL 16:8e0d178b1d1e 10133 wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_ENV_3);
wolfSSL 16:8e0d178b1d1e 10134 FALL_THROUGH;
wolfSSL 16:8e0d178b1d1e 10135
wolfSSL 16:8e0d178b1d1e 10136 case WC_PKCS7_ENV_3:
wolfSSL 16:8e0d178b1d1e 10137
wolfSSL 16:8e0d178b1d1e 10138 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 10139 if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_LENGTH_SZ +
wolfSSL 16:8e0d178b1d1e 10140 MAX_VERSION_SZ + ASN_TAG_SZ +
wolfSSL 16:8e0d178b1d1e 10141 MAX_LENGTH_SZ, &pkiMsg, &idx))
wolfSSL 16:8e0d178b1d1e 10142 != 0) {
wolfSSL 16:8e0d178b1d1e 10143 return ret;
wolfSSL 16:8e0d178b1d1e 10144 }
wolfSSL 16:8e0d178b1d1e 10145
wolfSSL 16:8e0d178b1d1e 10146 rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK, in,
wolfSSL 16:8e0d178b1d1e 10147 inSz);
wolfSSL 16:8e0d178b1d1e 10148 if (rc < 0) {
wolfSSL 16:8e0d178b1d1e 10149 ret = (int)rc;
wolfSSL 16:8e0d178b1d1e 10150 break;
wolfSSL 16:8e0d178b1d1e 10151 }
wolfSSL 16:8e0d178b1d1e 10152 pkiMsgSz = (word32)rc;
wolfSSL 16:8e0d178b1d1e 10153 #else
wolfSSL 16:8e0d178b1d1e 10154 ret = 0;
wolfSSL 16:8e0d178b1d1e 10155 #endif
wolfSSL 16:8e0d178b1d1e 10156
wolfSSL 16:8e0d178b1d1e 10157 /* remove EncryptedContentInfo */
wolfSSL 16:8e0d178b1d1e 10158 if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0) {
wolfSSL 16:8e0d178b1d1e 10159 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 10160 }
wolfSSL 16:8e0d178b1d1e 10161
wolfSSL 16:8e0d178b1d1e 10162 if (ret == 0 && wc_GetContentType(pkiMsg, &idx, &contentType,
wolfSSL 16:8e0d178b1d1e 10163 pkiMsgSz) < 0) {
wolfSSL 16:8e0d178b1d1e 10164 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 10165 }
wolfSSL 16:8e0d178b1d1e 10166
wolfSSL 16:8e0d178b1d1e 10167 if (ret == 0 && GetAlgoId(pkiMsg, &idx, &encOID, oidBlkType,
wolfSSL 16:8e0d178b1d1e 10168 pkiMsgSz) < 0) {
wolfSSL 16:8e0d178b1d1e 10169 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 10170 }
wolfSSL 16:8e0d178b1d1e 10171
wolfSSL 16:8e0d178b1d1e 10172 blockKeySz = wc_PKCS7_GetOIDKeySize(encOID);
wolfSSL 16:8e0d178b1d1e 10173 if (ret == 0 && blockKeySz < 0) {
wolfSSL 16:8e0d178b1d1e 10174 ret = blockKeySz;
wolfSSL 16:8e0d178b1d1e 10175 }
wolfSSL 16:8e0d178b1d1e 10176
wolfSSL 16:8e0d178b1d1e 10177 expBlockSz = wc_PKCS7_GetOIDBlockSize(encOID);
wolfSSL 16:8e0d178b1d1e 10178 if (ret == 0 && expBlockSz < 0) {
wolfSSL 16:8e0d178b1d1e 10179 ret = expBlockSz;
wolfSSL 16:8e0d178b1d1e 10180 }
wolfSSL 16:8e0d178b1d1e 10181
wolfSSL 16:8e0d178b1d1e 10182 /* get block cipher IV, stored in OPTIONAL parameter of AlgoID */
wolfSSL 16:8e0d178b1d1e 10183 if (ret == 0 && GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) != 0) {
wolfSSL 16:8e0d178b1d1e 10184 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 10185 }
wolfSSL 16:8e0d178b1d1e 10186
wolfSSL 16:8e0d178b1d1e 10187 if (ret == 0 && tag != ASN_OCTET_STRING) {
wolfSSL 16:8e0d178b1d1e 10188 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 10189 }
wolfSSL 16:8e0d178b1d1e 10190
wolfSSL 16:8e0d178b1d1e 10191 if (ret == 0 && GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0) {
wolfSSL 16:8e0d178b1d1e 10192 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 10193 }
wolfSSL 16:8e0d178b1d1e 10194
wolfSSL 16:8e0d178b1d1e 10195 if (ret == 0 && length != expBlockSz) {
wolfSSL 16:8e0d178b1d1e 10196 WOLFSSL_MSG("Incorrect IV length, must be of content alg block size");
wolfSSL 16:8e0d178b1d1e 10197 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 10198 }
wolfSSL 16:8e0d178b1d1e 10199
wolfSSL 16:8e0d178b1d1e 10200 if (ret != 0)
wolfSSL 16:8e0d178b1d1e 10201 break;
wolfSSL 16:8e0d178b1d1e 10202 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 10203 if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 10204 break;
wolfSSL 16:8e0d178b1d1e 10205 }
wolfSSL 16:8e0d178b1d1e 10206 wc_PKCS7_StreamStoreVar(pkcs7, encOID, expBlockSz, length);
wolfSSL 16:8e0d178b1d1e 10207 pkcs7->stream->contentSz = blockKeySz;
wolfSSL 16:8e0d178b1d1e 10208 pkcs7->stream->expected = length + MAX_LENGTH_SZ + MAX_LENGTH_SZ +
wolfSSL 16:8e0d178b1d1e 10209 ASN_TAG_SZ + ASN_TAG_SZ;
wolfSSL 16:8e0d178b1d1e 10210 #endif
wolfSSL 16:8e0d178b1d1e 10211 wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_ENV_4);
wolfSSL 16:8e0d178b1d1e 10212 FALL_THROUGH;
wolfSSL 16:8e0d178b1d1e 10213
wolfSSL 16:8e0d178b1d1e 10214 case WC_PKCS7_ENV_4:
wolfSSL 16:8e0d178b1d1e 10215
wolfSSL 16:8e0d178b1d1e 10216 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 10217 if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
wolfSSL 16:8e0d178b1d1e 10218 pkcs7->stream->expected, &pkiMsg, &idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 10219 return ret;
wolfSSL 16:8e0d178b1d1e 10220 }
wolfSSL 16:8e0d178b1d1e 10221
wolfSSL 16:8e0d178b1d1e 10222 rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK, in,
wolfSSL 16:8e0d178b1d1e 10223 inSz);
wolfSSL 16:8e0d178b1d1e 10224 if (rc < 0) {
wolfSSL 16:8e0d178b1d1e 10225 ret = (int)rc;
wolfSSL 16:8e0d178b1d1e 10226 break;
wolfSSL 16:8e0d178b1d1e 10227 }
wolfSSL 16:8e0d178b1d1e 10228 pkiMsgSz = (word32)rc;
wolfSSL 16:8e0d178b1d1e 10229
wolfSSL 16:8e0d178b1d1e 10230 wc_PKCS7_StreamGetVar(pkcs7, 0, 0, &length);
wolfSSL 16:8e0d178b1d1e 10231 tmpIv = pkcs7->stream->tmpIv;
wolfSSL 16:8e0d178b1d1e 10232 if (tmpIv == NULL) {
wolfSSL 16:8e0d178b1d1e 10233 /* check added to help out static analysis tool */
wolfSSL 16:8e0d178b1d1e 10234 ret = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 10235 break;
wolfSSL 16:8e0d178b1d1e 10236 }
wolfSSL 16:8e0d178b1d1e 10237 #else
wolfSSL 16:8e0d178b1d1e 10238 ret = 0;
wolfSSL 16:8e0d178b1d1e 10239 #endif
wolfSSL 16:8e0d178b1d1e 10240
wolfSSL 16:8e0d178b1d1e 10241 XMEMCPY(tmpIv, &pkiMsg[idx], length);
wolfSSL 16:8e0d178b1d1e 10242 idx += length;
wolfSSL 16:8e0d178b1d1e 10243
wolfSSL 16:8e0d178b1d1e 10244 explicitOctet = 0;
wolfSSL 16:8e0d178b1d1e 10245 localIdx = idx;
wolfSSL 16:8e0d178b1d1e 10246 if (GetASNTag(pkiMsg, &localIdx, &tag, pkiMsgSz) == 0 &&
wolfSSL 16:8e0d178b1d1e 10247 tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0)) {
wolfSSL 16:8e0d178b1d1e 10248 explicitOctet = 1;
wolfSSL 16:8e0d178b1d1e 10249 }
wolfSSL 16:8e0d178b1d1e 10250
wolfSSL 16:8e0d178b1d1e 10251 /* read encryptedContent, cont[0] */
wolfSSL 16:8e0d178b1d1e 10252 if (tag != (ASN_CONTEXT_SPECIFIC | 0) &&
wolfSSL 16:8e0d178b1d1e 10253 tag != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0)) {
wolfSSL 16:8e0d178b1d1e 10254 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 10255 }
wolfSSL 16:8e0d178b1d1e 10256 idx++;
wolfSSL 16:8e0d178b1d1e 10257
wolfSSL 16:8e0d178b1d1e 10258 if (ret == 0 && GetLength(pkiMsg, &idx, &encryptedContentTotalSz,
wolfSSL 16:8e0d178b1d1e 10259 pkiMsgSz) <= 0) {
wolfSSL 16:8e0d178b1d1e 10260 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 10261 }
wolfSSL 16:8e0d178b1d1e 10262
wolfSSL 16:8e0d178b1d1e 10263 if (ret != 0)
wolfSSL 16:8e0d178b1d1e 10264 break;
wolfSSL 16:8e0d178b1d1e 10265
wolfSSL 16:8e0d178b1d1e 10266 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 10267 if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 10268 break;
wolfSSL 16:8e0d178b1d1e 10269 }
wolfSSL 16:8e0d178b1d1e 10270 pkcs7->stream->expected = encryptedContentTotalSz;
wolfSSL 16:8e0d178b1d1e 10271 wc_PKCS7_StreamGetVar(pkcs7, &encOID, &expBlockSz, 0);
wolfSSL 16:8e0d178b1d1e 10272 wc_PKCS7_StreamStoreVar(pkcs7, encOID, expBlockSz, explicitOctet);
wolfSSL 16:8e0d178b1d1e 10273 #endif
wolfSSL 16:8e0d178b1d1e 10274 wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_ENV_5);
wolfSSL 16:8e0d178b1d1e 10275 FALL_THROUGH;
wolfSSL 16:8e0d178b1d1e 10276
wolfSSL 16:8e0d178b1d1e 10277 case WC_PKCS7_ENV_5:
wolfSSL 16:8e0d178b1d1e 10278
wolfSSL 16:8e0d178b1d1e 10279 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 10280 if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
wolfSSL 16:8e0d178b1d1e 10281 pkcs7->stream->expected, &pkiMsg, &idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 10282 return ret;
wolfSSL 16:8e0d178b1d1e 10283 }
wolfSSL 16:8e0d178b1d1e 10284
wolfSSL 16:8e0d178b1d1e 10285 wc_PKCS7_StreamGetVar(pkcs7, &encOID, &expBlockSz, &explicitOctet);
wolfSSL 16:8e0d178b1d1e 10286 tmpIv = pkcs7->stream->tmpIv;
wolfSSL 16:8e0d178b1d1e 10287 encryptedContentTotalSz = pkcs7->stream->expected;
wolfSSL 16:8e0d178b1d1e 10288
wolfSSL 16:8e0d178b1d1e 10289 /* restore decrypted key */
wolfSSL 16:8e0d178b1d1e 10290 decryptedKey = pkcs7->stream->aad;
wolfSSL 16:8e0d178b1d1e 10291 decryptedKeySz = pkcs7->stream->aadSz;
wolfSSL 16:8e0d178b1d1e 10292 blockKeySz = pkcs7->stream->contentSz;
wolfSSL 16:8e0d178b1d1e 10293 #else
wolfSSL 16:8e0d178b1d1e 10294 ret = 0;
wolfSSL 16:8e0d178b1d1e 10295 #endif
wolfSSL 16:8e0d178b1d1e 10296
wolfSSL 16:8e0d178b1d1e 10297 if (explicitOctet) {
wolfSSL 16:8e0d178b1d1e 10298 /* encrypted content may be fragmented into multiple
wolfSSL 16:8e0d178b1d1e 10299 * consecutive OCTET STRINGs, if so loop through
wolfSSL 16:8e0d178b1d1e 10300 * collecting and caching encrypted content bytes */
wolfSSL 16:8e0d178b1d1e 10301 localIdx = idx;
wolfSSL 16:8e0d178b1d1e 10302 while (idx < (localIdx + encryptedContentTotalSz)) {
wolfSSL 16:8e0d178b1d1e 10303
wolfSSL 16:8e0d178b1d1e 10304 if (GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0) {
wolfSSL 16:8e0d178b1d1e 10305 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 10306 }
wolfSSL 16:8e0d178b1d1e 10307
wolfSSL 16:8e0d178b1d1e 10308 if (ret == 0 && (tag != ASN_OCTET_STRING)) {
wolfSSL 16:8e0d178b1d1e 10309 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 10310 }
wolfSSL 16:8e0d178b1d1e 10311
wolfSSL 16:8e0d178b1d1e 10312 if (ret == 0 && GetLength(pkiMsg, &idx,
wolfSSL 16:8e0d178b1d1e 10313 &encryptedContentSz, pkiMsgSz) <= 0) {
wolfSSL 16:8e0d178b1d1e 10314 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 10315 }
wolfSSL 16:8e0d178b1d1e 10316
wolfSSL 16:8e0d178b1d1e 10317 if (ret == 0) {
wolfSSL 16:8e0d178b1d1e 10318 ret = PKCS7_CacheEncryptedContent(pkcs7, &pkiMsg[idx],
wolfSSL 16:8e0d178b1d1e 10319 encryptedContentSz);
wolfSSL 16:8e0d178b1d1e 10320 }
wolfSSL 16:8e0d178b1d1e 10321
wolfSSL 16:8e0d178b1d1e 10322 if (ret != 0) {
wolfSSL 16:8e0d178b1d1e 10323 break;
wolfSSL 16:8e0d178b1d1e 10324 }
wolfSSL 16:8e0d178b1d1e 10325
wolfSSL 16:8e0d178b1d1e 10326 /* advance idx past encrypted content */
wolfSSL 16:8e0d178b1d1e 10327 idx += encryptedContentSz;
wolfSSL 16:8e0d178b1d1e 10328 }
wolfSSL 16:8e0d178b1d1e 10329
wolfSSL 16:8e0d178b1d1e 10330 if (ret != 0) {
wolfSSL 16:8e0d178b1d1e 10331 break;
wolfSSL 16:8e0d178b1d1e 10332 }
wolfSSL 16:8e0d178b1d1e 10333
wolfSSL 16:8e0d178b1d1e 10334 } else {
wolfSSL 16:8e0d178b1d1e 10335 /* cache encrypted content, no OCTET STRING */
wolfSSL 16:8e0d178b1d1e 10336 ret = PKCS7_CacheEncryptedContent(pkcs7, &pkiMsg[idx],
wolfSSL 16:8e0d178b1d1e 10337 encryptedContentTotalSz);
wolfSSL 16:8e0d178b1d1e 10338 if (ret != 0) {
wolfSSL 16:8e0d178b1d1e 10339 break;
wolfSSL 16:8e0d178b1d1e 10340 }
wolfSSL 16:8e0d178b1d1e 10341 idx += encryptedContentTotalSz;
wolfSSL 16:8e0d178b1d1e 10342 }
wolfSSL 16:8e0d178b1d1e 10343
wolfSSL 16:8e0d178b1d1e 10344 /* use cached content */
wolfSSL 16:8e0d178b1d1e 10345 encryptedContent = pkcs7->cachedEncryptedContent;
wolfSSL 16:8e0d178b1d1e 10346 encryptedContentSz = pkcs7->cachedEncryptedContentSz;
wolfSSL 16:8e0d178b1d1e 10347
wolfSSL 16:8e0d178b1d1e 10348 /* decrypt encryptedContent */
wolfSSL 16:8e0d178b1d1e 10349 ret = wc_PKCS7_DecryptContent(pkcs7, encOID, decryptedKey,
wolfSSL 16:8e0d178b1d1e 10350 blockKeySz, tmpIv, expBlockSz, NULL, 0, NULL, 0,
wolfSSL 16:8e0d178b1d1e 10351 encryptedContent, encryptedContentSz, encryptedContent);
wolfSSL 16:8e0d178b1d1e 10352 if (ret != 0) {
wolfSSL 16:8e0d178b1d1e 10353 break;
wolfSSL 16:8e0d178b1d1e 10354 }
wolfSSL 16:8e0d178b1d1e 10355
wolfSSL 16:8e0d178b1d1e 10356 padLen = encryptedContent[encryptedContentSz-1];
wolfSSL 16:8e0d178b1d1e 10357
wolfSSL 16:8e0d178b1d1e 10358 /* copy plaintext to output */
wolfSSL 16:8e0d178b1d1e 10359 if (padLen > encryptedContentSz ||
wolfSSL 16:8e0d178b1d1e 10360 (word32)(encryptedContentSz - padLen) > outputSz) {
wolfSSL 16:8e0d178b1d1e 10361 ret = BUFFER_E;
wolfSSL 16:8e0d178b1d1e 10362 break;
wolfSSL 16:8e0d178b1d1e 10363 }
wolfSSL 16:8e0d178b1d1e 10364 XMEMCPY(output, encryptedContent, encryptedContentSz - padLen);
wolfSSL 16:8e0d178b1d1e 10365
wolfSSL 16:8e0d178b1d1e 10366 /* free memory, zero out keys */
wolfSSL 16:8e0d178b1d1e 10367 ForceZero(decryptedKey, MAX_ENCRYPTED_KEY_SZ);
wolfSSL 16:8e0d178b1d1e 10368 XFREE(decryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 10369 if (pkcs7->cachedEncryptedContent != NULL) {
wolfSSL 16:8e0d178b1d1e 10370 XFREE(pkcs7->cachedEncryptedContent, pkcs7->heap,
wolfSSL 16:8e0d178b1d1e 10371 DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 10372 pkcs7->cachedEncryptedContent = NULL;
wolfSSL 16:8e0d178b1d1e 10373 pkcs7->cachedEncryptedContentSz = 0;
wolfSSL 16:8e0d178b1d1e 10374 }
wolfSSL 16:8e0d178b1d1e 10375
wolfSSL 16:8e0d178b1d1e 10376 ret = encryptedContentSz - padLen;
wolfSSL 16:8e0d178b1d1e 10377 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 10378 pkcs7->stream->aad = NULL;
wolfSSL 16:8e0d178b1d1e 10379 pkcs7->stream->aadSz = 0;
wolfSSL 16:8e0d178b1d1e 10380 wc_PKCS7_ResetStream(pkcs7);
wolfSSL 16:8e0d178b1d1e 10381 #endif
wolfSSL 16:8e0d178b1d1e 10382 wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_START);
wolfSSL 16:8e0d178b1d1e 10383 break;
wolfSSL 16:8e0d178b1d1e 10384
wolfSSL 16:8e0d178b1d1e 10385 default:
wolfSSL 16:8e0d178b1d1e 10386 WOLFSSL_MSG("PKCS#7 unknown decode enveloped state");
wolfSSL 16:8e0d178b1d1e 10387 ret = BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 10388 }
wolfSSL 16:8e0d178b1d1e 10389
wolfSSL 16:8e0d178b1d1e 10390 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 10391 if (ret < 0 && ret != WC_PKCS7_WANT_READ_E) {
wolfSSL 16:8e0d178b1d1e 10392 wc_PKCS7_ResetStream(pkcs7);
wolfSSL 16:8e0d178b1d1e 10393 wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_START);
wolfSSL 16:8e0d178b1d1e 10394 if (pkcs7->cachedEncryptedContent != NULL) {
wolfSSL 16:8e0d178b1d1e 10395 XFREE(pkcs7->cachedEncryptedContent, pkcs7->heap,
wolfSSL 16:8e0d178b1d1e 10396 DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 10397 pkcs7->cachedEncryptedContent = NULL;
wolfSSL 16:8e0d178b1d1e 10398 pkcs7->cachedEncryptedContentSz = 0;
wolfSSL 16:8e0d178b1d1e 10399 }
wolfSSL 16:8e0d178b1d1e 10400 }
wolfSSL 16:8e0d178b1d1e 10401 #else
wolfSSL 16:8e0d178b1d1e 10402 if (decryptedKey != NULL && ret < 0) {
wolfSSL 16:8e0d178b1d1e 10403 ForceZero(decryptedKey, MAX_ENCRYPTED_KEY_SZ);
wolfSSL 15:117db924cf7c 10404 XFREE(decryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 10405 }
wolfSSL 16:8e0d178b1d1e 10406 if (pkcs7->cachedEncryptedContent != NULL && ret < 0) {
wolfSSL 16:8e0d178b1d1e 10407 XFREE(pkcs7->cachedEncryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 10408 pkcs7->cachedEncryptedContent = NULL;
wolfSSL 16:8e0d178b1d1e 10409 pkcs7->cachedEncryptedContentSz = 0;
wolfSSL 16:8e0d178b1d1e 10410 }
wolfSSL 16:8e0d178b1d1e 10411 #endif
wolfSSL 16:8e0d178b1d1e 10412 return ret;
wolfSSL 16:8e0d178b1d1e 10413 }
wolfSSL 16:8e0d178b1d1e 10414
wolfSSL 16:8e0d178b1d1e 10415
wolfSSL 16:8e0d178b1d1e 10416 /* build PKCS#7 authEnvelopedData content type, return enveloped size */
wolfSSL 16:8e0d178b1d1e 10417 int wc_PKCS7_EncodeAuthEnvelopedData(PKCS7* pkcs7, byte* output,
wolfSSL 16:8e0d178b1d1e 10418 word32 outputSz)
wolfSSL 16:8e0d178b1d1e 10419 {
wolfSSL 16:8e0d178b1d1e 10420 #if defined(HAVE_AESGCM) || defined(HAVE_AESCCM)
wolfSSL 16:8e0d178b1d1e 10421 int ret, idx = 0;
wolfSSL 16:8e0d178b1d1e 10422 int totalSz, encryptedOutSz;
wolfSSL 16:8e0d178b1d1e 10423
wolfSSL 16:8e0d178b1d1e 10424 int contentInfoSeqSz, outerContentTypeSz, outerContentSz;
wolfSSL 16:8e0d178b1d1e 10425 byte contentInfoSeq[MAX_SEQ_SZ];
wolfSSL 16:8e0d178b1d1e 10426 byte outerContentType[MAX_ALGO_SZ];
wolfSSL 16:8e0d178b1d1e 10427 byte outerContent[MAX_SEQ_SZ];
wolfSSL 16:8e0d178b1d1e 10428
wolfSSL 16:8e0d178b1d1e 10429 int envDataSeqSz, verSz;
wolfSSL 16:8e0d178b1d1e 10430 byte envDataSeq[MAX_SEQ_SZ];
wolfSSL 16:8e0d178b1d1e 10431 byte ver[MAX_VERSION_SZ];
wolfSSL 16:8e0d178b1d1e 10432
wolfSSL 16:8e0d178b1d1e 10433 WC_RNG rng;
wolfSSL 16:8e0d178b1d1e 10434 int blockSz, blockKeySz;
wolfSSL 16:8e0d178b1d1e 10435 byte* encryptedContent;
wolfSSL 16:8e0d178b1d1e 10436
wolfSSL 16:8e0d178b1d1e 10437 Pkcs7EncodedRecip* tmpRecip = NULL;
wolfSSL 16:8e0d178b1d1e 10438 int recipSz, recipSetSz;
wolfSSL 16:8e0d178b1d1e 10439 byte recipSet[MAX_SET_SZ];
wolfSSL 16:8e0d178b1d1e 10440
wolfSSL 16:8e0d178b1d1e 10441 int encContentOctetSz, encContentSeqSz, contentTypeSz;
wolfSSL 16:8e0d178b1d1e 10442 int contentEncAlgoSz, nonceOctetStringSz, macOctetStringSz;
wolfSSL 16:8e0d178b1d1e 10443 byte encContentSeq[MAX_SEQ_SZ];
wolfSSL 16:8e0d178b1d1e 10444 byte contentType[MAX_ALGO_SZ];
wolfSSL 16:8e0d178b1d1e 10445 byte contentEncAlgo[MAX_ALGO_SZ];
wolfSSL 16:8e0d178b1d1e 10446 byte nonceOctetString[MAX_OCTET_STR_SZ];
wolfSSL 16:8e0d178b1d1e 10447 byte encContentOctet[MAX_OCTET_STR_SZ];
wolfSSL 16:8e0d178b1d1e 10448 byte macOctetString[MAX_OCTET_STR_SZ];
wolfSSL 16:8e0d178b1d1e 10449
wolfSSL 16:8e0d178b1d1e 10450 byte authTag[AES_BLOCK_SIZE];
wolfSSL 16:8e0d178b1d1e 10451 byte nonce[GCM_NONCE_MID_SZ]; /* GCM nonce is larger than CCM */
wolfSSL 16:8e0d178b1d1e 10452 byte macInt[MAX_VERSION_SZ];
wolfSSL 16:8e0d178b1d1e 10453 word32 nonceSz = 0, macIntSz = 0;
wolfSSL 16:8e0d178b1d1e 10454
wolfSSL 16:8e0d178b1d1e 10455 /* authAttribs */
wolfSSL 16:8e0d178b1d1e 10456 byte* flatAuthAttribs = NULL;
wolfSSL 16:8e0d178b1d1e 10457 byte authAttribSet[MAX_SET_SZ];
wolfSSL 16:8e0d178b1d1e 10458 EncodedAttrib authAttribs[MAX_AUTH_ATTRIBS_SZ];
wolfSSL 16:8e0d178b1d1e 10459 word32 authAttribsSz = 0, authAttribsCount = 0;
wolfSSL 16:8e0d178b1d1e 10460 word32 authAttribsSetSz = 0;
wolfSSL 16:8e0d178b1d1e 10461
wolfSSL 16:8e0d178b1d1e 10462 byte* aadBuffer = NULL;
wolfSSL 16:8e0d178b1d1e 10463 word32 aadBufferSz = 0;
wolfSSL 16:8e0d178b1d1e 10464 byte authAttribAadSet[MAX_SET_SZ];
wolfSSL 16:8e0d178b1d1e 10465 word32 authAttribsAadSetSz = 0;
wolfSSL 16:8e0d178b1d1e 10466
wolfSSL 16:8e0d178b1d1e 10467 /* unauthAttribs */
wolfSSL 16:8e0d178b1d1e 10468 byte* flatUnauthAttribs = NULL;
wolfSSL 16:8e0d178b1d1e 10469 byte unauthAttribSet[MAX_SET_SZ];
wolfSSL 16:8e0d178b1d1e 10470 EncodedAttrib unauthAttribs[MAX_UNAUTH_ATTRIBS_SZ];
wolfSSL 16:8e0d178b1d1e 10471 word32 unauthAttribsSz = 0, unauthAttribsCount = 0;
wolfSSL 16:8e0d178b1d1e 10472 word32 unauthAttribsSetSz = 0;
wolfSSL 16:8e0d178b1d1e 10473
wolfSSL 16:8e0d178b1d1e 10474
wolfSSL 16:8e0d178b1d1e 10475 PKCS7Attrib contentTypeAttrib;
wolfSSL 16:8e0d178b1d1e 10476 byte contentTypeValue[MAX_OID_SZ];
wolfSSL 16:8e0d178b1d1e 10477 /* contentType OID (1.2.840.113549.1.9.3) */
wolfSSL 16:8e0d178b1d1e 10478 const byte contentTypeOid[] =
wolfSSL 16:8e0d178b1d1e 10479 { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xF7, 0x0d, 0x01,
wolfSSL 16:8e0d178b1d1e 10480 0x09, 0x03 };
wolfSSL 16:8e0d178b1d1e 10481
wolfSSL 16:8e0d178b1d1e 10482 if (pkcs7 == NULL || pkcs7->content == NULL || pkcs7->contentSz == 0)
wolfSSL 16:8e0d178b1d1e 10483 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 10484
wolfSSL 16:8e0d178b1d1e 10485 if (output == NULL || outputSz == 0)
wolfSSL 16:8e0d178b1d1e 10486 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 10487
wolfSSL 16:8e0d178b1d1e 10488 switch (pkcs7->encryptOID) {
wolfSSL 16:8e0d178b1d1e 10489 #ifdef HAVE_AESGCM
wolfSSL 16:8e0d178b1d1e 10490 #ifdef WOLFSSL_AES_128
wolfSSL 16:8e0d178b1d1e 10491 case AES128GCMb:
wolfSSL 16:8e0d178b1d1e 10492 break;
wolfSSL 16:8e0d178b1d1e 10493 #endif
wolfSSL 16:8e0d178b1d1e 10494 #ifdef WOLFSSL_AES_192
wolfSSL 16:8e0d178b1d1e 10495 case AES192GCMb:
wolfSSL 16:8e0d178b1d1e 10496 break;
wolfSSL 16:8e0d178b1d1e 10497 #endif
wolfSSL 16:8e0d178b1d1e 10498 #ifdef WOLFSSL_AES_256
wolfSSL 16:8e0d178b1d1e 10499 case AES256GCMb:
wolfSSL 16:8e0d178b1d1e 10500 break;
wolfSSL 16:8e0d178b1d1e 10501 #endif
wolfSSL 16:8e0d178b1d1e 10502 #endif
wolfSSL 16:8e0d178b1d1e 10503 #ifdef HAVE_AESCCM
wolfSSL 16:8e0d178b1d1e 10504 #ifdef WOLFSSL_AES_128
wolfSSL 16:8e0d178b1d1e 10505 case AES128CCMb:
wolfSSL 16:8e0d178b1d1e 10506 break;
wolfSSL 16:8e0d178b1d1e 10507 #endif
wolfSSL 16:8e0d178b1d1e 10508 #ifdef WOLFSSL_AES_192
wolfSSL 16:8e0d178b1d1e 10509 case AES192CCMb:
wolfSSL 16:8e0d178b1d1e 10510 break;
wolfSSL 16:8e0d178b1d1e 10511 #endif
wolfSSL 16:8e0d178b1d1e 10512 #ifdef WOLFSSL_AES_256
wolfSSL 16:8e0d178b1d1e 10513 case AES256CCMb:
wolfSSL 16:8e0d178b1d1e 10514 break;
wolfSSL 16:8e0d178b1d1e 10515 #endif
wolfSSL 16:8e0d178b1d1e 10516 #endif
wolfSSL 16:8e0d178b1d1e 10517 default:
wolfSSL 16:8e0d178b1d1e 10518 WOLFSSL_MSG("CMS AuthEnvelopedData must use AES-GCM or AES-CCM");
wolfSSL 16:8e0d178b1d1e 10519 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 10520 }
wolfSSL 16:8e0d178b1d1e 10521
wolfSSL 16:8e0d178b1d1e 10522 blockKeySz = wc_PKCS7_GetOIDKeySize(pkcs7->encryptOID);
wolfSSL 16:8e0d178b1d1e 10523 if (blockKeySz < 0)
wolfSSL 16:8e0d178b1d1e 10524 return blockKeySz;
wolfSSL 16:8e0d178b1d1e 10525
wolfSSL 16:8e0d178b1d1e 10526 blockSz = wc_PKCS7_GetOIDBlockSize(pkcs7->encryptOID);
wolfSSL 16:8e0d178b1d1e 10527 if (blockSz < 0)
wolfSSL 16:8e0d178b1d1e 10528 return blockSz;
wolfSSL 16:8e0d178b1d1e 10529
wolfSSL 16:8e0d178b1d1e 10530 /* outer content type */
wolfSSL 16:8e0d178b1d1e 10531 ret = wc_SetContentType(AUTH_ENVELOPED_DATA, outerContentType,
wolfSSL 16:8e0d178b1d1e 10532 sizeof(outerContentType));
wolfSSL 16:8e0d178b1d1e 10533 if (ret < 0)
wolfSSL 16:8e0d178b1d1e 10534 return ret;
wolfSSL 16:8e0d178b1d1e 10535
wolfSSL 16:8e0d178b1d1e 10536 outerContentTypeSz = ret;
wolfSSL 16:8e0d178b1d1e 10537
wolfSSL 16:8e0d178b1d1e 10538 /* version, defined as 0 in RFC 5083 */
wolfSSL 16:8e0d178b1d1e 10539 verSz = SetMyVersion(0, ver, 0);
wolfSSL 16:8e0d178b1d1e 10540
wolfSSL 16:8e0d178b1d1e 10541 /* generate random content encryption key */
wolfSSL 16:8e0d178b1d1e 10542 ret = PKCS7_GenerateContentEncryptionKey(pkcs7, blockKeySz);
wolfSSL 16:8e0d178b1d1e 10543 if (ret != 0) {
wolfSSL 16:8e0d178b1d1e 10544 return ret;
wolfSSL 16:8e0d178b1d1e 10545 }
wolfSSL 16:8e0d178b1d1e 10546
wolfSSL 16:8e0d178b1d1e 10547 /* build RecipientInfo, only if user manually set singleCert and size */
wolfSSL 16:8e0d178b1d1e 10548 if (pkcs7->singleCert != NULL && pkcs7->singleCertSz > 0) {
wolfSSL 16:8e0d178b1d1e 10549 switch (pkcs7->publicKeyOID) {
wolfSSL 16:8e0d178b1d1e 10550 #ifndef NO_RSA
wolfSSL 16:8e0d178b1d1e 10551 case RSAk:
wolfSSL 16:8e0d178b1d1e 10552 ret = wc_PKCS7_AddRecipient_KTRI(pkcs7, pkcs7->singleCert,
wolfSSL 16:8e0d178b1d1e 10553 pkcs7->singleCertSz, 0);
wolfSSL 16:8e0d178b1d1e 10554 break;
wolfSSL 16:8e0d178b1d1e 10555 #endif
wolfSSL 16:8e0d178b1d1e 10556 #ifdef HAVE_ECC
wolfSSL 16:8e0d178b1d1e 10557 case ECDSAk:
wolfSSL 16:8e0d178b1d1e 10558 ret = wc_PKCS7_AddRecipient_KARI(pkcs7, pkcs7->singleCert,
wolfSSL 16:8e0d178b1d1e 10559 pkcs7->singleCertSz,
wolfSSL 16:8e0d178b1d1e 10560 pkcs7->keyWrapOID,
wolfSSL 16:8e0d178b1d1e 10561 pkcs7->keyAgreeOID, pkcs7->ukm,
wolfSSL 16:8e0d178b1d1e 10562 pkcs7->ukmSz, 0);
wolfSSL 16:8e0d178b1d1e 10563 break;
wolfSSL 16:8e0d178b1d1e 10564 #endif
wolfSSL 16:8e0d178b1d1e 10565
wolfSSL 16:8e0d178b1d1e 10566 default:
wolfSSL 16:8e0d178b1d1e 10567 WOLFSSL_MSG("Unsupported RecipientInfo public key type");
wolfSSL 16:8e0d178b1d1e 10568 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 10569 };
wolfSSL 16:8e0d178b1d1e 10570
wolfSSL 16:8e0d178b1d1e 10571 if (ret < 0) {
wolfSSL 16:8e0d178b1d1e 10572 WOLFSSL_MSG("Failed to create RecipientInfo");
wolfSSL 16:8e0d178b1d1e 10573 return ret;
wolfSSL 16:8e0d178b1d1e 10574 }
wolfSSL 16:8e0d178b1d1e 10575 }
wolfSSL 16:8e0d178b1d1e 10576
wolfSSL 16:8e0d178b1d1e 10577 recipSz = wc_PKCS7_GetRecipientListSize(pkcs7);
wolfSSL 16:8e0d178b1d1e 10578 if (recipSz < 0) {
wolfSSL 16:8e0d178b1d1e 10579 return ret;
wolfSSL 16:8e0d178b1d1e 10580
wolfSSL 16:8e0d178b1d1e 10581 } else if (recipSz == 0) {
wolfSSL 16:8e0d178b1d1e 10582 WOLFSSL_MSG("You must add at least one CMS recipient");
wolfSSL 16:8e0d178b1d1e 10583 return PKCS7_RECIP_E;
wolfSSL 16:8e0d178b1d1e 10584 }
wolfSSL 16:8e0d178b1d1e 10585 recipSetSz = SetSet(recipSz, recipSet);
wolfSSL 16:8e0d178b1d1e 10586
wolfSSL 16:8e0d178b1d1e 10587 /* generate random nonce and IV for encryption */
wolfSSL 16:8e0d178b1d1e 10588 switch (pkcs7->encryptOID) {
wolfSSL 16:8e0d178b1d1e 10589 #ifdef HAVE_AESGCM
wolfSSL 16:8e0d178b1d1e 10590 #ifdef WOLFSSL_AES_128
wolfSSL 16:8e0d178b1d1e 10591 case AES128GCMb:
wolfSSL 16:8e0d178b1d1e 10592 FALL_THROUGH;
wolfSSL 16:8e0d178b1d1e 10593 #endif
wolfSSL 16:8e0d178b1d1e 10594 #ifdef WOLFSSL_AES_192
wolfSSL 16:8e0d178b1d1e 10595 case AES192GCMb:
wolfSSL 16:8e0d178b1d1e 10596 FALL_THROUGH;
wolfSSL 16:8e0d178b1d1e 10597 #endif
wolfSSL 16:8e0d178b1d1e 10598 #ifdef WOLFSSL_AES_256
wolfSSL 16:8e0d178b1d1e 10599 case AES256GCMb:
wolfSSL 16:8e0d178b1d1e 10600 #endif
wolfSSL 16:8e0d178b1d1e 10601 #if defined(WOLFSSL_AES_128) || defined(WOLFSSL_AES_192) || \
wolfSSL 16:8e0d178b1d1e 10602 defined(WOLFSSL_AES_256)
wolfSSL 16:8e0d178b1d1e 10603 /* GCM nonce is GCM_NONCE_MID_SZ (12) */
wolfSSL 16:8e0d178b1d1e 10604 nonceSz = GCM_NONCE_MID_SZ;
wolfSSL 16:8e0d178b1d1e 10605 break;
wolfSSL 16:8e0d178b1d1e 10606 #endif
wolfSSL 16:8e0d178b1d1e 10607 #endif /* HAVE_AESGCM */
wolfSSL 16:8e0d178b1d1e 10608 #ifdef HAVE_AESCCM
wolfSSL 16:8e0d178b1d1e 10609 #ifdef WOLFSSL_AES_128
wolfSSL 16:8e0d178b1d1e 10610 case AES128CCMb:
wolfSSL 16:8e0d178b1d1e 10611 FALL_THROUGH;
wolfSSL 16:8e0d178b1d1e 10612 #endif
wolfSSL 16:8e0d178b1d1e 10613 #ifdef WOLFSSL_AES_192
wolfSSL 16:8e0d178b1d1e 10614 case AES192CCMb:
wolfSSL 16:8e0d178b1d1e 10615 FALL_THROUGH;
wolfSSL 16:8e0d178b1d1e 10616 #endif
wolfSSL 16:8e0d178b1d1e 10617 #ifdef WOLFSSL_AES_256
wolfSSL 16:8e0d178b1d1e 10618 case AES256CCMb:
wolfSSL 16:8e0d178b1d1e 10619 #endif
wolfSSL 16:8e0d178b1d1e 10620 #if defined(WOLFSSL_AES_128) || defined(WOLFSSL_AES_192) || \
wolfSSL 16:8e0d178b1d1e 10621 defined(WOLFSSL_AES_256)
wolfSSL 16:8e0d178b1d1e 10622 /* CCM nonce is CCM_NONCE_MIN_SZ (7) */
wolfSSL 16:8e0d178b1d1e 10623 nonceSz = CCM_NONCE_MIN_SZ;
wolfSSL 16:8e0d178b1d1e 10624 break;
wolfSSL 16:8e0d178b1d1e 10625 #endif
wolfSSL 16:8e0d178b1d1e 10626 #endif /* HAVE_AESCCM */
wolfSSL 16:8e0d178b1d1e 10627 }
wolfSSL 16:8e0d178b1d1e 10628
wolfSSL 16:8e0d178b1d1e 10629 ret = wc_InitRng_ex(&rng, pkcs7->heap, pkcs7->devId);
wolfSSL 16:8e0d178b1d1e 10630 if (ret != 0)
wolfSSL 16:8e0d178b1d1e 10631 return ret;
wolfSSL 16:8e0d178b1d1e 10632
wolfSSL 16:8e0d178b1d1e 10633 ret = wc_PKCS7_GenerateBlock(pkcs7, &rng, nonce, nonceSz);
wolfSSL 16:8e0d178b1d1e 10634 wc_FreeRng(&rng);
wolfSSL 16:8e0d178b1d1e 10635 if (ret != 0) {
wolfSSL 16:8e0d178b1d1e 10636 return ret;
wolfSSL 16:8e0d178b1d1e 10637 }
wolfSSL 16:8e0d178b1d1e 10638
wolfSSL 16:8e0d178b1d1e 10639
wolfSSL 16:8e0d178b1d1e 10640 /* authAttribs: add contentType attrib if needed */
wolfSSL 16:8e0d178b1d1e 10641 if (pkcs7->contentOID != DATA) {
wolfSSL 16:8e0d178b1d1e 10642
wolfSSL 16:8e0d178b1d1e 10643 /* if type is not id-data, contentType attribute MUST be added */
wolfSSL 16:8e0d178b1d1e 10644 contentTypeAttrib.oid = contentTypeOid;
wolfSSL 16:8e0d178b1d1e 10645 contentTypeAttrib.oidSz = sizeof(contentTypeOid);
wolfSSL 16:8e0d178b1d1e 10646
wolfSSL 16:8e0d178b1d1e 10647 /* try to set from contentOID first, known types */
wolfSSL 16:8e0d178b1d1e 10648 ret = wc_SetContentType(pkcs7->contentOID, contentTypeValue,
wolfSSL 16:8e0d178b1d1e 10649 sizeof(contentTypeValue));
wolfSSL 16:8e0d178b1d1e 10650 if (ret > 0) {
wolfSSL 16:8e0d178b1d1e 10651 contentTypeAttrib.value = contentTypeValue;
wolfSSL 16:8e0d178b1d1e 10652 contentTypeAttrib.valueSz = ret;
wolfSSL 16:8e0d178b1d1e 10653
wolfSSL 16:8e0d178b1d1e 10654 /* otherwise, try to set from custom content type */
wolfSSL 16:8e0d178b1d1e 10655 } else {
wolfSSL 16:8e0d178b1d1e 10656 if (pkcs7->contentTypeSz == 0) {
wolfSSL 16:8e0d178b1d1e 10657 WOLFSSL_MSG("CMS pkcs7->contentType must be set if "
wolfSSL 16:8e0d178b1d1e 10658 "contentOID is not");
wolfSSL 16:8e0d178b1d1e 10659 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 10660 }
wolfSSL 16:8e0d178b1d1e 10661 contentTypeAttrib.value = pkcs7->contentType;
wolfSSL 16:8e0d178b1d1e 10662 contentTypeAttrib.valueSz = pkcs7->contentTypeSz;
wolfSSL 16:8e0d178b1d1e 10663 }
wolfSSL 16:8e0d178b1d1e 10664
wolfSSL 16:8e0d178b1d1e 10665 authAttribsSz += EncodeAttributes(authAttribs, 1,
wolfSSL 16:8e0d178b1d1e 10666 &contentTypeAttrib, 1);
wolfSSL 16:8e0d178b1d1e 10667 authAttribsCount += 1;
wolfSSL 16:8e0d178b1d1e 10668 }
wolfSSL 16:8e0d178b1d1e 10669
wolfSSL 16:8e0d178b1d1e 10670 /* authAttribs: add in user authenticated attributes */
wolfSSL 16:8e0d178b1d1e 10671 if (pkcs7->authAttribs != NULL && pkcs7->authAttribsSz > 0) {
wolfSSL 16:8e0d178b1d1e 10672 authAttribsSz += EncodeAttributes(authAttribs + authAttribsCount,
wolfSSL 16:8e0d178b1d1e 10673 MAX_AUTH_ATTRIBS_SZ - authAttribsCount,
wolfSSL 16:8e0d178b1d1e 10674 pkcs7->authAttribs,
wolfSSL 16:8e0d178b1d1e 10675 pkcs7->authAttribsSz);
wolfSSL 16:8e0d178b1d1e 10676 authAttribsCount += pkcs7->authAttribsSz;
wolfSSL 16:8e0d178b1d1e 10677 }
wolfSSL 16:8e0d178b1d1e 10678
wolfSSL 16:8e0d178b1d1e 10679 /* authAttribs: flatten authAttribs */
wolfSSL 16:8e0d178b1d1e 10680 if (authAttribsSz > 0 && authAttribsCount > 0) {
wolfSSL 16:8e0d178b1d1e 10681 flatAuthAttribs = (byte*)XMALLOC(authAttribsSz, pkcs7->heap,
wolfSSL 16:8e0d178b1d1e 10682 DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 10683 if (flatAuthAttribs == NULL) {
wolfSSL 16:8e0d178b1d1e 10684 return MEMORY_E;
wolfSSL 16:8e0d178b1d1e 10685 }
wolfSSL 16:8e0d178b1d1e 10686
wolfSSL 16:8e0d178b1d1e 10687 FlattenAttributes(pkcs7, flatAuthAttribs, authAttribs,
wolfSSL 16:8e0d178b1d1e 10688 authAttribsCount);
wolfSSL 16:8e0d178b1d1e 10689
wolfSSL 16:8e0d178b1d1e 10690 authAttribsSetSz = SetImplicit(ASN_SET, 1, authAttribsSz,
wolfSSL 16:8e0d178b1d1e 10691 authAttribSet);
wolfSSL 16:8e0d178b1d1e 10692
wolfSSL 16:8e0d178b1d1e 10693 /* From RFC5083, "For the purpose of constructing the AAD, the
wolfSSL 16:8e0d178b1d1e 10694 * IMPLICIT [1] tag in the authAttrs field is not used for the
wolfSSL 16:8e0d178b1d1e 10695 * DER encoding: rather a universal SET OF tag is used. */
wolfSSL 16:8e0d178b1d1e 10696 authAttribsAadSetSz = SetSet(authAttribsSz, authAttribAadSet);
wolfSSL 16:8e0d178b1d1e 10697
wolfSSL 16:8e0d178b1d1e 10698 /* allocate temp buffer to hold alternate attrib encoding for aad */
wolfSSL 16:8e0d178b1d1e 10699 aadBuffer = (byte*)XMALLOC(authAttribsSz + authAttribsAadSetSz,
wolfSSL 16:8e0d178b1d1e 10700 pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 10701 if (aadBuffer == NULL) {
wolfSSL 16:8e0d178b1d1e 10702 XFREE(flatAuthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 10703 return MEMORY_E;
wolfSSL 16:8e0d178b1d1e 10704 }
wolfSSL 16:8e0d178b1d1e 10705
wolfSSL 16:8e0d178b1d1e 10706 /* build up alternate attrib encoding for aad */
wolfSSL 16:8e0d178b1d1e 10707 aadBufferSz = 0;
wolfSSL 16:8e0d178b1d1e 10708 XMEMCPY(aadBuffer + aadBufferSz, authAttribAadSet, authAttribsAadSetSz);
wolfSSL 16:8e0d178b1d1e 10709 aadBufferSz += authAttribsAadSetSz;
wolfSSL 16:8e0d178b1d1e 10710 XMEMCPY(aadBuffer + aadBufferSz, flatAuthAttribs, authAttribsSz);
wolfSSL 16:8e0d178b1d1e 10711 aadBufferSz += authAttribsSz;
wolfSSL 16:8e0d178b1d1e 10712 }
wolfSSL 16:8e0d178b1d1e 10713
wolfSSL 16:8e0d178b1d1e 10714 /* build up unauthenticated attributes (unauthAttrs) */
wolfSSL 16:8e0d178b1d1e 10715 if (pkcs7->unauthAttribsSz > 0) {
wolfSSL 16:8e0d178b1d1e 10716 unauthAttribsSz = EncodeAttributes(unauthAttribs + unauthAttribsCount,
wolfSSL 16:8e0d178b1d1e 10717 MAX_UNAUTH_ATTRIBS_SZ - unauthAttribsCount,
wolfSSL 16:8e0d178b1d1e 10718 pkcs7->unauthAttribs,
wolfSSL 16:8e0d178b1d1e 10719 pkcs7->unauthAttribsSz);
wolfSSL 16:8e0d178b1d1e 10720 unauthAttribsCount = pkcs7->unauthAttribsSz;
wolfSSL 16:8e0d178b1d1e 10721
wolfSSL 16:8e0d178b1d1e 10722 flatUnauthAttribs = (byte*)XMALLOC(unauthAttribsSz, pkcs7->heap,
wolfSSL 16:8e0d178b1d1e 10723 DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 10724 if (flatUnauthAttribs == NULL) {
wolfSSL 16:8e0d178b1d1e 10725 if (aadBuffer)
wolfSSL 16:8e0d178b1d1e 10726 XFREE(aadBuffer, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 10727 if (flatAuthAttribs)
wolfSSL 16:8e0d178b1d1e 10728 XFREE(flatAuthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 10729 return MEMORY_E;
wolfSSL 16:8e0d178b1d1e 10730 }
wolfSSL 16:8e0d178b1d1e 10731
wolfSSL 16:8e0d178b1d1e 10732 FlattenAttributes(pkcs7, flatUnauthAttribs, unauthAttribs,
wolfSSL 16:8e0d178b1d1e 10733 unauthAttribsCount);
wolfSSL 16:8e0d178b1d1e 10734 unauthAttribsSetSz = SetImplicit(ASN_SET, 2, unauthAttribsSz,
wolfSSL 16:8e0d178b1d1e 10735 unauthAttribSet);
wolfSSL 16:8e0d178b1d1e 10736 }
wolfSSL 16:8e0d178b1d1e 10737
wolfSSL 16:8e0d178b1d1e 10738 /* allocate encrypted content buffer */
wolfSSL 16:8e0d178b1d1e 10739 encryptedOutSz = pkcs7->contentSz;
wolfSSL 16:8e0d178b1d1e 10740 encryptedContent = (byte*)XMALLOC(encryptedOutSz, pkcs7->heap,
wolfSSL 16:8e0d178b1d1e 10741 DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 10742 if (encryptedContent == NULL) {
wolfSSL 16:8e0d178b1d1e 10743 if (aadBuffer)
wolfSSL 16:8e0d178b1d1e 10744 XFREE(aadBuffer, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 10745 if (flatUnauthAttribs)
wolfSSL 16:8e0d178b1d1e 10746 XFREE(flatUnauthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 10747 if (flatAuthAttribs)
wolfSSL 16:8e0d178b1d1e 10748 XFREE(flatAuthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 10749 return MEMORY_E;
wolfSSL 16:8e0d178b1d1e 10750 }
wolfSSL 16:8e0d178b1d1e 10751
wolfSSL 16:8e0d178b1d1e 10752 /* encrypt content */
wolfSSL 16:8e0d178b1d1e 10753 ret = wc_PKCS7_EncryptContent(pkcs7->encryptOID, pkcs7->cek,
wolfSSL 16:8e0d178b1d1e 10754 pkcs7->cekSz, nonce, nonceSz, aadBuffer, aadBufferSz, authTag,
wolfSSL 16:8e0d178b1d1e 10755 sizeof(authTag), pkcs7->content, encryptedOutSz, encryptedContent);
wolfSSL 16:8e0d178b1d1e 10756
wolfSSL 16:8e0d178b1d1e 10757 if (aadBuffer) {
wolfSSL 16:8e0d178b1d1e 10758 XFREE(aadBuffer, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 10759 aadBuffer = NULL;
wolfSSL 16:8e0d178b1d1e 10760 }
wolfSSL 16:8e0d178b1d1e 10761
wolfSSL 16:8e0d178b1d1e 10762 if (ret != 0) {
wolfSSL 16:8e0d178b1d1e 10763 if (flatUnauthAttribs)
wolfSSL 16:8e0d178b1d1e 10764 XFREE(flatUnauthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 10765 if (flatAuthAttribs)
wolfSSL 16:8e0d178b1d1e 10766 XFREE(flatAuthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 10767 XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 10768 return ret;
wolfSSL 16:8e0d178b1d1e 10769 }
wolfSSL 16:8e0d178b1d1e 10770
wolfSSL 16:8e0d178b1d1e 10771 /* EncryptedContentInfo */
wolfSSL 16:8e0d178b1d1e 10772 ret = wc_SetContentType(pkcs7->contentOID, contentType,
wolfSSL 16:8e0d178b1d1e 10773 sizeof(contentType));
wolfSSL 16:8e0d178b1d1e 10774 if (ret < 0) {
wolfSSL 16:8e0d178b1d1e 10775 if (flatUnauthAttribs)
wolfSSL 16:8e0d178b1d1e 10776 XFREE(flatUnauthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 10777 if (flatAuthAttribs)
wolfSSL 16:8e0d178b1d1e 10778 XFREE(flatAuthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 10779 XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 10780 return ret;
wolfSSL 16:8e0d178b1d1e 10781 }
wolfSSL 16:8e0d178b1d1e 10782
wolfSSL 16:8e0d178b1d1e 10783 contentTypeSz = ret;
wolfSSL 16:8e0d178b1d1e 10784
wolfSSL 16:8e0d178b1d1e 10785 /* put together nonce OCTET STRING */
wolfSSL 16:8e0d178b1d1e 10786 nonceOctetStringSz = SetOctetString(nonceSz, nonceOctetString);
wolfSSL 16:8e0d178b1d1e 10787
wolfSSL 16:8e0d178b1d1e 10788 /* put together aes-ICVlen INTEGER */
wolfSSL 16:8e0d178b1d1e 10789 macIntSz = SetMyVersion(sizeof(authTag), macInt, 0);
wolfSSL 16:8e0d178b1d1e 10790
wolfSSL 16:8e0d178b1d1e 10791 /* build up our ContentEncryptionAlgorithmIdentifier sequence,
wolfSSL 16:8e0d178b1d1e 10792 * adding (nonceOctetStringSz + blockSz + macIntSz) for nonce OCTET STRING
wolfSSL 16:8e0d178b1d1e 10793 * and tag size */
wolfSSL 16:8e0d178b1d1e 10794 contentEncAlgoSz = SetAlgoID(pkcs7->encryptOID, contentEncAlgo,
wolfSSL 16:8e0d178b1d1e 10795 oidBlkType, nonceOctetStringSz + nonceSz +
wolfSSL 16:8e0d178b1d1e 10796 macIntSz);
wolfSSL 16:8e0d178b1d1e 10797
wolfSSL 16:8e0d178b1d1e 10798 if (contentEncAlgoSz == 0) {
wolfSSL 16:8e0d178b1d1e 10799 if (flatUnauthAttribs)
wolfSSL 16:8e0d178b1d1e 10800 XFREE(flatUnauthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 10801 if (flatAuthAttribs)
wolfSSL 16:8e0d178b1d1e 10802 XFREE(flatAuthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 10803 XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 10804 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 10805 }
wolfSSL 16:8e0d178b1d1e 10806
wolfSSL 16:8e0d178b1d1e 10807 encContentOctetSz = SetImplicit(ASN_OCTET_STRING, 0, encryptedOutSz,
wolfSSL 16:8e0d178b1d1e 10808 encContentOctet);
wolfSSL 16:8e0d178b1d1e 10809
wolfSSL 16:8e0d178b1d1e 10810 encContentSeqSz = SetSequence(contentTypeSz + contentEncAlgoSz +
wolfSSL 16:8e0d178b1d1e 10811 nonceOctetStringSz + nonceSz + macIntSz +
wolfSSL 16:8e0d178b1d1e 10812 encContentOctetSz + encryptedOutSz,
wolfSSL 16:8e0d178b1d1e 10813 encContentSeq);
wolfSSL 16:8e0d178b1d1e 10814
wolfSSL 16:8e0d178b1d1e 10815 macOctetStringSz = SetOctetString(sizeof(authTag), macOctetString);
wolfSSL 16:8e0d178b1d1e 10816
wolfSSL 16:8e0d178b1d1e 10817 /* keep track of sizes for outer wrapper layering */
wolfSSL 16:8e0d178b1d1e 10818 totalSz = verSz + recipSetSz + recipSz + encContentSeqSz + contentTypeSz +
wolfSSL 16:8e0d178b1d1e 10819 contentEncAlgoSz + nonceOctetStringSz + nonceSz + macIntSz +
wolfSSL 16:8e0d178b1d1e 10820 encContentOctetSz + encryptedOutSz + authAttribsSz +
wolfSSL 16:8e0d178b1d1e 10821 authAttribsSetSz + macOctetStringSz + sizeof(authTag) +
wolfSSL 16:8e0d178b1d1e 10822 unauthAttribsSz + unauthAttribsSetSz;
wolfSSL 16:8e0d178b1d1e 10823
wolfSSL 16:8e0d178b1d1e 10824 /* EnvelopedData */
wolfSSL 16:8e0d178b1d1e 10825 envDataSeqSz = SetSequence(totalSz, envDataSeq);
wolfSSL 16:8e0d178b1d1e 10826 totalSz += envDataSeqSz;
wolfSSL 16:8e0d178b1d1e 10827
wolfSSL 16:8e0d178b1d1e 10828 /* outer content */
wolfSSL 16:8e0d178b1d1e 10829 outerContentSz = SetExplicit(0, totalSz, outerContent);
wolfSSL 16:8e0d178b1d1e 10830 totalSz += outerContentTypeSz;
wolfSSL 16:8e0d178b1d1e 10831 totalSz += outerContentSz;
wolfSSL 16:8e0d178b1d1e 10832
wolfSSL 16:8e0d178b1d1e 10833 /* ContentInfo */
wolfSSL 16:8e0d178b1d1e 10834 contentInfoSeqSz = SetSequence(totalSz, contentInfoSeq);
wolfSSL 16:8e0d178b1d1e 10835 totalSz += contentInfoSeqSz;
wolfSSL 16:8e0d178b1d1e 10836
wolfSSL 16:8e0d178b1d1e 10837 if (totalSz > (int)outputSz) {
wolfSSL 16:8e0d178b1d1e 10838 WOLFSSL_MSG("Pkcs7_encrypt output buffer too small");
wolfSSL 16:8e0d178b1d1e 10839 if (flatUnauthAttribs)
wolfSSL 16:8e0d178b1d1e 10840 XFREE(flatUnauthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 10841 if (flatAuthAttribs)
wolfSSL 16:8e0d178b1d1e 10842 XFREE(flatAuthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 10843 XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 10844 return BUFFER_E;
wolfSSL 16:8e0d178b1d1e 10845 }
wolfSSL 16:8e0d178b1d1e 10846
wolfSSL 16:8e0d178b1d1e 10847 XMEMCPY(output + idx, contentInfoSeq, contentInfoSeqSz);
wolfSSL 16:8e0d178b1d1e 10848 idx += contentInfoSeqSz;
wolfSSL 16:8e0d178b1d1e 10849 XMEMCPY(output + idx, outerContentType, outerContentTypeSz);
wolfSSL 16:8e0d178b1d1e 10850 idx += outerContentTypeSz;
wolfSSL 16:8e0d178b1d1e 10851 XMEMCPY(output + idx, outerContent, outerContentSz);
wolfSSL 16:8e0d178b1d1e 10852 idx += outerContentSz;
wolfSSL 16:8e0d178b1d1e 10853 XMEMCPY(output + idx, envDataSeq, envDataSeqSz);
wolfSSL 16:8e0d178b1d1e 10854 idx += envDataSeqSz;
wolfSSL 16:8e0d178b1d1e 10855 XMEMCPY(output + idx, ver, verSz);
wolfSSL 16:8e0d178b1d1e 10856 idx += verSz;
wolfSSL 16:8e0d178b1d1e 10857 XMEMCPY(output + idx, recipSet, recipSetSz);
wolfSSL 16:8e0d178b1d1e 10858 idx += recipSetSz;
wolfSSL 16:8e0d178b1d1e 10859 /* copy in recipients from list */
wolfSSL 16:8e0d178b1d1e 10860 tmpRecip = pkcs7->recipList;
wolfSSL 16:8e0d178b1d1e 10861 while (tmpRecip != NULL) {
wolfSSL 16:8e0d178b1d1e 10862 XMEMCPY(output + idx, tmpRecip->recip, tmpRecip->recipSz);
wolfSSL 16:8e0d178b1d1e 10863 idx += tmpRecip->recipSz;
wolfSSL 16:8e0d178b1d1e 10864 tmpRecip = tmpRecip->next;
wolfSSL 16:8e0d178b1d1e 10865 }
wolfSSL 16:8e0d178b1d1e 10866 wc_PKCS7_FreeEncodedRecipientSet(pkcs7);
wolfSSL 16:8e0d178b1d1e 10867 XMEMCPY(output + idx, encContentSeq, encContentSeqSz);
wolfSSL 16:8e0d178b1d1e 10868 idx += encContentSeqSz;
wolfSSL 16:8e0d178b1d1e 10869 XMEMCPY(output + idx, contentType, contentTypeSz);
wolfSSL 16:8e0d178b1d1e 10870 idx += contentTypeSz;
wolfSSL 16:8e0d178b1d1e 10871 XMEMCPY(output + idx, contentEncAlgo, contentEncAlgoSz);
wolfSSL 16:8e0d178b1d1e 10872 idx += contentEncAlgoSz;
wolfSSL 16:8e0d178b1d1e 10873 XMEMCPY(output + idx, nonceOctetString, nonceOctetStringSz);
wolfSSL 16:8e0d178b1d1e 10874 idx += nonceOctetStringSz;
wolfSSL 16:8e0d178b1d1e 10875 XMEMCPY(output + idx, nonce, nonceSz);
wolfSSL 16:8e0d178b1d1e 10876 idx += nonceSz;
wolfSSL 16:8e0d178b1d1e 10877 XMEMCPY(output + idx, macInt, macIntSz);
wolfSSL 16:8e0d178b1d1e 10878 idx += macIntSz;
wolfSSL 16:8e0d178b1d1e 10879 XMEMCPY(output + idx, encContentOctet, encContentOctetSz);
wolfSSL 16:8e0d178b1d1e 10880 idx += encContentOctetSz;
wolfSSL 16:8e0d178b1d1e 10881 XMEMCPY(output + idx, encryptedContent, encryptedOutSz);
wolfSSL 16:8e0d178b1d1e 10882 idx += encryptedOutSz;
wolfSSL 16:8e0d178b1d1e 10883
wolfSSL 16:8e0d178b1d1e 10884 /* authenticated attributes */
wolfSSL 16:8e0d178b1d1e 10885 if (flatAuthAttribs && authAttribsSz > 0) {
wolfSSL 16:8e0d178b1d1e 10886 XMEMCPY(output + idx, authAttribSet, authAttribsSetSz);
wolfSSL 16:8e0d178b1d1e 10887 idx += authAttribsSetSz;
wolfSSL 16:8e0d178b1d1e 10888 XMEMCPY(output + idx, flatAuthAttribs, authAttribsSz);
wolfSSL 16:8e0d178b1d1e 10889 idx += authAttribsSz;
wolfSSL 16:8e0d178b1d1e 10890 XFREE(flatAuthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 10891 }
wolfSSL 16:8e0d178b1d1e 10892
wolfSSL 16:8e0d178b1d1e 10893 XMEMCPY(output + idx, macOctetString, macOctetStringSz);
wolfSSL 16:8e0d178b1d1e 10894 idx += macOctetStringSz;
wolfSSL 16:8e0d178b1d1e 10895 XMEMCPY(output + idx, authTag, sizeof(authTag));
wolfSSL 16:8e0d178b1d1e 10896 idx += sizeof(authTag);
wolfSSL 16:8e0d178b1d1e 10897
wolfSSL 16:8e0d178b1d1e 10898 /* unauthenticated attributes */
wolfSSL 16:8e0d178b1d1e 10899 if (unauthAttribsSz > 0) {
wolfSSL 16:8e0d178b1d1e 10900 XMEMCPY(output + idx, unauthAttribSet, unauthAttribsSetSz);
wolfSSL 16:8e0d178b1d1e 10901 idx += unauthAttribsSetSz;
wolfSSL 16:8e0d178b1d1e 10902 XMEMCPY(output + idx, flatUnauthAttribs, unauthAttribsSz);
wolfSSL 16:8e0d178b1d1e 10903 idx += unauthAttribsSz;
wolfSSL 16:8e0d178b1d1e 10904 }
wolfSSL 16:8e0d178b1d1e 10905
wolfSSL 16:8e0d178b1d1e 10906 if (flatUnauthAttribs != NULL) {
wolfSSL 16:8e0d178b1d1e 10907 XFREE(flatUnauthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 10908 }
wolfSSL 16:8e0d178b1d1e 10909
wolfSSL 16:8e0d178b1d1e 10910 XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 10911
wolfSSL 16:8e0d178b1d1e 10912 return idx;
wolfSSL 16:8e0d178b1d1e 10913
wolfSSL 16:8e0d178b1d1e 10914 #else
wolfSSL 16:8e0d178b1d1e 10915 WOLFSSL_MSG("AuthEnvelopedData requires AES-GCM or AES-CCM to be enabled");
wolfSSL 16:8e0d178b1d1e 10916 (void)pkcs7;
wolfSSL 16:8e0d178b1d1e 10917 (void)output;
wolfSSL 16:8e0d178b1d1e 10918 (void)outputSz;
wolfSSL 16:8e0d178b1d1e 10919
wolfSSL 16:8e0d178b1d1e 10920 return NOT_COMPILED_IN;
wolfSSL 16:8e0d178b1d1e 10921 #endif /* HAVE_AESGCM | HAVE_AESCCM */
wolfSSL 16:8e0d178b1d1e 10922 }
wolfSSL 16:8e0d178b1d1e 10923
wolfSSL 16:8e0d178b1d1e 10924
wolfSSL 16:8e0d178b1d1e 10925 /* unwrap and decrypt PKCS#7 AuthEnvelopedData object, return decoded size */
wolfSSL 16:8e0d178b1d1e 10926 WOLFSSL_API int wc_PKCS7_DecodeAuthEnvelopedData(PKCS7* pkcs7, byte* in,
wolfSSL 16:8e0d178b1d1e 10927 word32 inSz, byte* output,
wolfSSL 16:8e0d178b1d1e 10928 word32 outputSz)
wolfSSL 16:8e0d178b1d1e 10929 {
wolfSSL 16:8e0d178b1d1e 10930 #if defined(HAVE_AESGCM) || defined(HAVE_AESCCM)
wolfSSL 16:8e0d178b1d1e 10931 int recipFound = 0;
wolfSSL 16:8e0d178b1d1e 10932 int ret = 0, length;
wolfSSL 16:8e0d178b1d1e 10933 word32 idx = 0;
wolfSSL 16:8e0d178b1d1e 10934 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 10935 word32 tmpIdx = 0;
wolfSSL 16:8e0d178b1d1e 10936 long rc;
wolfSSL 16:8e0d178b1d1e 10937 #endif
wolfSSL 16:8e0d178b1d1e 10938 word32 contentType, encOID = 0;
wolfSSL 16:8e0d178b1d1e 10939 word32 decryptedKeySz = 0;
wolfSSL 16:8e0d178b1d1e 10940 byte* pkiMsg = in;
wolfSSL 16:8e0d178b1d1e 10941 word32 pkiMsgSz = inSz;
wolfSSL 16:8e0d178b1d1e 10942
wolfSSL 16:8e0d178b1d1e 10943 int expBlockSz = 0, blockKeySz = 0;
wolfSSL 16:8e0d178b1d1e 10944 byte authTag[AES_BLOCK_SIZE];
wolfSSL 16:8e0d178b1d1e 10945 byte nonce[GCM_NONCE_MID_SZ]; /* GCM nonce is larger than CCM */
wolfSSL 16:8e0d178b1d1e 10946 int nonceSz = 0, authTagSz = 0, macSz = 0;
wolfSSL 16:8e0d178b1d1e 10947
wolfSSL 16:8e0d178b1d1e 10948 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 10949 byte* decryptedKey = NULL;
wolfSSL 16:8e0d178b1d1e 10950 #else
wolfSSL 16:8e0d178b1d1e 10951 byte decryptedKey[MAX_ENCRYPTED_KEY_SZ];
wolfSSL 16:8e0d178b1d1e 10952 #endif
wolfSSL 16:8e0d178b1d1e 10953 int encryptedContentSz = 0;
wolfSSL 16:8e0d178b1d1e 10954 byte* encryptedContent = NULL;
wolfSSL 16:8e0d178b1d1e 10955 int explicitOctet = 0;
wolfSSL 16:8e0d178b1d1e 10956
wolfSSL 16:8e0d178b1d1e 10957 byte authAttribSetByte = 0;
wolfSSL 16:8e0d178b1d1e 10958 byte* encodedAttribs = NULL;
wolfSSL 16:8e0d178b1d1e 10959 word32 encodedAttribIdx = 0, encodedAttribSz = 0;
wolfSSL 16:8e0d178b1d1e 10960 byte* authAttrib = NULL;
wolfSSL 16:8e0d178b1d1e 10961 int authAttribSz = 0;
wolfSSL 16:8e0d178b1d1e 10962 word32 localIdx;
wolfSSL 16:8e0d178b1d1e 10963 byte tag;
wolfSSL 16:8e0d178b1d1e 10964
wolfSSL 16:8e0d178b1d1e 10965 if (pkcs7 == NULL)
wolfSSL 16:8e0d178b1d1e 10966 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 10967
wolfSSL 16:8e0d178b1d1e 10968 if (pkiMsg == NULL || pkiMsgSz == 0 ||
wolfSSL 16:8e0d178b1d1e 10969 output == NULL || outputSz == 0)
wolfSSL 16:8e0d178b1d1e 10970 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 10971 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 10972 if (pkcs7->stream == NULL) {
wolfSSL 16:8e0d178b1d1e 10973 if ((ret = wc_PKCS7_CreateStream(pkcs7)) != 0) {
wolfSSL 16:8e0d178b1d1e 10974 return ret;
wolfSSL 16:8e0d178b1d1e 10975 }
wolfSSL 16:8e0d178b1d1e 10976 }
wolfSSL 16:8e0d178b1d1e 10977 #endif
wolfSSL 16:8e0d178b1d1e 10978
wolfSSL 16:8e0d178b1d1e 10979 switch (pkcs7->state) {
wolfSSL 16:8e0d178b1d1e 10980 case WC_PKCS7_START:
wolfSSL 16:8e0d178b1d1e 10981 case WC_PKCS7_INFOSET_START:
wolfSSL 16:8e0d178b1d1e 10982 case WC_PKCS7_INFOSET_STAGE1:
wolfSSL 16:8e0d178b1d1e 10983 case WC_PKCS7_INFOSET_STAGE2:
wolfSSL 16:8e0d178b1d1e 10984 case WC_PKCS7_INFOSET_END:
wolfSSL 16:8e0d178b1d1e 10985 ret = wc_PKCS7_ParseToRecipientInfoSet(pkcs7, pkiMsg, pkiMsgSz,
wolfSSL 16:8e0d178b1d1e 10986 &idx, AUTH_ENVELOPED_DATA);
wolfSSL 16:8e0d178b1d1e 10987 if (ret < 0)
wolfSSL 16:8e0d178b1d1e 10988 break;
wolfSSL 16:8e0d178b1d1e 10989
wolfSSL 16:8e0d178b1d1e 10990 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 10991 tmpIdx = idx;
wolfSSL 16:8e0d178b1d1e 10992 #endif
wolfSSL 16:8e0d178b1d1e 10993 wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_AUTHENV_2);
wolfSSL 16:8e0d178b1d1e 10994 FALL_THROUGH;
wolfSSL 16:8e0d178b1d1e 10995
wolfSSL 16:8e0d178b1d1e 10996 case WC_PKCS7_AUTHENV_2:
wolfSSL 16:8e0d178b1d1e 10997 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 10998 if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_LENGTH_SZ +
wolfSSL 16:8e0d178b1d1e 10999 MAX_VERSION_SZ + ASN_TAG_SZ, &pkiMsg, &idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 11000 break;
wolfSSL 16:8e0d178b1d1e 11001 }
wolfSSL 16:8e0d178b1d1e 11002 #endif
wolfSSL 16:8e0d178b1d1e 11003 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 11004 decryptedKey = (byte*)XMALLOC(MAX_ENCRYPTED_KEY_SZ, pkcs7->heap,
wolfSSL 16:8e0d178b1d1e 11005 DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 11006 if (decryptedKey == NULL) {
wolfSSL 16:8e0d178b1d1e 11007 ret = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 11008 break;
wolfSSL 16:8e0d178b1d1e 11009 }
wolfSSL 16:8e0d178b1d1e 11010 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 11011 pkcs7->stream->key = decryptedKey;
wolfSSL 16:8e0d178b1d1e 11012 #endif
wolfSSL 16:8e0d178b1d1e 11013 #endif
wolfSSL 16:8e0d178b1d1e 11014 FALL_THROUGH;
wolfSSL 16:8e0d178b1d1e 11015
wolfSSL 16:8e0d178b1d1e 11016 case WC_PKCS7_DECRYPT_KTRI:
wolfSSL 16:8e0d178b1d1e 11017 case WC_PKCS7_DECRYPT_KTRI_2:
wolfSSL 16:8e0d178b1d1e 11018 case WC_PKCS7_DECRYPT_KTRI_3:
wolfSSL 16:8e0d178b1d1e 11019 case WC_PKCS7_DECRYPT_KARI:
wolfSSL 16:8e0d178b1d1e 11020 case WC_PKCS7_DECRYPT_KEKRI:
wolfSSL 16:8e0d178b1d1e 11021 case WC_PKCS7_DECRYPT_PWRI:
wolfSSL 16:8e0d178b1d1e 11022 case WC_PKCS7_DECRYPT_ORI:
wolfSSL 16:8e0d178b1d1e 11023
wolfSSL 16:8e0d178b1d1e 11024 decryptedKeySz = MAX_ENCRYPTED_KEY_SZ;
wolfSSL 16:8e0d178b1d1e 11025 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 11026 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 11027 decryptedKey = pkcs7->stream->key;
wolfSSL 16:8e0d178b1d1e 11028 #endif
wolfSSL 16:8e0d178b1d1e 11029 #endif
wolfSSL 16:8e0d178b1d1e 11030
wolfSSL 16:8e0d178b1d1e 11031 ret = wc_PKCS7_DecryptRecipientInfos(pkcs7, in, inSz, &idx,
wolfSSL 16:8e0d178b1d1e 11032 decryptedKey, &decryptedKeySz,
wolfSSL 16:8e0d178b1d1e 11033 &recipFound);
wolfSSL 16:8e0d178b1d1e 11034 if (ret != 0) {
wolfSSL 16:8e0d178b1d1e 11035 break;
wolfSSL 16:8e0d178b1d1e 11036 }
wolfSSL 16:8e0d178b1d1e 11037
wolfSSL 16:8e0d178b1d1e 11038 if (recipFound == 0) {
wolfSSL 16:8e0d178b1d1e 11039 WOLFSSL_MSG("No recipient found in envelopedData that matches input");
wolfSSL 16:8e0d178b1d1e 11040 ret = PKCS7_RECIP_E;
wolfSSL 16:8e0d178b1d1e 11041 break;
wolfSSL 16:8e0d178b1d1e 11042 }
wolfSSL 16:8e0d178b1d1e 11043
wolfSSL 16:8e0d178b1d1e 11044 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 11045 tmpIdx = idx;
wolfSSL 16:8e0d178b1d1e 11046 #endif
wolfSSL 16:8e0d178b1d1e 11047 wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_AUTHENV_3);
wolfSSL 16:8e0d178b1d1e 11048 FALL_THROUGH;
wolfSSL 16:8e0d178b1d1e 11049
wolfSSL 16:8e0d178b1d1e 11050 case WC_PKCS7_AUTHENV_3:
wolfSSL 16:8e0d178b1d1e 11051 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 11052 if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_SEQ_SZ +
wolfSSL 16:8e0d178b1d1e 11053 MAX_ALGO_SZ + MAX_ALGO_SZ + ASN_TAG_SZ,
wolfSSL 16:8e0d178b1d1e 11054 &pkiMsg, &idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 11055 break;
wolfSSL 16:8e0d178b1d1e 11056 }
wolfSSL 16:8e0d178b1d1e 11057
wolfSSL 16:8e0d178b1d1e 11058 rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK,
wolfSSL 16:8e0d178b1d1e 11059 in, inSz);
wolfSSL 16:8e0d178b1d1e 11060 if (rc < 0) {
wolfSSL 16:8e0d178b1d1e 11061 ret = (int)rc;
wolfSSL 16:8e0d178b1d1e 11062 break;
wolfSSL 16:8e0d178b1d1e 11063 }
wolfSSL 16:8e0d178b1d1e 11064 pkiMsgSz = (word32)rc;
wolfSSL 16:8e0d178b1d1e 11065 #endif
wolfSSL 16:8e0d178b1d1e 11066
wolfSSL 16:8e0d178b1d1e 11067 /* remove EncryptedContentInfo */
wolfSSL 16:8e0d178b1d1e 11068 if (ret == 0 && GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0) {
wolfSSL 16:8e0d178b1d1e 11069 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 11070 }
wolfSSL 16:8e0d178b1d1e 11071
wolfSSL 16:8e0d178b1d1e 11072 if (ret == 0 && wc_GetContentType(pkiMsg, &idx, &contentType,
wolfSSL 16:8e0d178b1d1e 11073 pkiMsgSz) < 0) {
wolfSSL 16:8e0d178b1d1e 11074 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 11075 }
wolfSSL 16:8e0d178b1d1e 11076
wolfSSL 16:8e0d178b1d1e 11077 if (ret == 0 && GetAlgoId(pkiMsg, &idx, &encOID, oidBlkType,
wolfSSL 16:8e0d178b1d1e 11078 pkiMsgSz) < 0) {
wolfSSL 16:8e0d178b1d1e 11079 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 11080 }
wolfSSL 16:8e0d178b1d1e 11081
wolfSSL 16:8e0d178b1d1e 11082 blockKeySz = wc_PKCS7_GetOIDKeySize(encOID);
wolfSSL 16:8e0d178b1d1e 11083 if (ret == 0 && blockKeySz < 0) {
wolfSSL 16:8e0d178b1d1e 11084 ret = blockKeySz;
wolfSSL 16:8e0d178b1d1e 11085 }
wolfSSL 16:8e0d178b1d1e 11086
wolfSSL 16:8e0d178b1d1e 11087 expBlockSz = wc_PKCS7_GetOIDBlockSize(encOID);
wolfSSL 16:8e0d178b1d1e 11088 if (ret == 0 && expBlockSz < 0) {
wolfSSL 16:8e0d178b1d1e 11089 ret = expBlockSz;
wolfSSL 16:8e0d178b1d1e 11090 }
wolfSSL 16:8e0d178b1d1e 11091
wolfSSL 16:8e0d178b1d1e 11092 /* get nonce, stored in OPTIONAL parameter of AlgoID */
wolfSSL 16:8e0d178b1d1e 11093 if (ret == 0 && GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0) {
wolfSSL 16:8e0d178b1d1e 11094 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 11095 }
wolfSSL 16:8e0d178b1d1e 11096
wolfSSL 16:8e0d178b1d1e 11097 if (ret == 0 && tag != ASN_OCTET_STRING) {
wolfSSL 16:8e0d178b1d1e 11098 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 11099 }
wolfSSL 16:8e0d178b1d1e 11100
wolfSSL 16:8e0d178b1d1e 11101 if (ret < 0)
wolfSSL 16:8e0d178b1d1e 11102 break;
wolfSSL 16:8e0d178b1d1e 11103
wolfSSL 16:8e0d178b1d1e 11104 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 11105 if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 11106 break;
wolfSSL 16:8e0d178b1d1e 11107 }
wolfSSL 16:8e0d178b1d1e 11108 wc_PKCS7_StreamStoreVar(pkcs7, encOID, blockKeySz, 0);
wolfSSL 16:8e0d178b1d1e 11109 #endif
wolfSSL 16:8e0d178b1d1e 11110 wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_AUTHENV_4);
wolfSSL 16:8e0d178b1d1e 11111 FALL_THROUGH;
wolfSSL 16:8e0d178b1d1e 11112
wolfSSL 16:8e0d178b1d1e 11113 case WC_PKCS7_AUTHENV_4:
wolfSSL 16:8e0d178b1d1e 11114
wolfSSL 16:8e0d178b1d1e 11115 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 11116 if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_LENGTH_SZ +
wolfSSL 16:8e0d178b1d1e 11117 MAX_VERSION_SZ + ASN_TAG_SZ + MAX_LENGTH_SZ,
wolfSSL 16:8e0d178b1d1e 11118 &pkiMsg, &idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 11119 break;
wolfSSL 16:8e0d178b1d1e 11120 }
wolfSSL 16:8e0d178b1d1e 11121
wolfSSL 16:8e0d178b1d1e 11122 rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK, in,
wolfSSL 16:8e0d178b1d1e 11123 inSz);
wolfSSL 16:8e0d178b1d1e 11124 if (rc < 0) {
wolfSSL 16:8e0d178b1d1e 11125 ret = (int)rc;
wolfSSL 16:8e0d178b1d1e 11126 break;
wolfSSL 16:8e0d178b1d1e 11127 }
wolfSSL 16:8e0d178b1d1e 11128 pkiMsgSz = (word32)rc;
wolfSSL 16:8e0d178b1d1e 11129 #endif
wolfSSL 16:8e0d178b1d1e 11130 if (ret == 0 && GetLength(pkiMsg, &idx, &nonceSz, pkiMsgSz) < 0) {
wolfSSL 16:8e0d178b1d1e 11131 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 11132 }
wolfSSL 16:8e0d178b1d1e 11133
wolfSSL 16:8e0d178b1d1e 11134 if (ret == 0 && nonceSz > (int)sizeof(nonce)) {
wolfSSL 16:8e0d178b1d1e 11135 WOLFSSL_MSG("AuthEnvelopedData nonce too large for buffer");
wolfSSL 16:8e0d178b1d1e 11136 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 11137 }
wolfSSL 16:8e0d178b1d1e 11138
wolfSSL 16:8e0d178b1d1e 11139 if (ret == 0) {
wolfSSL 16:8e0d178b1d1e 11140 XMEMCPY(nonce, &pkiMsg[idx], nonceSz);
wolfSSL 16:8e0d178b1d1e 11141 idx += nonceSz;
wolfSSL 16:8e0d178b1d1e 11142 }
wolfSSL 16:8e0d178b1d1e 11143
wolfSSL 16:8e0d178b1d1e 11144 /* get mac size, also stored in OPTIONAL parameter of AlgoID */
wolfSSL 16:8e0d178b1d1e 11145 if (ret == 0 && GetMyVersion(pkiMsg, &idx, &macSz, pkiMsgSz) < 0) {
wolfSSL 16:8e0d178b1d1e 11146 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 11147 }
wolfSSL 16:8e0d178b1d1e 11148
wolfSSL 16:8e0d178b1d1e 11149 if (ret == 0) {
wolfSSL 16:8e0d178b1d1e 11150 explicitOctet = 0;
wolfSSL 16:8e0d178b1d1e 11151 localIdx = idx;
wolfSSL 16:8e0d178b1d1e 11152 if (GetASNTag(pkiMsg, &localIdx, &tag, pkiMsgSz) == 0 &&
wolfSSL 16:8e0d178b1d1e 11153 tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0))
wolfSSL 16:8e0d178b1d1e 11154 explicitOctet = 1;
wolfSSL 16:8e0d178b1d1e 11155
wolfSSL 16:8e0d178b1d1e 11156 /* read encryptedContent, cont[0] */
wolfSSL 16:8e0d178b1d1e 11157 ret = GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz);
wolfSSL 16:8e0d178b1d1e 11158 }
wolfSSL 16:8e0d178b1d1e 11159
wolfSSL 16:8e0d178b1d1e 11160 if (ret == 0 &&
wolfSSL 16:8e0d178b1d1e 11161 tag != (ASN_CONTEXT_SPECIFIC | 0) &&
wolfSSL 16:8e0d178b1d1e 11162 tag != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0)) {
wolfSSL 16:8e0d178b1d1e 11163 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 11164 }
wolfSSL 16:8e0d178b1d1e 11165
wolfSSL 16:8e0d178b1d1e 11166 if (ret == 0 && GetLength(pkiMsg, &idx, &encryptedContentSz,
wolfSSL 16:8e0d178b1d1e 11167 pkiMsgSz) <= 0) {
wolfSSL 16:8e0d178b1d1e 11168 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 11169 }
wolfSSL 16:8e0d178b1d1e 11170
wolfSSL 16:8e0d178b1d1e 11171 if (explicitOctet) {
wolfSSL 16:8e0d178b1d1e 11172 if (ret == 0 && GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0) {
wolfSSL 16:8e0d178b1d1e 11173 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 11174 }
wolfSSL 16:8e0d178b1d1e 11175 if (ret == 0 && tag != ASN_OCTET_STRING) {
wolfSSL 16:8e0d178b1d1e 11176 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 11177 }
wolfSSL 16:8e0d178b1d1e 11178
wolfSSL 16:8e0d178b1d1e 11179 if (ret == 0 && GetLength(pkiMsg, &idx, &encryptedContentSz,
wolfSSL 16:8e0d178b1d1e 11180 pkiMsgSz) <= 0) {
wolfSSL 16:8e0d178b1d1e 11181 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 11182 }
wolfSSL 16:8e0d178b1d1e 11183 }
wolfSSL 16:8e0d178b1d1e 11184
wolfSSL 16:8e0d178b1d1e 11185 if (ret < 0)
wolfSSL 16:8e0d178b1d1e 11186 break;
wolfSSL 16:8e0d178b1d1e 11187
wolfSSL 16:8e0d178b1d1e 11188 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 11189 if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 11190 break;
wolfSSL 16:8e0d178b1d1e 11191 }
wolfSSL 16:8e0d178b1d1e 11192
wolfSSL 16:8e0d178b1d1e 11193 /* store nonce for later */
wolfSSL 16:8e0d178b1d1e 11194 if (nonceSz > 0) {
wolfSSL 16:8e0d178b1d1e 11195 pkcs7->stream->nonceSz = nonceSz;
wolfSSL 16:8e0d178b1d1e 11196 pkcs7->stream->nonce = (byte*)XMALLOC(nonceSz, pkcs7->heap,
wolfSSL 16:8e0d178b1d1e 11197 DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 11198 if (pkcs7->stream->nonce == NULL) {
wolfSSL 16:8e0d178b1d1e 11199 ret = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 11200 break;
wolfSSL 16:8e0d178b1d1e 11201 }
wolfSSL 16:8e0d178b1d1e 11202 else {
wolfSSL 16:8e0d178b1d1e 11203 XMEMCPY(pkcs7->stream->nonce, nonce, nonceSz);
wolfSSL 16:8e0d178b1d1e 11204 }
wolfSSL 16:8e0d178b1d1e 11205 }
wolfSSL 16:8e0d178b1d1e 11206
wolfSSL 16:8e0d178b1d1e 11207 pkcs7->stream->expected = encryptedContentSz;
wolfSSL 16:8e0d178b1d1e 11208 wc_PKCS7_StreamStoreVar(pkcs7, encOID, blockKeySz,
wolfSSL 16:8e0d178b1d1e 11209 encryptedContentSz);
wolfSSL 16:8e0d178b1d1e 11210 #endif
wolfSSL 16:8e0d178b1d1e 11211
wolfSSL 16:8e0d178b1d1e 11212 wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_AUTHENV_5);
wolfSSL 16:8e0d178b1d1e 11213 FALL_THROUGH;
wolfSSL 16:8e0d178b1d1e 11214
wolfSSL 16:8e0d178b1d1e 11215 case WC_PKCS7_AUTHENV_5:
wolfSSL 16:8e0d178b1d1e 11216 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 11217 if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_LENGTH_SZ +
wolfSSL 16:8e0d178b1d1e 11218 ASN_TAG_SZ + ASN_TAG_SZ + pkcs7->stream->expected,
wolfSSL 16:8e0d178b1d1e 11219 &pkiMsg, &idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 11220 break;
wolfSSL 16:8e0d178b1d1e 11221 }
wolfSSL 16:8e0d178b1d1e 11222
wolfSSL 16:8e0d178b1d1e 11223 rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK, in,
wolfSSL 16:8e0d178b1d1e 11224 inSz);
wolfSSL 16:8e0d178b1d1e 11225 if (rc < 0) {
wolfSSL 16:8e0d178b1d1e 11226 ret = (int)rc;
wolfSSL 16:8e0d178b1d1e 11227 break;
wolfSSL 16:8e0d178b1d1e 11228 }
wolfSSL 16:8e0d178b1d1e 11229 pkiMsgSz = (word32)rc;
wolfSSL 16:8e0d178b1d1e 11230
wolfSSL 16:8e0d178b1d1e 11231 encryptedContentSz = pkcs7->stream->expected;
wolfSSL 16:8e0d178b1d1e 11232 #endif
wolfSSL 16:8e0d178b1d1e 11233
wolfSSL 16:8e0d178b1d1e 11234 encryptedContent = (byte*)XMALLOC(encryptedContentSz, pkcs7->heap,
wolfSSL 16:8e0d178b1d1e 11235 DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 11236 if (ret == 0 && encryptedContent == NULL) {
wolfSSL 16:8e0d178b1d1e 11237 ret = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 11238 }
wolfSSL 16:8e0d178b1d1e 11239
wolfSSL 16:8e0d178b1d1e 11240 if (ret == 0) {
wolfSSL 16:8e0d178b1d1e 11241 XMEMCPY(encryptedContent, &pkiMsg[idx], encryptedContentSz);
wolfSSL 16:8e0d178b1d1e 11242 idx += encryptedContentSz;
wolfSSL 16:8e0d178b1d1e 11243 }
wolfSSL 16:8e0d178b1d1e 11244 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 11245 pkcs7->stream->bufferPt = encryptedContent;
wolfSSL 16:8e0d178b1d1e 11246 #endif
wolfSSL 16:8e0d178b1d1e 11247
wolfSSL 16:8e0d178b1d1e 11248 /* may have IMPLICIT [1] authenticatedAttributes */
wolfSSL 16:8e0d178b1d1e 11249 localIdx = idx;
wolfSSL 16:8e0d178b1d1e 11250 if (ret == 0 && GetASNTag(pkiMsg, &localIdx, &tag, pkiMsgSz) == 0 &&
wolfSSL 16:8e0d178b1d1e 11251 tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) {
wolfSSL 16:8e0d178b1d1e 11252 encodedAttribIdx = idx;
wolfSSL 16:8e0d178b1d1e 11253 encodedAttribs = pkiMsg + idx;
wolfSSL 16:8e0d178b1d1e 11254 idx++;
wolfSSL 16:8e0d178b1d1e 11255
wolfSSL 16:8e0d178b1d1e 11256 if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
wolfSSL 16:8e0d178b1d1e 11257 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 11258 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 11259 pkcs7->stream->expected = length;
wolfSSL 16:8e0d178b1d1e 11260 #endif
wolfSSL 16:8e0d178b1d1e 11261 encodedAttribSz = length + (idx - encodedAttribIdx);
wolfSSL 16:8e0d178b1d1e 11262
wolfSSL 16:8e0d178b1d1e 11263 if (ret != 0)
wolfSSL 16:8e0d178b1d1e 11264 break;
wolfSSL 16:8e0d178b1d1e 11265
wolfSSL 16:8e0d178b1d1e 11266 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 11267 if (encodedAttribSz > 0) {
wolfSSL 16:8e0d178b1d1e 11268 pkcs7->stream->aadSz = encodedAttribSz;
wolfSSL 16:8e0d178b1d1e 11269 pkcs7->stream->aad = (byte*)XMALLOC(encodedAttribSz,
wolfSSL 16:8e0d178b1d1e 11270 pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 11271 if (pkcs7->stream->aad == NULL) {
wolfSSL 16:8e0d178b1d1e 11272 ret = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 11273 break;
wolfSSL 16:8e0d178b1d1e 11274 }
wolfSSL 16:8e0d178b1d1e 11275 else {
wolfSSL 16:8e0d178b1d1e 11276 XMEMCPY(pkcs7->stream->aad, encodedAttribs,
wolfSSL 16:8e0d178b1d1e 11277 (idx - encodedAttribIdx));
wolfSSL 16:8e0d178b1d1e 11278 }
wolfSSL 16:8e0d178b1d1e 11279 }
wolfSSL 16:8e0d178b1d1e 11280
wolfSSL 16:8e0d178b1d1e 11281 if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 11282 break;
wolfSSL 16:8e0d178b1d1e 11283 }
wolfSSL 16:8e0d178b1d1e 11284 #endif
wolfSSL 16:8e0d178b1d1e 11285 wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_AUTHENV_ATRB);
wolfSSL 16:8e0d178b1d1e 11286 }
wolfSSL 16:8e0d178b1d1e 11287 else {
wolfSSL 16:8e0d178b1d1e 11288 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 11289 if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 11290 break;
wolfSSL 16:8e0d178b1d1e 11291 }
wolfSSL 16:8e0d178b1d1e 11292 #endif
wolfSSL 16:8e0d178b1d1e 11293 goto authenv_atrbend; /* jump over attribute cases */
wolfSSL 16:8e0d178b1d1e 11294 }
wolfSSL 16:8e0d178b1d1e 11295 FALL_THROUGH;
wolfSSL 16:8e0d178b1d1e 11296
wolfSSL 16:8e0d178b1d1e 11297 case WC_PKCS7_AUTHENV_ATRB:
wolfSSL 16:8e0d178b1d1e 11298 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 11299 if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
wolfSSL 16:8e0d178b1d1e 11300 pkcs7->stream->expected, &pkiMsg, &idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 11301 return ret;
wolfSSL 16:8e0d178b1d1e 11302 }
wolfSSL 16:8e0d178b1d1e 11303
wolfSSL 16:8e0d178b1d1e 11304 length = pkcs7->stream->expected;
wolfSSL 16:8e0d178b1d1e 11305 encodedAttribs = pkcs7->stream->aad;
wolfSSL 16:8e0d178b1d1e 11306 #else
wolfSSL 16:8e0d178b1d1e 11307 length = 0;
wolfSSL 16:8e0d178b1d1e 11308 #endif
wolfSSL 16:8e0d178b1d1e 11309
wolfSSL 16:8e0d178b1d1e 11310 /* save pointer and length */
wolfSSL 16:8e0d178b1d1e 11311 authAttrib = &pkiMsg[idx];
wolfSSL 16:8e0d178b1d1e 11312 authAttribSz = length;
wolfSSL 16:8e0d178b1d1e 11313
wolfSSL 16:8e0d178b1d1e 11314 if (ret == 0 && wc_PKCS7_ParseAttribs(pkcs7, authAttrib, authAttribSz) < 0) {
wolfSSL 16:8e0d178b1d1e 11315 WOLFSSL_MSG("Error parsing authenticated attributes");
wolfSSL 16:8e0d178b1d1e 11316 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 11317 break;
wolfSSL 16:8e0d178b1d1e 11318 }
wolfSSL 16:8e0d178b1d1e 11319
wolfSSL 16:8e0d178b1d1e 11320 idx += length;
wolfSSL 16:8e0d178b1d1e 11321
wolfSSL 16:8e0d178b1d1e 11322 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 11323 if (encodedAttribSz > 0) {
wolfSSL 16:8e0d178b1d1e 11324 XMEMCPY(pkcs7->stream->aad + (encodedAttribSz - length),
wolfSSL 16:8e0d178b1d1e 11325 authAttrib, authAttribSz);
wolfSSL 16:8e0d178b1d1e 11326 }
wolfSSL 16:8e0d178b1d1e 11327 if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 11328 break;
wolfSSL 16:8e0d178b1d1e 11329 }
wolfSSL 16:8e0d178b1d1e 11330
wolfSSL 16:8e0d178b1d1e 11331 #endif
wolfSSL 16:8e0d178b1d1e 11332 wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_AUTHENV_ATRBEND);
wolfSSL 16:8e0d178b1d1e 11333 FALL_THROUGH;
wolfSSL 16:8e0d178b1d1e 11334
wolfSSL 16:8e0d178b1d1e 11335 authenv_atrbend:
wolfSSL 16:8e0d178b1d1e 11336 case WC_PKCS7_AUTHENV_ATRBEND:
wolfSSL 16:8e0d178b1d1e 11337 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 11338 if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_LENGTH_SZ +
wolfSSL 16:8e0d178b1d1e 11339 ASN_TAG_SZ, &pkiMsg, &idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 11340 return ret;
wolfSSL 16:8e0d178b1d1e 11341 }
wolfSSL 16:8e0d178b1d1e 11342
wolfSSL 16:8e0d178b1d1e 11343 rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK,
wolfSSL 16:8e0d178b1d1e 11344 in, inSz);
wolfSSL 16:8e0d178b1d1e 11345 if (rc < 0) {
wolfSSL 16:8e0d178b1d1e 11346 ret = (int)rc;
wolfSSL 16:8e0d178b1d1e 11347 break;
wolfSSL 16:8e0d178b1d1e 11348 }
wolfSSL 16:8e0d178b1d1e 11349 pkiMsgSz = (word32)rc;
wolfSSL 16:8e0d178b1d1e 11350
wolfSSL 16:8e0d178b1d1e 11351 if (pkcs7->stream->aadSz > 0) {
wolfSSL 16:8e0d178b1d1e 11352 encodedAttribSz = pkcs7->stream->aadSz;
wolfSSL 16:8e0d178b1d1e 11353 encodedAttribs = pkcs7->stream->aad;
wolfSSL 16:8e0d178b1d1e 11354 }
wolfSSL 16:8e0d178b1d1e 11355 #endif
wolfSSL 16:8e0d178b1d1e 11356
wolfSSL 16:8e0d178b1d1e 11357
wolfSSL 16:8e0d178b1d1e 11358 /* get authTag OCTET STRING */
wolfSSL 16:8e0d178b1d1e 11359 if (ret == 0 && GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0) {
wolfSSL 16:8e0d178b1d1e 11360 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 11361 }
wolfSSL 16:8e0d178b1d1e 11362 if (ret == 0 && tag != ASN_OCTET_STRING) {
wolfSSL 16:8e0d178b1d1e 11363 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 11364 }
wolfSSL 16:8e0d178b1d1e 11365
wolfSSL 16:8e0d178b1d1e 11366 if (ret == 0 && GetLength(pkiMsg, &idx, &authTagSz, pkiMsgSz) < 0) {
wolfSSL 16:8e0d178b1d1e 11367 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 11368 }
wolfSSL 16:8e0d178b1d1e 11369
wolfSSL 16:8e0d178b1d1e 11370 if (ret == 0 && authTagSz > (int)sizeof(authTag)) {
wolfSSL 16:8e0d178b1d1e 11371 WOLFSSL_MSG("AuthEnvelopedData authTag too large for buffer");
wolfSSL 16:8e0d178b1d1e 11372 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 11373 }
wolfSSL 16:8e0d178b1d1e 11374
wolfSSL 16:8e0d178b1d1e 11375 if (ret == 0) {
wolfSSL 16:8e0d178b1d1e 11376 XMEMCPY(authTag, &pkiMsg[idx], authTagSz);
wolfSSL 16:8e0d178b1d1e 11377 idx += authTagSz;
wolfSSL 16:8e0d178b1d1e 11378 }
wolfSSL 16:8e0d178b1d1e 11379
wolfSSL 16:8e0d178b1d1e 11380 if (ret == 0 && authAttrib != NULL) {
wolfSSL 16:8e0d178b1d1e 11381 /* temporarily swap authAttribs byte[0] to SET OF instead of
wolfSSL 16:8e0d178b1d1e 11382 * IMPLICIT [1], for aad calculation */
wolfSSL 16:8e0d178b1d1e 11383 authAttribSetByte = encodedAttribs[0];
wolfSSL 16:8e0d178b1d1e 11384
wolfSSL 16:8e0d178b1d1e 11385 encodedAttribs[0] = ASN_SET | ASN_CONSTRUCTED;
wolfSSL 16:8e0d178b1d1e 11386 }
wolfSSL 16:8e0d178b1d1e 11387
wolfSSL 16:8e0d178b1d1e 11388 if (ret < 0)
wolfSSL 16:8e0d178b1d1e 11389 break;
wolfSSL 16:8e0d178b1d1e 11390
wolfSSL 16:8e0d178b1d1e 11391 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 11392 if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 11393 break;
wolfSSL 16:8e0d178b1d1e 11394 }
wolfSSL 16:8e0d178b1d1e 11395 pkcs7->stream->expected = (pkcs7->stream->maxLen -
wolfSSL 16:8e0d178b1d1e 11396 pkcs7->stream->totalRd) + pkcs7->stream->length;
wolfSSL 16:8e0d178b1d1e 11397
wolfSSL 16:8e0d178b1d1e 11398
wolfSSL 16:8e0d178b1d1e 11399 /* store tag for later */
wolfSSL 16:8e0d178b1d1e 11400 if (authTagSz > 0) {
wolfSSL 16:8e0d178b1d1e 11401 pkcs7->stream->tagSz = authTagSz;
wolfSSL 16:8e0d178b1d1e 11402 pkcs7->stream->tag = (byte*)XMALLOC(authTagSz, pkcs7->heap,
wolfSSL 16:8e0d178b1d1e 11403 DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 11404 if (pkcs7->stream->tag == NULL) {
wolfSSL 16:8e0d178b1d1e 11405 ret = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 11406 break;
wolfSSL 16:8e0d178b1d1e 11407 }
wolfSSL 16:8e0d178b1d1e 11408 else {
wolfSSL 16:8e0d178b1d1e 11409 XMEMCPY(pkcs7->stream->tag, authTag, authTagSz);
wolfSSL 16:8e0d178b1d1e 11410 }
wolfSSL 16:8e0d178b1d1e 11411 }
wolfSSL 16:8e0d178b1d1e 11412
wolfSSL 16:8e0d178b1d1e 11413 #endif
wolfSSL 16:8e0d178b1d1e 11414 wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_AUTHENV_6);
wolfSSL 16:8e0d178b1d1e 11415 FALL_THROUGH;
wolfSSL 16:8e0d178b1d1e 11416
wolfSSL 16:8e0d178b1d1e 11417 case WC_PKCS7_AUTHENV_6:
wolfSSL 16:8e0d178b1d1e 11418 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 11419 if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
wolfSSL 16:8e0d178b1d1e 11420 pkcs7->stream->expected, &pkiMsg, &idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 11421 break;
wolfSSL 16:8e0d178b1d1e 11422 }
wolfSSL 16:8e0d178b1d1e 11423
wolfSSL 16:8e0d178b1d1e 11424 /* restore all variables needed */
wolfSSL 16:8e0d178b1d1e 11425 if (pkcs7->stream->nonceSz > 0) {
wolfSSL 16:8e0d178b1d1e 11426 nonceSz = pkcs7->stream->nonceSz;
wolfSSL 16:8e0d178b1d1e 11427 if (nonceSz > GCM_NONCE_MID_SZ) {
wolfSSL 16:8e0d178b1d1e 11428 WOLFSSL_MSG("PKCS7 saved nonce is too large");
wolfSSL 16:8e0d178b1d1e 11429 ret = BUFFER_E;
wolfSSL 16:8e0d178b1d1e 11430 break;
wolfSSL 16:8e0d178b1d1e 11431 }
wolfSSL 16:8e0d178b1d1e 11432 else {
wolfSSL 16:8e0d178b1d1e 11433 XMEMCPY(nonce, pkcs7->stream->nonce, nonceSz);
wolfSSL 16:8e0d178b1d1e 11434 }
wolfSSL 16:8e0d178b1d1e 11435 }
wolfSSL 16:8e0d178b1d1e 11436
wolfSSL 16:8e0d178b1d1e 11437 if (pkcs7->stream->tagSz > 0) {
wolfSSL 16:8e0d178b1d1e 11438 authTagSz = pkcs7->stream->tagSz;
wolfSSL 16:8e0d178b1d1e 11439 if (authTagSz > AES_BLOCK_SIZE) {
wolfSSL 16:8e0d178b1d1e 11440 WOLFSSL_MSG("PKCS7 saved tag is too large");
wolfSSL 16:8e0d178b1d1e 11441 ret = BUFFER_E;
wolfSSL 16:8e0d178b1d1e 11442 break;
wolfSSL 16:8e0d178b1d1e 11443 }
wolfSSL 16:8e0d178b1d1e 11444 else {
wolfSSL 16:8e0d178b1d1e 11445 XMEMCPY(authTag, pkcs7->stream->tag, authTagSz);
wolfSSL 16:8e0d178b1d1e 11446 }
wolfSSL 16:8e0d178b1d1e 11447 }
wolfSSL 16:8e0d178b1d1e 11448
wolfSSL 16:8e0d178b1d1e 11449 if (pkcs7->stream->aadSz > 0) {
wolfSSL 16:8e0d178b1d1e 11450 encodedAttribSz = pkcs7->stream->aadSz;
wolfSSL 16:8e0d178b1d1e 11451 encodedAttribs = pkcs7->stream->aad;
wolfSSL 16:8e0d178b1d1e 11452 }
wolfSSL 16:8e0d178b1d1e 11453
wolfSSL 16:8e0d178b1d1e 11454 wc_PKCS7_StreamGetVar(pkcs7, &encOID, &blockKeySz,
wolfSSL 16:8e0d178b1d1e 11455 &encryptedContentSz);
wolfSSL 16:8e0d178b1d1e 11456 encryptedContent = pkcs7->stream->bufferPt;
wolfSSL 16:8e0d178b1d1e 11457 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 11458 decryptedKey = pkcs7->stream->key;
wolfSSL 16:8e0d178b1d1e 11459 #endif
wolfSSL 16:8e0d178b1d1e 11460 #endif
wolfSSL 16:8e0d178b1d1e 11461
wolfSSL 16:8e0d178b1d1e 11462 /* decrypt encryptedContent */
wolfSSL 16:8e0d178b1d1e 11463 ret = wc_PKCS7_DecryptContent(pkcs7, encOID, decryptedKey,
wolfSSL 16:8e0d178b1d1e 11464 blockKeySz, nonce, nonceSz, encodedAttribs, encodedAttribSz,
wolfSSL 16:8e0d178b1d1e 11465 authTag, authTagSz, encryptedContent, encryptedContentSz,
wolfSSL 16:8e0d178b1d1e 11466 encryptedContent);
wolfSSL 16:8e0d178b1d1e 11467 if (ret != 0) {
wolfSSL 16:8e0d178b1d1e 11468 XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 11469 return ret;
wolfSSL 16:8e0d178b1d1e 11470 }
wolfSSL 16:8e0d178b1d1e 11471
wolfSSL 16:8e0d178b1d1e 11472 if (authAttrib != NULL) {
wolfSSL 16:8e0d178b1d1e 11473 /* restore authAttrib IMPLICIT [1] */
wolfSSL 16:8e0d178b1d1e 11474 encodedAttribs[0] = authAttribSetByte;
wolfSSL 16:8e0d178b1d1e 11475 }
wolfSSL 16:8e0d178b1d1e 11476
wolfSSL 16:8e0d178b1d1e 11477 /* copy plaintext to output */
wolfSSL 16:8e0d178b1d1e 11478 XMEMCPY(output, encryptedContent, encryptedContentSz);
wolfSSL 16:8e0d178b1d1e 11479
wolfSSL 16:8e0d178b1d1e 11480 /* free memory, zero out keys */
wolfSSL 16:8e0d178b1d1e 11481 ForceZero(encryptedContent, encryptedContentSz);
wolfSSL 16:8e0d178b1d1e 11482 XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 11483 ForceZero(decryptedKey, MAX_ENCRYPTED_KEY_SZ);
wolfSSL 16:8e0d178b1d1e 11484 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 11485 XFREE(decryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 11486 decryptedKey = NULL;
wolfSSL 16:8e0d178b1d1e 11487 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 11488 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 11489 pkcs7->stream->key = NULL;
wolfSSL 16:8e0d178b1d1e 11490 #endif
wolfSSL 16:8e0d178b1d1e 11491 #endif
wolfSSL 16:8e0d178b1d1e 11492 #endif
wolfSSL 16:8e0d178b1d1e 11493 ret = encryptedContentSz;
wolfSSL 16:8e0d178b1d1e 11494 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 11495 wc_PKCS7_ResetStream(pkcs7);
wolfSSL 16:8e0d178b1d1e 11496 #endif
wolfSSL 16:8e0d178b1d1e 11497 wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_START);
wolfSSL 16:8e0d178b1d1e 11498 break;
wolfSSL 16:8e0d178b1d1e 11499 default:
wolfSSL 16:8e0d178b1d1e 11500 WOLFSSL_MSG("Unknown PKCS7 state");
wolfSSL 16:8e0d178b1d1e 11501 ret = BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 11502 }
wolfSSL 16:8e0d178b1d1e 11503
wolfSSL 16:8e0d178b1d1e 11504 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 11505 if (ret != 0 && ret != WC_PKCS7_WANT_READ_E) {
wolfSSL 16:8e0d178b1d1e 11506 if (decryptedKey != NULL) {
wolfSSL 16:8e0d178b1d1e 11507 ForceZero(decryptedKey, MAX_ENCRYPTED_KEY_SZ);
wolfSSL 16:8e0d178b1d1e 11508 }
wolfSSL 15:117db924cf7c 11509 XFREE(decryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 11510 }
wolfSSL 16:8e0d178b1d1e 11511 #endif
wolfSSL 16:8e0d178b1d1e 11512 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 11513 if (ret != 0 && ret != WC_PKCS7_WANT_READ_E) {
wolfSSL 16:8e0d178b1d1e 11514 wc_PKCS7_ResetStream(pkcs7);
wolfSSL 16:8e0d178b1d1e 11515 }
wolfSSL 16:8e0d178b1d1e 11516 #endif
wolfSSL 16:8e0d178b1d1e 11517
wolfSSL 16:8e0d178b1d1e 11518 return ret;
wolfSSL 16:8e0d178b1d1e 11519
wolfSSL 16:8e0d178b1d1e 11520 #else
wolfSSL 16:8e0d178b1d1e 11521 WOLFSSL_MSG("AuthEnvelopedData requires AES-GCM or AES-CCM to be enabled");
wolfSSL 16:8e0d178b1d1e 11522 (void)pkcs7;
wolfSSL 16:8e0d178b1d1e 11523 (void)in;
wolfSSL 16:8e0d178b1d1e 11524 (void)inSz;
wolfSSL 16:8e0d178b1d1e 11525 (void)output;
wolfSSL 16:8e0d178b1d1e 11526 (void)outputSz;
wolfSSL 16:8e0d178b1d1e 11527
wolfSSL 16:8e0d178b1d1e 11528 return NOT_COMPILED_IN;
wolfSSL 16:8e0d178b1d1e 11529 #endif /* HAVE_AESGCM | HAVE_AESCCM */
wolfSSL 15:117db924cf7c 11530 }
wolfSSL 15:117db924cf7c 11531
wolfSSL 15:117db924cf7c 11532
wolfSSL 15:117db924cf7c 11533 #ifndef NO_PKCS7_ENCRYPTED_DATA
wolfSSL 15:117db924cf7c 11534
wolfSSL 15:117db924cf7c 11535 /* build PKCS#7 encryptedData content type, return encrypted size */
wolfSSL 15:117db924cf7c 11536 int wc_PKCS7_EncodeEncryptedData(PKCS7* pkcs7, byte* output, word32 outputSz)
wolfSSL 15:117db924cf7c 11537 {
wolfSSL 15:117db924cf7c 11538 int ret, idx = 0;
wolfSSL 15:117db924cf7c 11539 int totalSz, padSz, encryptedOutSz;
wolfSSL 15:117db924cf7c 11540
wolfSSL 15:117db924cf7c 11541 int contentInfoSeqSz, outerContentTypeSz, outerContentSz;
wolfSSL 15:117db924cf7c 11542 byte contentInfoSeq[MAX_SEQ_SZ];
wolfSSL 15:117db924cf7c 11543 byte outerContentType[MAX_ALGO_SZ];
wolfSSL 15:117db924cf7c 11544 byte outerContent[MAX_SEQ_SZ];
wolfSSL 15:117db924cf7c 11545
wolfSSL 15:117db924cf7c 11546 int encDataSeqSz, verSz, blockSz;
wolfSSL 15:117db924cf7c 11547 byte encDataSeq[MAX_SEQ_SZ];
wolfSSL 15:117db924cf7c 11548 byte ver[MAX_VERSION_SZ];
wolfSSL 15:117db924cf7c 11549
wolfSSL 15:117db924cf7c 11550 byte* plain = NULL;
wolfSSL 15:117db924cf7c 11551 byte* encryptedContent = NULL;
wolfSSL 15:117db924cf7c 11552
wolfSSL 15:117db924cf7c 11553 int encContentOctetSz, encContentSeqSz, contentTypeSz;
wolfSSL 15:117db924cf7c 11554 int contentEncAlgoSz, ivOctetStringSz;
wolfSSL 15:117db924cf7c 11555 byte encContentSeq[MAX_SEQ_SZ];
wolfSSL 16:8e0d178b1d1e 11556 byte contentType[MAX_OID_SZ];
wolfSSL 15:117db924cf7c 11557 byte contentEncAlgo[MAX_ALGO_SZ];
wolfSSL 15:117db924cf7c 11558 byte tmpIv[MAX_CONTENT_IV_SIZE];
wolfSSL 15:117db924cf7c 11559 byte ivOctetString[MAX_OCTET_STR_SZ];
wolfSSL 15:117db924cf7c 11560 byte encContentOctet[MAX_OCTET_STR_SZ];
wolfSSL 15:117db924cf7c 11561
wolfSSL 15:117db924cf7c 11562 byte attribSet[MAX_SET_SZ];
wolfSSL 15:117db924cf7c 11563 EncodedAttrib* attribs = NULL;
wolfSSL 15:117db924cf7c 11564 word32 attribsSz;
wolfSSL 15:117db924cf7c 11565 word32 attribsCount;
wolfSSL 15:117db924cf7c 11566 word32 attribsSetSz;
wolfSSL 15:117db924cf7c 11567
wolfSSL 15:117db924cf7c 11568 byte* flatAttribs = NULL;
wolfSSL 15:117db924cf7c 11569
wolfSSL 15:117db924cf7c 11570 if (pkcs7 == NULL || pkcs7->content == NULL || pkcs7->contentSz == 0 ||
wolfSSL 15:117db924cf7c 11571 pkcs7->encryptOID == 0 || pkcs7->encryptionKey == NULL ||
wolfSSL 15:117db924cf7c 11572 pkcs7->encryptionKeySz == 0)
wolfSSL 15:117db924cf7c 11573 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 11574
wolfSSL 15:117db924cf7c 11575 if (output == NULL || outputSz == 0)
wolfSSL 15:117db924cf7c 11576 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 11577
wolfSSL 16:8e0d178b1d1e 11578 if (pkcs7->version == 3) {
wolfSSL 15:117db924cf7c 11579 verSz = SetMyVersion(0, ver, 0);
wolfSSL 16:8e0d178b1d1e 11580 outerContentTypeSz = 0;
wolfSSL 16:8e0d178b1d1e 11581 }
wolfSSL 16:8e0d178b1d1e 11582 else {
wolfSSL 16:8e0d178b1d1e 11583 /* outer content type */
wolfSSL 16:8e0d178b1d1e 11584 ret = wc_SetContentType(ENCRYPTED_DATA, outerContentType,
wolfSSL 16:8e0d178b1d1e 11585 sizeof(outerContentType));
wolfSSL 16:8e0d178b1d1e 11586 if (ret < 0)
wolfSSL 16:8e0d178b1d1e 11587 return ret;
wolfSSL 16:8e0d178b1d1e 11588
wolfSSL 16:8e0d178b1d1e 11589 outerContentTypeSz = ret;
wolfSSL 16:8e0d178b1d1e 11590
wolfSSL 16:8e0d178b1d1e 11591 /* version, 2 if unprotectedAttrs present, 0 if absent */
wolfSSL 16:8e0d178b1d1e 11592 if (pkcs7->unprotectedAttribsSz > 0) {
wolfSSL 16:8e0d178b1d1e 11593 verSz = SetMyVersion(2, ver, 0);
wolfSSL 16:8e0d178b1d1e 11594 } else {
wolfSSL 16:8e0d178b1d1e 11595 verSz = SetMyVersion(0, ver, 0);
wolfSSL 16:8e0d178b1d1e 11596 }
wolfSSL 15:117db924cf7c 11597 }
wolfSSL 15:117db924cf7c 11598
wolfSSL 15:117db924cf7c 11599 /* EncryptedContentInfo */
wolfSSL 16:8e0d178b1d1e 11600 ret = wc_SetContentType(pkcs7->contentOID, contentType,
wolfSSL 16:8e0d178b1d1e 11601 sizeof(contentType));
wolfSSL 16:8e0d178b1d1e 11602 if (ret < 0)
wolfSSL 16:8e0d178b1d1e 11603 return ret;
wolfSSL 16:8e0d178b1d1e 11604
wolfSSL 16:8e0d178b1d1e 11605 contentTypeSz = ret;
wolfSSL 15:117db924cf7c 11606
wolfSSL 15:117db924cf7c 11607 /* allocate encrypted content buffer, do PKCS#7 padding */
wolfSSL 15:117db924cf7c 11608 blockSz = wc_PKCS7_GetOIDBlockSize(pkcs7->encryptOID);
wolfSSL 15:117db924cf7c 11609 if (blockSz < 0)
wolfSSL 15:117db924cf7c 11610 return blockSz;
wolfSSL 15:117db924cf7c 11611
wolfSSL 15:117db924cf7c 11612 padSz = wc_PKCS7_GetPadSize(pkcs7->contentSz, blockSz);
wolfSSL 15:117db924cf7c 11613 if (padSz < 0)
wolfSSL 15:117db924cf7c 11614 return padSz;
wolfSSL 15:117db924cf7c 11615
wolfSSL 15:117db924cf7c 11616 encryptedOutSz = pkcs7->contentSz + padSz;
wolfSSL 15:117db924cf7c 11617
wolfSSL 15:117db924cf7c 11618 plain = (byte*)XMALLOC(encryptedOutSz, pkcs7->heap,
wolfSSL 15:117db924cf7c 11619 DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 11620 if (plain == NULL)
wolfSSL 15:117db924cf7c 11621 return MEMORY_E;
wolfSSL 15:117db924cf7c 11622
wolfSSL 15:117db924cf7c 11623 ret = wc_PKCS7_PadData(pkcs7->content, pkcs7->contentSz, plain,
wolfSSL 15:117db924cf7c 11624 encryptedOutSz, blockSz);
wolfSSL 15:117db924cf7c 11625 if (ret < 0) {
wolfSSL 15:117db924cf7c 11626 XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 11627 return ret;
wolfSSL 15:117db924cf7c 11628 }
wolfSSL 15:117db924cf7c 11629
wolfSSL 15:117db924cf7c 11630 encryptedContent = (byte*)XMALLOC(encryptedOutSz, pkcs7->heap,
wolfSSL 15:117db924cf7c 11631 DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 11632 if (encryptedContent == NULL) {
wolfSSL 15:117db924cf7c 11633 XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 11634 return MEMORY_E;
wolfSSL 15:117db924cf7c 11635 }
wolfSSL 15:117db924cf7c 11636
wolfSSL 15:117db924cf7c 11637 /* put together IV OCTET STRING */
wolfSSL 15:117db924cf7c 11638 ivOctetStringSz = SetOctetString(blockSz, ivOctetString);
wolfSSL 15:117db924cf7c 11639
wolfSSL 15:117db924cf7c 11640 /* build up ContentEncryptionAlgorithmIdentifier sequence,
wolfSSL 15:117db924cf7c 11641 adding (ivOctetStringSz + blockSz) for IV OCTET STRING */
wolfSSL 15:117db924cf7c 11642 contentEncAlgoSz = SetAlgoID(pkcs7->encryptOID, contentEncAlgo,
wolfSSL 15:117db924cf7c 11643 oidBlkType, ivOctetStringSz + blockSz);
wolfSSL 15:117db924cf7c 11644 if (contentEncAlgoSz == 0) {
wolfSSL 15:117db924cf7c 11645 XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 11646 XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 11647 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 11648 }
wolfSSL 15:117db924cf7c 11649
wolfSSL 15:117db924cf7c 11650 /* encrypt content */
wolfSSL 16:8e0d178b1d1e 11651 WOLFSSL_MSG("Encrypting the content");
wolfSSL 16:8e0d178b1d1e 11652 ret = wc_PKCS7_GenerateBlock(pkcs7, NULL, tmpIv, blockSz);
wolfSSL 15:117db924cf7c 11653 if (ret != 0) {
wolfSSL 15:117db924cf7c 11654 XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 11655 XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 11656 return ret;
wolfSSL 15:117db924cf7c 11657 }
wolfSSL 15:117db924cf7c 11658
wolfSSL 15:117db924cf7c 11659 ret = wc_PKCS7_EncryptContent(pkcs7->encryptOID, pkcs7->encryptionKey,
wolfSSL 16:8e0d178b1d1e 11660 pkcs7->encryptionKeySz, tmpIv, blockSz, NULL, 0, NULL, 0,
wolfSSL 16:8e0d178b1d1e 11661 plain, encryptedOutSz, encryptedContent);
wolfSSL 15:117db924cf7c 11662 if (ret != 0) {
wolfSSL 15:117db924cf7c 11663 XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 11664 XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 11665 return ret;
wolfSSL 15:117db924cf7c 11666 }
wolfSSL 15:117db924cf7c 11667
wolfSSL 15:117db924cf7c 11668 encContentOctetSz = SetImplicit(ASN_OCTET_STRING, 0,
wolfSSL 15:117db924cf7c 11669 encryptedOutSz, encContentOctet);
wolfSSL 15:117db924cf7c 11670
wolfSSL 15:117db924cf7c 11671 encContentSeqSz = SetSequence(contentTypeSz + contentEncAlgoSz +
wolfSSL 15:117db924cf7c 11672 ivOctetStringSz + blockSz +
wolfSSL 15:117db924cf7c 11673 encContentOctetSz + encryptedOutSz,
wolfSSL 15:117db924cf7c 11674 encContentSeq);
wolfSSL 15:117db924cf7c 11675
wolfSSL 15:117db924cf7c 11676 /* optional UnprotectedAttributes */
wolfSSL 15:117db924cf7c 11677 if (pkcs7->unprotectedAttribsSz != 0) {
wolfSSL 15:117db924cf7c 11678
wolfSSL 15:117db924cf7c 11679 if (pkcs7->unprotectedAttribs == NULL) {
wolfSSL 15:117db924cf7c 11680 XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 11681 XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 11682 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 11683 }
wolfSSL 15:117db924cf7c 11684
wolfSSL 15:117db924cf7c 11685 attribs = (EncodedAttrib*)XMALLOC(
wolfSSL 15:117db924cf7c 11686 sizeof(EncodedAttrib) * pkcs7->unprotectedAttribsSz,
wolfSSL 15:117db924cf7c 11687 pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 11688 if (attribs == NULL) {
wolfSSL 15:117db924cf7c 11689 XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 11690 XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 11691 return MEMORY_E;
wolfSSL 15:117db924cf7c 11692 }
wolfSSL 15:117db924cf7c 11693
wolfSSL 15:117db924cf7c 11694 attribsCount = pkcs7->unprotectedAttribsSz;
wolfSSL 15:117db924cf7c 11695 attribsSz = EncodeAttributes(attribs, pkcs7->unprotectedAttribsSz,
wolfSSL 15:117db924cf7c 11696 pkcs7->unprotectedAttribs,
wolfSSL 15:117db924cf7c 11697 pkcs7->unprotectedAttribsSz);
wolfSSL 15:117db924cf7c 11698
wolfSSL 15:117db924cf7c 11699 flatAttribs = (byte*)XMALLOC(attribsSz, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 11700 if (flatAttribs == NULL) {
wolfSSL 15:117db924cf7c 11701 XFREE(attribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 11702 XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 11703 XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 11704 return MEMORY_E;
wolfSSL 15:117db924cf7c 11705 }
wolfSSL 15:117db924cf7c 11706
wolfSSL 16:8e0d178b1d1e 11707 FlattenAttributes(pkcs7, flatAttribs, attribs, attribsCount);
wolfSSL 15:117db924cf7c 11708 attribsSetSz = SetImplicit(ASN_SET, 1, attribsSz, attribSet);
wolfSSL 15:117db924cf7c 11709
wolfSSL 15:117db924cf7c 11710 } else {
wolfSSL 15:117db924cf7c 11711 attribsSz = 0;
wolfSSL 15:117db924cf7c 11712 attribsSetSz = 0;
wolfSSL 15:117db924cf7c 11713 }
wolfSSL 15:117db924cf7c 11714
wolfSSL 15:117db924cf7c 11715 /* keep track of sizes for outer wrapper layering */
wolfSSL 15:117db924cf7c 11716 totalSz = verSz + encContentSeqSz + contentTypeSz + contentEncAlgoSz +
wolfSSL 15:117db924cf7c 11717 ivOctetStringSz + blockSz + encContentOctetSz + encryptedOutSz +
wolfSSL 16:8e0d178b1d1e 11718 attribsSz + attribsSetSz;
wolfSSL 15:117db924cf7c 11719
wolfSSL 15:117db924cf7c 11720 /* EncryptedData */
wolfSSL 15:117db924cf7c 11721 encDataSeqSz = SetSequence(totalSz, encDataSeq);
wolfSSL 15:117db924cf7c 11722 totalSz += encDataSeqSz;
wolfSSL 15:117db924cf7c 11723
wolfSSL 16:8e0d178b1d1e 11724 if (pkcs7->version != 3) {
wolfSSL 16:8e0d178b1d1e 11725 /* outer content */
wolfSSL 16:8e0d178b1d1e 11726 outerContentSz = SetExplicit(0, totalSz, outerContent);
wolfSSL 16:8e0d178b1d1e 11727 totalSz += outerContentTypeSz;
wolfSSL 16:8e0d178b1d1e 11728 totalSz += outerContentSz;
wolfSSL 16:8e0d178b1d1e 11729 /* ContentInfo */
wolfSSL 16:8e0d178b1d1e 11730 contentInfoSeqSz = SetSequence(totalSz, contentInfoSeq);
wolfSSL 16:8e0d178b1d1e 11731 totalSz += contentInfoSeqSz;
wolfSSL 16:8e0d178b1d1e 11732 } else {
wolfSSL 16:8e0d178b1d1e 11733 contentInfoSeqSz = 0;
wolfSSL 16:8e0d178b1d1e 11734 outerContentSz = 0;
wolfSSL 16:8e0d178b1d1e 11735 }
wolfSSL 15:117db924cf7c 11736
wolfSSL 15:117db924cf7c 11737 if (totalSz > (int)outputSz) {
wolfSSL 15:117db924cf7c 11738 WOLFSSL_MSG("PKCS#7 output buffer too small");
wolfSSL 15:117db924cf7c 11739 if (pkcs7->unprotectedAttribsSz != 0) {
wolfSSL 15:117db924cf7c 11740 XFREE(attribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 11741 XFREE(flatAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 11742 }
wolfSSL 15:117db924cf7c 11743 XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 11744 XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 11745 return BUFFER_E;
wolfSSL 15:117db924cf7c 11746 }
wolfSSL 15:117db924cf7c 11747
wolfSSL 15:117db924cf7c 11748 XMEMCPY(output + idx, contentInfoSeq, contentInfoSeqSz);
wolfSSL 15:117db924cf7c 11749 idx += contentInfoSeqSz;
wolfSSL 15:117db924cf7c 11750 XMEMCPY(output + idx, outerContentType, outerContentTypeSz);
wolfSSL 15:117db924cf7c 11751 idx += outerContentTypeSz;
wolfSSL 15:117db924cf7c 11752 XMEMCPY(output + idx, outerContent, outerContentSz);
wolfSSL 15:117db924cf7c 11753 idx += outerContentSz;
wolfSSL 15:117db924cf7c 11754 XMEMCPY(output + idx, encDataSeq, encDataSeqSz);
wolfSSL 15:117db924cf7c 11755 idx += encDataSeqSz;
wolfSSL 15:117db924cf7c 11756 XMEMCPY(output + idx, ver, verSz);
wolfSSL 15:117db924cf7c 11757 idx += verSz;
wolfSSL 15:117db924cf7c 11758 XMEMCPY(output + idx, encContentSeq, encContentSeqSz);
wolfSSL 15:117db924cf7c 11759 idx += encContentSeqSz;
wolfSSL 15:117db924cf7c 11760 XMEMCPY(output + idx, contentType, contentTypeSz);
wolfSSL 15:117db924cf7c 11761 idx += contentTypeSz;
wolfSSL 15:117db924cf7c 11762 XMEMCPY(output + idx, contentEncAlgo, contentEncAlgoSz);
wolfSSL 15:117db924cf7c 11763 idx += contentEncAlgoSz;
wolfSSL 15:117db924cf7c 11764 XMEMCPY(output + idx, ivOctetString, ivOctetStringSz);
wolfSSL 15:117db924cf7c 11765 idx += ivOctetStringSz;
wolfSSL 15:117db924cf7c 11766 XMEMCPY(output + idx, tmpIv, blockSz);
wolfSSL 15:117db924cf7c 11767 idx += blockSz;
wolfSSL 15:117db924cf7c 11768 XMEMCPY(output + idx, encContentOctet, encContentOctetSz);
wolfSSL 15:117db924cf7c 11769 idx += encContentOctetSz;
wolfSSL 15:117db924cf7c 11770 XMEMCPY(output + idx, encryptedContent, encryptedOutSz);
wolfSSL 15:117db924cf7c 11771 idx += encryptedOutSz;
wolfSSL 15:117db924cf7c 11772
wolfSSL 15:117db924cf7c 11773 if (pkcs7->unprotectedAttribsSz != 0) {
wolfSSL 15:117db924cf7c 11774 XMEMCPY(output + idx, attribSet, attribsSetSz);
wolfSSL 15:117db924cf7c 11775 idx += attribsSetSz;
wolfSSL 15:117db924cf7c 11776 XMEMCPY(output + idx, flatAttribs, attribsSz);
wolfSSL 15:117db924cf7c 11777 idx += attribsSz;
wolfSSL 15:117db924cf7c 11778 XFREE(attribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 11779 XFREE(flatAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 11780 }
wolfSSL 15:117db924cf7c 11781
wolfSSL 15:117db924cf7c 11782 XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 11783 XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 11784
wolfSSL 15:117db924cf7c 11785 return idx;
wolfSSL 15:117db924cf7c 11786 }
wolfSSL 15:117db924cf7c 11787
wolfSSL 15:117db924cf7c 11788
wolfSSL 15:117db924cf7c 11789 /* decode and store unprotected attributes in PKCS7->decodedAttrib. Return
wolfSSL 15:117db924cf7c 11790 * 0 on success, negative on error. User must call wc_PKCS7_Free(). */
wolfSSL 15:117db924cf7c 11791 static int wc_PKCS7_DecodeUnprotectedAttributes(PKCS7* pkcs7, byte* pkiMsg,
wolfSSL 15:117db924cf7c 11792 word32 pkiMsgSz, word32* inOutIdx)
wolfSSL 15:117db924cf7c 11793 {
wolfSSL 15:117db924cf7c 11794 int ret, attribLen;
wolfSSL 15:117db924cf7c 11795 word32 idx;
wolfSSL 16:8e0d178b1d1e 11796 byte tag;
wolfSSL 15:117db924cf7c 11797
wolfSSL 15:117db924cf7c 11798 if (pkcs7 == NULL || pkiMsg == NULL ||
wolfSSL 15:117db924cf7c 11799 pkiMsgSz == 0 || inOutIdx == NULL)
wolfSSL 15:117db924cf7c 11800 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 11801
wolfSSL 15:117db924cf7c 11802 idx = *inOutIdx;
wolfSSL 15:117db924cf7c 11803
wolfSSL 16:8e0d178b1d1e 11804 if (GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 11805 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 11806
wolfSSL 16:8e0d178b1d1e 11807 if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1))
wolfSSL 16:8e0d178b1d1e 11808 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 11809
wolfSSL 15:117db924cf7c 11810 if (GetLength(pkiMsg, &idx, &attribLen, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 11811 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 11812
wolfSSL 15:117db924cf7c 11813 /* loop through attributes */
wolfSSL 15:117db924cf7c 11814 if ((ret = wc_PKCS7_ParseAttribs(pkcs7, pkiMsg + idx, attribLen)) < 0) {
wolfSSL 15:117db924cf7c 11815 return ret;
wolfSSL 15:117db924cf7c 11816 }
wolfSSL 15:117db924cf7c 11817
wolfSSL 15:117db924cf7c 11818 *inOutIdx = idx;
wolfSSL 15:117db924cf7c 11819
wolfSSL 15:117db924cf7c 11820 return 0;
wolfSSL 15:117db924cf7c 11821 }
wolfSSL 15:117db924cf7c 11822
wolfSSL 15:117db924cf7c 11823
wolfSSL 15:117db924cf7c 11824 /* unwrap and decrypt PKCS#7/CMS encrypted-data object, returned decoded size */
wolfSSL 16:8e0d178b1d1e 11825 int wc_PKCS7_DecodeEncryptedData(PKCS7* pkcs7, byte* in, word32 inSz,
wolfSSL 15:117db924cf7c 11826 byte* output, word32 outputSz)
wolfSSL 15:117db924cf7c 11827 {
wolfSSL 16:8e0d178b1d1e 11828 int ret = 0, version, length = 0, haveAttribs = 0;
wolfSSL 15:117db924cf7c 11829 word32 idx = 0;
wolfSSL 16:8e0d178b1d1e 11830
wolfSSL 16:8e0d178b1d1e 11831 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 11832 word32 tmpIdx = 0;
wolfSSL 16:8e0d178b1d1e 11833 long rc;
wolfSSL 16:8e0d178b1d1e 11834 #endif
wolfSSL 15:117db924cf7c 11835 word32 contentType, encOID;
wolfSSL 15:117db924cf7c 11836
wolfSSL 16:8e0d178b1d1e 11837 int expBlockSz = 0;
wolfSSL 16:8e0d178b1d1e 11838 byte tmpIvBuf[MAX_CONTENT_IV_SIZE];
wolfSSL 16:8e0d178b1d1e 11839 byte *tmpIv = tmpIvBuf;
wolfSSL 16:8e0d178b1d1e 11840
wolfSSL 16:8e0d178b1d1e 11841 int encryptedContentSz = 0;
wolfSSL 15:117db924cf7c 11842 byte padLen;
wolfSSL 15:117db924cf7c 11843 byte* encryptedContent = NULL;
wolfSSL 15:117db924cf7c 11844
wolfSSL 16:8e0d178b1d1e 11845 byte* pkiMsg = in;
wolfSSL 16:8e0d178b1d1e 11846 word32 pkiMsgSz = inSz;
wolfSSL 16:8e0d178b1d1e 11847 byte tag;
wolfSSL 16:8e0d178b1d1e 11848
wolfSSL 16:8e0d178b1d1e 11849 if (pkcs7 == NULL ||
wolfSSL 16:8e0d178b1d1e 11850 ((pkcs7->encryptionKey == NULL || pkcs7->encryptionKeySz == 0) &&
wolfSSL 16:8e0d178b1d1e 11851 pkcs7->decryptionCb == NULL))
wolfSSL 15:117db924cf7c 11852 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 11853
wolfSSL 15:117db924cf7c 11854 if (pkiMsg == NULL || pkiMsgSz == 0 ||
wolfSSL 15:117db924cf7c 11855 output == NULL || outputSz == 0)
wolfSSL 15:117db924cf7c 11856 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 11857
wolfSSL 16:8e0d178b1d1e 11858 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 11859 (void)tmpIv; /* help out static analysis */
wolfSSL 16:8e0d178b1d1e 11860 if (pkcs7->stream == NULL) {
wolfSSL 16:8e0d178b1d1e 11861 if ((ret = wc_PKCS7_CreateStream(pkcs7)) != 0) {
wolfSSL 16:8e0d178b1d1e 11862 return ret;
wolfSSL 16:8e0d178b1d1e 11863 }
wolfSSL 16:8e0d178b1d1e 11864 }
wolfSSL 16:8e0d178b1d1e 11865 #endif
wolfSSL 16:8e0d178b1d1e 11866
wolfSSL 16:8e0d178b1d1e 11867 switch (pkcs7->state) {
wolfSSL 16:8e0d178b1d1e 11868 case WC_PKCS7_START:
wolfSSL 16:8e0d178b1d1e 11869 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 11870 if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_SEQ_SZ +
wolfSSL 16:8e0d178b1d1e 11871 MAX_ALGO_SZ, &pkiMsg, &idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 11872 return ret;
wolfSSL 16:8e0d178b1d1e 11873 }
wolfSSL 16:8e0d178b1d1e 11874
wolfSSL 16:8e0d178b1d1e 11875 rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_SEQ_PEEK, in, inSz);
wolfSSL 16:8e0d178b1d1e 11876 if (rc < 0) {
wolfSSL 16:8e0d178b1d1e 11877 ret = (int)rc;
wolfSSL 16:8e0d178b1d1e 11878 break;
wolfSSL 16:8e0d178b1d1e 11879 }
wolfSSL 16:8e0d178b1d1e 11880 pkiMsgSz = (word32)rc;
wolfSSL 16:8e0d178b1d1e 11881 #endif
wolfSSL 16:8e0d178b1d1e 11882
wolfSSL 16:8e0d178b1d1e 11883 if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
wolfSSL 16:8e0d178b1d1e 11884 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 11885
wolfSSL 16:8e0d178b1d1e 11886 if (pkcs7->version != 3) { /* ContentInfo not in firmware bundles */
wolfSSL 16:8e0d178b1d1e 11887 /* read past ContentInfo, verify type is encrypted-data */
wolfSSL 16:8e0d178b1d1e 11888 if (ret == 0 && wc_GetContentType(pkiMsg, &idx, &contentType,
wolfSSL 16:8e0d178b1d1e 11889 pkiMsgSz) < 0)
wolfSSL 16:8e0d178b1d1e 11890 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 11891
wolfSSL 16:8e0d178b1d1e 11892 if (ret == 0 && contentType != ENCRYPTED_DATA) {
wolfSSL 16:8e0d178b1d1e 11893 WOLFSSL_MSG("PKCS#7 input not of type EncryptedData");
wolfSSL 16:8e0d178b1d1e 11894 ret = PKCS7_OID_E;
wolfSSL 16:8e0d178b1d1e 11895 }
wolfSSL 16:8e0d178b1d1e 11896 }
wolfSSL 16:8e0d178b1d1e 11897 if (ret != 0) break;
wolfSSL 16:8e0d178b1d1e 11898 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 11899 if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 11900 break;
wolfSSL 16:8e0d178b1d1e 11901 }
wolfSSL 16:8e0d178b1d1e 11902 #endif
wolfSSL 16:8e0d178b1d1e 11903 wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_STAGE2);
wolfSSL 16:8e0d178b1d1e 11904 FALL_THROUGH;
wolfSSL 16:8e0d178b1d1e 11905 /* end of stage 1 */
wolfSSL 16:8e0d178b1d1e 11906
wolfSSL 16:8e0d178b1d1e 11907 case WC_PKCS7_STAGE2:
wolfSSL 16:8e0d178b1d1e 11908 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 11909 if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
wolfSSL 16:8e0d178b1d1e 11910 MAX_LENGTH_SZ + MAX_SEQ_SZ + ASN_TAG_SZ, &pkiMsg,
wolfSSL 16:8e0d178b1d1e 11911 &idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 11912 return ret;
wolfSSL 16:8e0d178b1d1e 11913 }
wolfSSL 16:8e0d178b1d1e 11914
wolfSSL 16:8e0d178b1d1e 11915 rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK, in,
wolfSSL 16:8e0d178b1d1e 11916 inSz);
wolfSSL 16:8e0d178b1d1e 11917 if (rc < 0) {
wolfSSL 16:8e0d178b1d1e 11918 ret = (int)rc;
wolfSSL 16:8e0d178b1d1e 11919 break;
wolfSSL 16:8e0d178b1d1e 11920 }
wolfSSL 16:8e0d178b1d1e 11921 pkiMsgSz = (word32)rc;
wolfSSL 16:8e0d178b1d1e 11922 #endif
wolfSSL 16:8e0d178b1d1e 11923 if (pkcs7->version != 3) {
wolfSSL 16:8e0d178b1d1e 11924 if (ret == 0 && GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0)
wolfSSL 16:8e0d178b1d1e 11925 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 11926 if (ret == 0 && tag !=
wolfSSL 16:8e0d178b1d1e 11927 (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
wolfSSL 16:8e0d178b1d1e 11928 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 11929
wolfSSL 16:8e0d178b1d1e 11930 if (ret == 0 && GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
wolfSSL 16:8e0d178b1d1e 11931 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 11932
wolfSSL 16:8e0d178b1d1e 11933 /* remove EncryptedData and version */
wolfSSL 16:8e0d178b1d1e 11934 if (ret == 0 && GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
wolfSSL 16:8e0d178b1d1e 11935 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 11936 }
wolfSSL 16:8e0d178b1d1e 11937
wolfSSL 16:8e0d178b1d1e 11938 if (ret != 0) break;
wolfSSL 16:8e0d178b1d1e 11939 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 11940 if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 11941 break;
wolfSSL 16:8e0d178b1d1e 11942 }
wolfSSL 16:8e0d178b1d1e 11943 #endif
wolfSSL 16:8e0d178b1d1e 11944 wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_STAGE3);
wolfSSL 16:8e0d178b1d1e 11945 FALL_THROUGH;
wolfSSL 16:8e0d178b1d1e 11946 /* end of stage 2 */
wolfSSL 16:8e0d178b1d1e 11947
wolfSSL 16:8e0d178b1d1e 11948 case WC_PKCS7_STAGE3:
wolfSSL 16:8e0d178b1d1e 11949 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 11950 if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
wolfSSL 16:8e0d178b1d1e 11951 MAX_VERSION_SZ + MAX_SEQ_SZ + MAX_ALGO_SZ * 2,
wolfSSL 16:8e0d178b1d1e 11952 &pkiMsg, &idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 11953 return ret;
wolfSSL 16:8e0d178b1d1e 11954 }
wolfSSL 16:8e0d178b1d1e 11955
wolfSSL 16:8e0d178b1d1e 11956 rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK, in,
wolfSSL 16:8e0d178b1d1e 11957 inSz);
wolfSSL 16:8e0d178b1d1e 11958 if (rc < 0) {
wolfSSL 16:8e0d178b1d1e 11959 ret = (int)rc;
wolfSSL 16:8e0d178b1d1e 11960 break;
wolfSSL 16:8e0d178b1d1e 11961 }
wolfSSL 16:8e0d178b1d1e 11962 pkiMsgSz = (word32)rc;
wolfSSL 16:8e0d178b1d1e 11963 #endif
wolfSSL 16:8e0d178b1d1e 11964 /* get version, check later */
wolfSSL 16:8e0d178b1d1e 11965 haveAttribs = 0;
wolfSSL 16:8e0d178b1d1e 11966 if (ret == 0 && GetMyVersion(pkiMsg, &idx, &version, pkiMsgSz) < 0)
wolfSSL 16:8e0d178b1d1e 11967 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 11968
wolfSSL 16:8e0d178b1d1e 11969 /* remove EncryptedContentInfo */
wolfSSL 16:8e0d178b1d1e 11970 if (ret == 0 && GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
wolfSSL 16:8e0d178b1d1e 11971 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 11972
wolfSSL 16:8e0d178b1d1e 11973 if (ret == 0 && wc_GetContentType(pkiMsg, &idx, &contentType,
wolfSSL 16:8e0d178b1d1e 11974 pkiMsgSz) < 0)
wolfSSL 16:8e0d178b1d1e 11975 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 11976
wolfSSL 16:8e0d178b1d1e 11977 if (ret == 0 && (ret = GetAlgoId(pkiMsg, &idx, &encOID, oidBlkType,
wolfSSL 16:8e0d178b1d1e 11978 pkiMsgSz)) < 0)
wolfSSL 16:8e0d178b1d1e 11979 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 11980 if (ret == 0 && (expBlockSz = wc_PKCS7_GetOIDBlockSize(encOID)) < 0)
wolfSSL 16:8e0d178b1d1e 11981 ret = expBlockSz;
wolfSSL 16:8e0d178b1d1e 11982
wolfSSL 16:8e0d178b1d1e 11983 if (ret != 0) break;
wolfSSL 16:8e0d178b1d1e 11984 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 11985 /* store expBlockSz for later */
wolfSSL 16:8e0d178b1d1e 11986 pkcs7->stream->varOne = expBlockSz;
wolfSSL 16:8e0d178b1d1e 11987 pkcs7->stream->varTwo = encOID;
wolfSSL 16:8e0d178b1d1e 11988
wolfSSL 16:8e0d178b1d1e 11989 if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 11990 break;
wolfSSL 16:8e0d178b1d1e 11991 }
wolfSSL 16:8e0d178b1d1e 11992
wolfSSL 16:8e0d178b1d1e 11993 /* store version for later */
wolfSSL 16:8e0d178b1d1e 11994 pkcs7->stream->vers = version;
wolfSSL 16:8e0d178b1d1e 11995 #endif
wolfSSL 16:8e0d178b1d1e 11996 wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_STAGE4);
wolfSSL 16:8e0d178b1d1e 11997 FALL_THROUGH;
wolfSSL 16:8e0d178b1d1e 11998 /* end of stage 3 */
wolfSSL 16:8e0d178b1d1e 11999
wolfSSL 16:8e0d178b1d1e 12000 /* get block cipher IV, stored in OPTIONAL parameter of AlgoID */
wolfSSL 16:8e0d178b1d1e 12001 case WC_PKCS7_STAGE4:
wolfSSL 16:8e0d178b1d1e 12002 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 12003 if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
wolfSSL 16:8e0d178b1d1e 12004 ASN_TAG_SZ + MAX_LENGTH_SZ, &pkiMsg, &idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 12005 return ret;
wolfSSL 16:8e0d178b1d1e 12006 }
wolfSSL 16:8e0d178b1d1e 12007
wolfSSL 16:8e0d178b1d1e 12008 rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK, in,
wolfSSL 16:8e0d178b1d1e 12009 inSz);
wolfSSL 16:8e0d178b1d1e 12010 if (rc < 0) {
wolfSSL 16:8e0d178b1d1e 12011 ret = (int)rc;
wolfSSL 16:8e0d178b1d1e 12012 break;
wolfSSL 16:8e0d178b1d1e 12013 }
wolfSSL 16:8e0d178b1d1e 12014 pkiMsgSz = (word32)rc;
wolfSSL 16:8e0d178b1d1e 12015
wolfSSL 16:8e0d178b1d1e 12016 /* restore saved variables */
wolfSSL 16:8e0d178b1d1e 12017 expBlockSz = pkcs7->stream->varOne;
wolfSSL 16:8e0d178b1d1e 12018 #endif
wolfSSL 16:8e0d178b1d1e 12019 if (ret == 0 && GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0)
wolfSSL 16:8e0d178b1d1e 12020 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 12021 if (ret == 0 && tag != ASN_OCTET_STRING)
wolfSSL 16:8e0d178b1d1e 12022 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 12023
wolfSSL 16:8e0d178b1d1e 12024 if (ret == 0 && GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
wolfSSL 16:8e0d178b1d1e 12025 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 12026
wolfSSL 16:8e0d178b1d1e 12027 if (ret == 0 && length != expBlockSz) {
wolfSSL 16:8e0d178b1d1e 12028 WOLFSSL_MSG("Incorrect IV length, must be of content alg block size");
wolfSSL 16:8e0d178b1d1e 12029 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 12030 }
wolfSSL 16:8e0d178b1d1e 12031
wolfSSL 16:8e0d178b1d1e 12032 if (ret != 0) break;
wolfSSL 16:8e0d178b1d1e 12033 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 12034 /* next chunk of data expected should have the IV */
wolfSSL 16:8e0d178b1d1e 12035 pkcs7->stream->expected = length;
wolfSSL 16:8e0d178b1d1e 12036
wolfSSL 16:8e0d178b1d1e 12037 if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 12038 break;
wolfSSL 16:8e0d178b1d1e 12039 }
wolfSSL 16:8e0d178b1d1e 12040 #endif
wolfSSL 16:8e0d178b1d1e 12041 wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_STAGE5);
wolfSSL 16:8e0d178b1d1e 12042 FALL_THROUGH;
wolfSSL 16:8e0d178b1d1e 12043 /* end of stage 4 */
wolfSSL 16:8e0d178b1d1e 12044
wolfSSL 16:8e0d178b1d1e 12045 case WC_PKCS7_STAGE5:
wolfSSL 16:8e0d178b1d1e 12046 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 12047 if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
wolfSSL 16:8e0d178b1d1e 12048 pkcs7->stream->expected + ASN_TAG_SZ +
wolfSSL 16:8e0d178b1d1e 12049 MAX_LENGTH_SZ, &pkiMsg, &idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 12050 return ret;
wolfSSL 16:8e0d178b1d1e 12051 }
wolfSSL 16:8e0d178b1d1e 12052
wolfSSL 16:8e0d178b1d1e 12053 rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK, in,
wolfSSL 16:8e0d178b1d1e 12054 inSz);
wolfSSL 16:8e0d178b1d1e 12055 if (rc < 0) {
wolfSSL 16:8e0d178b1d1e 12056 ret = (int)rc;
wolfSSL 16:8e0d178b1d1e 12057 break;
wolfSSL 16:8e0d178b1d1e 12058 }
wolfSSL 16:8e0d178b1d1e 12059 pkiMsgSz = (word32)rc;
wolfSSL 16:8e0d178b1d1e 12060
wolfSSL 16:8e0d178b1d1e 12061 /* use IV buffer from stream structure */
wolfSSL 16:8e0d178b1d1e 12062 tmpIv = pkcs7->stream->tmpIv;
wolfSSL 16:8e0d178b1d1e 12063 length = pkcs7->stream->expected;
wolfSSL 16:8e0d178b1d1e 12064 #endif
wolfSSL 16:8e0d178b1d1e 12065 XMEMCPY(tmpIv, &pkiMsg[idx], length);
wolfSSL 16:8e0d178b1d1e 12066 idx += length;
wolfSSL 16:8e0d178b1d1e 12067 /* read encryptedContent, cont[0] */
wolfSSL 16:8e0d178b1d1e 12068 if (ret == 0 && GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0)
wolfSSL 16:8e0d178b1d1e 12069 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 12070 if (ret == 0 && tag != (ASN_CONTEXT_SPECIFIC | 0))
wolfSSL 16:8e0d178b1d1e 12071 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 12072
wolfSSL 16:8e0d178b1d1e 12073 if (ret == 0 && GetLength(pkiMsg, &idx, &encryptedContentSz,
wolfSSL 16:8e0d178b1d1e 12074 pkiMsgSz) <= 0)
wolfSSL 16:8e0d178b1d1e 12075 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 12076
wolfSSL 16:8e0d178b1d1e 12077 if (ret < 0)
wolfSSL 16:8e0d178b1d1e 12078 break;
wolfSSL 16:8e0d178b1d1e 12079 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 12080 /* next chunk of data should contain encrypted content */
wolfSSL 16:8e0d178b1d1e 12081 pkcs7->stream->varThree = encryptedContentSz;
wolfSSL 16:8e0d178b1d1e 12082 if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 12083 break;
wolfSSL 16:8e0d178b1d1e 12084 }
wolfSSL 16:8e0d178b1d1e 12085
wolfSSL 16:8e0d178b1d1e 12086 if (pkcs7->stream->totalRd + encryptedContentSz < pkiMsgSz) {
wolfSSL 16:8e0d178b1d1e 12087 pkcs7->stream->flagOne = 1;
wolfSSL 16:8e0d178b1d1e 12088 }
wolfSSL 16:8e0d178b1d1e 12089
wolfSSL 16:8e0d178b1d1e 12090 pkcs7->stream->expected = (pkcs7->stream->maxLen -
wolfSSL 16:8e0d178b1d1e 12091 pkcs7->stream->totalRd) + pkcs7->stream->length;
wolfSSL 16:8e0d178b1d1e 12092
wolfSSL 16:8e0d178b1d1e 12093 #endif
wolfSSL 16:8e0d178b1d1e 12094 wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_STAGE6);
wolfSSL 16:8e0d178b1d1e 12095 FALL_THROUGH;
wolfSSL 16:8e0d178b1d1e 12096 /* end of stage 5 */
wolfSSL 16:8e0d178b1d1e 12097
wolfSSL 16:8e0d178b1d1e 12098 case WC_PKCS7_STAGE6:
wolfSSL 16:8e0d178b1d1e 12099 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 12100 if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
wolfSSL 16:8e0d178b1d1e 12101 pkcs7->stream->expected, &pkiMsg, &idx)) != 0) {
wolfSSL 16:8e0d178b1d1e 12102 return ret;
wolfSSL 16:8e0d178b1d1e 12103 }
wolfSSL 16:8e0d178b1d1e 12104
wolfSSL 16:8e0d178b1d1e 12105 rc = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK, in,
wolfSSL 16:8e0d178b1d1e 12106 inSz);
wolfSSL 16:8e0d178b1d1e 12107 if (rc < 0) {
wolfSSL 16:8e0d178b1d1e 12108 ret = (int)rc;
wolfSSL 16:8e0d178b1d1e 12109 break;
wolfSSL 16:8e0d178b1d1e 12110 }
wolfSSL 16:8e0d178b1d1e 12111 pkiMsgSz = (word32)rc;
wolfSSL 16:8e0d178b1d1e 12112
wolfSSL 16:8e0d178b1d1e 12113 /* restore saved variables */
wolfSSL 16:8e0d178b1d1e 12114 expBlockSz = pkcs7->stream->varOne;
wolfSSL 16:8e0d178b1d1e 12115 encOID = pkcs7->stream->varTwo;
wolfSSL 16:8e0d178b1d1e 12116 encryptedContentSz = pkcs7->stream->varThree;
wolfSSL 16:8e0d178b1d1e 12117 version = pkcs7->stream->vers;
wolfSSL 16:8e0d178b1d1e 12118 tmpIv = pkcs7->stream->tmpIv;
wolfSSL 16:8e0d178b1d1e 12119 #else
wolfSSL 16:8e0d178b1d1e 12120 encOID = 0;
wolfSSL 16:8e0d178b1d1e 12121 #endif
wolfSSL 16:8e0d178b1d1e 12122 if (ret == 0 && (encryptedContent = (byte*)XMALLOC(
wolfSSL 16:8e0d178b1d1e 12123 encryptedContentSz, pkcs7->heap, DYNAMIC_TYPE_PKCS7)) == NULL) {
wolfSSL 16:8e0d178b1d1e 12124 ret = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 12125 break;
wolfSSL 16:8e0d178b1d1e 12126 }
wolfSSL 16:8e0d178b1d1e 12127
wolfSSL 16:8e0d178b1d1e 12128 if (ret == 0) {
wolfSSL 16:8e0d178b1d1e 12129 XMEMCPY(encryptedContent, &pkiMsg[idx], encryptedContentSz);
wolfSSL 16:8e0d178b1d1e 12130 idx += encryptedContentSz;
wolfSSL 16:8e0d178b1d1e 12131
wolfSSL 16:8e0d178b1d1e 12132 /* decrypt encryptedContent */
wolfSSL 16:8e0d178b1d1e 12133 ret = wc_PKCS7_DecryptContent(pkcs7, encOID,
wolfSSL 16:8e0d178b1d1e 12134 pkcs7->encryptionKey, pkcs7->encryptionKeySz, tmpIv,
wolfSSL 16:8e0d178b1d1e 12135 expBlockSz, NULL, 0, NULL, 0, encryptedContent,
wolfSSL 16:8e0d178b1d1e 12136 encryptedContentSz, encryptedContent);
wolfSSL 16:8e0d178b1d1e 12137 if (ret != 0) {
wolfSSL 16:8e0d178b1d1e 12138 XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 12139 }
wolfSSL 16:8e0d178b1d1e 12140 }
wolfSSL 16:8e0d178b1d1e 12141
wolfSSL 16:8e0d178b1d1e 12142 if (ret == 0) {
wolfSSL 16:8e0d178b1d1e 12143 padLen = encryptedContent[encryptedContentSz-1];
wolfSSL 16:8e0d178b1d1e 12144
wolfSSL 16:8e0d178b1d1e 12145 if (padLen > encryptedContentSz) {
wolfSSL 16:8e0d178b1d1e 12146 WOLFSSL_MSG("Bad padding size found");
wolfSSL 16:8e0d178b1d1e 12147 ret = BUFFER_E;
wolfSSL 16:8e0d178b1d1e 12148 XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 12149 break;
wolfSSL 16:8e0d178b1d1e 12150 }
wolfSSL 16:8e0d178b1d1e 12151
wolfSSL 16:8e0d178b1d1e 12152 /* copy plaintext to output */
wolfSSL 16:8e0d178b1d1e 12153 XMEMCPY(output, encryptedContent, encryptedContentSz - padLen);
wolfSSL 16:8e0d178b1d1e 12154
wolfSSL 16:8e0d178b1d1e 12155 /* get implicit[1] unprotected attributes, optional */
wolfSSL 16:8e0d178b1d1e 12156 wc_PKCS7_FreeDecodedAttrib(pkcs7->decodedAttrib, pkcs7->heap);
wolfSSL 16:8e0d178b1d1e 12157 pkcs7->decodedAttrib = NULL;
wolfSSL 16:8e0d178b1d1e 12158 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 12159 if (pkcs7->stream->flagOne)
wolfSSL 16:8e0d178b1d1e 12160 #else
wolfSSL 16:8e0d178b1d1e 12161 if (idx < pkiMsgSz)
wolfSSL 16:8e0d178b1d1e 12162 #endif
wolfSSL 16:8e0d178b1d1e 12163 {
wolfSSL 16:8e0d178b1d1e 12164 haveAttribs = 1;
wolfSSL 16:8e0d178b1d1e 12165
wolfSSL 16:8e0d178b1d1e 12166 ret = wc_PKCS7_DecodeUnprotectedAttributes(pkcs7, pkiMsg,
wolfSSL 16:8e0d178b1d1e 12167 pkiMsgSz, &idx);
wolfSSL 16:8e0d178b1d1e 12168 if (ret != 0) {
wolfSSL 16:8e0d178b1d1e 12169 ForceZero(encryptedContent, encryptedContentSz);
wolfSSL 16:8e0d178b1d1e 12170 XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 12171 ret = ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 12172 }
wolfSSL 16:8e0d178b1d1e 12173 }
wolfSSL 16:8e0d178b1d1e 12174 }
wolfSSL 16:8e0d178b1d1e 12175
wolfSSL 16:8e0d178b1d1e 12176 if (ret == 0) {
wolfSSL 16:8e0d178b1d1e 12177 ForceZero(encryptedContent, encryptedContentSz);
wolfSSL 16:8e0d178b1d1e 12178 XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 12179
wolfSSL 16:8e0d178b1d1e 12180 /* go back and check the version now that attribs have been processed */
wolfSSL 16:8e0d178b1d1e 12181 if (pkcs7->version == 3 && version != 0) {
wolfSSL 16:8e0d178b1d1e 12182 WOLFSSL_MSG("Wrong PKCS#7 FirmwareEncryptedData version");
wolfSSL 16:8e0d178b1d1e 12183 return ASN_VERSION_E;
wolfSSL 16:8e0d178b1d1e 12184 }
wolfSSL 16:8e0d178b1d1e 12185
wolfSSL 16:8e0d178b1d1e 12186 if (pkcs7->version != 3 &&
wolfSSL 16:8e0d178b1d1e 12187 ((haveAttribs == 0 && version != 0) ||
wolfSSL 16:8e0d178b1d1e 12188 (haveAttribs == 1 && version != 2))) {
wolfSSL 16:8e0d178b1d1e 12189 WOLFSSL_MSG("Wrong PKCS#7 EncryptedData version");
wolfSSL 16:8e0d178b1d1e 12190 return ASN_VERSION_E;
wolfSSL 16:8e0d178b1d1e 12191 }
wolfSSL 16:8e0d178b1d1e 12192 ret = encryptedContentSz - padLen;
wolfSSL 16:8e0d178b1d1e 12193 }
wolfSSL 16:8e0d178b1d1e 12194
wolfSSL 16:8e0d178b1d1e 12195 if (ret != 0) break;
wolfSSL 16:8e0d178b1d1e 12196 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 12197 wc_PKCS7_ResetStream(pkcs7);
wolfSSL 16:8e0d178b1d1e 12198 #endif
wolfSSL 16:8e0d178b1d1e 12199 wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_START);
wolfSSL 16:8e0d178b1d1e 12200 break;
wolfSSL 16:8e0d178b1d1e 12201
wolfSSL 16:8e0d178b1d1e 12202 default:
wolfSSL 16:8e0d178b1d1e 12203 WOLFSSL_MSG("Error in unknown PKCS#7 Decode Encrypted Data state");
wolfSSL 16:8e0d178b1d1e 12204 return BAD_STATE_E;
wolfSSL 16:8e0d178b1d1e 12205 }
wolfSSL 16:8e0d178b1d1e 12206
wolfSSL 16:8e0d178b1d1e 12207 if (ret != 0) {
wolfSSL 16:8e0d178b1d1e 12208 #ifndef NO_PKCS7_STREAM
wolfSSL 16:8e0d178b1d1e 12209 /* restart in error case */
wolfSSL 16:8e0d178b1d1e 12210 wc_PKCS7_ResetStream(pkcs7);
wolfSSL 16:8e0d178b1d1e 12211 #endif
wolfSSL 16:8e0d178b1d1e 12212 wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_START);
wolfSSL 16:8e0d178b1d1e 12213 }
wolfSSL 16:8e0d178b1d1e 12214 return ret;
wolfSSL 16:8e0d178b1d1e 12215 }
wolfSSL 16:8e0d178b1d1e 12216
wolfSSL 16:8e0d178b1d1e 12217
wolfSSL 16:8e0d178b1d1e 12218 /* Function to set callback during decryption, this overrides the default
wolfSSL 16:8e0d178b1d1e 12219 * decryption function and can be used for choosing a key at run time based
wolfSSL 16:8e0d178b1d1e 12220 * on the parsed bundle so far.
wolfSSL 16:8e0d178b1d1e 12221 * returns 0 on success
wolfSSL 16:8e0d178b1d1e 12222 */
wolfSSL 16:8e0d178b1d1e 12223 int wc_PKCS7_SetDecodeEncryptedCb(PKCS7* pkcs7,
wolfSSL 16:8e0d178b1d1e 12224 CallbackDecryptContent decryptionCb)
wolfSSL 16:8e0d178b1d1e 12225 {
wolfSSL 16:8e0d178b1d1e 12226 if (pkcs7 != NULL) {
wolfSSL 16:8e0d178b1d1e 12227 pkcs7->decryptionCb = decryptionCb;
wolfSSL 16:8e0d178b1d1e 12228 }
wolfSSL 16:8e0d178b1d1e 12229 return 0;
wolfSSL 16:8e0d178b1d1e 12230 }
wolfSSL 16:8e0d178b1d1e 12231
wolfSSL 16:8e0d178b1d1e 12232
wolfSSL 16:8e0d178b1d1e 12233 /* Set an optional user context that gets passed to callback
wolfSSL 16:8e0d178b1d1e 12234 * returns 0 on success
wolfSSL 16:8e0d178b1d1e 12235 */
wolfSSL 16:8e0d178b1d1e 12236 int wc_PKCS7_SetDecodeEncryptedCtx(PKCS7* pkcs7, void* ctx)
wolfSSL 16:8e0d178b1d1e 12237 {
wolfSSL 16:8e0d178b1d1e 12238 if (pkcs7 != NULL) {
wolfSSL 16:8e0d178b1d1e 12239 pkcs7->decryptionCtx = ctx;
wolfSSL 16:8e0d178b1d1e 12240 }
wolfSSL 16:8e0d178b1d1e 12241 return 0;
wolfSSL 16:8e0d178b1d1e 12242 }
wolfSSL 16:8e0d178b1d1e 12243 #endif /* NO_PKCS7_ENCRYPTED_DATA */
wolfSSL 16:8e0d178b1d1e 12244
wolfSSL 16:8e0d178b1d1e 12245 #if defined(HAVE_LIBZ) && !defined(NO_PKCS7_COMPRESSED_DATA)
wolfSSL 16:8e0d178b1d1e 12246
wolfSSL 16:8e0d178b1d1e 12247 /* build PKCS#7 compressedData content type, return encrypted size */
wolfSSL 16:8e0d178b1d1e 12248 int wc_PKCS7_EncodeCompressedData(PKCS7* pkcs7, byte* output, word32 outputSz)
wolfSSL 16:8e0d178b1d1e 12249 {
wolfSSL 16:8e0d178b1d1e 12250 byte contentInfoSeq[MAX_SEQ_SZ];
wolfSSL 16:8e0d178b1d1e 12251 byte contentInfoTypeOid[MAX_OID_SZ];
wolfSSL 16:8e0d178b1d1e 12252 byte contentInfoContentSeq[MAX_SEQ_SZ]; /* EXPLICIT [0] */
wolfSSL 16:8e0d178b1d1e 12253 byte compressedDataSeq[MAX_SEQ_SZ];
wolfSSL 16:8e0d178b1d1e 12254 byte cmsVersion[MAX_VERSION_SZ];
wolfSSL 16:8e0d178b1d1e 12255 byte compressAlgId[MAX_ALGO_SZ];
wolfSSL 16:8e0d178b1d1e 12256 byte encapContentInfoSeq[MAX_SEQ_SZ];
wolfSSL 16:8e0d178b1d1e 12257 byte contentTypeOid[MAX_OID_SZ];
wolfSSL 16:8e0d178b1d1e 12258 byte contentSeq[MAX_SEQ_SZ]; /* EXPLICIT [0] */
wolfSSL 16:8e0d178b1d1e 12259 byte contentOctetStr[MAX_OCTET_STR_SZ];
wolfSSL 16:8e0d178b1d1e 12260
wolfSSL 16:8e0d178b1d1e 12261 int ret;
wolfSSL 16:8e0d178b1d1e 12262 word32 totalSz, idx;
wolfSSL 16:8e0d178b1d1e 12263 word32 contentInfoSeqSz, contentInfoContentSeqSz, contentInfoTypeOidSz;
wolfSSL 16:8e0d178b1d1e 12264 word32 compressedDataSeqSz, cmsVersionSz, compressAlgIdSz;
wolfSSL 16:8e0d178b1d1e 12265 word32 encapContentInfoSeqSz, contentTypeOidSz, contentSeqSz;
wolfSSL 16:8e0d178b1d1e 12266 word32 contentOctetStrSz;
wolfSSL 16:8e0d178b1d1e 12267
wolfSSL 16:8e0d178b1d1e 12268 byte* compressed;
wolfSSL 16:8e0d178b1d1e 12269 word32 compressedSz;
wolfSSL 16:8e0d178b1d1e 12270
wolfSSL 16:8e0d178b1d1e 12271 if (pkcs7 == NULL || pkcs7->content == NULL || pkcs7->contentSz == 0 ||
wolfSSL 16:8e0d178b1d1e 12272 output == NULL || outputSz == 0) {
wolfSSL 16:8e0d178b1d1e 12273 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 12274 }
wolfSSL 16:8e0d178b1d1e 12275
wolfSSL 16:8e0d178b1d1e 12276 /* allocate space for compressed content. The libz code says the compressed
wolfSSL 16:8e0d178b1d1e 12277 * buffer should be srcSz + 0.1% + 12. */
wolfSSL 16:8e0d178b1d1e 12278 compressedSz = (pkcs7->contentSz + (word32)(pkcs7->contentSz * 0.001) + 12);
wolfSSL 16:8e0d178b1d1e 12279 compressed = (byte*)XMALLOC(compressedSz, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 12280 if (compressed == NULL) {
wolfSSL 16:8e0d178b1d1e 12281 WOLFSSL_MSG("Error allocating memory for CMS compressed content");
wolfSSL 16:8e0d178b1d1e 12282 return MEMORY_E;
wolfSSL 16:8e0d178b1d1e 12283 }
wolfSSL 16:8e0d178b1d1e 12284
wolfSSL 16:8e0d178b1d1e 12285 /* compress content */
wolfSSL 16:8e0d178b1d1e 12286 ret = wc_Compress(compressed, compressedSz, pkcs7->content,
wolfSSL 16:8e0d178b1d1e 12287 pkcs7->contentSz, 0);
wolfSSL 16:8e0d178b1d1e 12288 if (ret < 0) {
wolfSSL 16:8e0d178b1d1e 12289 XFREE(compressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 12290 return ret;
wolfSSL 16:8e0d178b1d1e 12291 }
wolfSSL 16:8e0d178b1d1e 12292 compressedSz = (word32)ret;
wolfSSL 16:8e0d178b1d1e 12293
wolfSSL 16:8e0d178b1d1e 12294 /* eContent OCTET STRING, working backwards */
wolfSSL 16:8e0d178b1d1e 12295 contentOctetStrSz = SetOctetString(compressedSz, contentOctetStr);
wolfSSL 16:8e0d178b1d1e 12296 totalSz = contentOctetStrSz + compressedSz;
wolfSSL 16:8e0d178b1d1e 12297
wolfSSL 16:8e0d178b1d1e 12298 /* EXPLICIT [0] eContentType */
wolfSSL 16:8e0d178b1d1e 12299 contentSeqSz = SetExplicit(0, totalSz, contentSeq);
wolfSSL 16:8e0d178b1d1e 12300 totalSz += contentSeqSz;
wolfSSL 16:8e0d178b1d1e 12301
wolfSSL 16:8e0d178b1d1e 12302 /* eContentType OBJECT IDENTIFIER */
wolfSSL 16:8e0d178b1d1e 12303 ret = wc_SetContentType(pkcs7->contentOID, contentTypeOid,
wolfSSL 16:8e0d178b1d1e 12304 sizeof(contentTypeOid));
wolfSSL 16:8e0d178b1d1e 12305 if (ret < 0) {
wolfSSL 16:8e0d178b1d1e 12306 XFREE(compressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 12307 return ret;
wolfSSL 16:8e0d178b1d1e 12308 }
wolfSSL 16:8e0d178b1d1e 12309
wolfSSL 16:8e0d178b1d1e 12310 contentTypeOidSz = ret;
wolfSSL 16:8e0d178b1d1e 12311 totalSz += contentTypeOidSz;
wolfSSL 16:8e0d178b1d1e 12312
wolfSSL 16:8e0d178b1d1e 12313 /* EncapsulatedContentInfo SEQUENCE */
wolfSSL 16:8e0d178b1d1e 12314 encapContentInfoSeqSz = SetSequence(totalSz, encapContentInfoSeq);
wolfSSL 16:8e0d178b1d1e 12315 totalSz += encapContentInfoSeqSz;
wolfSSL 16:8e0d178b1d1e 12316
wolfSSL 16:8e0d178b1d1e 12317 /* compressionAlgorithm AlgorithmIdentifier */
wolfSSL 16:8e0d178b1d1e 12318 /* Only supports zlib for compression currently:
wolfSSL 16:8e0d178b1d1e 12319 * id-alg-zlibCompress (1.2.840.113549.1.9.16.3.8) */
wolfSSL 16:8e0d178b1d1e 12320 compressAlgIdSz = SetAlgoID(ZLIBc, compressAlgId, oidCompressType, 0);
wolfSSL 16:8e0d178b1d1e 12321 totalSz += compressAlgIdSz;
wolfSSL 16:8e0d178b1d1e 12322
wolfSSL 16:8e0d178b1d1e 12323 /* version */
wolfSSL 16:8e0d178b1d1e 12324 cmsVersionSz = SetMyVersion(0, cmsVersion, 0);
wolfSSL 16:8e0d178b1d1e 12325 totalSz += cmsVersionSz;
wolfSSL 16:8e0d178b1d1e 12326
wolfSSL 16:8e0d178b1d1e 12327 /* CompressedData SEQUENCE */
wolfSSL 16:8e0d178b1d1e 12328 compressedDataSeqSz = SetSequence(totalSz, compressedDataSeq);
wolfSSL 16:8e0d178b1d1e 12329 totalSz += compressedDataSeqSz;
wolfSSL 16:8e0d178b1d1e 12330
wolfSSL 16:8e0d178b1d1e 12331 /* ContentInfo content EXPLICIT SEQUENCE */
wolfSSL 16:8e0d178b1d1e 12332 contentInfoContentSeqSz = SetExplicit(0, totalSz, contentInfoContentSeq);
wolfSSL 16:8e0d178b1d1e 12333 totalSz += contentInfoContentSeqSz;
wolfSSL 16:8e0d178b1d1e 12334
wolfSSL 16:8e0d178b1d1e 12335 /* ContentInfo ContentType (compressedData) */
wolfSSL 16:8e0d178b1d1e 12336 if (pkcs7->version == 3) {
wolfSSL 16:8e0d178b1d1e 12337 contentInfoTypeOidSz = 0;
wolfSSL 16:8e0d178b1d1e 12338 }
wolfSSL 16:8e0d178b1d1e 12339 else {
wolfSSL 16:8e0d178b1d1e 12340 ret = wc_SetContentType(COMPRESSED_DATA, contentInfoTypeOid,
wolfSSL 16:8e0d178b1d1e 12341 sizeof(contentInfoTypeOid));
wolfSSL 16:8e0d178b1d1e 12342 if (ret < 0) {
wolfSSL 16:8e0d178b1d1e 12343 XFREE(compressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 12344 return ret;
wolfSSL 16:8e0d178b1d1e 12345 }
wolfSSL 16:8e0d178b1d1e 12346
wolfSSL 16:8e0d178b1d1e 12347 contentInfoTypeOidSz = ret;
wolfSSL 16:8e0d178b1d1e 12348 totalSz += contentInfoTypeOidSz;
wolfSSL 16:8e0d178b1d1e 12349 }
wolfSSL 16:8e0d178b1d1e 12350
wolfSSL 16:8e0d178b1d1e 12351 /* ContentInfo SEQUENCE */
wolfSSL 16:8e0d178b1d1e 12352 contentInfoSeqSz = SetSequence(totalSz, contentInfoSeq);
wolfSSL 16:8e0d178b1d1e 12353 totalSz += contentInfoSeqSz;
wolfSSL 16:8e0d178b1d1e 12354
wolfSSL 16:8e0d178b1d1e 12355 if (outputSz < totalSz) {
wolfSSL 16:8e0d178b1d1e 12356 XFREE(compressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 12357 return BUFFER_E;
wolfSSL 16:8e0d178b1d1e 12358 }
wolfSSL 16:8e0d178b1d1e 12359
wolfSSL 16:8e0d178b1d1e 12360 idx = 0;
wolfSSL 16:8e0d178b1d1e 12361 XMEMCPY(output + idx, contentInfoSeq, contentInfoSeqSz);
wolfSSL 16:8e0d178b1d1e 12362 idx += contentInfoSeqSz;
wolfSSL 16:8e0d178b1d1e 12363 XMEMCPY(output + idx, contentInfoTypeOid, contentInfoTypeOidSz);
wolfSSL 16:8e0d178b1d1e 12364 idx += contentInfoTypeOidSz;
wolfSSL 16:8e0d178b1d1e 12365 XMEMCPY(output + idx, contentInfoContentSeq, contentInfoContentSeqSz);
wolfSSL 16:8e0d178b1d1e 12366 idx += contentInfoContentSeqSz;
wolfSSL 16:8e0d178b1d1e 12367 XMEMCPY(output + idx, compressedDataSeq, compressedDataSeqSz);
wolfSSL 16:8e0d178b1d1e 12368 idx += compressedDataSeqSz;
wolfSSL 16:8e0d178b1d1e 12369 XMEMCPY(output + idx, cmsVersion, cmsVersionSz);
wolfSSL 16:8e0d178b1d1e 12370 idx += cmsVersionSz;
wolfSSL 16:8e0d178b1d1e 12371 XMEMCPY(output + idx, compressAlgId, compressAlgIdSz);
wolfSSL 16:8e0d178b1d1e 12372 idx += compressAlgIdSz;
wolfSSL 16:8e0d178b1d1e 12373 XMEMCPY(output + idx, encapContentInfoSeq, encapContentInfoSeqSz);
wolfSSL 16:8e0d178b1d1e 12374 idx += encapContentInfoSeqSz;
wolfSSL 16:8e0d178b1d1e 12375 XMEMCPY(output + idx, contentTypeOid, contentTypeOidSz);
wolfSSL 16:8e0d178b1d1e 12376 idx += contentTypeOidSz;
wolfSSL 16:8e0d178b1d1e 12377 XMEMCPY(output + idx, contentSeq, contentSeqSz);
wolfSSL 16:8e0d178b1d1e 12378 idx += contentSeqSz;
wolfSSL 16:8e0d178b1d1e 12379 XMEMCPY(output + idx, contentOctetStr, contentOctetStrSz);
wolfSSL 16:8e0d178b1d1e 12380 idx += contentOctetStrSz;
wolfSSL 16:8e0d178b1d1e 12381 XMEMCPY(output + idx, compressed, compressedSz);
wolfSSL 16:8e0d178b1d1e 12382 idx += compressedSz;
wolfSSL 16:8e0d178b1d1e 12383
wolfSSL 16:8e0d178b1d1e 12384 XFREE(compressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 12385
wolfSSL 16:8e0d178b1d1e 12386 return idx;
wolfSSL 16:8e0d178b1d1e 12387 }
wolfSSL 16:8e0d178b1d1e 12388
wolfSSL 16:8e0d178b1d1e 12389 /* unwrap and decompress PKCS#7/CMS compressedData object,
wolfSSL 16:8e0d178b1d1e 12390 * returned decoded size */
wolfSSL 16:8e0d178b1d1e 12391 int wc_PKCS7_DecodeCompressedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz,
wolfSSL 16:8e0d178b1d1e 12392 byte* output, word32 outputSz)
wolfSSL 16:8e0d178b1d1e 12393 {
wolfSSL 16:8e0d178b1d1e 12394 int length, version, ret;
wolfSSL 16:8e0d178b1d1e 12395 word32 idx = 0, algOID, contentType;
wolfSSL 16:8e0d178b1d1e 12396 byte tag;
wolfSSL 16:8e0d178b1d1e 12397
wolfSSL 16:8e0d178b1d1e 12398 byte* decompressed;
wolfSSL 16:8e0d178b1d1e 12399 word32 decompressedSz;
wolfSSL 16:8e0d178b1d1e 12400
wolfSSL 16:8e0d178b1d1e 12401 if (pkcs7 == NULL || pkiMsg == NULL || pkiMsgSz == 0 ||
wolfSSL 16:8e0d178b1d1e 12402 output == NULL || outputSz == 0) {
wolfSSL 16:8e0d178b1d1e 12403 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 12404 }
wolfSSL 16:8e0d178b1d1e 12405
wolfSSL 16:8e0d178b1d1e 12406 /* get ContentInfo SEQUENCE */
wolfSSL 15:117db924cf7c 12407 if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 12408 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 12409
wolfSSL 16:8e0d178b1d1e 12410 if (pkcs7->version != 3) {
wolfSSL 16:8e0d178b1d1e 12411 /* get ContentInfo contentType */
wolfSSL 16:8e0d178b1d1e 12412 if (wc_GetContentType(pkiMsg, &idx, &contentType, pkiMsgSz) < 0)
wolfSSL 16:8e0d178b1d1e 12413 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 12414
wolfSSL 16:8e0d178b1d1e 12415 if (contentType != COMPRESSED_DATA)
wolfSSL 16:8e0d178b1d1e 12416 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 12417 }
wolfSSL 16:8e0d178b1d1e 12418
wolfSSL 16:8e0d178b1d1e 12419 /* get ContentInfo content EXPLICIT SEQUENCE */
wolfSSL 16:8e0d178b1d1e 12420 if (GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 12421 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 12422
wolfSSL 16:8e0d178b1d1e 12423 if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
wolfSSL 15:117db924cf7c 12424 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 12425
wolfSSL 15:117db924cf7c 12426 if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 12427 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 12428
wolfSSL 16:8e0d178b1d1e 12429 /* get CompressedData SEQUENCE */
wolfSSL 16:8e0d178b1d1e 12430 if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
wolfSSL 16:8e0d178b1d1e 12431 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 12432
wolfSSL 16:8e0d178b1d1e 12433 /* get version */
wolfSSL 16:8e0d178b1d1e 12434 if (GetMyVersion(pkiMsg, &idx, &version, pkiMsgSz) < 0)
wolfSSL 16:8e0d178b1d1e 12435 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 12436
wolfSSL 16:8e0d178b1d1e 12437 if (version != 0) {
wolfSSL 16:8e0d178b1d1e 12438 WOLFSSL_MSG("CMS CompressedData version MUST be 0, but is not");
wolfSSL 15:117db924cf7c 12439 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 12440 }
wolfSSL 15:117db924cf7c 12441
wolfSSL 16:8e0d178b1d1e 12442 /* get CompressionAlgorithmIdentifier */
wolfSSL 16:8e0d178b1d1e 12443 if (GetAlgoId(pkiMsg, &idx, &algOID, oidIgnoreType, pkiMsgSz) < 0)
wolfSSL 16:8e0d178b1d1e 12444 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 12445
wolfSSL 16:8e0d178b1d1e 12446 /* Only supports zlib for compression currently:
wolfSSL 16:8e0d178b1d1e 12447 * id-alg-zlibCompress (1.2.840.113549.1.9.16.3.8) */
wolfSSL 16:8e0d178b1d1e 12448 if (algOID != ZLIBc) {
wolfSSL 16:8e0d178b1d1e 12449 WOLFSSL_MSG("CMS CompressedData only supports zlib algorithm");
wolfSSL 15:117db924cf7c 12450 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 12451 }
wolfSSL 16:8e0d178b1d1e 12452
wolfSSL 16:8e0d178b1d1e 12453 /* get EncapsulatedContentInfo SEQUENCE */
wolfSSL 16:8e0d178b1d1e 12454 if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
wolfSSL 16:8e0d178b1d1e 12455 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 12456
wolfSSL 16:8e0d178b1d1e 12457 /* get ContentType OID */
wolfSSL 16:8e0d178b1d1e 12458 if (wc_GetContentType(pkiMsg, &idx, &contentType, pkiMsgSz) < 0)
wolfSSL 15:117db924cf7c 12459 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 12460
wolfSSL 16:8e0d178b1d1e 12461 pkcs7->contentOID = contentType;
wolfSSL 16:8e0d178b1d1e 12462
wolfSSL 16:8e0d178b1d1e 12463 /* get eContent EXPLICIT SEQUENCE */
wolfSSL 16:8e0d178b1d1e 12464 if (GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0)
wolfSSL 16:8e0d178b1d1e 12465 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 12466
wolfSSL 16:8e0d178b1d1e 12467 if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
wolfSSL 16:8e0d178b1d1e 12468 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 12469
wolfSSL 16:8e0d178b1d1e 12470 if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
wolfSSL 16:8e0d178b1d1e 12471 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 12472
wolfSSL 16:8e0d178b1d1e 12473 /* get content OCTET STRING */
wolfSSL 16:8e0d178b1d1e 12474 if (GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0)
wolfSSL 16:8e0d178b1d1e 12475 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 12476
wolfSSL 16:8e0d178b1d1e 12477 if (tag != ASN_OCTET_STRING)
wolfSSL 16:8e0d178b1d1e 12478 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 12479
wolfSSL 16:8e0d178b1d1e 12480 if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
wolfSSL 16:8e0d178b1d1e 12481 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 12482
wolfSSL 16:8e0d178b1d1e 12483 /* allocate space for decompressed data */
wolfSSL 16:8e0d178b1d1e 12484 decompressed = (byte*)XMALLOC(length, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 12485 if (decompressed == NULL) {
wolfSSL 16:8e0d178b1d1e 12486 WOLFSSL_MSG("Error allocating memory for CMS decompression buffer");
wolfSSL 15:117db924cf7c 12487 return MEMORY_E;
wolfSSL 16:8e0d178b1d1e 12488 }
wolfSSL 16:8e0d178b1d1e 12489
wolfSSL 16:8e0d178b1d1e 12490 /* decompress content */
wolfSSL 16:8e0d178b1d1e 12491 ret = wc_DeCompress(decompressed, length, &pkiMsg[idx], length);
wolfSSL 16:8e0d178b1d1e 12492 if (ret < 0) {
wolfSSL 16:8e0d178b1d1e 12493 XFREE(decompressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 15:117db924cf7c 12494 return ret;
wolfSSL 15:117db924cf7c 12495 }
wolfSSL 16:8e0d178b1d1e 12496 decompressedSz = (word32)ret;
wolfSSL 16:8e0d178b1d1e 12497
wolfSSL 16:8e0d178b1d1e 12498 /* get content */
wolfSSL 16:8e0d178b1d1e 12499 if (outputSz < decompressedSz) {
wolfSSL 16:8e0d178b1d1e 12500 WOLFSSL_MSG("CMS output buffer too small to hold decompressed data");
wolfSSL 16:8e0d178b1d1e 12501 XFREE(decompressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 12502 return BUFFER_E;
wolfSSL 16:8e0d178b1d1e 12503 }
wolfSSL 16:8e0d178b1d1e 12504
wolfSSL 16:8e0d178b1d1e 12505 XMEMCPY(output, decompressed, decompressedSz);
wolfSSL 16:8e0d178b1d1e 12506 XFREE(decompressed, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
wolfSSL 16:8e0d178b1d1e 12507
wolfSSL 16:8e0d178b1d1e 12508 return decompressedSz;
wolfSSL 16:8e0d178b1d1e 12509 }
wolfSSL 16:8e0d178b1d1e 12510
wolfSSL 16:8e0d178b1d1e 12511 #endif /* HAVE_LIBZ && !NO_PKCS7_COMPRESSED_DATA */
wolfSSL 15:117db924cf7c 12512
wolfSSL 15:117db924cf7c 12513 #else /* HAVE_PKCS7 */
wolfSSL 15:117db924cf7c 12514
wolfSSL 15:117db924cf7c 12515
wolfSSL 15:117db924cf7c 12516 #ifdef _MSC_VER
wolfSSL 15:117db924cf7c 12517 /* 4206 warning for blank file */
wolfSSL 15:117db924cf7c 12518 #pragma warning(disable: 4206)
wolfSSL 15:117db924cf7c 12519 #endif
wolfSSL 15:117db924cf7c 12520
wolfSSL 15:117db924cf7c 12521
wolfSSL 15:117db924cf7c 12522 #endif /* HAVE_PKCS7 */
wolfSSL 15:117db924cf7c 12523
wolfSSL 15:117db924cf7c 12524