wolfSSL SSL/TLS library, support up to TLS1.3
Dependents: CyaSSL-Twitter-OAuth4Tw Example-client-tls-cert TwitterReader TweetTest ... more
wolfcrypt/src/pkcs7.c@17:a5f916481144, 2020-06-05 (annotated)
- 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?
User | Revision | Line number | New 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 |