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

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

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

Who changed what in which revision?

UserRevisionLine numberNew contents of line
wolfSSL 15:117db924cf7c 1 /* pkcs12.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 16:8e0d178b1d1e 29 #if !defined(NO_ASN) && !defined(NO_PWDBASED) && defined(HAVE_PKCS12)
wolfSSL 15:117db924cf7c 30
wolfSSL 15:117db924cf7c 31 #include <wolfssl/wolfcrypt/asn.h>
wolfSSL 15:117db924cf7c 32 #include <wolfssl/wolfcrypt/asn_public.h>
wolfSSL 15:117db924cf7c 33 #include <wolfssl/wolfcrypt/error-crypt.h>
wolfSSL 15:117db924cf7c 34 #include <wolfssl/wolfcrypt/hmac.h>
wolfSSL 15:117db924cf7c 35 #include <wolfssl/wolfcrypt/logging.h>
wolfSSL 15:117db924cf7c 36 #ifdef NO_INLINE
wolfSSL 15:117db924cf7c 37 #include <wolfssl/wolfcrypt/misc.h>
wolfSSL 15:117db924cf7c 38 #else
wolfSSL 15:117db924cf7c 39 #define WOLFSSL_MISC_INCLUDED
wolfSSL 15:117db924cf7c 40 #include <wolfcrypt/src/misc.c>
wolfSSL 15:117db924cf7c 41 #endif
wolfSSL 15:117db924cf7c 42 #include <wolfssl/wolfcrypt/pkcs12.h>
wolfSSL 15:117db924cf7c 43 #include <wolfssl/wolfcrypt/pwdbased.h>
wolfSSL 15:117db924cf7c 44 #include <wolfssl/wolfcrypt/hash.h>
wolfSSL 15:117db924cf7c 45
wolfSSL 15:117db924cf7c 46
wolfSSL 15:117db924cf7c 47 #define ERROR_OUT(err, eLabel) { ret = (err); goto eLabel; }
wolfSSL 15:117db924cf7c 48
wolfSSL 15:117db924cf7c 49 enum {
wolfSSL 15:117db924cf7c 50 WC_PKCS12_KeyBag = 667,
wolfSSL 15:117db924cf7c 51 WC_PKCS12_ShroudedKeyBag = 668,
wolfSSL 15:117db924cf7c 52 WC_PKCS12_CertBag = 669,
wolfSSL 15:117db924cf7c 53 WC_PKCS12_CertBag_Type1 = 675,
wolfSSL 15:117db924cf7c 54 WC_PKCS12_CrlBag = 670,
wolfSSL 15:117db924cf7c 55 WC_PKCS12_SecretBag = 671,
wolfSSL 15:117db924cf7c 56 WC_PKCS12_SafeContentsBag = 672,
wolfSSL 15:117db924cf7c 57 WC_PKCS12_DATA = 651,
wolfSSL 15:117db924cf7c 58 WC_PKCS12_ENCRYPTED_DATA = 656,
wolfSSL 15:117db924cf7c 59
wolfSSL 15:117db924cf7c 60 WC_PKCS12_DATA_OBJ_SZ = 11,
wolfSSL 15:117db924cf7c 61 };
wolfSSL 15:117db924cf7c 62
wolfSSL 16:8e0d178b1d1e 63 static const byte WC_PKCS12_ENCRYPTED_OID[] =
wolfSSL 16:8e0d178b1d1e 64 {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x06};
wolfSSL 15:117db924cf7c 65 static const byte WC_PKCS12_DATA_OID[] =
wolfSSL 15:117db924cf7c 66 {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x01};
wolfSSL 15:117db924cf7c 67 static const byte WC_PKCS12_CertBag_Type1_OID[] =
wolfSSL 15:117db924cf7c 68 {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x16, 0x01};
wolfSSL 15:117db924cf7c 69 static const byte WC_PKCS12_CertBag_OID[] =
wolfSSL 15:117db924cf7c 70 {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0c, 0x0a, 0x01, 0x03};
wolfSSL 15:117db924cf7c 71 static const byte WC_PKCS12_KeyBag_OID[] =
wolfSSL 15:117db924cf7c 72 {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0c, 0x0a, 0x01, 0x01};
wolfSSL 15:117db924cf7c 73 static const byte WC_PKCS12_ShroudedKeyBag_OID[] =
wolfSSL 15:117db924cf7c 74 {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x0c, 0x0a, 0x01, 0x02};
wolfSSL 15:117db924cf7c 75
wolfSSL 15:117db924cf7c 76
wolfSSL 15:117db924cf7c 77 typedef struct ContentInfo {
wolfSSL 15:117db924cf7c 78 byte* data;
wolfSSL 15:117db924cf7c 79 struct ContentInfo* next;
wolfSSL 15:117db924cf7c 80 word32 encC; /* encryptedContent */
wolfSSL 15:117db924cf7c 81 word32 dataSz;
wolfSSL 16:8e0d178b1d1e 82 int type; /* DATA / encrypted / enveloped */
wolfSSL 15:117db924cf7c 83 } ContentInfo;
wolfSSL 15:117db924cf7c 84
wolfSSL 15:117db924cf7c 85
wolfSSL 15:117db924cf7c 86 typedef struct AuthenticatedSafe {
wolfSSL 15:117db924cf7c 87 ContentInfo* CI;
wolfSSL 15:117db924cf7c 88 byte* data; /* T contents.... */
wolfSSL 15:117db924cf7c 89 word32 oid; /* encrypted or not */
wolfSSL 15:117db924cf7c 90 word32 numCI; /* number of Content Info structs */
wolfSSL 15:117db924cf7c 91 word32 dataSz;
wolfSSL 15:117db924cf7c 92 } AuthenticatedSafe;
wolfSSL 15:117db924cf7c 93
wolfSSL 15:117db924cf7c 94
wolfSSL 15:117db924cf7c 95 typedef struct MacData {
wolfSSL 15:117db924cf7c 96 byte* digest;
wolfSSL 15:117db924cf7c 97 byte* salt;
wolfSSL 15:117db924cf7c 98 word32 oid;
wolfSSL 15:117db924cf7c 99 word32 digestSz;
wolfSSL 15:117db924cf7c 100 word32 saltSz;
wolfSSL 16:8e0d178b1d1e 101 int itt; /* number of iterations when creating HMAC key */
wolfSSL 15:117db924cf7c 102 } MacData;
wolfSSL 15:117db924cf7c 103
wolfSSL 15:117db924cf7c 104
wolfSSL 15:117db924cf7c 105 struct WC_PKCS12 {
wolfSSL 15:117db924cf7c 106 void* heap;
wolfSSL 15:117db924cf7c 107 AuthenticatedSafe* safe;
wolfSSL 15:117db924cf7c 108 MacData* signData;
wolfSSL 15:117db924cf7c 109 word32 oid; /* DATA / Enveloped DATA ... */
wolfSSL 15:117db924cf7c 110 };
wolfSSL 15:117db924cf7c 111
wolfSSL 15:117db924cf7c 112
wolfSSL 15:117db924cf7c 113 /* for friendlyName, localKeyId .... */
wolfSSL 15:117db924cf7c 114 typedef struct WC_PKCS12_ATTRIBUTE {
wolfSSL 15:117db924cf7c 115 byte* data;
wolfSSL 15:117db924cf7c 116 word32 oid;
wolfSSL 15:117db924cf7c 117 word32 dataSz;
wolfSSL 15:117db924cf7c 118 } WC_PKCS12_ATTRIBUTE;
wolfSSL 15:117db924cf7c 119
wolfSSL 15:117db924cf7c 120
wolfSSL 15:117db924cf7c 121 WC_PKCS12* wc_PKCS12_new(void)
wolfSSL 15:117db924cf7c 122 {
wolfSSL 15:117db924cf7c 123 WC_PKCS12* pkcs12 = (WC_PKCS12*)XMALLOC(sizeof(WC_PKCS12),
wolfSSL 15:117db924cf7c 124 NULL, DYNAMIC_TYPE_PKCS);
wolfSSL 15:117db924cf7c 125 if (pkcs12 == NULL) {
wolfSSL 15:117db924cf7c 126 WOLFSSL_MSG("Memory issue when creating WC_PKCS12 struct");
wolfSSL 15:117db924cf7c 127 return NULL;
wolfSSL 15:117db924cf7c 128 }
wolfSSL 15:117db924cf7c 129
wolfSSL 15:117db924cf7c 130 XMEMSET(pkcs12, 0, sizeof(WC_PKCS12));
wolfSSL 15:117db924cf7c 131
wolfSSL 15:117db924cf7c 132 return pkcs12;
wolfSSL 15:117db924cf7c 133 }
wolfSSL 15:117db924cf7c 134
wolfSSL 15:117db924cf7c 135
wolfSSL 15:117db924cf7c 136 static void freeSafe(AuthenticatedSafe* safe, void* heap)
wolfSSL 15:117db924cf7c 137 {
wolfSSL 15:117db924cf7c 138 int i;
wolfSSL 15:117db924cf7c 139
wolfSSL 15:117db924cf7c 140 if (safe == NULL) {
wolfSSL 15:117db924cf7c 141 return;
wolfSSL 15:117db924cf7c 142 }
wolfSSL 15:117db924cf7c 143
wolfSSL 15:117db924cf7c 144 /* free content info structs */
wolfSSL 15:117db924cf7c 145 for (i = safe->numCI; i > 0; i--) {
wolfSSL 15:117db924cf7c 146 ContentInfo* ci = safe->CI;
wolfSSL 15:117db924cf7c 147 safe->CI = ci->next;
wolfSSL 15:117db924cf7c 148 XFREE(ci, heap, DYNAMIC_TYPE_PKCS);
wolfSSL 15:117db924cf7c 149 }
wolfSSL 15:117db924cf7c 150 if (safe->data != NULL) {
wolfSSL 15:117db924cf7c 151 XFREE(safe->data, heap, DYNAMIC_TYPE_PKCS);
wolfSSL 15:117db924cf7c 152 }
wolfSSL 15:117db924cf7c 153 XFREE(safe, heap, DYNAMIC_TYPE_PKCS);
wolfSSL 15:117db924cf7c 154
wolfSSL 15:117db924cf7c 155 (void)heap;
wolfSSL 15:117db924cf7c 156 }
wolfSSL 15:117db924cf7c 157
wolfSSL 15:117db924cf7c 158
wolfSSL 15:117db924cf7c 159 void wc_PKCS12_free(WC_PKCS12* pkcs12)
wolfSSL 15:117db924cf7c 160 {
wolfSSL 15:117db924cf7c 161 void* heap;
wolfSSL 15:117db924cf7c 162
wolfSSL 15:117db924cf7c 163 /* if null pointer is passed in do nothing */
wolfSSL 15:117db924cf7c 164 if (pkcs12 == NULL) {
wolfSSL 15:117db924cf7c 165 WOLFSSL_MSG("Trying to free null WC_PKCS12 object");
wolfSSL 15:117db924cf7c 166 return;
wolfSSL 15:117db924cf7c 167 }
wolfSSL 15:117db924cf7c 168
wolfSSL 15:117db924cf7c 169 heap = pkcs12->heap;
wolfSSL 15:117db924cf7c 170 if (pkcs12->safe != NULL) {
wolfSSL 15:117db924cf7c 171 freeSafe(pkcs12->safe, heap);
wolfSSL 15:117db924cf7c 172 }
wolfSSL 15:117db924cf7c 173
wolfSSL 15:117db924cf7c 174 /* free mac data */
wolfSSL 15:117db924cf7c 175 if (pkcs12->signData != NULL) {
wolfSSL 15:117db924cf7c 176 if (pkcs12->signData->digest != NULL) {
wolfSSL 15:117db924cf7c 177 XFREE(pkcs12->signData->digest, heap, DYNAMIC_TYPE_DIGEST);
wolfSSL 15:117db924cf7c 178 pkcs12->signData->digest = NULL;
wolfSSL 15:117db924cf7c 179 }
wolfSSL 15:117db924cf7c 180 if (pkcs12->signData->salt != NULL) {
wolfSSL 15:117db924cf7c 181 XFREE(pkcs12->signData->salt, heap, DYNAMIC_TYPE_SALT);
wolfSSL 15:117db924cf7c 182 pkcs12->signData->salt = NULL;
wolfSSL 15:117db924cf7c 183 }
wolfSSL 15:117db924cf7c 184 XFREE(pkcs12->signData, heap, DYNAMIC_TYPE_PKCS);
wolfSSL 15:117db924cf7c 185 pkcs12->signData = NULL;
wolfSSL 15:117db924cf7c 186 }
wolfSSL 15:117db924cf7c 187
wolfSSL 15:117db924cf7c 188 XFREE(pkcs12, NULL, DYNAMIC_TYPE_PKCS);
wolfSSL 15:117db924cf7c 189 pkcs12 = NULL;
wolfSSL 15:117db924cf7c 190 }
wolfSSL 15:117db924cf7c 191
wolfSSL 15:117db924cf7c 192
wolfSSL 15:117db924cf7c 193 static int GetSafeContent(WC_PKCS12* pkcs12, const byte* input,
wolfSSL 15:117db924cf7c 194 word32* idx, int maxIdx)
wolfSSL 15:117db924cf7c 195 {
wolfSSL 15:117db924cf7c 196 AuthenticatedSafe* safe;
wolfSSL 15:117db924cf7c 197 word32 oid;
wolfSSL 15:117db924cf7c 198 word32 localIdx = *idx;
wolfSSL 15:117db924cf7c 199 int ret;
wolfSSL 15:117db924cf7c 200 int size = 0;
wolfSSL 16:8e0d178b1d1e 201 byte tag;
wolfSSL 15:117db924cf7c 202
wolfSSL 15:117db924cf7c 203 safe = (AuthenticatedSafe*)XMALLOC(sizeof(AuthenticatedSafe), pkcs12->heap,
wolfSSL 15:117db924cf7c 204 DYNAMIC_TYPE_PKCS);
wolfSSL 15:117db924cf7c 205 if (safe == NULL) {
wolfSSL 15:117db924cf7c 206 return MEMORY_E;
wolfSSL 15:117db924cf7c 207 }
wolfSSL 15:117db924cf7c 208 XMEMSET(safe, 0, sizeof(AuthenticatedSafe));
wolfSSL 15:117db924cf7c 209
wolfSSL 15:117db924cf7c 210 ret = GetObjectId(input, &localIdx, &oid, oidIgnoreType, maxIdx);
wolfSSL 15:117db924cf7c 211 if (ret < 0) {
wolfSSL 15:117db924cf7c 212 WOLFSSL_LEAVE("Get object id failed", ret);
wolfSSL 15:117db924cf7c 213 freeSafe(safe, pkcs12->heap);
wolfSSL 15:117db924cf7c 214 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 215 }
wolfSSL 15:117db924cf7c 216
wolfSSL 15:117db924cf7c 217 safe->oid = oid;
wolfSSL 15:117db924cf7c 218 /* check tag, length */
wolfSSL 16:8e0d178b1d1e 219 if (GetASNTag(input, &localIdx, &tag, maxIdx) < 0) {
wolfSSL 16:8e0d178b1d1e 220 freeSafe(safe, pkcs12->heap);
wolfSSL 16:8e0d178b1d1e 221 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 222 }
wolfSSL 16:8e0d178b1d1e 223
wolfSSL 16:8e0d178b1d1e 224 if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) {
wolfSSL 15:117db924cf7c 225 WOLFSSL_MSG("Unexpected tag in PKCS12 DER");
wolfSSL 15:117db924cf7c 226 freeSafe(safe, pkcs12->heap);
wolfSSL 15:117db924cf7c 227 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 228 }
wolfSSL 15:117db924cf7c 229 if ((ret = GetLength(input, &localIdx, &size, maxIdx)) <= 0) {
wolfSSL 15:117db924cf7c 230 freeSafe(safe, pkcs12->heap);
wolfSSL 15:117db924cf7c 231 return ret;
wolfSSL 15:117db924cf7c 232 }
wolfSSL 15:117db924cf7c 233
wolfSSL 15:117db924cf7c 234 switch (oid) {
wolfSSL 15:117db924cf7c 235 case WC_PKCS12_ENCRYPTED_DATA:
wolfSSL 15:117db924cf7c 236 WOLFSSL_MSG("Found PKCS12 OBJECT: ENCRYPTED DATA\n");
wolfSSL 15:117db924cf7c 237 break;
wolfSSL 15:117db924cf7c 238
wolfSSL 15:117db924cf7c 239 case WC_PKCS12_DATA:
wolfSSL 15:117db924cf7c 240 WOLFSSL_MSG("Found PKCS12 OBJECT: DATA");
wolfSSL 15:117db924cf7c 241 /* get octets holding contents */
wolfSSL 16:8e0d178b1d1e 242 if (GetASNTag(input, &localIdx, &tag, maxIdx) < 0) {
wolfSSL 16:8e0d178b1d1e 243 freeSafe(safe, pkcs12->heap);
wolfSSL 16:8e0d178b1d1e 244 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 245 }
wolfSSL 16:8e0d178b1d1e 246
wolfSSL 16:8e0d178b1d1e 247 if (tag != ASN_OCTET_STRING) {
wolfSSL 15:117db924cf7c 248 WOLFSSL_MSG("Wrong tag with content PKCS12 type DATA");
wolfSSL 15:117db924cf7c 249 freeSafe(safe, pkcs12->heap);
wolfSSL 15:117db924cf7c 250 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 251 }
wolfSSL 15:117db924cf7c 252 if ((ret = GetLength(input, &localIdx, &size, maxIdx)) <= 0) {
wolfSSL 15:117db924cf7c 253 freeSafe(safe, pkcs12->heap);
wolfSSL 15:117db924cf7c 254 return ret;
wolfSSL 15:117db924cf7c 255 }
wolfSSL 15:117db924cf7c 256
wolfSSL 15:117db924cf7c 257 break;
wolfSSL 15:117db924cf7c 258 }
wolfSSL 15:117db924cf7c 259
wolfSSL 15:117db924cf7c 260 safe->dataSz = size;
wolfSSL 15:117db924cf7c 261 safe->data = (byte*)XMALLOC(size, pkcs12->heap, DYNAMIC_TYPE_PKCS);
wolfSSL 15:117db924cf7c 262 if (safe->data == NULL) {
wolfSSL 15:117db924cf7c 263 freeSafe(safe, pkcs12->heap);
wolfSSL 15:117db924cf7c 264 return MEMORY_E;
wolfSSL 15:117db924cf7c 265 }
wolfSSL 15:117db924cf7c 266 XMEMCPY(safe->data, input + localIdx, size);
wolfSSL 15:117db924cf7c 267 *idx = localIdx;
wolfSSL 15:117db924cf7c 268
wolfSSL 15:117db924cf7c 269 /* an instance of AuthenticatedSafe is created from
wolfSSL 16:8e0d178b1d1e 270 * ContentInfo's strung together in a SEQUENCE. Here we iterate
wolfSSL 15:117db924cf7c 271 * through the ContentInfo's and add them to our
wolfSSL 15:117db924cf7c 272 * AuthenticatedSafe struct */
wolfSSL 15:117db924cf7c 273 localIdx = 0;
wolfSSL 15:117db924cf7c 274 input = safe->data;
wolfSSL 15:117db924cf7c 275 {
wolfSSL 15:117db924cf7c 276 int CISz;
wolfSSL 15:117db924cf7c 277 ret = GetSequence(input, &localIdx, &CISz, safe->dataSz);
wolfSSL 15:117db924cf7c 278 if (ret < 0) {
wolfSSL 15:117db924cf7c 279 freeSafe(safe, pkcs12->heap);
wolfSSL 15:117db924cf7c 280 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 281 }
wolfSSL 15:117db924cf7c 282 CISz += localIdx;
wolfSSL 15:117db924cf7c 283 while ((int)localIdx < CISz) {
wolfSSL 15:117db924cf7c 284 int curSz = 0;
wolfSSL 15:117db924cf7c 285 word32 curIdx;
wolfSSL 15:117db924cf7c 286 ContentInfo* ci = NULL;
wolfSSL 15:117db924cf7c 287
wolfSSL 15:117db924cf7c 288 #ifdef WOLFSSL_DEBUG_PKCS12
wolfSSL 15:117db924cf7c 289 printf("\t\tlooking for Content Info.... ");
wolfSSL 15:117db924cf7c 290 #endif
wolfSSL 15:117db924cf7c 291
wolfSSL 15:117db924cf7c 292 if ((ret = GetSequence(input, &localIdx, &curSz, safe->dataSz))
wolfSSL 15:117db924cf7c 293 < 0) {
wolfSSL 15:117db924cf7c 294 freeSafe(safe, pkcs12->heap);
wolfSSL 15:117db924cf7c 295 return ret;
wolfSSL 15:117db924cf7c 296 }
wolfSSL 15:117db924cf7c 297
wolfSSL 15:117db924cf7c 298 if (curSz > CISz) {
wolfSSL 15:117db924cf7c 299 /* subset should not be larger than universe */
wolfSSL 15:117db924cf7c 300 freeSafe(safe, pkcs12->heap);
wolfSSL 15:117db924cf7c 301 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 302 }
wolfSSL 15:117db924cf7c 303
wolfSSL 15:117db924cf7c 304 curIdx = localIdx;
wolfSSL 15:117db924cf7c 305 if ((ret = GetObjectId(input, &localIdx, &oid, oidIgnoreType,
wolfSSL 15:117db924cf7c 306 safe->dataSz)) < 0) {
wolfSSL 15:117db924cf7c 307 WOLFSSL_LEAVE("Get object id failed", ret);
wolfSSL 15:117db924cf7c 308 freeSafe(safe, pkcs12->heap);
wolfSSL 15:117db924cf7c 309 return ret;
wolfSSL 15:117db924cf7c 310 }
wolfSSL 15:117db924cf7c 311
wolfSSL 15:117db924cf7c 312 /* create new content info struct ... possible OID sanity check? */
wolfSSL 15:117db924cf7c 313 ci = (ContentInfo*)XMALLOC(sizeof(ContentInfo), pkcs12->heap,
wolfSSL 15:117db924cf7c 314 DYNAMIC_TYPE_PKCS);
wolfSSL 15:117db924cf7c 315 if (ci == NULL) {
wolfSSL 15:117db924cf7c 316 freeSafe(safe, pkcs12->heap);
wolfSSL 15:117db924cf7c 317 return MEMORY_E;
wolfSSL 15:117db924cf7c 318 }
wolfSSL 15:117db924cf7c 319
wolfSSL 15:117db924cf7c 320 ci->type = oid;
wolfSSL 15:117db924cf7c 321 ci->dataSz = curSz - (localIdx-curIdx);
wolfSSL 15:117db924cf7c 322 ci->data = (byte*)input + localIdx;
wolfSSL 15:117db924cf7c 323 localIdx += ci->dataSz;
wolfSSL 15:117db924cf7c 324
wolfSSL 15:117db924cf7c 325 #ifdef WOLFSSL_DEBUG_PKCS12
wolfSSL 15:117db924cf7c 326 switch (oid) {
wolfSSL 15:117db924cf7c 327 case WC_PKCS12_ENCRYPTED_DATA:
wolfSSL 15:117db924cf7c 328 printf("CONTENT INFO: ENCRYPTED DATA, size = %d\n", ci->dataSz);
wolfSSL 15:117db924cf7c 329 break;
wolfSSL 15:117db924cf7c 330
wolfSSL 15:117db924cf7c 331 case WC_PKCS12_DATA:
wolfSSL 15:117db924cf7c 332 printf("CONTENT INFO: DATA, size = %d\n", ci->dataSz);
wolfSSL 15:117db924cf7c 333 break;
wolfSSL 15:117db924cf7c 334 default:
wolfSSL 15:117db924cf7c 335 printf("CONTENT INFO: UNKNOWN, size = %d\n", ci->dataSz);
wolfSSL 15:117db924cf7c 336 }
wolfSSL 15:117db924cf7c 337 #endif
wolfSSL 15:117db924cf7c 338
wolfSSL 15:117db924cf7c 339 /* insert to head of list */
wolfSSL 15:117db924cf7c 340 ci->next = safe->CI;
wolfSSL 15:117db924cf7c 341 safe->CI = ci;
wolfSSL 15:117db924cf7c 342 safe->numCI += 1;
wolfSSL 15:117db924cf7c 343 }
wolfSSL 15:117db924cf7c 344 }
wolfSSL 15:117db924cf7c 345
wolfSSL 15:117db924cf7c 346 pkcs12->safe = safe;
wolfSSL 15:117db924cf7c 347 *idx += localIdx;
wolfSSL 15:117db924cf7c 348
wolfSSL 15:117db924cf7c 349 return ret;
wolfSSL 15:117db924cf7c 350 }
wolfSSL 15:117db924cf7c 351
wolfSSL 15:117db924cf7c 352
wolfSSL 15:117db924cf7c 353 /* optional mac data */
wolfSSL 15:117db924cf7c 354 static int GetSignData(WC_PKCS12* pkcs12, const byte* mem, word32* idx,
wolfSSL 15:117db924cf7c 355 word32 totalSz)
wolfSSL 15:117db924cf7c 356 {
wolfSSL 15:117db924cf7c 357 MacData* mac;
wolfSSL 15:117db924cf7c 358 word32 curIdx = *idx;
wolfSSL 15:117db924cf7c 359 word32 oid = 0;
wolfSSL 15:117db924cf7c 360 int size, ret;
wolfSSL 16:8e0d178b1d1e 361 byte tag;
wolfSSL 15:117db924cf7c 362
wolfSSL 15:117db924cf7c 363 /* Digest Info : Sequence
wolfSSL 15:117db924cf7c 364 * DigestAlgorithmIdentifier
wolfSSL 15:117db924cf7c 365 * Digest
wolfSSL 15:117db924cf7c 366 */
wolfSSL 15:117db924cf7c 367 if ((ret = GetSequence(mem, &curIdx, &size, totalSz)) <= 0) {
wolfSSL 15:117db924cf7c 368 WOLFSSL_MSG("Failed to get PKCS12 sequence");
wolfSSL 15:117db924cf7c 369 return ret;
wolfSSL 15:117db924cf7c 370 }
wolfSSL 15:117db924cf7c 371
wolfSSL 15:117db924cf7c 372 #ifdef WOLFSSL_DEBUG_PKCS12
wolfSSL 15:117db924cf7c 373 printf("\t\tSEQUENCE: DigestInfo size = %d\n", size);
wolfSSL 15:117db924cf7c 374 #endif
wolfSSL 15:117db924cf7c 375
wolfSSL 15:117db924cf7c 376 mac = (MacData*)XMALLOC(sizeof(MacData), pkcs12->heap, DYNAMIC_TYPE_PKCS);
wolfSSL 15:117db924cf7c 377 if (mac == NULL) {
wolfSSL 15:117db924cf7c 378 return MEMORY_E;
wolfSSL 15:117db924cf7c 379 }
wolfSSL 15:117db924cf7c 380 XMEMSET(mac, 0, sizeof(MacData));
wolfSSL 15:117db924cf7c 381
wolfSSL 15:117db924cf7c 382 /* DigestAlgorithmIdentifier */
wolfSSL 15:117db924cf7c 383 if ((ret = GetAlgoId(mem, &curIdx, &oid, oidIgnoreType, totalSz)) < 0) {
wolfSSL 15:117db924cf7c 384 WOLFSSL_MSG("Failed to get PKCS12 sequence");
wolfSSL 15:117db924cf7c 385 XFREE(mac, pkcs12->heap, DYNAMIC_TYPE_PKCS);
wolfSSL 15:117db924cf7c 386 return ret;
wolfSSL 15:117db924cf7c 387 }
wolfSSL 15:117db924cf7c 388 mac->oid = oid;
wolfSSL 15:117db924cf7c 389
wolfSSL 15:117db924cf7c 390 #ifdef WOLFSSL_DEBUG_PKCS12
wolfSSL 15:117db924cf7c 391 printf("\t\tALGO ID = %d\n", oid);
wolfSSL 15:117db924cf7c 392 #endif
wolfSSL 15:117db924cf7c 393
wolfSSL 15:117db924cf7c 394 /* Digest: should be octet type holding digest */
wolfSSL 16:8e0d178b1d1e 395 if (GetASNTag(mem, &curIdx, &tag, totalSz) < 0) {
wolfSSL 16:8e0d178b1d1e 396 XFREE(mac, pkcs12->heap, DYNAMIC_TYPE_PKCS);
wolfSSL 16:8e0d178b1d1e 397 return ASN_PARSE_E;
wolfSSL 16:8e0d178b1d1e 398 }
wolfSSL 16:8e0d178b1d1e 399
wolfSSL 16:8e0d178b1d1e 400 if (tag != ASN_OCTET_STRING) {
wolfSSL 15:117db924cf7c 401 WOLFSSL_MSG("Failed to get digest");
wolfSSL 15:117db924cf7c 402 XFREE(mac, pkcs12->heap, DYNAMIC_TYPE_PKCS);
wolfSSL 15:117db924cf7c 403 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 404 }
wolfSSL 15:117db924cf7c 405
wolfSSL 15:117db924cf7c 406 if ((ret = GetLength(mem, &curIdx, &size, totalSz)) <= 0) {
wolfSSL 15:117db924cf7c 407 XFREE(mac, pkcs12->heap, DYNAMIC_TYPE_PKCS);
wolfSSL 15:117db924cf7c 408 return ret;
wolfSSL 15:117db924cf7c 409 }
wolfSSL 15:117db924cf7c 410 mac->digestSz = size;
wolfSSL 15:117db924cf7c 411 mac->digest = (byte*)XMALLOC(mac->digestSz, pkcs12->heap,
wolfSSL 15:117db924cf7c 412 DYNAMIC_TYPE_DIGEST);
wolfSSL 15:117db924cf7c 413 if (mac->digest == NULL || mac->digestSz + curIdx > totalSz) {
wolfSSL 15:117db924cf7c 414 ERROR_OUT(MEMORY_E, exit_gsd);
wolfSSL 15:117db924cf7c 415 }
wolfSSL 15:117db924cf7c 416 XMEMCPY(mac->digest, mem + curIdx, mac->digestSz);
wolfSSL 15:117db924cf7c 417
wolfSSL 15:117db924cf7c 418 #ifdef WOLFSSL_DEBUG_PKCS12
wolfSSL 15:117db924cf7c 419 {
wolfSSL 15:117db924cf7c 420 byte* p;
wolfSSL 15:117db924cf7c 421 for (printf("\t\tDigest = "), p = (byte*)mem+curIdx;
wolfSSL 15:117db924cf7c 422 p < (byte*)mem + curIdx + mac->digestSz;
wolfSSL 15:117db924cf7c 423 printf("%02X", *p), p++);
wolfSSL 15:117db924cf7c 424 printf(" : size = %d\n", mac->digestSz);
wolfSSL 15:117db924cf7c 425 }
wolfSSL 15:117db924cf7c 426 #endif
wolfSSL 15:117db924cf7c 427
wolfSSL 15:117db924cf7c 428 curIdx += mac->digestSz;
wolfSSL 15:117db924cf7c 429
wolfSSL 15:117db924cf7c 430 /* get salt, should be octet string */
wolfSSL 16:8e0d178b1d1e 431 if (GetASNTag(mem, &curIdx, &tag, totalSz) < 0) {
wolfSSL 16:8e0d178b1d1e 432 ERROR_OUT(ASN_PARSE_E, exit_gsd);
wolfSSL 16:8e0d178b1d1e 433 }
wolfSSL 16:8e0d178b1d1e 434
wolfSSL 16:8e0d178b1d1e 435 if (tag != ASN_OCTET_STRING) {
wolfSSL 15:117db924cf7c 436 WOLFSSL_MSG("Failed to get salt");
wolfSSL 15:117db924cf7c 437 ERROR_OUT(ASN_PARSE_E, exit_gsd);
wolfSSL 15:117db924cf7c 438 }
wolfSSL 15:117db924cf7c 439
wolfSSL 16:8e0d178b1d1e 440 if ((ret = GetLength(mem, &curIdx, &size, totalSz)) < 0) {
wolfSSL 15:117db924cf7c 441 goto exit_gsd;
wolfSSL 15:117db924cf7c 442 }
wolfSSL 15:117db924cf7c 443 mac->saltSz = size;
wolfSSL 15:117db924cf7c 444 mac->salt = (byte*)XMALLOC(mac->saltSz, pkcs12->heap, DYNAMIC_TYPE_SALT);
wolfSSL 15:117db924cf7c 445 if (mac->salt == NULL || mac->saltSz + curIdx > totalSz) {
wolfSSL 15:117db924cf7c 446 ERROR_OUT(MEMORY_E, exit_gsd);
wolfSSL 15:117db924cf7c 447 }
wolfSSL 15:117db924cf7c 448 XMEMCPY(mac->salt, mem + curIdx, mac->saltSz);
wolfSSL 15:117db924cf7c 449
wolfSSL 15:117db924cf7c 450 #ifdef WOLFSSL_DEBUG_PKCS12
wolfSSL 15:117db924cf7c 451 {
wolfSSL 15:117db924cf7c 452 byte* p;
wolfSSL 15:117db924cf7c 453 for (printf("\t\tSalt = "), p = (byte*)mem + curIdx;
wolfSSL 15:117db924cf7c 454 p < (byte*)mem + curIdx + mac->saltSz;
wolfSSL 15:117db924cf7c 455 printf("%02X", *p), p++);
wolfSSL 15:117db924cf7c 456 printf(" : size = %d\n", mac->saltSz);
wolfSSL 15:117db924cf7c 457 }
wolfSSL 15:117db924cf7c 458 #endif
wolfSSL 15:117db924cf7c 459
wolfSSL 15:117db924cf7c 460 curIdx += mac->saltSz;
wolfSSL 15:117db924cf7c 461
wolfSSL 15:117db924cf7c 462 /* check for MAC iterations, default to 1 */
wolfSSL 15:117db924cf7c 463 mac->itt = WC_PKCS12_MAC_DEFAULT;
wolfSSL 15:117db924cf7c 464 if (curIdx < totalSz) {
wolfSSL 15:117db924cf7c 465 int number = 0;
wolfSSL 15:117db924cf7c 466 if ((ret = GetShortInt(mem, &curIdx, &number, totalSz)) >= 0) {
wolfSSL 15:117db924cf7c 467 /* found a iteration value */
wolfSSL 15:117db924cf7c 468 mac->itt = number;
wolfSSL 15:117db924cf7c 469 }
wolfSSL 15:117db924cf7c 470 }
wolfSSL 15:117db924cf7c 471
wolfSSL 15:117db924cf7c 472 #ifdef WOLFSSL_DEBUG_PKCS12
wolfSSL 16:8e0d178b1d1e 473 printf("\t\tITERATIONS : %d\n", mac->itt);
wolfSSL 15:117db924cf7c 474 #endif
wolfSSL 15:117db924cf7c 475
wolfSSL 15:117db924cf7c 476 *idx = curIdx;
wolfSSL 15:117db924cf7c 477 pkcs12->signData = mac;
wolfSSL 15:117db924cf7c 478 ret = 0; /* success */
wolfSSL 15:117db924cf7c 479
wolfSSL 15:117db924cf7c 480 exit_gsd:
wolfSSL 15:117db924cf7c 481
wolfSSL 15:117db924cf7c 482 /* failure cleanup */
wolfSSL 15:117db924cf7c 483 if (ret != 0) {
wolfSSL 15:117db924cf7c 484 if (mac) {
wolfSSL 15:117db924cf7c 485 if (mac->digest)
wolfSSL 15:117db924cf7c 486 XFREE(mac->digest, pkcs12->heap, DYNAMIC_TYPE_DIGEST);
wolfSSL 15:117db924cf7c 487 XFREE(mac, pkcs12->heap, DYNAMIC_TYPE_PKCS);
wolfSSL 15:117db924cf7c 488 }
wolfSSL 15:117db924cf7c 489 }
wolfSSL 15:117db924cf7c 490
wolfSSL 15:117db924cf7c 491 return ret;
wolfSSL 15:117db924cf7c 492 }
wolfSSL 15:117db924cf7c 493
wolfSSL 15:117db924cf7c 494
wolfSSL 15:117db924cf7c 495 /* expects PKCS12 signData to be set up with OID
wolfSSL 15:117db924cf7c 496 *
wolfSSL 15:117db924cf7c 497 * returns the size of mac created on success. A negative value will be returned
wolfSSL 15:117db924cf7c 498 * in the case that an error happened.
wolfSSL 15:117db924cf7c 499 */
wolfSSL 15:117db924cf7c 500 static int wc_PKCS12_create_mac(WC_PKCS12* pkcs12, byte* data, word32 dataSz,
wolfSSL 15:117db924cf7c 501 const byte* psw, word32 pswSz, byte* out, word32 outSz)
wolfSSL 15:117db924cf7c 502 {
wolfSSL 15:117db924cf7c 503 Hmac hmac;
wolfSSL 15:117db924cf7c 504 MacData* mac;
wolfSSL 15:117db924cf7c 505 int ret, kLen;
wolfSSL 15:117db924cf7c 506 enum wc_HashType hashT;
wolfSSL 15:117db924cf7c 507 int idx = 0;
wolfSSL 15:117db924cf7c 508 int id = 3; /* value from RFC 7292 indicating key is used for MAC */
wolfSSL 15:117db924cf7c 509 word32 i;
wolfSSL 15:117db924cf7c 510 byte unicodePasswd[MAX_UNICODE_SZ];
wolfSSL 15:117db924cf7c 511 byte key[MAX_KEY_SIZE];
wolfSSL 15:117db924cf7c 512
wolfSSL 15:117db924cf7c 513 if (pkcs12 == NULL || pkcs12->signData == NULL || data == NULL ||
wolfSSL 15:117db924cf7c 514 out == NULL) {
wolfSSL 15:117db924cf7c 515 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 516 }
wolfSSL 15:117db924cf7c 517
wolfSSL 15:117db924cf7c 518 mac = pkcs12->signData;
wolfSSL 15:117db924cf7c 519
wolfSSL 15:117db924cf7c 520 /* unicode set up from asn.c */
wolfSSL 15:117db924cf7c 521 if ((pswSz * 2 + 2) > (int)sizeof(unicodePasswd)) {
wolfSSL 15:117db924cf7c 522 WOLFSSL_MSG("PKCS12 max unicode size too small");
wolfSSL 15:117db924cf7c 523 return UNICODE_SIZE_E;
wolfSSL 15:117db924cf7c 524 }
wolfSSL 15:117db924cf7c 525
wolfSSL 15:117db924cf7c 526 for (i = 0; i < pswSz; i++) {
wolfSSL 15:117db924cf7c 527 unicodePasswd[idx++] = 0x00;
wolfSSL 15:117db924cf7c 528 unicodePasswd[idx++] = (byte)psw[i];
wolfSSL 15:117db924cf7c 529 }
wolfSSL 15:117db924cf7c 530 /* add trailing NULL */
wolfSSL 15:117db924cf7c 531 unicodePasswd[idx++] = 0x00;
wolfSSL 15:117db924cf7c 532 unicodePasswd[idx++] = 0x00;
wolfSSL 15:117db924cf7c 533
wolfSSL 15:117db924cf7c 534 /* get hash type used and resulting size of HMAC key */
wolfSSL 15:117db924cf7c 535 hashT = wc_OidGetHash(mac->oid);
wolfSSL 15:117db924cf7c 536 if (hashT == WC_HASH_TYPE_NONE) {
wolfSSL 15:117db924cf7c 537 WOLFSSL_MSG("Unsupported hash used");
wolfSSL 15:117db924cf7c 538 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 539 }
wolfSSL 15:117db924cf7c 540 kLen = wc_HashGetDigestSize(hashT);
wolfSSL 15:117db924cf7c 541
wolfSSL 15:117db924cf7c 542 /* check out buffer is large enough */
wolfSSL 15:117db924cf7c 543 if (kLen < 0 || outSz < (word32)kLen) {
wolfSSL 15:117db924cf7c 544 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 545 }
wolfSSL 15:117db924cf7c 546
wolfSSL 15:117db924cf7c 547 /* idx contains size of unicodePasswd */
wolfSSL 15:117db924cf7c 548 if ((ret = wc_PKCS12_PBKDF_ex(key, unicodePasswd, idx, mac->salt,
wolfSSL 15:117db924cf7c 549 mac->saltSz, mac->itt, kLen, (int)hashT, id, pkcs12->heap)) < 0) {
wolfSSL 15:117db924cf7c 550 return ret;
wolfSSL 15:117db924cf7c 551 }
wolfSSL 15:117db924cf7c 552
wolfSSL 15:117db924cf7c 553 /* now that key has been created use it to get HMAC hash on data */
wolfSSL 15:117db924cf7c 554 if ((ret = wc_HmacInit(&hmac, pkcs12->heap, INVALID_DEVID)) != 0) {
wolfSSL 15:117db924cf7c 555 return ret;
wolfSSL 15:117db924cf7c 556 }
wolfSSL 15:117db924cf7c 557 ret = wc_HmacSetKey(&hmac, (int)hashT, key, kLen);
wolfSSL 15:117db924cf7c 558 if (ret == 0)
wolfSSL 15:117db924cf7c 559 ret = wc_HmacUpdate(&hmac, data, dataSz);
wolfSSL 15:117db924cf7c 560 if (ret == 0)
wolfSSL 15:117db924cf7c 561 ret = wc_HmacFinal(&hmac, out);
wolfSSL 15:117db924cf7c 562 wc_HmacFree(&hmac);
wolfSSL 15:117db924cf7c 563
wolfSSL 15:117db924cf7c 564 if (ret != 0)
wolfSSL 15:117db924cf7c 565 return ret;
wolfSSL 15:117db924cf7c 566
wolfSSL 15:117db924cf7c 567 return kLen; /* same as digest size */
wolfSSL 15:117db924cf7c 568 }
wolfSSL 15:117db924cf7c 569
wolfSSL 15:117db924cf7c 570
wolfSSL 15:117db924cf7c 571 /* check mac on pkcs12, pkcs12->mac has been sanity checked before entering *
wolfSSL 15:117db924cf7c 572 * returns the result of comparison, success is 0 */
wolfSSL 15:117db924cf7c 573 static int wc_PKCS12_verify(WC_PKCS12* pkcs12, byte* data, word32 dataSz,
wolfSSL 15:117db924cf7c 574 const byte* psw, word32 pswSz)
wolfSSL 15:117db924cf7c 575 {
wolfSSL 15:117db924cf7c 576 MacData* mac;
wolfSSL 15:117db924cf7c 577 int ret;
wolfSSL 15:117db924cf7c 578 byte digest[WC_MAX_DIGEST_SIZE];
wolfSSL 15:117db924cf7c 579
wolfSSL 15:117db924cf7c 580 if (pkcs12 == NULL || pkcs12->signData == NULL || data == NULL) {
wolfSSL 15:117db924cf7c 581 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 582 }
wolfSSL 15:117db924cf7c 583
wolfSSL 15:117db924cf7c 584 mac = pkcs12->signData;
wolfSSL 15:117db924cf7c 585
wolfSSL 15:117db924cf7c 586 #ifdef WOLFSSL_DEBUG_PKCS12
wolfSSL 15:117db924cf7c 587 printf("Verifying MAC with OID = %d\n", mac->oid);
wolfSSL 15:117db924cf7c 588 #endif
wolfSSL 15:117db924cf7c 589
wolfSSL 15:117db924cf7c 590 /* check if this builds digest size is too small */
wolfSSL 15:117db924cf7c 591 if (mac->digestSz > WC_MAX_DIGEST_SIZE) {
wolfSSL 15:117db924cf7c 592 WOLFSSL_MSG("PKCS12 max digest size too small");
wolfSSL 15:117db924cf7c 593 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 594 }
wolfSSL 15:117db924cf7c 595
wolfSSL 15:117db924cf7c 596 if ((ret = wc_PKCS12_create_mac(pkcs12, data, dataSz, psw, pswSz,
wolfSSL 15:117db924cf7c 597 digest, WC_MAX_DIGEST_SIZE)) < 0) {
wolfSSL 15:117db924cf7c 598 return ret;
wolfSSL 15:117db924cf7c 599 }
wolfSSL 15:117db924cf7c 600
wolfSSL 15:117db924cf7c 601 #ifdef WOLFSSL_DEBUG_PKCS12
wolfSSL 15:117db924cf7c 602 {
wolfSSL 15:117db924cf7c 603 byte* p;
wolfSSL 15:117db924cf7c 604 for (printf("\t\tHash = "), p = (byte*)digest;
wolfSSL 15:117db924cf7c 605 p < (byte*)digest + mac->digestSz;
wolfSSL 15:117db924cf7c 606 printf("%02X", *p), p++);
wolfSSL 15:117db924cf7c 607 printf(" : size = %d\n", mac->digestSz);
wolfSSL 15:117db924cf7c 608 }
wolfSSL 15:117db924cf7c 609 #endif
wolfSSL 15:117db924cf7c 610
wolfSSL 15:117db924cf7c 611 return XMEMCMP(digest, mac->digest, mac->digestSz);
wolfSSL 15:117db924cf7c 612 }
wolfSSL 15:117db924cf7c 613
wolfSSL 15:117db924cf7c 614
wolfSSL 15:117db924cf7c 615 /* Convert DER format stored in der buffer to WC_PKCS12 struct
wolfSSL 16:8e0d178b1d1e 616 * Puts the raw contents of Content Info into structure without completely
wolfSSL 15:117db924cf7c 617 * parsing or decoding.
wolfSSL 15:117db924cf7c 618 * der : pointer to der buffer holding PKCS12
wolfSSL 15:117db924cf7c 619 * derSz : size of der buffer
wolfSSL 15:117db924cf7c 620 * pkcs12 : non-null pkcs12 pointer
wolfSSL 15:117db924cf7c 621 * return 0 on success and negative on failure.
wolfSSL 15:117db924cf7c 622 */
wolfSSL 15:117db924cf7c 623 int wc_d2i_PKCS12(const byte* der, word32 derSz, WC_PKCS12* pkcs12)
wolfSSL 15:117db924cf7c 624 {
wolfSSL 15:117db924cf7c 625 word32 idx = 0;
wolfSSL 15:117db924cf7c 626 word32 totalSz = 0;
wolfSSL 15:117db924cf7c 627 int ret;
wolfSSL 15:117db924cf7c 628 int size = 0;
wolfSSL 15:117db924cf7c 629 int version = 0;
wolfSSL 15:117db924cf7c 630
wolfSSL 15:117db924cf7c 631 WOLFSSL_ENTER("wolfSSL_d2i_PKCS12_bio");
wolfSSL 15:117db924cf7c 632
wolfSSL 15:117db924cf7c 633 if (der == NULL || pkcs12 == NULL) {
wolfSSL 15:117db924cf7c 634 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 635 }
wolfSSL 15:117db924cf7c 636
wolfSSL 15:117db924cf7c 637 totalSz = derSz;
wolfSSL 15:117db924cf7c 638 if ((ret = GetSequence(der, &idx, &size, totalSz)) <= 0) {
wolfSSL 15:117db924cf7c 639 WOLFSSL_MSG("Failed to get PKCS12 sequence");
wolfSSL 15:117db924cf7c 640 return ret;
wolfSSL 15:117db924cf7c 641 }
wolfSSL 15:117db924cf7c 642
wolfSSL 15:117db924cf7c 643 /* get version */
wolfSSL 15:117db924cf7c 644 if ((ret = GetMyVersion(der, &idx, &version, totalSz)) < 0) {
wolfSSL 15:117db924cf7c 645 return ret;
wolfSSL 15:117db924cf7c 646 }
wolfSSL 15:117db924cf7c 647
wolfSSL 15:117db924cf7c 648 #ifdef WOLFSSL_DEBUG_PKCS12
wolfSSL 15:117db924cf7c 649 printf("\nBEGIN: PKCS12 size = %d\n", totalSz);
wolfSSL 15:117db924cf7c 650 printf("version = %d\n", version);
wolfSSL 15:117db924cf7c 651 #endif
wolfSSL 15:117db924cf7c 652
wolfSSL 16:8e0d178b1d1e 653 if (version != WC_PKCS12_VERSION_DEFAULT) {
wolfSSL 15:117db924cf7c 654 WOLFSSL_MSG("PKCS12 unsupported version!");
wolfSSL 15:117db924cf7c 655 return ASN_VERSION_E;
wolfSSL 15:117db924cf7c 656 }
wolfSSL 15:117db924cf7c 657
wolfSSL 15:117db924cf7c 658 if ((ret = GetSequence(der, &idx, &size, totalSz)) < 0) {
wolfSSL 15:117db924cf7c 659 return ret;
wolfSSL 15:117db924cf7c 660 }
wolfSSL 15:117db924cf7c 661
wolfSSL 15:117db924cf7c 662 #ifdef WOLFSSL_DEBUG_PKCS12
wolfSSL 15:117db924cf7c 663 printf("\tSEQUENCE: AuthenticatedSafe size = %d\n", size);
wolfSSL 15:117db924cf7c 664 #endif
wolfSSL 15:117db924cf7c 665
wolfSSL 15:117db924cf7c 666 if ((ret = GetSafeContent(pkcs12, der, &idx, size + idx)) < 0) {
wolfSSL 15:117db924cf7c 667 WOLFSSL_MSG("GetSafeContent error");
wolfSSL 15:117db924cf7c 668 return ret;
wolfSSL 15:117db924cf7c 669 }
wolfSSL 15:117db924cf7c 670
wolfSSL 15:117db924cf7c 671 /* if more buffer left check for MAC data */
wolfSSL 15:117db924cf7c 672 if (idx < totalSz) {
wolfSSL 15:117db924cf7c 673 if ((ret = GetSequence(der, &idx, &size, totalSz)) < 0) {
wolfSSL 15:117db924cf7c 674 WOLFSSL_MSG("Ignoring unknown data at end of PKCS12 DER buffer");
wolfSSL 15:117db924cf7c 675 }
wolfSSL 15:117db924cf7c 676 else {
wolfSSL 15:117db924cf7c 677 #ifdef WOLFSSL_DEBUG_PKCS12
wolfSSL 15:117db924cf7c 678 printf("\tSEQUENCE: Signature size = %d\n", size);
wolfSSL 15:117db924cf7c 679 #endif
wolfSSL 15:117db924cf7c 680
wolfSSL 15:117db924cf7c 681 if ((ret = GetSignData(pkcs12, der, &idx, totalSz)) < 0) {
wolfSSL 15:117db924cf7c 682 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 683 }
wolfSSL 15:117db924cf7c 684 }
wolfSSL 15:117db924cf7c 685 }
wolfSSL 15:117db924cf7c 686
wolfSSL 15:117db924cf7c 687 #ifdef WOLFSSL_DEBUG_PKCS12
wolfSSL 15:117db924cf7c 688 printf("END: PKCS12\n");
wolfSSL 15:117db924cf7c 689 #endif
wolfSSL 15:117db924cf7c 690
wolfSSL 15:117db924cf7c 691 return ret;
wolfSSL 15:117db924cf7c 692 }
wolfSSL 15:117db924cf7c 693
wolfSSL 16:8e0d178b1d1e 694 /* Convert WC_PKCS12 struct to allocated DER buffer.
wolfSSL 16:8e0d178b1d1e 695 * pkcs12 : non-null pkcs12 pointer
wolfSSL 16:8e0d178b1d1e 696 * der : pointer-pointer to der buffer. If NULL space will be
wolfSSL 16:8e0d178b1d1e 697 * allocated for der, which must be freed by application.
wolfSSL 16:8e0d178b1d1e 698 * derSz : size of buffer passed in when der is not NULL. NULL arg disables
wolfSSL 16:8e0d178b1d1e 699 * sanity checks on buffer read/writes. Max size gets set to derSz when
wolfSSL 16:8e0d178b1d1e 700 * the "der" buffer passed in is NULL and LENGTH_ONLY_E is returned.
wolfSSL 16:8e0d178b1d1e 701 * return size of DER on success and negative on failure.
wolfSSL 16:8e0d178b1d1e 702 */
wolfSSL 16:8e0d178b1d1e 703 int wc_i2d_PKCS12(WC_PKCS12* pkcs12, byte** der, int* derSz)
wolfSSL 16:8e0d178b1d1e 704 {
wolfSSL 16:8e0d178b1d1e 705 int ret = 0;
wolfSSL 16:8e0d178b1d1e 706 word32 seqSz = 0, verSz = 0, totalSz = 0, idx = 0, sdBufSz = 0;
wolfSSL 16:8e0d178b1d1e 707 byte *buf = NULL;
wolfSSL 16:8e0d178b1d1e 708 byte ver[MAX_VERSION_SZ];
wolfSSL 16:8e0d178b1d1e 709 byte seq[MAX_SEQ_SZ];
wolfSSL 16:8e0d178b1d1e 710 byte *sdBuf = NULL;
wolfSSL 16:8e0d178b1d1e 711
wolfSSL 16:8e0d178b1d1e 712 if ((pkcs12 == NULL) || (pkcs12->safe == NULL) ||
wolfSSL 16:8e0d178b1d1e 713 (der == NULL && derSz == NULL)) {
wolfSSL 16:8e0d178b1d1e 714 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 715 }
wolfSSL 16:8e0d178b1d1e 716
wolfSSL 16:8e0d178b1d1e 717 /* Create the MAC portion */
wolfSSL 16:8e0d178b1d1e 718 if (pkcs12->signData != NULL) {
wolfSSL 16:8e0d178b1d1e 719 MacData *mac = (MacData*)pkcs12->signData;
wolfSSL 16:8e0d178b1d1e 720 word32 innerSz = 0;
wolfSSL 16:8e0d178b1d1e 721 word32 outerSz = 0;
wolfSSL 16:8e0d178b1d1e 722
wolfSSL 16:8e0d178b1d1e 723 /* get exact size */
wolfSSL 16:8e0d178b1d1e 724 {
wolfSSL 16:8e0d178b1d1e 725 byte ASNLENGTH[MAX_LENGTH_SZ];
wolfSSL 16:8e0d178b1d1e 726 byte ASNSHORT[MAX_SHORT_SZ];
wolfSSL 16:8e0d178b1d1e 727 byte ASNALGO[MAX_ALGO_SZ];
wolfSSL 16:8e0d178b1d1e 728 word32 tmpIdx = 0;
wolfSSL 16:8e0d178b1d1e 729
wolfSSL 16:8e0d178b1d1e 730 /* algo id */
wolfSSL 16:8e0d178b1d1e 731 innerSz += SetAlgoID(mac->oid, ASNALGO, oidHashType, 0);
wolfSSL 16:8e0d178b1d1e 732
wolfSSL 16:8e0d178b1d1e 733 /* Octet string holding digest */
wolfSSL 16:8e0d178b1d1e 734 innerSz += ASN_TAG_SZ;
wolfSSL 16:8e0d178b1d1e 735 innerSz += SetLength(mac->digestSz, ASNLENGTH);
wolfSSL 16:8e0d178b1d1e 736 innerSz += mac->digestSz;
wolfSSL 16:8e0d178b1d1e 737
wolfSSL 16:8e0d178b1d1e 738 /* salt */
wolfSSL 16:8e0d178b1d1e 739 outerSz += ASN_TAG_SZ;
wolfSSL 16:8e0d178b1d1e 740 outerSz += SetLength(mac->saltSz, ASNLENGTH);
wolfSSL 16:8e0d178b1d1e 741 outerSz += mac->saltSz;
wolfSSL 16:8e0d178b1d1e 742
wolfSSL 16:8e0d178b1d1e 743 /* MAC iterations */
wolfSSL 16:8e0d178b1d1e 744 outerSz += SetShortInt(ASNSHORT, &tmpIdx, mac->itt, MAX_SHORT_SZ);
wolfSSL 16:8e0d178b1d1e 745
wolfSSL 16:8e0d178b1d1e 746 /* sequence of inner data */
wolfSSL 16:8e0d178b1d1e 747 outerSz += SetSequence(innerSz, seq);
wolfSSL 16:8e0d178b1d1e 748 outerSz += innerSz;
wolfSSL 16:8e0d178b1d1e 749 }
wolfSSL 16:8e0d178b1d1e 750 sdBufSz = outerSz + SetSequence(outerSz, seq);
wolfSSL 16:8e0d178b1d1e 751 sdBuf = (byte*)XMALLOC(sdBufSz, pkcs12->heap, DYNAMIC_TYPE_PKCS);
wolfSSL 16:8e0d178b1d1e 752 if (sdBuf == NULL) {
wolfSSL 16:8e0d178b1d1e 753 ret = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 754 }
wolfSSL 16:8e0d178b1d1e 755
wolfSSL 16:8e0d178b1d1e 756 if (ret == 0) {
wolfSSL 16:8e0d178b1d1e 757 idx += SetSequence(outerSz, sdBuf);
wolfSSL 16:8e0d178b1d1e 758 idx += SetSequence(innerSz, &sdBuf[idx]);
wolfSSL 16:8e0d178b1d1e 759
wolfSSL 16:8e0d178b1d1e 760 /* Set Algorithm Identifier */
wolfSSL 16:8e0d178b1d1e 761 {
wolfSSL 16:8e0d178b1d1e 762 word32 algoIdSz;
wolfSSL 16:8e0d178b1d1e 763
wolfSSL 16:8e0d178b1d1e 764 algoIdSz = SetAlgoID(mac->oid, &sdBuf[idx], oidHashType, 0);
wolfSSL 16:8e0d178b1d1e 765 if (algoIdSz == 0) {
wolfSSL 16:8e0d178b1d1e 766 ret = ALGO_ID_E;
wolfSSL 16:8e0d178b1d1e 767 }
wolfSSL 16:8e0d178b1d1e 768 else {
wolfSSL 16:8e0d178b1d1e 769 idx += algoIdSz;
wolfSSL 16:8e0d178b1d1e 770 }
wolfSSL 16:8e0d178b1d1e 771 }
wolfSSL 16:8e0d178b1d1e 772 }
wolfSSL 16:8e0d178b1d1e 773
wolfSSL 16:8e0d178b1d1e 774 if (ret == 0) {
wolfSSL 16:8e0d178b1d1e 775
wolfSSL 16:8e0d178b1d1e 776
wolfSSL 16:8e0d178b1d1e 777 /* Octet string holding digest */
wolfSSL 16:8e0d178b1d1e 778 idx += SetOctetString(mac->digestSz, &sdBuf[idx]);
wolfSSL 16:8e0d178b1d1e 779 XMEMCPY(&sdBuf[idx], mac->digest, mac->digestSz);
wolfSSL 16:8e0d178b1d1e 780 idx += mac->digestSz;
wolfSSL 16:8e0d178b1d1e 781
wolfSSL 16:8e0d178b1d1e 782 /* Set salt */
wolfSSL 16:8e0d178b1d1e 783 idx += SetOctetString(mac->saltSz, &sdBuf[idx]);
wolfSSL 16:8e0d178b1d1e 784 XMEMCPY(&sdBuf[idx], mac->salt, mac->saltSz);
wolfSSL 16:8e0d178b1d1e 785 idx += mac->saltSz;
wolfSSL 16:8e0d178b1d1e 786
wolfSSL 16:8e0d178b1d1e 787 /* MAC iterations */
wolfSSL 16:8e0d178b1d1e 788 {
wolfSSL 16:8e0d178b1d1e 789 int tmpSz;
wolfSSL 16:8e0d178b1d1e 790 word32 tmpIdx = 0;
wolfSSL 16:8e0d178b1d1e 791 byte ar[MAX_SHORT_SZ];
wolfSSL 16:8e0d178b1d1e 792 tmpSz = SetShortInt(ar, &tmpIdx, mac->itt, MAX_SHORT_SZ);
wolfSSL 16:8e0d178b1d1e 793 if (tmpSz < 0) {
wolfSSL 16:8e0d178b1d1e 794 ret = tmpSz;
wolfSSL 16:8e0d178b1d1e 795 }
wolfSSL 16:8e0d178b1d1e 796 else {
wolfSSL 16:8e0d178b1d1e 797 XMEMCPY(&sdBuf[idx], ar, tmpSz);
wolfSSL 16:8e0d178b1d1e 798 }
wolfSSL 16:8e0d178b1d1e 799 }
wolfSSL 16:8e0d178b1d1e 800 totalSz += sdBufSz;
wolfSSL 16:8e0d178b1d1e 801 }
wolfSSL 16:8e0d178b1d1e 802 }
wolfSSL 16:8e0d178b1d1e 803
wolfSSL 16:8e0d178b1d1e 804 /* Calculate size of der */
wolfSSL 16:8e0d178b1d1e 805 if (ret == 0) {
wolfSSL 16:8e0d178b1d1e 806 totalSz += pkcs12->safe->dataSz;
wolfSSL 16:8e0d178b1d1e 807
wolfSSL 16:8e0d178b1d1e 808 totalSz += 4; /* Octet string */
wolfSSL 16:8e0d178b1d1e 809
wolfSSL 16:8e0d178b1d1e 810 totalSz += 4; /* Element */
wolfSSL 16:8e0d178b1d1e 811
wolfSSL 16:8e0d178b1d1e 812 totalSz += 2 + sizeof(WC_PKCS12_DATA_OID);
wolfSSL 16:8e0d178b1d1e 813
wolfSSL 16:8e0d178b1d1e 814 totalSz += 4; /* Seq */
wolfSSL 16:8e0d178b1d1e 815
wolfSSL 16:8e0d178b1d1e 816 ret = SetMyVersion(WC_PKCS12_VERSION_DEFAULT, ver, FALSE);
wolfSSL 16:8e0d178b1d1e 817 if (ret > 0) {
wolfSSL 16:8e0d178b1d1e 818 verSz = (word32)ret;
wolfSSL 16:8e0d178b1d1e 819 ret = 0; /* value larger than 0 is success */
wolfSSL 16:8e0d178b1d1e 820 totalSz += verSz;
wolfSSL 16:8e0d178b1d1e 821
wolfSSL 16:8e0d178b1d1e 822 seqSz = SetSequence(totalSz, seq);
wolfSSL 16:8e0d178b1d1e 823 totalSz += seqSz;
wolfSSL 16:8e0d178b1d1e 824
wolfSSL 16:8e0d178b1d1e 825 /* check if getting length only */
wolfSSL 16:8e0d178b1d1e 826 if (der == NULL && derSz != NULL) {
wolfSSL 16:8e0d178b1d1e 827 *derSz = totalSz;
wolfSSL 16:8e0d178b1d1e 828 XFREE(sdBuf, pkcs12->heap, DYNAMIC_TYPE_PKCS);
wolfSSL 16:8e0d178b1d1e 829 return LENGTH_ONLY_E;
wolfSSL 16:8e0d178b1d1e 830 }
wolfSSL 16:8e0d178b1d1e 831
wolfSSL 16:8e0d178b1d1e 832 if (*der == NULL) {
wolfSSL 16:8e0d178b1d1e 833 /* Allocate if requested */
wolfSSL 16:8e0d178b1d1e 834 buf = (byte*)XMALLOC(totalSz, NULL, DYNAMIC_TYPE_PKCS);
wolfSSL 16:8e0d178b1d1e 835 }
wolfSSL 16:8e0d178b1d1e 836 else {
wolfSSL 16:8e0d178b1d1e 837 buf = *der;
wolfSSL 16:8e0d178b1d1e 838
wolfSSL 16:8e0d178b1d1e 839 /* sanity check on buffer size if passed in */
wolfSSL 16:8e0d178b1d1e 840 if (derSz != NULL) {
wolfSSL 16:8e0d178b1d1e 841 if (*derSz < (int)totalSz) {
wolfSSL 16:8e0d178b1d1e 842 WOLFSSL_MSG("Buffer passed in is too small");
wolfSSL 16:8e0d178b1d1e 843 ret = BUFFER_E;
wolfSSL 16:8e0d178b1d1e 844 }
wolfSSL 16:8e0d178b1d1e 845 }
wolfSSL 16:8e0d178b1d1e 846 }
wolfSSL 16:8e0d178b1d1e 847 }
wolfSSL 16:8e0d178b1d1e 848 }
wolfSSL 16:8e0d178b1d1e 849
wolfSSL 16:8e0d178b1d1e 850 if (buf == NULL) {
wolfSSL 16:8e0d178b1d1e 851 ret = MEMORY_E;
wolfSSL 16:8e0d178b1d1e 852 }
wolfSSL 16:8e0d178b1d1e 853
wolfSSL 16:8e0d178b1d1e 854 if (ret == 0) {
wolfSSL 16:8e0d178b1d1e 855 idx = 0;
wolfSSL 16:8e0d178b1d1e 856
wolfSSL 16:8e0d178b1d1e 857 /* Copy parts to buf */
wolfSSL 16:8e0d178b1d1e 858 XMEMCPY(&buf[idx], seq, seqSz);
wolfSSL 16:8e0d178b1d1e 859 idx += seqSz;
wolfSSL 16:8e0d178b1d1e 860
wolfSSL 16:8e0d178b1d1e 861 XMEMCPY(&buf[idx], ver, verSz);
wolfSSL 16:8e0d178b1d1e 862 idx += verSz;
wolfSSL 16:8e0d178b1d1e 863
wolfSSL 16:8e0d178b1d1e 864 seqSz = SetSequence(totalSz - sdBufSz - idx - 4, seq);
wolfSSL 16:8e0d178b1d1e 865 XMEMCPY(&buf[idx], seq, seqSz);
wolfSSL 16:8e0d178b1d1e 866 idx += seqSz;
wolfSSL 16:8e0d178b1d1e 867
wolfSSL 16:8e0d178b1d1e 868 /* OID */
wolfSSL 16:8e0d178b1d1e 869 idx += SetObjectId(sizeof(WC_PKCS12_DATA_OID), &buf[idx]);
wolfSSL 16:8e0d178b1d1e 870 XMEMCPY(&buf[idx], WC_PKCS12_DATA_OID, sizeof(WC_PKCS12_DATA_OID));
wolfSSL 16:8e0d178b1d1e 871 idx += sizeof(WC_PKCS12_DATA_OID);
wolfSSL 16:8e0d178b1d1e 872
wolfSSL 16:8e0d178b1d1e 873 /* Element */
wolfSSL 16:8e0d178b1d1e 874 buf[idx++] = ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC;
wolfSSL 16:8e0d178b1d1e 875 idx += SetLength(totalSz - sdBufSz - idx - 3, &buf[idx]);
wolfSSL 16:8e0d178b1d1e 876
wolfSSL 16:8e0d178b1d1e 877 /* Octet string */
wolfSSL 16:8e0d178b1d1e 878 idx += SetOctetString(totalSz - sdBufSz - idx - 4, &buf[idx]);
wolfSSL 16:8e0d178b1d1e 879
wolfSSL 16:8e0d178b1d1e 880 XMEMCPY(&buf[idx], pkcs12->safe->data, pkcs12->safe->dataSz);
wolfSSL 16:8e0d178b1d1e 881 idx += pkcs12->safe->dataSz;
wolfSSL 16:8e0d178b1d1e 882
wolfSSL 16:8e0d178b1d1e 883 if (pkcs12->signData != NULL) {
wolfSSL 16:8e0d178b1d1e 884 XMEMCPY(&buf[idx], sdBuf, sdBufSz);
wolfSSL 16:8e0d178b1d1e 885 }
wolfSSL 16:8e0d178b1d1e 886
wolfSSL 16:8e0d178b1d1e 887 if (*der == NULL) {
wolfSSL 16:8e0d178b1d1e 888 /* Point to start of data allocated for DER */
wolfSSL 16:8e0d178b1d1e 889 *der = buf;
wolfSSL 16:8e0d178b1d1e 890 }
wolfSSL 16:8e0d178b1d1e 891 else {
wolfSSL 16:8e0d178b1d1e 892 /* Increment pointer to byte past DER */
wolfSSL 16:8e0d178b1d1e 893 *der = &buf[totalSz];
wolfSSL 16:8e0d178b1d1e 894 }
wolfSSL 16:8e0d178b1d1e 895
wolfSSL 16:8e0d178b1d1e 896 /* Return size of der */
wolfSSL 16:8e0d178b1d1e 897 ret = totalSz;
wolfSSL 16:8e0d178b1d1e 898 }
wolfSSL 16:8e0d178b1d1e 899
wolfSSL 16:8e0d178b1d1e 900 XFREE(sdBuf, pkcs12->heap, DYNAMIC_TYPE_PKCS);
wolfSSL 16:8e0d178b1d1e 901 /* Allocation of buf was the last time ret could be a failure,
wolfSSL 16:8e0d178b1d1e 902 * so no need to free here */
wolfSSL 16:8e0d178b1d1e 903
wolfSSL 16:8e0d178b1d1e 904 return ret;
wolfSSL 16:8e0d178b1d1e 905 }
wolfSSL 16:8e0d178b1d1e 906
wolfSSL 15:117db924cf7c 907
wolfSSL 15:117db924cf7c 908 /* helper function to free WC_DerCertList */
wolfSSL 15:117db924cf7c 909 void wc_FreeCertList(WC_DerCertList* list, void* heap)
wolfSSL 15:117db924cf7c 910 {
wolfSSL 15:117db924cf7c 911 WC_DerCertList* current = list;
wolfSSL 15:117db924cf7c 912 WC_DerCertList* next;
wolfSSL 15:117db924cf7c 913
wolfSSL 15:117db924cf7c 914 if (list == NULL) {
wolfSSL 15:117db924cf7c 915 return;
wolfSSL 15:117db924cf7c 916 }
wolfSSL 15:117db924cf7c 917
wolfSSL 15:117db924cf7c 918 while (current != NULL) {
wolfSSL 15:117db924cf7c 919 next = current->next;
wolfSSL 15:117db924cf7c 920 if (current->buffer != NULL) {
wolfSSL 15:117db924cf7c 921 XFREE(current->buffer, heap, DYNAMIC_TYPE_PKCS);
wolfSSL 15:117db924cf7c 922 }
wolfSSL 15:117db924cf7c 923 XFREE(current, heap, DYNAMIC_TYPE_PKCS);
wolfSSL 15:117db924cf7c 924 current = next;
wolfSSL 15:117db924cf7c 925 }
wolfSSL 15:117db924cf7c 926
wolfSSL 15:117db924cf7c 927 (void)heap;
wolfSSL 15:117db924cf7c 928 }
wolfSSL 15:117db924cf7c 929
wolfSSL 15:117db924cf7c 930 static void freeDecCertList(WC_DerCertList** list, byte** pkey, word32* pkeySz,
wolfSSL 15:117db924cf7c 931 byte** cert, word32* certSz, void* heap)
wolfSSL 15:117db924cf7c 932 {
wolfSSL 15:117db924cf7c 933 WC_DerCertList* current = *list;
wolfSSL 15:117db924cf7c 934 WC_DerCertList* previous = NULL;
wolfSSL 15:117db924cf7c 935 DecodedCert DeCert;
wolfSSL 15:117db924cf7c 936
wolfSSL 15:117db924cf7c 937 while (current != NULL) {
wolfSSL 15:117db924cf7c 938
wolfSSL 15:117db924cf7c 939 InitDecodedCert(&DeCert, current->buffer, current->bufferSz, heap);
wolfSSL 15:117db924cf7c 940 if (ParseCertRelative(&DeCert, CERT_TYPE, NO_VERIFY, NULL) == 0) {
wolfSSL 15:117db924cf7c 941 if (wc_CheckPrivateKey(*pkey, *pkeySz, &DeCert) == 1) {
wolfSSL 15:117db924cf7c 942 WOLFSSL_MSG("Key Pair found");
wolfSSL 15:117db924cf7c 943 *cert = current->buffer;
wolfSSL 15:117db924cf7c 944 *certSz = current->bufferSz;
wolfSSL 15:117db924cf7c 945
wolfSSL 15:117db924cf7c 946 if (previous == NULL) {
wolfSSL 15:117db924cf7c 947 *list = current->next;
wolfSSL 15:117db924cf7c 948 }
wolfSSL 15:117db924cf7c 949 else {
wolfSSL 15:117db924cf7c 950 previous->next = current->next;
wolfSSL 15:117db924cf7c 951 }
wolfSSL 15:117db924cf7c 952 FreeDecodedCert(&DeCert);
wolfSSL 15:117db924cf7c 953 XFREE(current, heap, DYNAMIC_TYPE_PKCS);
wolfSSL 15:117db924cf7c 954 break;
wolfSSL 15:117db924cf7c 955 }
wolfSSL 15:117db924cf7c 956 }
wolfSSL 15:117db924cf7c 957 FreeDecodedCert(&DeCert);
wolfSSL 15:117db924cf7c 958
wolfSSL 15:117db924cf7c 959 previous = current;
wolfSSL 15:117db924cf7c 960 current = current->next;
wolfSSL 15:117db924cf7c 961 }
wolfSSL 15:117db924cf7c 962 }
wolfSSL 15:117db924cf7c 963
wolfSSL 15:117db924cf7c 964
wolfSSL 15:117db924cf7c 965 /* return 0 on success and negative on failure.
wolfSSL 15:117db924cf7c 966 * By side effect returns private key, cert, and optionally ca.
wolfSSL 15:117db924cf7c 967 * Parses and decodes the parts of PKCS12
wolfSSL 15:117db924cf7c 968 *
wolfSSL 15:117db924cf7c 969 * NOTE: can parse with USER RSA enabled but may return cert that is not the
wolfSSL 15:117db924cf7c 970 * pair for the key when using RSA key pairs.
wolfSSL 15:117db924cf7c 971 *
wolfSSL 15:117db924cf7c 972 * pkcs12 : non-null WC_PKCS12 struct
wolfSSL 15:117db924cf7c 973 * psw : password to use for PKCS12 decode
wolfSSL 15:117db924cf7c 974 * pkey : Private key returned
wolfSSL 15:117db924cf7c 975 * cert : x509 cert returned
wolfSSL 15:117db924cf7c 976 * ca : optional ca returned
wolfSSL 15:117db924cf7c 977 */
wolfSSL 15:117db924cf7c 978 int wc_PKCS12_parse(WC_PKCS12* pkcs12, const char* psw,
wolfSSL 15:117db924cf7c 979 byte** pkey, word32* pkeySz, byte** cert, word32* certSz,
wolfSSL 15:117db924cf7c 980 WC_DerCertList** ca)
wolfSSL 15:117db924cf7c 981 {
wolfSSL 15:117db924cf7c 982 ContentInfo* ci = NULL;
wolfSSL 15:117db924cf7c 983 WC_DerCertList* certList = NULL;
wolfSSL 15:117db924cf7c 984 WC_DerCertList* tailList = NULL;
wolfSSL 15:117db924cf7c 985 byte* buf = NULL;
wolfSSL 15:117db924cf7c 986 word32 i, oid;
wolfSSL 15:117db924cf7c 987 int ret, pswSz;
wolfSSL 16:8e0d178b1d1e 988 word32 algId;
wolfSSL 15:117db924cf7c 989
wolfSSL 15:117db924cf7c 990 WOLFSSL_ENTER("wc_PKCS12_parse");
wolfSSL 15:117db924cf7c 991
wolfSSL 15:117db924cf7c 992 if (pkcs12 == NULL || psw == NULL || cert == NULL || certSz == NULL ||
wolfSSL 15:117db924cf7c 993 pkey == NULL || pkeySz == NULL) {
wolfSSL 15:117db924cf7c 994 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 995 }
wolfSSL 15:117db924cf7c 996
wolfSSL 15:117db924cf7c 997 pswSz = (int)XSTRLEN(psw);
wolfSSL 15:117db924cf7c 998 *cert = NULL;
wolfSSL 15:117db924cf7c 999 *pkey = NULL;
wolfSSL 15:117db924cf7c 1000 if (ca != NULL)
wolfSSL 15:117db924cf7c 1001 *ca = NULL;
wolfSSL 15:117db924cf7c 1002
wolfSSL 15:117db924cf7c 1003 /* if there is sign data then verify the MAC */
wolfSSL 15:117db924cf7c 1004 if (pkcs12->signData != NULL ) {
wolfSSL 15:117db924cf7c 1005 if ((ret = wc_PKCS12_verify(pkcs12, pkcs12->safe->data,
wolfSSL 15:117db924cf7c 1006 pkcs12->safe->dataSz, (byte*)psw, pswSz)) != 0) {
wolfSSL 15:117db924cf7c 1007 WOLFSSL_MSG("PKCS12 Bad MAC on verify");
wolfSSL 15:117db924cf7c 1008 WOLFSSL_LEAVE("wc_PKCS12_parse verify ", ret);
wolfSSL 15:117db924cf7c 1009 return MAC_CMP_FAILED_E;
wolfSSL 15:117db924cf7c 1010 }
wolfSSL 15:117db924cf7c 1011 }
wolfSSL 15:117db924cf7c 1012
wolfSSL 15:117db924cf7c 1013 if (pkcs12->safe == NULL) {
wolfSSL 15:117db924cf7c 1014 WOLFSSL_MSG("No PKCS12 safes to parse");
wolfSSL 15:117db924cf7c 1015 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 1016 }
wolfSSL 15:117db924cf7c 1017
wolfSSL 15:117db924cf7c 1018 /* Decode content infos */
wolfSSL 15:117db924cf7c 1019 ci = pkcs12->safe->CI;
wolfSSL 15:117db924cf7c 1020 for (i = 0; i < pkcs12->safe->numCI; i++) {
wolfSSL 15:117db924cf7c 1021 byte* data;
wolfSSL 15:117db924cf7c 1022 word32 idx = 0;
wolfSSL 15:117db924cf7c 1023 int size, totalSz;
wolfSSL 16:8e0d178b1d1e 1024 byte tag;
wolfSSL 15:117db924cf7c 1025
wolfSSL 15:117db924cf7c 1026 if (ci->type == WC_PKCS12_ENCRYPTED_DATA) {
wolfSSL 15:117db924cf7c 1027 int number;
wolfSSL 15:117db924cf7c 1028
wolfSSL 15:117db924cf7c 1029 WOLFSSL_MSG("Decrypting PKCS12 Content Info Container");
wolfSSL 15:117db924cf7c 1030 data = ci->data;
wolfSSL 16:8e0d178b1d1e 1031 if (GetASNTag(data, &idx, &tag, ci->dataSz) < 0) {
wolfSSL 16:8e0d178b1d1e 1032 ERROR_OUT(ASN_PARSE_E, exit_pk12par);
wolfSSL 16:8e0d178b1d1e 1033 }
wolfSSL 16:8e0d178b1d1e 1034
wolfSSL 16:8e0d178b1d1e 1035 if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) {
wolfSSL 15:117db924cf7c 1036 ERROR_OUT(ASN_PARSE_E, exit_pk12par);
wolfSSL 15:117db924cf7c 1037 }
wolfSSL 15:117db924cf7c 1038 if ((ret = GetLength(data, &idx, &size, ci->dataSz)) < 0) {
wolfSSL 15:117db924cf7c 1039 goto exit_pk12par;
wolfSSL 15:117db924cf7c 1040 }
wolfSSL 15:117db924cf7c 1041
wolfSSL 15:117db924cf7c 1042 if ((ret = GetSequence(data, &idx, &size, ci->dataSz)) < 0) {
wolfSSL 15:117db924cf7c 1043 goto exit_pk12par;
wolfSSL 15:117db924cf7c 1044 }
wolfSSL 15:117db924cf7c 1045
wolfSSL 15:117db924cf7c 1046 if ((ret = GetShortInt(data, &idx, &number, ci->dataSz)) < 0) {
wolfSSL 15:117db924cf7c 1047 goto exit_pk12par;
wolfSSL 15:117db924cf7c 1048 }
wolfSSL 15:117db924cf7c 1049
wolfSSL 15:117db924cf7c 1050 if (number != 0) {
wolfSSL 15:117db924cf7c 1051 WOLFSSL_MSG("Expecting 0 for Integer with Encrypted PKCS12");
wolfSSL 15:117db924cf7c 1052 }
wolfSSL 15:117db924cf7c 1053
wolfSSL 15:117db924cf7c 1054 if ((ret = GetSequence(data, &idx, &size, ci->dataSz)) < 0) {
wolfSSL 15:117db924cf7c 1055 goto exit_pk12par;
wolfSSL 15:117db924cf7c 1056 }
wolfSSL 15:117db924cf7c 1057
wolfSSL 15:117db924cf7c 1058 ret = GetObjectId(data, &idx, &oid, oidIgnoreType, ci->dataSz);
wolfSSL 15:117db924cf7c 1059 if (ret < 0 || oid != WC_PKCS12_DATA) {
wolfSSL 15:117db924cf7c 1060 WOLFSSL_MSG("Not PKCS12 DATA object or get object parse error");
wolfSSL 15:117db924cf7c 1061 ERROR_OUT(ASN_PARSE_E, exit_pk12par);
wolfSSL 15:117db924cf7c 1062 }
wolfSSL 15:117db924cf7c 1063
wolfSSL 15:117db924cf7c 1064 /* decrypted content overwrites input buffer */
wolfSSL 15:117db924cf7c 1065 size = ci->dataSz - idx;
wolfSSL 15:117db924cf7c 1066 buf = (byte*)XMALLOC(size, pkcs12->heap, DYNAMIC_TYPE_PKCS);
wolfSSL 15:117db924cf7c 1067 if (buf == NULL) {
wolfSSL 15:117db924cf7c 1068 ERROR_OUT(MEMORY_E, exit_pk12par);
wolfSSL 15:117db924cf7c 1069 }
wolfSSL 15:117db924cf7c 1070 XMEMCPY(buf, data + idx, size);
wolfSSL 15:117db924cf7c 1071
wolfSSL 15:117db924cf7c 1072 if ((ret = DecryptContent(buf, size, psw, pswSz)) < 0) {
wolfSSL 15:117db924cf7c 1073 WOLFSSL_MSG("Decryption failed, algorithm not compiled in?");
wolfSSL 15:117db924cf7c 1074 goto exit_pk12par;
wolfSSL 15:117db924cf7c 1075 }
wolfSSL 15:117db924cf7c 1076
wolfSSL 15:117db924cf7c 1077 data = buf;
wolfSSL 15:117db924cf7c 1078 idx = 0;
wolfSSL 15:117db924cf7c 1079
wolfSSL 15:117db924cf7c 1080 #ifdef WOLFSSL_DEBUG_PKCS12
wolfSSL 15:117db924cf7c 1081 {
wolfSSL 15:117db924cf7c 1082 byte* p;
wolfSSL 15:117db924cf7c 1083 for (printf("\tData = "), p = (byte*)buf;
wolfSSL 15:117db924cf7c 1084 p < (byte*)buf + size;
wolfSSL 15:117db924cf7c 1085 printf("%02X", *p), p++);
wolfSSL 15:117db924cf7c 1086 printf("\n");
wolfSSL 15:117db924cf7c 1087 }
wolfSSL 15:117db924cf7c 1088 #endif
wolfSSL 15:117db924cf7c 1089 }
wolfSSL 15:117db924cf7c 1090 else { /* type DATA */
wolfSSL 15:117db924cf7c 1091 WOLFSSL_MSG("Parsing PKCS12 DATA Content Info Container");
wolfSSL 15:117db924cf7c 1092 data = ci->data;
wolfSSL 16:8e0d178b1d1e 1093 if (GetASNTag(data, &idx, &tag, ci->dataSz) < 0) {
wolfSSL 16:8e0d178b1d1e 1094 ERROR_OUT(ASN_PARSE_E, exit_pk12par);
wolfSSL 16:8e0d178b1d1e 1095 }
wolfSSL 16:8e0d178b1d1e 1096
wolfSSL 16:8e0d178b1d1e 1097 if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) {
wolfSSL 15:117db924cf7c 1098 ERROR_OUT(ASN_PARSE_E, exit_pk12par);
wolfSSL 15:117db924cf7c 1099 }
wolfSSL 15:117db924cf7c 1100 if ((ret = GetLength(data, &idx, &size, ci->dataSz)) <= 0) {
wolfSSL 16:8e0d178b1d1e 1101 ERROR_OUT(ASN_PARSE_E, exit_pk12par);
wolfSSL 15:117db924cf7c 1102 }
wolfSSL 16:8e0d178b1d1e 1103
wolfSSL 16:8e0d178b1d1e 1104 if (GetASNTag(data, &idx, &tag, ci->dataSz) < 0) {
wolfSSL 16:8e0d178b1d1e 1105 ERROR_OUT(ASN_PARSE_E, exit_pk12par);
wolfSSL 16:8e0d178b1d1e 1106 }
wolfSSL 16:8e0d178b1d1e 1107 if (tag != ASN_OCTET_STRING) {
wolfSSL 15:117db924cf7c 1108 ERROR_OUT(ASN_PARSE_E, exit_pk12par);
wolfSSL 15:117db924cf7c 1109 }
wolfSSL 15:117db924cf7c 1110 if ((ret = GetLength(data, &idx, &size, ci->dataSz)) < 0) {
wolfSSL 15:117db924cf7c 1111 goto exit_pk12par;
wolfSSL 15:117db924cf7c 1112 }
wolfSSL 15:117db924cf7c 1113
wolfSSL 15:117db924cf7c 1114 }
wolfSSL 15:117db924cf7c 1115
wolfSSL 15:117db924cf7c 1116 /* parse through bags in ContentInfo */
wolfSSL 15:117db924cf7c 1117 if ((ret = GetSequence(data, &idx, &totalSz, ci->dataSz)) < 0) {
wolfSSL 15:117db924cf7c 1118 goto exit_pk12par;
wolfSSL 15:117db924cf7c 1119 }
wolfSSL 15:117db924cf7c 1120 totalSz += idx;
wolfSSL 15:117db924cf7c 1121
wolfSSL 15:117db924cf7c 1122 while ((int)idx < totalSz) {
wolfSSL 15:117db924cf7c 1123 int bagSz;
wolfSSL 15:117db924cf7c 1124 if ((ret = GetSequence(data, &idx, &bagSz, ci->dataSz)) < 0) {
wolfSSL 15:117db924cf7c 1125 goto exit_pk12par;
wolfSSL 15:117db924cf7c 1126 }
wolfSSL 15:117db924cf7c 1127 bagSz += idx;
wolfSSL 15:117db924cf7c 1128
wolfSSL 15:117db924cf7c 1129 if ((ret = GetObjectId(data, &idx, &oid, oidIgnoreType,
wolfSSL 15:117db924cf7c 1130 ci->dataSz)) < 0) {
wolfSSL 15:117db924cf7c 1131 goto exit_pk12par;
wolfSSL 15:117db924cf7c 1132 }
wolfSSL 15:117db924cf7c 1133
wolfSSL 15:117db924cf7c 1134 switch (oid) {
wolfSSL 15:117db924cf7c 1135 case WC_PKCS12_KeyBag: /* 667 */
wolfSSL 15:117db924cf7c 1136 WOLFSSL_MSG("PKCS12 Key Bag found");
wolfSSL 16:8e0d178b1d1e 1137 if (GetASNTag(data, &idx, &tag, ci->dataSz) < 0) {
wolfSSL 16:8e0d178b1d1e 1138 ERROR_OUT(ASN_PARSE_E, exit_pk12par);
wolfSSL 16:8e0d178b1d1e 1139 }
wolfSSL 16:8e0d178b1d1e 1140 if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) {
wolfSSL 15:117db924cf7c 1141 ERROR_OUT(ASN_PARSE_E, exit_pk12par);
wolfSSL 15:117db924cf7c 1142 }
wolfSSL 15:117db924cf7c 1143 if ((ret = GetLength(data, &idx, &size, ci->dataSz)) <= 0) {
wolfSSL 16:8e0d178b1d1e 1144 if (ret == 0)
wolfSSL 16:8e0d178b1d1e 1145 ret = ASN_PARSE_E;
wolfSSL 15:117db924cf7c 1146 goto exit_pk12par;
wolfSSL 15:117db924cf7c 1147 }
wolfSSL 15:117db924cf7c 1148 if (*pkey == NULL) {
wolfSSL 15:117db924cf7c 1149 *pkey = (byte*)XMALLOC(size, pkcs12->heap,
wolfSSL 15:117db924cf7c 1150 DYNAMIC_TYPE_PUBLIC_KEY);
wolfSSL 15:117db924cf7c 1151 if (*pkey == NULL) {
wolfSSL 15:117db924cf7c 1152 ERROR_OUT(MEMORY_E, exit_pk12par);
wolfSSL 15:117db924cf7c 1153 }
wolfSSL 15:117db924cf7c 1154 XMEMCPY(*pkey, data + idx, size);
wolfSSL 16:8e0d178b1d1e 1155 *pkeySz = ToTraditional_ex(*pkey, size, &algId);
wolfSSL 15:117db924cf7c 1156 }
wolfSSL 15:117db924cf7c 1157
wolfSSL 15:117db924cf7c 1158 #ifdef WOLFSSL_DEBUG_PKCS12
wolfSSL 15:117db924cf7c 1159 {
wolfSSL 15:117db924cf7c 1160 byte* p;
wolfSSL 15:117db924cf7c 1161 for (printf("\tKey = "), p = (byte*)*pkey;
wolfSSL 15:117db924cf7c 1162 p < (byte*)*pkey + size;
wolfSSL 15:117db924cf7c 1163 printf("%02X", *p), p++);
wolfSSL 15:117db924cf7c 1164 printf("\n");
wolfSSL 15:117db924cf7c 1165 }
wolfSSL 15:117db924cf7c 1166 #endif
wolfSSL 15:117db924cf7c 1167 idx += size;
wolfSSL 15:117db924cf7c 1168 break;
wolfSSL 15:117db924cf7c 1169
wolfSSL 15:117db924cf7c 1170 case WC_PKCS12_ShroudedKeyBag: /* 668 */
wolfSSL 15:117db924cf7c 1171 {
wolfSSL 15:117db924cf7c 1172 byte* k;
wolfSSL 15:117db924cf7c 1173
wolfSSL 15:117db924cf7c 1174 WOLFSSL_MSG("PKCS12 Shrouded Key Bag found");
wolfSSL 16:8e0d178b1d1e 1175 if (GetASNTag(data, &idx, &tag, ci->dataSz) < 0) {
wolfSSL 16:8e0d178b1d1e 1176 ERROR_OUT(ASN_PARSE_E, exit_pk12par);
wolfSSL 16:8e0d178b1d1e 1177 }
wolfSSL 16:8e0d178b1d1e 1178 if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) {
wolfSSL 15:117db924cf7c 1179 ERROR_OUT(ASN_PARSE_E, exit_pk12par);
wolfSSL 15:117db924cf7c 1180 }
wolfSSL 15:117db924cf7c 1181 if ((ret = GetLength(data, &idx, &size,
wolfSSL 15:117db924cf7c 1182 ci->dataSz)) < 0) {
wolfSSL 15:117db924cf7c 1183 goto exit_pk12par;
wolfSSL 15:117db924cf7c 1184 }
wolfSSL 15:117db924cf7c 1185
wolfSSL 15:117db924cf7c 1186 k = (byte*)XMALLOC(size, pkcs12->heap,
wolfSSL 15:117db924cf7c 1187 DYNAMIC_TYPE_PUBLIC_KEY);
wolfSSL 15:117db924cf7c 1188 if (k == NULL) {
wolfSSL 15:117db924cf7c 1189 ERROR_OUT(MEMORY_E, exit_pk12par);
wolfSSL 15:117db924cf7c 1190 }
wolfSSL 15:117db924cf7c 1191 XMEMCPY(k, data + idx, size);
wolfSSL 15:117db924cf7c 1192
wolfSSL 15:117db924cf7c 1193 /* overwrites input, be warned */
wolfSSL 16:8e0d178b1d1e 1194 if ((ret = ToTraditionalEnc(k, size, psw, pswSz,
wolfSSL 16:8e0d178b1d1e 1195 &algId)) < 0) {
wolfSSL 15:117db924cf7c 1196 XFREE(k, pkcs12->heap, DYNAMIC_TYPE_PUBLIC_KEY);
wolfSSL 15:117db924cf7c 1197 goto exit_pk12par;
wolfSSL 15:117db924cf7c 1198 }
wolfSSL 15:117db924cf7c 1199
wolfSSL 15:117db924cf7c 1200 if (ret < size) {
wolfSSL 15:117db924cf7c 1201 /* shrink key buffer */
wolfSSL 15:117db924cf7c 1202 byte* tmp = (byte*)XMALLOC(ret, pkcs12->heap,
wolfSSL 15:117db924cf7c 1203 DYNAMIC_TYPE_PUBLIC_KEY);
wolfSSL 15:117db924cf7c 1204 if (tmp == NULL) {
wolfSSL 15:117db924cf7c 1205 XFREE(k, pkcs12->heap, DYNAMIC_TYPE_PUBLIC_KEY);
wolfSSL 15:117db924cf7c 1206 ERROR_OUT(MEMORY_E, exit_pk12par);
wolfSSL 15:117db924cf7c 1207 }
wolfSSL 15:117db924cf7c 1208 XMEMCPY(tmp, k, ret);
wolfSSL 15:117db924cf7c 1209 XFREE(k, pkcs12->heap, DYNAMIC_TYPE_PUBLIC_KEY);
wolfSSL 15:117db924cf7c 1210 k = tmp;
wolfSSL 15:117db924cf7c 1211 }
wolfSSL 15:117db924cf7c 1212 size = ret;
wolfSSL 15:117db924cf7c 1213
wolfSSL 15:117db924cf7c 1214 if (*pkey == NULL) {
wolfSSL 15:117db924cf7c 1215 *pkey = k;
wolfSSL 15:117db924cf7c 1216 *pkeySz = size;
wolfSSL 15:117db924cf7c 1217 }
wolfSSL 15:117db924cf7c 1218 else { /* only expecting one key */
wolfSSL 15:117db924cf7c 1219 XFREE(k, pkcs12->heap, DYNAMIC_TYPE_PUBLIC_KEY);
wolfSSL 15:117db924cf7c 1220 }
wolfSSL 15:117db924cf7c 1221 idx += size;
wolfSSL 15:117db924cf7c 1222
wolfSSL 15:117db924cf7c 1223 #ifdef WOLFSSL_DEBUG_PKCS12
wolfSSL 15:117db924cf7c 1224 {
wolfSSL 15:117db924cf7c 1225 byte* p;
wolfSSL 15:117db924cf7c 1226 for (printf("\tKey = "), p = (byte*)k;
wolfSSL 15:117db924cf7c 1227 p < (byte*)k + ret;
wolfSSL 15:117db924cf7c 1228 printf("%02X", *p), p++);
wolfSSL 15:117db924cf7c 1229 printf("\n");
wolfSSL 15:117db924cf7c 1230 }
wolfSSL 15:117db924cf7c 1231 #endif
wolfSSL 15:117db924cf7c 1232 }
wolfSSL 15:117db924cf7c 1233 break;
wolfSSL 15:117db924cf7c 1234
wolfSSL 15:117db924cf7c 1235 case WC_PKCS12_CertBag: /* 669 */
wolfSSL 15:117db924cf7c 1236 {
wolfSSL 15:117db924cf7c 1237 WC_DerCertList* node;
wolfSSL 15:117db924cf7c 1238 WOLFSSL_MSG("PKCS12 Cert Bag found");
wolfSSL 16:8e0d178b1d1e 1239 if (GetASNTag(data, &idx, &tag, ci->dataSz) < 0) {
wolfSSL 16:8e0d178b1d1e 1240 ERROR_OUT(ASN_PARSE_E, exit_pk12par);
wolfSSL 16:8e0d178b1d1e 1241 }
wolfSSL 16:8e0d178b1d1e 1242 if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) {
wolfSSL 15:117db924cf7c 1243 ERROR_OUT(ASN_PARSE_E, exit_pk12par);
wolfSSL 15:117db924cf7c 1244 }
wolfSSL 15:117db924cf7c 1245 if ((ret = GetLength(data, &idx, &size, ci->dataSz)) < 0) {
wolfSSL 15:117db924cf7c 1246 goto exit_pk12par;
wolfSSL 15:117db924cf7c 1247 }
wolfSSL 15:117db924cf7c 1248
wolfSSL 15:117db924cf7c 1249 /* get cert bag type */
wolfSSL 15:117db924cf7c 1250 if ((ret = GetSequence(data, &idx, &size, ci->dataSz)) <0) {
wolfSSL 15:117db924cf7c 1251 goto exit_pk12par;
wolfSSL 15:117db924cf7c 1252 }
wolfSSL 15:117db924cf7c 1253
wolfSSL 15:117db924cf7c 1254 if ((ret = GetObjectId(data, &idx, &oid, oidIgnoreType,
wolfSSL 15:117db924cf7c 1255 ci->dataSz)) < 0) {
wolfSSL 15:117db924cf7c 1256 goto exit_pk12par;
wolfSSL 15:117db924cf7c 1257 }
wolfSSL 15:117db924cf7c 1258
wolfSSL 15:117db924cf7c 1259 switch (oid) {
wolfSSL 15:117db924cf7c 1260 case WC_PKCS12_CertBag_Type1: /* 675 */
wolfSSL 15:117db924cf7c 1261 /* type 1 */
wolfSSL 15:117db924cf7c 1262 WOLFSSL_MSG("PKCS12 cert bag type 1");
wolfSSL 16:8e0d178b1d1e 1263 if (GetASNTag(data, &idx, &tag, ci->dataSz) < 0) {
wolfSSL 16:8e0d178b1d1e 1264 ERROR_OUT(ASN_PARSE_E, exit_pk12par);
wolfSSL 16:8e0d178b1d1e 1265 }
wolfSSL 16:8e0d178b1d1e 1266 if (tag != (ASN_CONSTRUCTED |
wolfSSL 16:8e0d178b1d1e 1267 ASN_CONTEXT_SPECIFIC)) {
wolfSSL 15:117db924cf7c 1268 ERROR_OUT(ASN_PARSE_E, exit_pk12par);
wolfSSL 15:117db924cf7c 1269 }
wolfSSL 15:117db924cf7c 1270 if ((ret = GetLength(data, &idx, &size, ci->dataSz))
wolfSSL 15:117db924cf7c 1271 <= 0) {
wolfSSL 16:8e0d178b1d1e 1272 if (ret == 0)
wolfSSL 16:8e0d178b1d1e 1273 ret = ASN_PARSE_E;
wolfSSL 15:117db924cf7c 1274 goto exit_pk12par;
wolfSSL 15:117db924cf7c 1275 }
wolfSSL 16:8e0d178b1d1e 1276 if (GetASNTag(data, &idx, &tag, ci->dataSz) < 0) {
wolfSSL 16:8e0d178b1d1e 1277 ERROR_OUT(ASN_PARSE_E, exit_pk12par);
wolfSSL 16:8e0d178b1d1e 1278 }
wolfSSL 16:8e0d178b1d1e 1279 if (tag != ASN_OCTET_STRING) {
wolfSSL 15:117db924cf7c 1280 ERROR_OUT(ASN_PARSE_E, exit_pk12par);
wolfSSL 15:117db924cf7c 1281
wolfSSL 15:117db924cf7c 1282 }
wolfSSL 15:117db924cf7c 1283 if ((ret = GetLength(data, &idx, &size, ci->dataSz))
wolfSSL 15:117db924cf7c 1284 < 0) {
wolfSSL 15:117db924cf7c 1285 goto exit_pk12par;
wolfSSL 15:117db924cf7c 1286 }
wolfSSL 15:117db924cf7c 1287 break;
wolfSSL 15:117db924cf7c 1288 default:
wolfSSL 15:117db924cf7c 1289 WOLFSSL_MSG("Unknown PKCS12 cert bag type");
wolfSSL 15:117db924cf7c 1290 }
wolfSSL 15:117db924cf7c 1291
wolfSSL 15:117db924cf7c 1292 if (size + idx > (word32)bagSz) {
wolfSSL 15:117db924cf7c 1293 ERROR_OUT(ASN_PARSE_E, exit_pk12par);
wolfSSL 15:117db924cf7c 1294 }
wolfSSL 15:117db924cf7c 1295
wolfSSL 15:117db924cf7c 1296 /* list to hold all certs found */
wolfSSL 15:117db924cf7c 1297 node = (WC_DerCertList*)XMALLOC(sizeof(WC_DerCertList),
wolfSSL 15:117db924cf7c 1298 pkcs12->heap, DYNAMIC_TYPE_PKCS);
wolfSSL 15:117db924cf7c 1299 if (node == NULL) {
wolfSSL 15:117db924cf7c 1300 ERROR_OUT(MEMORY_E, exit_pk12par);
wolfSSL 15:117db924cf7c 1301 }
wolfSSL 15:117db924cf7c 1302 XMEMSET(node, 0, sizeof(WC_DerCertList));
wolfSSL 15:117db924cf7c 1303
wolfSSL 15:117db924cf7c 1304 node->buffer = (byte*)XMALLOC(size, pkcs12->heap,
wolfSSL 15:117db924cf7c 1305 DYNAMIC_TYPE_PKCS);
wolfSSL 15:117db924cf7c 1306 if (node->buffer == NULL) {
wolfSSL 15:117db924cf7c 1307 XFREE(node, pkcs12->heap, DYNAMIC_TYPE_PKCS);
wolfSSL 15:117db924cf7c 1308 ERROR_OUT(MEMORY_E, exit_pk12par);
wolfSSL 15:117db924cf7c 1309 }
wolfSSL 15:117db924cf7c 1310 XMEMCPY(node->buffer, data + idx, size);
wolfSSL 15:117db924cf7c 1311 node->bufferSz = size;
wolfSSL 15:117db924cf7c 1312
wolfSSL 15:117db924cf7c 1313 /* put the new node into the list */
wolfSSL 15:117db924cf7c 1314 if (certList != NULL) {
wolfSSL 15:117db924cf7c 1315 WOLFSSL_MSG("Pushing new cert onto queue");
wolfSSL 15:117db924cf7c 1316 tailList->next = node;
wolfSSL 15:117db924cf7c 1317 tailList = node;
wolfSSL 15:117db924cf7c 1318 }
wolfSSL 15:117db924cf7c 1319 else {
wolfSSL 15:117db924cf7c 1320 certList = node;
wolfSSL 15:117db924cf7c 1321 tailList = node;
wolfSSL 15:117db924cf7c 1322 }
wolfSSL 15:117db924cf7c 1323
wolfSSL 15:117db924cf7c 1324 /* on to next */
wolfSSL 15:117db924cf7c 1325 idx += size;
wolfSSL 15:117db924cf7c 1326 }
wolfSSL 15:117db924cf7c 1327 break;
wolfSSL 15:117db924cf7c 1328
wolfSSL 15:117db924cf7c 1329 case WC_PKCS12_CrlBag: /* 670 */
wolfSSL 15:117db924cf7c 1330 WOLFSSL_MSG("PKCS12 CRL BAG not yet supported");
wolfSSL 15:117db924cf7c 1331 break;
wolfSSL 15:117db924cf7c 1332
wolfSSL 15:117db924cf7c 1333 case WC_PKCS12_SecretBag: /* 671 */
wolfSSL 15:117db924cf7c 1334 WOLFSSL_MSG("PKCS12 Secret BAG not yet supported");
wolfSSL 15:117db924cf7c 1335 break;
wolfSSL 15:117db924cf7c 1336
wolfSSL 15:117db924cf7c 1337 case WC_PKCS12_SafeContentsBag: /* 672 */
wolfSSL 15:117db924cf7c 1338 WOLFSSL_MSG("PKCS12 Safe Contents BAG not yet supported");
wolfSSL 15:117db924cf7c 1339 break;
wolfSSL 15:117db924cf7c 1340
wolfSSL 15:117db924cf7c 1341 default:
wolfSSL 15:117db924cf7c 1342 WOLFSSL_MSG("Unknown PKCS12 BAG type found");
wolfSSL 15:117db924cf7c 1343 }
wolfSSL 15:117db924cf7c 1344
wolfSSL 15:117db924cf7c 1345 /* Attribute, unknown bag or unsupported */
wolfSSL 15:117db924cf7c 1346 if ((int)idx < bagSz) {
wolfSSL 15:117db924cf7c 1347 idx = bagSz; /* skip for now */
wolfSSL 15:117db924cf7c 1348 }
wolfSSL 15:117db924cf7c 1349 }
wolfSSL 15:117db924cf7c 1350
wolfSSL 15:117db924cf7c 1351 /* free temporary buffer */
wolfSSL 15:117db924cf7c 1352 if (buf != NULL) {
wolfSSL 15:117db924cf7c 1353 XFREE(buf, pkcs12->heap, DYNAMIC_TYPE_PKCS);
wolfSSL 15:117db924cf7c 1354 buf = NULL;
wolfSSL 15:117db924cf7c 1355 }
wolfSSL 15:117db924cf7c 1356
wolfSSL 15:117db924cf7c 1357 ci = ci->next;
wolfSSL 15:117db924cf7c 1358 WOLFSSL_MSG("Done Parsing PKCS12 Content Info Container");
wolfSSL 15:117db924cf7c 1359 }
wolfSSL 15:117db924cf7c 1360
wolfSSL 15:117db924cf7c 1361 /* check if key pair, remove from list */
wolfSSL 15:117db924cf7c 1362 if (*pkey != NULL) {
wolfSSL 15:117db924cf7c 1363 freeDecCertList(&certList, pkey, pkeySz, cert, certSz, pkcs12->heap);
wolfSSL 15:117db924cf7c 1364 }
wolfSSL 15:117db924cf7c 1365
wolfSSL 15:117db924cf7c 1366 /* if ca arg provided return certList, otherwise free it */
wolfSSL 15:117db924cf7c 1367 if (ca != NULL) {
wolfSSL 15:117db924cf7c 1368 *ca = certList;
wolfSSL 15:117db924cf7c 1369 }
wolfSSL 15:117db924cf7c 1370 else {
wolfSSL 15:117db924cf7c 1371 /* free list, not wanted */
wolfSSL 15:117db924cf7c 1372 wc_FreeCertList(certList, pkcs12->heap);
wolfSSL 15:117db924cf7c 1373 }
wolfSSL 16:8e0d178b1d1e 1374 (void)tailList; /* not used */
wolfSSL 15:117db924cf7c 1375
wolfSSL 15:117db924cf7c 1376 ret = 0; /* success */
wolfSSL 15:117db924cf7c 1377
wolfSSL 15:117db924cf7c 1378 exit_pk12par:
wolfSSL 15:117db924cf7c 1379
wolfSSL 15:117db924cf7c 1380 if (ret != 0) {
wolfSSL 15:117db924cf7c 1381 /* failure cleanup */
wolfSSL 15:117db924cf7c 1382 if (*pkey) {
wolfSSL 15:117db924cf7c 1383 XFREE(*pkey, pkcs12->heap, DYNAMIC_TYPE_PUBLIC_KEY);
wolfSSL 15:117db924cf7c 1384 *pkey = NULL;
wolfSSL 15:117db924cf7c 1385 }
wolfSSL 15:117db924cf7c 1386 if (buf) {
wolfSSL 15:117db924cf7c 1387 XFREE(buf, pkcs12->heap, DYNAMIC_TYPE_PKCS);
wolfSSL 15:117db924cf7c 1388 buf = NULL;
wolfSSL 15:117db924cf7c 1389 }
wolfSSL 15:117db924cf7c 1390
wolfSSL 15:117db924cf7c 1391 wc_FreeCertList(certList, pkcs12->heap);
wolfSSL 15:117db924cf7c 1392 }
wolfSSL 15:117db924cf7c 1393
wolfSSL 15:117db924cf7c 1394 return ret;
wolfSSL 15:117db924cf7c 1395 }
wolfSSL 15:117db924cf7c 1396
wolfSSL 15:117db924cf7c 1397
wolfSSL 15:117db924cf7c 1398 /* Helper function to shroud keys.
wolfSSL 15:117db924cf7c 1399 *
wolfSSL 15:117db924cf7c 1400 * pkcs12 structure to use with shrouding key
wolfSSL 15:117db924cf7c 1401 * rng random number generator used
wolfSSL 15:117db924cf7c 1402 * out buffer to hold results
wolfSSL 15:117db924cf7c 1403 * outSz size of out buffer
wolfSSL 15:117db924cf7c 1404 * key key that is going to be shrouded
wolfSSL 15:117db924cf7c 1405 * keySz size of key buffer
wolfSSL 15:117db924cf7c 1406 * vAlgo algorithm version
wolfSSL 15:117db924cf7c 1407 * pass password to use
wolfSSL 15:117db924cf7c 1408 * passSz size of pass buffer
wolfSSL 15:117db924cf7c 1409 * itt number of iterations
wolfSSL 15:117db924cf7c 1410 *
wolfSSL 15:117db924cf7c 1411 * returns the size of the shrouded key on success
wolfSSL 15:117db924cf7c 1412 */
wolfSSL 15:117db924cf7c 1413 static int wc_PKCS12_shroud_key(WC_PKCS12* pkcs12, WC_RNG* rng,
wolfSSL 15:117db924cf7c 1414 byte* out, word32* outSz, byte* key, word32 keySz, int vAlgo,
wolfSSL 15:117db924cf7c 1415 const char* pass, int passSz, int itt)
wolfSSL 15:117db924cf7c 1416 {
wolfSSL 15:117db924cf7c 1417 void* heap;
wolfSSL 15:117db924cf7c 1418 word32 tmpIdx = 0;
wolfSSL 15:117db924cf7c 1419 int vPKCS = 1; /* PKCS#12 default set to 1 */
wolfSSL 15:117db924cf7c 1420 word32 sz;
wolfSSL 15:117db924cf7c 1421 word32 totalSz = 0;
wolfSSL 15:117db924cf7c 1422 int ret;
wolfSSL 15:117db924cf7c 1423
wolfSSL 15:117db924cf7c 1424
wolfSSL 15:117db924cf7c 1425 if (outSz == NULL || pkcs12 == NULL || rng == NULL || key == NULL ||
wolfSSL 15:117db924cf7c 1426 pass == NULL) {
wolfSSL 15:117db924cf7c 1427 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 1428 }
wolfSSL 15:117db924cf7c 1429
wolfSSL 15:117db924cf7c 1430 heap = wc_PKCS12_GetHeap(pkcs12);
wolfSSL 15:117db924cf7c 1431
wolfSSL 15:117db924cf7c 1432 /* check if trying to get size */
wolfSSL 15:117db924cf7c 1433 if (out != NULL) {
wolfSSL 15:117db924cf7c 1434 tmpIdx += MAX_LENGTH_SZ + 1; /* save room for length and tag (+1) */
wolfSSL 15:117db924cf7c 1435 sz = *outSz - tmpIdx;
wolfSSL 15:117db924cf7c 1436 }
wolfSSL 15:117db924cf7c 1437
wolfSSL 15:117db924cf7c 1438 /* case of no encryption */
wolfSSL 15:117db924cf7c 1439 if (vAlgo < 0) {
wolfSSL 15:117db924cf7c 1440 const byte* curveOID = NULL;
wolfSSL 15:117db924cf7c 1441 word32 oidSz = 0;
wolfSSL 15:117db924cf7c 1442 int algoID;
wolfSSL 15:117db924cf7c 1443
wolfSSL 15:117db924cf7c 1444 WOLFSSL_MSG("creating PKCS12 Key Bag");
wolfSSL 15:117db924cf7c 1445
wolfSSL 15:117db924cf7c 1446 /* check key type and get OID if ECC */
wolfSSL 15:117db924cf7c 1447 if ((ret = wc_GetKeyOID(key, keySz, &curveOID, &oidSz, &algoID, heap))
wolfSSL 15:117db924cf7c 1448 < 0) {
wolfSSL 15:117db924cf7c 1449 return ret;
wolfSSL 15:117db924cf7c 1450 }
wolfSSL 15:117db924cf7c 1451
wolfSSL 15:117db924cf7c 1452 /* PKCS#8 wrapping around key */
wolfSSL 15:117db924cf7c 1453 ret = wc_CreatePKCS8Key(out + tmpIdx, &sz, key, keySz, algoID,
wolfSSL 15:117db924cf7c 1454 curveOID, oidSz);
wolfSSL 15:117db924cf7c 1455 }
wolfSSL 15:117db924cf7c 1456 else {
wolfSSL 15:117db924cf7c 1457 WOLFSSL_MSG("creating PKCS12 Shrouded Key Bag");
wolfSSL 15:117db924cf7c 1458
wolfSSL 15:117db924cf7c 1459 if (vAlgo == PBE_SHA1_DES) {
wolfSSL 15:117db924cf7c 1460 vPKCS = PKCS5;
wolfSSL 15:117db924cf7c 1461 vAlgo = 10;
wolfSSL 15:117db924cf7c 1462 }
wolfSSL 15:117db924cf7c 1463
wolfSSL 15:117db924cf7c 1464 ret = UnTraditionalEnc(key, keySz, out + tmpIdx, &sz, pass, passSz,
wolfSSL 15:117db924cf7c 1465 vPKCS, vAlgo, NULL, 0, itt, rng, heap);
wolfSSL 15:117db924cf7c 1466 }
wolfSSL 15:117db924cf7c 1467 if (ret == LENGTH_ONLY_E) {
wolfSSL 15:117db924cf7c 1468 *outSz = sz + MAX_LENGTH_SZ + 1;
wolfSSL 15:117db924cf7c 1469 return LENGTH_ONLY_E;
wolfSSL 15:117db924cf7c 1470 }
wolfSSL 15:117db924cf7c 1471 if (ret < 0) {
wolfSSL 15:117db924cf7c 1472 return ret;
wolfSSL 15:117db924cf7c 1473 }
wolfSSL 15:117db924cf7c 1474
wolfSSL 15:117db924cf7c 1475 totalSz += ret;
wolfSSL 15:117db924cf7c 1476
wolfSSL 15:117db924cf7c 1477 /* out should not be null at this point but check before writing */
wolfSSL 15:117db924cf7c 1478 if (out == NULL) {
wolfSSL 15:117db924cf7c 1479 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 1480 }
wolfSSL 15:117db924cf7c 1481
wolfSSL 15:117db924cf7c 1482 /* rewind index and set tag and length */
wolfSSL 15:117db924cf7c 1483 tmpIdx -= MAX_LENGTH_SZ + 1;
wolfSSL 15:117db924cf7c 1484 sz = SetExplicit(0, ret, out + tmpIdx);
wolfSSL 15:117db924cf7c 1485 tmpIdx += sz; totalSz += sz;
wolfSSL 15:117db924cf7c 1486 XMEMMOVE(out + tmpIdx, out + MAX_LENGTH_SZ + 1, ret);
wolfSSL 15:117db924cf7c 1487
wolfSSL 15:117db924cf7c 1488 return totalSz;
wolfSSL 15:117db924cf7c 1489 }
wolfSSL 15:117db924cf7c 1490
wolfSSL 15:117db924cf7c 1491
wolfSSL 15:117db924cf7c 1492 /* Helper function to create key bag.
wolfSSL 15:117db924cf7c 1493 *
wolfSSL 15:117db924cf7c 1494 * pkcs12 structure to use with key bag
wolfSSL 15:117db924cf7c 1495 * rng random number generator used
wolfSSL 15:117db924cf7c 1496 * out buffer to hold results
wolfSSL 15:117db924cf7c 1497 * outSz size of out buffer
wolfSSL 15:117db924cf7c 1498 * key key that is going into key bag
wolfSSL 15:117db924cf7c 1499 * keySz size of key buffer
wolfSSL 15:117db924cf7c 1500 * algo algorithm version
wolfSSL 15:117db924cf7c 1501 * iter number of iterations
wolfSSL 15:117db924cf7c 1502 * pass password to use
wolfSSL 15:117db924cf7c 1503 * passSz size of pass buffer
wolfSSL 15:117db924cf7c 1504 *
wolfSSL 15:117db924cf7c 1505 * returns the size of the key bag on success
wolfSSL 15:117db924cf7c 1506 */
wolfSSL 15:117db924cf7c 1507 static int wc_PKCS12_create_key_bag(WC_PKCS12* pkcs12, WC_RNG* rng,
wolfSSL 15:117db924cf7c 1508 byte* out, word32* outSz, byte* key, word32 keySz, int algo, int iter,
wolfSSL 15:117db924cf7c 1509 char* pass, int passSz)
wolfSSL 15:117db924cf7c 1510 {
wolfSSL 15:117db924cf7c 1511 void* heap;
wolfSSL 15:117db924cf7c 1512 byte* tmp;
wolfSSL 15:117db924cf7c 1513 word32 length = 0;
wolfSSL 15:117db924cf7c 1514 word32 idx = 0;
wolfSSL 15:117db924cf7c 1515 word32 totalSz = 0;
wolfSSL 15:117db924cf7c 1516 word32 sz;
wolfSSL 15:117db924cf7c 1517 word32 i;
wolfSSL 15:117db924cf7c 1518 word32 tmpSz;
wolfSSL 15:117db924cf7c 1519 int ret;
wolfSSL 15:117db924cf7c 1520
wolfSSL 15:117db924cf7c 1521 /* get max size for shrouded key */
wolfSSL 15:117db924cf7c 1522 ret = wc_PKCS12_shroud_key(pkcs12, rng, NULL, &length, key, keySz,
wolfSSL 15:117db924cf7c 1523 algo, pass, passSz, iter);
wolfSSL 15:117db924cf7c 1524 if (ret != LENGTH_ONLY_E && ret < 0) {
wolfSSL 15:117db924cf7c 1525 return ret;
wolfSSL 15:117db924cf7c 1526 }
wolfSSL 15:117db924cf7c 1527
wolfSSL 15:117db924cf7c 1528 if (out == NULL) {
wolfSSL 15:117db924cf7c 1529 *outSz = MAX_SEQ_SZ + WC_PKCS12_DATA_OBJ_SZ + 1 + MAX_LENGTH_SZ +
wolfSSL 15:117db924cf7c 1530 length;
wolfSSL 15:117db924cf7c 1531 return LENGTH_ONLY_E;
wolfSSL 15:117db924cf7c 1532 }
wolfSSL 15:117db924cf7c 1533
wolfSSL 15:117db924cf7c 1534 heap = wc_PKCS12_GetHeap(pkcs12);
wolfSSL 15:117db924cf7c 1535
wolfSSL 15:117db924cf7c 1536 /* leave room for sequence */
wolfSSL 15:117db924cf7c 1537 idx += MAX_SEQ_SZ;
wolfSSL 15:117db924cf7c 1538
wolfSSL 15:117db924cf7c 1539 if (algo < 0) { /* not encrypted */
wolfSSL 15:117db924cf7c 1540 out[idx++] = ASN_OBJECT_ID; totalSz++;
wolfSSL 15:117db924cf7c 1541 sz = SetLength(sizeof(WC_PKCS12_KeyBag_OID), out + idx);
wolfSSL 15:117db924cf7c 1542 idx += sz; totalSz += sz;
wolfSSL 15:117db924cf7c 1543 for (i = 0; i < sizeof(WC_PKCS12_KeyBag_OID); i++) {
wolfSSL 15:117db924cf7c 1544 out[idx++] = WC_PKCS12_KeyBag_OID[i]; totalSz++;
wolfSSL 15:117db924cf7c 1545 }
wolfSSL 15:117db924cf7c 1546 }
wolfSSL 15:117db924cf7c 1547 else { /* encrypted */
wolfSSL 15:117db924cf7c 1548 out[idx++] = ASN_OBJECT_ID; totalSz++;
wolfSSL 15:117db924cf7c 1549 sz = SetLength(sizeof(WC_PKCS12_ShroudedKeyBag_OID), out + idx);
wolfSSL 15:117db924cf7c 1550 idx += sz; totalSz += sz;
wolfSSL 15:117db924cf7c 1551 for (i = 0; i < sizeof(WC_PKCS12_ShroudedKeyBag_OID); i++) {
wolfSSL 15:117db924cf7c 1552 out[idx++] = WC_PKCS12_ShroudedKeyBag_OID[i]; totalSz++;
wolfSSL 15:117db924cf7c 1553 }
wolfSSL 15:117db924cf7c 1554 }
wolfSSL 15:117db924cf7c 1555
wolfSSL 15:117db924cf7c 1556 /* shroud key */
wolfSSL 15:117db924cf7c 1557 tmp = (byte*)XMALLOC(length, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1558 if (tmp == NULL) {
wolfSSL 15:117db924cf7c 1559 return MEMORY_E;
wolfSSL 15:117db924cf7c 1560 }
wolfSSL 15:117db924cf7c 1561
wolfSSL 15:117db924cf7c 1562 ret = wc_PKCS12_shroud_key(pkcs12, rng, tmp, &length, key, keySz,
wolfSSL 15:117db924cf7c 1563 algo, pass, passSz, iter);
wolfSSL 15:117db924cf7c 1564 if (ret < 0) {
wolfSSL 15:117db924cf7c 1565 XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1566 return ret;
wolfSSL 15:117db924cf7c 1567 }
wolfSSL 15:117db924cf7c 1568 length = ret;
wolfSSL 15:117db924cf7c 1569 XMEMCPY(out + idx, tmp, length);
wolfSSL 15:117db924cf7c 1570 XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1571 totalSz += length;
wolfSSL 15:117db924cf7c 1572
wolfSSL 16:8e0d178b1d1e 1573 /* set beginning sequence */
wolfSSL 15:117db924cf7c 1574 tmpSz = SetSequence(totalSz, out);
wolfSSL 15:117db924cf7c 1575 XMEMMOVE(out + tmpSz, out + MAX_SEQ_SZ, totalSz);
wolfSSL 15:117db924cf7c 1576
wolfSSL 15:117db924cf7c 1577 (void)heap;
wolfSSL 15:117db924cf7c 1578 return totalSz + tmpSz;
wolfSSL 15:117db924cf7c 1579 }
wolfSSL 15:117db924cf7c 1580
wolfSSL 15:117db924cf7c 1581
wolfSSL 15:117db924cf7c 1582 /* Helper function to create cert bag.
wolfSSL 15:117db924cf7c 1583 *
wolfSSL 15:117db924cf7c 1584 * pkcs12 structure to use with cert bag
wolfSSL 15:117db924cf7c 1585 * out buffer to hold results
wolfSSL 15:117db924cf7c 1586 * outSz size of out buffer
wolfSSL 15:117db924cf7c 1587 * cert cert that is going into cert bag
wolfSSL 15:117db924cf7c 1588 * certSz size of cert buffer
wolfSSL 15:117db924cf7c 1589 *
wolfSSL 15:117db924cf7c 1590 * returns the size of the cert bag on success
wolfSSL 15:117db924cf7c 1591 */
wolfSSL 15:117db924cf7c 1592 static int wc_PKCS12_create_cert_bag(WC_PKCS12* pkcs12,
wolfSSL 15:117db924cf7c 1593 byte* out, word32* outSz, byte* cert, word32 certSz)
wolfSSL 15:117db924cf7c 1594 {
wolfSSL 15:117db924cf7c 1595 word32 length = 0;
wolfSSL 15:117db924cf7c 1596 word32 idx = 0;
wolfSSL 15:117db924cf7c 1597 word32 totalSz = 0;
wolfSSL 15:117db924cf7c 1598 word32 sz;
wolfSSL 15:117db924cf7c 1599 int WC_CERTBAG_OBJECT_ID = 13;
wolfSSL 15:117db924cf7c 1600 int WC_CERTBAG1_OBJECT_ID = 12;
wolfSSL 15:117db924cf7c 1601 word32 i;
wolfSSL 15:117db924cf7c 1602 word32 tmpSz;
wolfSSL 15:117db924cf7c 1603
wolfSSL 15:117db924cf7c 1604 if (out == NULL) {
wolfSSL 15:117db924cf7c 1605 *outSz = MAX_SEQ_SZ + WC_CERTBAG_OBJECT_ID + 1 + MAX_LENGTH_SZ +
wolfSSL 15:117db924cf7c 1606 MAX_SEQ_SZ + WC_CERTBAG1_OBJECT_ID + 1 + MAX_LENGTH_SZ + 1 +
wolfSSL 15:117db924cf7c 1607 MAX_LENGTH_SZ + certSz;
wolfSSL 15:117db924cf7c 1608 return LENGTH_ONLY_E;
wolfSSL 15:117db924cf7c 1609 }
wolfSSL 15:117db924cf7c 1610
wolfSSL 15:117db924cf7c 1611 /* check buffer size able to handle max size */
wolfSSL 15:117db924cf7c 1612 if (*outSz < (MAX_SEQ_SZ + WC_CERTBAG_OBJECT_ID + 1 + MAX_LENGTH_SZ +
wolfSSL 15:117db924cf7c 1613 MAX_SEQ_SZ + WC_CERTBAG1_OBJECT_ID + 1 + MAX_LENGTH_SZ + 1 +
wolfSSL 15:117db924cf7c 1614 MAX_LENGTH_SZ + certSz)) {
wolfSSL 15:117db924cf7c 1615 return BUFFER_E;
wolfSSL 15:117db924cf7c 1616 }
wolfSSL 15:117db924cf7c 1617
wolfSSL 15:117db924cf7c 1618 /* save room for sequence */
wolfSSL 15:117db924cf7c 1619 idx += MAX_SEQ_SZ;
wolfSSL 15:117db924cf7c 1620
wolfSSL 15:117db924cf7c 1621 /* objectId WC_PKCS12_CertBag */
wolfSSL 15:117db924cf7c 1622 out[idx++] = ASN_OBJECT_ID; totalSz++;
wolfSSL 15:117db924cf7c 1623 sz = SetLength(sizeof(WC_PKCS12_CertBag_OID), out + idx);
wolfSSL 15:117db924cf7c 1624 idx += sz; totalSz += sz;
wolfSSL 15:117db924cf7c 1625 for (i = 0; i < sizeof(WC_PKCS12_CertBag_OID); i++) {
wolfSSL 15:117db924cf7c 1626 out[idx++] = WC_PKCS12_CertBag_OID[i]; totalSz++;
wolfSSL 15:117db924cf7c 1627 }
wolfSSL 15:117db924cf7c 1628
wolfSSL 15:117db924cf7c 1629 /**** Cert Bag type 1 ****/
wolfSSL 15:117db924cf7c 1630 out[idx++] = (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC); totalSz++;
wolfSSL 15:117db924cf7c 1631
wolfSSL 15:117db924cf7c 1632 /* save room for length and sequence */
wolfSSL 15:117db924cf7c 1633 idx += MAX_LENGTH_SZ;
wolfSSL 15:117db924cf7c 1634 idx += MAX_SEQ_SZ;
wolfSSL 15:117db924cf7c 1635
wolfSSL 15:117db924cf7c 1636 /* object id WC_PKCS12_CertBag_Type1 */
wolfSSL 15:117db924cf7c 1637 out[idx++] = ASN_OBJECT_ID; length++;
wolfSSL 15:117db924cf7c 1638 sz = SetLength(sizeof(WC_PKCS12_CertBag_Type1_OID), out + idx);
wolfSSL 15:117db924cf7c 1639 idx += sz; length += sz;
wolfSSL 15:117db924cf7c 1640 for (i = 0; i < sizeof(WC_PKCS12_CertBag_Type1_OID); i++) {
wolfSSL 15:117db924cf7c 1641 out[idx++] = WC_PKCS12_CertBag_Type1_OID[i]; length++;
wolfSSL 15:117db924cf7c 1642 }
wolfSSL 15:117db924cf7c 1643
wolfSSL 15:117db924cf7c 1644 out[idx++] = (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC); length++;
wolfSSL 15:117db924cf7c 1645 sz = 0;
wolfSSL 15:117db924cf7c 1646 idx += MAX_LENGTH_SZ; /* save room for length */
wolfSSL 15:117db924cf7c 1647
wolfSSL 15:117db924cf7c 1648 /* place the cert in the buffer */
wolfSSL 15:117db924cf7c 1649 out[idx++] = ASN_OCTET_STRING; sz++;
wolfSSL 15:117db924cf7c 1650 tmpSz = SetLength(certSz, out + idx);
wolfSSL 15:117db924cf7c 1651 idx += tmpSz; sz += tmpSz;
wolfSSL 15:117db924cf7c 1652 XMEMCPY(out + idx, cert, certSz);
wolfSSL 15:117db924cf7c 1653 idx += certSz; sz += certSz;
wolfSSL 15:117db924cf7c 1654
wolfSSL 15:117db924cf7c 1655 /* rewind idx and place length */
wolfSSL 15:117db924cf7c 1656 idx -= (sz + MAX_LENGTH_SZ);
wolfSSL 15:117db924cf7c 1657 tmpSz = SetLength(sz, out + idx);
wolfSSL 15:117db924cf7c 1658 XMEMMOVE(out + idx + tmpSz, out + idx + MAX_LENGTH_SZ, sz);
wolfSSL 15:117db924cf7c 1659 idx += tmpSz + sz; length += tmpSz + sz;
wolfSSL 15:117db924cf7c 1660
wolfSSL 15:117db924cf7c 1661 /* rewind idx and set sequence */
wolfSSL 15:117db924cf7c 1662 idx -= (length + MAX_SEQ_SZ);
wolfSSL 15:117db924cf7c 1663 tmpSz = SetSequence(length, out + idx);
wolfSSL 15:117db924cf7c 1664 XMEMMOVE(out + idx + tmpSz, out + idx + MAX_SEQ_SZ, length);
wolfSSL 15:117db924cf7c 1665 length += tmpSz;
wolfSSL 15:117db924cf7c 1666
wolfSSL 15:117db924cf7c 1667 /* place final length */
wolfSSL 15:117db924cf7c 1668 idx -= MAX_LENGTH_SZ;
wolfSSL 15:117db924cf7c 1669 tmpSz = SetLength(length, out + idx);
wolfSSL 15:117db924cf7c 1670 XMEMMOVE(out + idx + tmpSz, out + idx + MAX_LENGTH_SZ, length);
wolfSSL 15:117db924cf7c 1671 length += tmpSz;
wolfSSL 15:117db924cf7c 1672
wolfSSL 15:117db924cf7c 1673 /* place final sequence */
wolfSSL 15:117db924cf7c 1674 totalSz += length;
wolfSSL 15:117db924cf7c 1675 tmpSz = SetSequence(totalSz, out);
wolfSSL 15:117db924cf7c 1676 XMEMMOVE(out + tmpSz, out + MAX_SEQ_SZ, totalSz);
wolfSSL 15:117db924cf7c 1677
wolfSSL 15:117db924cf7c 1678 (void)pkcs12;
wolfSSL 15:117db924cf7c 1679
wolfSSL 15:117db924cf7c 1680 return totalSz + tmpSz;
wolfSSL 15:117db924cf7c 1681 }
wolfSSL 15:117db924cf7c 1682
wolfSSL 15:117db924cf7c 1683
wolfSSL 15:117db924cf7c 1684 /* Helper function to encrypt content.
wolfSSL 15:117db924cf7c 1685 *
wolfSSL 15:117db924cf7c 1686 * pkcs12 structure to use with key bag
wolfSSL 15:117db924cf7c 1687 * rng random number generator used
wolfSSL 15:117db924cf7c 1688 * out buffer to hold results
wolfSSL 15:117db924cf7c 1689 * outSz size of out buffer
wolfSSL 15:117db924cf7c 1690 * content content to encrypt
wolfSSL 15:117db924cf7c 1691 * contentSz size of content buffer
wolfSSL 15:117db924cf7c 1692 * vAlgo algorithm version
wolfSSL 15:117db924cf7c 1693 * pass password to use
wolfSSL 15:117db924cf7c 1694 * passSz size of pass buffer
wolfSSL 15:117db924cf7c 1695 * iter number of iterations
wolfSSL 15:117db924cf7c 1696 * type content type i.e WC_PKCS12_ENCRYPTED_DATA or WC_PKCS12_DATA
wolfSSL 15:117db924cf7c 1697 *
wolfSSL 15:117db924cf7c 1698 * returns the size of result on success
wolfSSL 15:117db924cf7c 1699 */
wolfSSL 15:117db924cf7c 1700 static int wc_PKCS12_encrypt_content(WC_PKCS12* pkcs12, WC_RNG* rng,
wolfSSL 15:117db924cf7c 1701 byte* out, word32* outSz, byte* content, word32 contentSz, int vAlgo,
wolfSSL 15:117db924cf7c 1702 const char* pass, int passSz, int iter, int type)
wolfSSL 15:117db924cf7c 1703 {
wolfSSL 15:117db924cf7c 1704 void* heap;
wolfSSL 15:117db924cf7c 1705 int vPKCS = 1; /* PKCS#12 is always set to 1 */
wolfSSL 15:117db924cf7c 1706 int ret;
wolfSSL 15:117db924cf7c 1707 byte* tmp;
wolfSSL 15:117db924cf7c 1708 word32 idx = 0;
wolfSSL 15:117db924cf7c 1709 word32 totalSz = 0;
wolfSSL 15:117db924cf7c 1710 word32 length = 0;
wolfSSL 15:117db924cf7c 1711 word32 tmpSz;
wolfSSL 15:117db924cf7c 1712 word32 encSz;
wolfSSL 16:8e0d178b1d1e 1713
wolfSSL 16:8e0d178b1d1e 1714 byte seq[MAX_SEQ_SZ];
wolfSSL 15:117db924cf7c 1715
wolfSSL 15:117db924cf7c 1716 WOLFSSL_MSG("encrypting PKCS12 content");
wolfSSL 15:117db924cf7c 1717
wolfSSL 15:117db924cf7c 1718 heap = wc_PKCS12_GetHeap(pkcs12);
wolfSSL 15:117db924cf7c 1719
wolfSSL 15:117db924cf7c 1720 /* ENCRYPTED DATA
wolfSSL 15:117db924cf7c 1721 * ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC
wolfSSL 15:117db924cf7c 1722 * length
wolfSSL 15:117db924cf7c 1723 * sequence
wolfSSL 15:117db924cf7c 1724 * short int
wolfSSL 15:117db924cf7c 1725 * sequence
wolfSSL 15:117db924cf7c 1726 * get object id */
wolfSSL 15:117db924cf7c 1727 if (type == WC_PKCS12_ENCRYPTED_DATA) {
wolfSSL 16:8e0d178b1d1e 1728 word32 outerSz = 0;
wolfSSL 15:117db924cf7c 1729
wolfSSL 15:117db924cf7c 1730 encSz = contentSz;
wolfSSL 15:117db924cf7c 1731 if ((ret = EncryptContent(NULL, contentSz, NULL, &encSz,
wolfSSL 15:117db924cf7c 1732 pass, passSz, vPKCS, vAlgo, NULL, 0, iter, rng, heap)) < 0) {
wolfSSL 15:117db924cf7c 1733 if (ret != LENGTH_ONLY_E) {
wolfSSL 15:117db924cf7c 1734 return ret;
wolfSSL 15:117db924cf7c 1735 }
wolfSSL 15:117db924cf7c 1736 }
wolfSSL 15:117db924cf7c 1737
wolfSSL 16:8e0d178b1d1e 1738 /* calculate size */
wolfSSL 16:8e0d178b1d1e 1739 totalSz = SetObjectId(sizeof(WC_PKCS12_ENCRYPTED_OID), seq);
wolfSSL 16:8e0d178b1d1e 1740 totalSz += sizeof(WC_PKCS12_ENCRYPTED_OID);
wolfSSL 16:8e0d178b1d1e 1741 totalSz += ASN_TAG_SZ;
wolfSSL 16:8e0d178b1d1e 1742
wolfSSL 16:8e0d178b1d1e 1743 length = SetMyVersion(0, seq, 0);
wolfSSL 16:8e0d178b1d1e 1744 tmpSz = SetObjectId(sizeof(WC_PKCS12_DATA_OID), seq);
wolfSSL 16:8e0d178b1d1e 1745 tmpSz += sizeof(WC_PKCS12_DATA_OID);
wolfSSL 16:8e0d178b1d1e 1746 tmpSz += encSz;
wolfSSL 16:8e0d178b1d1e 1747 length += SetSequence(tmpSz, seq) + tmpSz;
wolfSSL 16:8e0d178b1d1e 1748 outerSz = SetSequence(length, seq) + length;
wolfSSL 16:8e0d178b1d1e 1749
wolfSSL 16:8e0d178b1d1e 1750 totalSz += SetLength(outerSz, seq) + outerSz;
wolfSSL 16:8e0d178b1d1e 1751 if (out == NULL) {
wolfSSL 16:8e0d178b1d1e 1752 *outSz = totalSz + SetSequence(totalSz, seq);
wolfSSL 16:8e0d178b1d1e 1753 return LENGTH_ONLY_E;
wolfSSL 16:8e0d178b1d1e 1754 }
wolfSSL 16:8e0d178b1d1e 1755
wolfSSL 16:8e0d178b1d1e 1756 if (*outSz < totalSz + SetSequence(totalSz, seq)) {
wolfSSL 15:117db924cf7c 1757 return BUFFER_E;
wolfSSL 15:117db924cf7c 1758 }
wolfSSL 16:8e0d178b1d1e 1759
wolfSSL 16:8e0d178b1d1e 1760 idx = 0;
wolfSSL 16:8e0d178b1d1e 1761 idx += SetSequence(totalSz, out + idx);
wolfSSL 16:8e0d178b1d1e 1762 idx += SetObjectId(sizeof(WC_PKCS12_ENCRYPTED_OID), out + idx);
wolfSSL 16:8e0d178b1d1e 1763 if (idx + sizeof(WC_PKCS12_ENCRYPTED_OID) > *outSz){
wolfSSL 16:8e0d178b1d1e 1764 return BUFFER_E;
wolfSSL 16:8e0d178b1d1e 1765 }
wolfSSL 16:8e0d178b1d1e 1766 XMEMCPY(out + idx, WC_PKCS12_ENCRYPTED_OID,
wolfSSL 16:8e0d178b1d1e 1767 sizeof(WC_PKCS12_ENCRYPTED_OID));
wolfSSL 16:8e0d178b1d1e 1768 idx += sizeof(WC_PKCS12_ENCRYPTED_OID);
wolfSSL 16:8e0d178b1d1e 1769
wolfSSL 16:8e0d178b1d1e 1770 if (idx + 1 > *outSz){
wolfSSL 16:8e0d178b1d1e 1771 return BUFFER_E;
wolfSSL 16:8e0d178b1d1e 1772 }
wolfSSL 16:8e0d178b1d1e 1773 out[idx++] = (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC);
wolfSSL 16:8e0d178b1d1e 1774 idx += SetLength(outerSz, out + idx);
wolfSSL 16:8e0d178b1d1e 1775
wolfSSL 16:8e0d178b1d1e 1776 idx += SetSequence(length, out + idx);
wolfSSL 16:8e0d178b1d1e 1777 idx += SetMyVersion(0, out + idx, 0);
wolfSSL 15:117db924cf7c 1778 tmp = (byte*)XMALLOC(encSz, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1779 if (tmp == NULL) {
wolfSSL 15:117db924cf7c 1780 return MEMORY_E;
wolfSSL 15:117db924cf7c 1781 }
wolfSSL 15:117db924cf7c 1782
wolfSSL 15:117db924cf7c 1783 if ((ret = EncryptContent(content, contentSz, tmp, &encSz,
wolfSSL 15:117db924cf7c 1784 pass, passSz, vPKCS, vAlgo, NULL, 0, iter, rng, heap)) < 0) {
wolfSSL 15:117db924cf7c 1785 XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1786 return ret;
wolfSSL 15:117db924cf7c 1787 }
wolfSSL 15:117db924cf7c 1788 encSz = ret;
wolfSSL 15:117db924cf7c 1789
wolfSSL 15:117db924cf7c 1790 #ifdef WOLFSSL_DEBUG_PKCS12
wolfSSL 15:117db924cf7c 1791 {
wolfSSL 15:117db924cf7c 1792 byte* p;
wolfSSL 15:117db924cf7c 1793 for (printf("(size %u) Encrypted Content = ", encSz),
wolfSSL 15:117db924cf7c 1794 p = (byte*)tmp;
wolfSSL 15:117db924cf7c 1795 p < (byte*)tmp + encSz;
wolfSSL 15:117db924cf7c 1796 printf("%02X", *p), p++);
wolfSSL 15:117db924cf7c 1797 printf("\n");
wolfSSL 15:117db924cf7c 1798 }
wolfSSL 15:117db924cf7c 1799 #endif
wolfSSL 15:117db924cf7c 1800
wolfSSL 16:8e0d178b1d1e 1801 idx += SetSequence(WC_PKCS12_DATA_OBJ_SZ + encSz, out + idx);
wolfSSL 16:8e0d178b1d1e 1802 idx += SetObjectId(sizeof(WC_PKCS12_DATA_OID), out + idx);
wolfSSL 16:8e0d178b1d1e 1803 if (idx + sizeof(WC_PKCS12_DATA_OID) > *outSz){
wolfSSL 16:8e0d178b1d1e 1804 WOLFSSL_MSG("Buffer not large enough for DATA OID");
wolfSSL 16:8e0d178b1d1e 1805 return BUFFER_E;
wolfSSL 15:117db924cf7c 1806 }
wolfSSL 16:8e0d178b1d1e 1807 XMEMCPY(out + idx, WC_PKCS12_DATA_OID, sizeof(WC_PKCS12_DATA_OID));
wolfSSL 16:8e0d178b1d1e 1808 idx += sizeof(WC_PKCS12_DATA_OID);
wolfSSL 15:117db924cf7c 1809
wolfSSL 15:117db924cf7c 1810 /* copy over encrypted data */
wolfSSL 16:8e0d178b1d1e 1811 if (idx + encSz > *outSz){
wolfSSL 16:8e0d178b1d1e 1812 return BUFFER_E;
wolfSSL 16:8e0d178b1d1e 1813 }
wolfSSL 15:117db924cf7c 1814 XMEMCPY(out + idx, tmp, encSz);
wolfSSL 15:117db924cf7c 1815 XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 1816 idx += encSz;
wolfSSL 16:8e0d178b1d1e 1817 return idx;
wolfSSL 15:117db924cf7c 1818 }
wolfSSL 15:117db924cf7c 1819
wolfSSL 15:117db924cf7c 1820 /* DATA
wolfSSL 15:117db924cf7c 1821 * ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC
wolfSSL 15:117db924cf7c 1822 * length
wolfSSL 15:117db924cf7c 1823 * ASN_OCTET_STRING
wolfSSL 15:117db924cf7c 1824 * length
wolfSSL 15:117db924cf7c 1825 * sequence containing all bags */
wolfSSL 15:117db924cf7c 1826 if (type == WC_PKCS12_DATA) {
wolfSSL 16:8e0d178b1d1e 1827 /* calculate size */
wolfSSL 16:8e0d178b1d1e 1828 totalSz = SetObjectId(sizeof(WC_PKCS12_DATA_OID), seq);
wolfSSL 16:8e0d178b1d1e 1829 totalSz += sizeof(WC_PKCS12_DATA_OID);
wolfSSL 16:8e0d178b1d1e 1830 totalSz += ASN_TAG_SZ;
wolfSSL 16:8e0d178b1d1e 1831
wolfSSL 16:8e0d178b1d1e 1832 length = SetOctetString(contentSz, seq);
wolfSSL 16:8e0d178b1d1e 1833 length += contentSz;
wolfSSL 16:8e0d178b1d1e 1834 totalSz += SetLength(length, seq);
wolfSSL 16:8e0d178b1d1e 1835 totalSz += length;
wolfSSL 16:8e0d178b1d1e 1836
wolfSSL 15:117db924cf7c 1837 if (out == NULL) {
wolfSSL 16:8e0d178b1d1e 1838 *outSz = totalSz + SetSequence(totalSz, seq);
wolfSSL 15:117db924cf7c 1839 return LENGTH_ONLY_E;
wolfSSL 15:117db924cf7c 1840 }
wolfSSL 15:117db924cf7c 1841
wolfSSL 16:8e0d178b1d1e 1842 if (*outSz < (totalSz + SetSequence(totalSz, seq))) {
wolfSSL 15:117db924cf7c 1843 return BUFFER_E;
wolfSSL 15:117db924cf7c 1844 }
wolfSSL 15:117db924cf7c 1845
wolfSSL 16:8e0d178b1d1e 1846 /* place data in output buffer */
wolfSSL 16:8e0d178b1d1e 1847 idx = 0;
wolfSSL 16:8e0d178b1d1e 1848 idx += SetSequence(totalSz, out);
wolfSSL 16:8e0d178b1d1e 1849 idx += SetObjectId(sizeof(WC_PKCS12_DATA_OID), out + idx);
wolfSSL 16:8e0d178b1d1e 1850 if (idx + sizeof(WC_PKCS12_DATA_OID) > *outSz){
wolfSSL 16:8e0d178b1d1e 1851 WOLFSSL_MSG("Buffer not large enough for DATA OID");
wolfSSL 16:8e0d178b1d1e 1852 return BUFFER_E;
wolfSSL 16:8e0d178b1d1e 1853 }
wolfSSL 16:8e0d178b1d1e 1854 XMEMCPY(out + idx, WC_PKCS12_DATA_OID, sizeof(WC_PKCS12_DATA_OID));
wolfSSL 16:8e0d178b1d1e 1855 idx += sizeof(WC_PKCS12_DATA_OID);
wolfSSL 15:117db924cf7c 1856
wolfSSL 16:8e0d178b1d1e 1857 if (idx + 1 > *outSz){
wolfSSL 16:8e0d178b1d1e 1858 return BUFFER_E;
wolfSSL 16:8e0d178b1d1e 1859 }
wolfSSL 16:8e0d178b1d1e 1860 out[idx++] = (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC);
wolfSSL 16:8e0d178b1d1e 1861 idx += SetLength(length, out + idx);
wolfSSL 16:8e0d178b1d1e 1862 idx += SetOctetString(contentSz, out + idx);
wolfSSL 15:117db924cf7c 1863
wolfSSL 16:8e0d178b1d1e 1864 if (idx + contentSz > *outSz){
wolfSSL 16:8e0d178b1d1e 1865 return BUFFER_E;
wolfSSL 16:8e0d178b1d1e 1866 }
wolfSSL 16:8e0d178b1d1e 1867 XMEMCPY(out + idx, content, contentSz);
wolfSSL 16:8e0d178b1d1e 1868 idx += contentSz;
wolfSSL 15:117db924cf7c 1869
wolfSSL 16:8e0d178b1d1e 1870 return idx;
wolfSSL 15:117db924cf7c 1871 }
wolfSSL 15:117db924cf7c 1872
wolfSSL 15:117db924cf7c 1873 WOLFSSL_MSG("Unknown/Unsupported content type");
wolfSSL 15:117db924cf7c 1874 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 1875 }
wolfSSL 15:117db924cf7c 1876
wolfSSL 15:117db924cf7c 1877
wolfSSL 16:8e0d178b1d1e 1878 /* helper function to create the PKCS12 key content
wolfSSL 16:8e0d178b1d1e 1879 * keyCiSz is output buffer size
wolfSSL 16:8e0d178b1d1e 1880 * returns a pointer to be free'd by caller on success and NULL on failure */
wolfSSL 16:8e0d178b1d1e 1881 static byte* PKCS12_create_key_content(WC_PKCS12* pkcs12, int nidKey,
wolfSSL 16:8e0d178b1d1e 1882 word32* keyCiSz, WC_RNG* rng, char* pass, word32 passSz,
wolfSSL 16:8e0d178b1d1e 1883 byte* key, word32 keySz, int iter)
wolfSSL 16:8e0d178b1d1e 1884 {
wolfSSL 16:8e0d178b1d1e 1885 byte* keyBuf;
wolfSSL 16:8e0d178b1d1e 1886 word32 keyBufSz = 0;
wolfSSL 16:8e0d178b1d1e 1887 byte* keyCi = NULL;
wolfSSL 16:8e0d178b1d1e 1888 word32 tmpSz;
wolfSSL 16:8e0d178b1d1e 1889 int ret;
wolfSSL 16:8e0d178b1d1e 1890 int algo;
wolfSSL 16:8e0d178b1d1e 1891 void* heap;
wolfSSL 16:8e0d178b1d1e 1892
wolfSSL 16:8e0d178b1d1e 1893 heap = wc_PKCS12_GetHeap(pkcs12);
wolfSSL 16:8e0d178b1d1e 1894 *keyCiSz = 0;
wolfSSL 16:8e0d178b1d1e 1895 switch (nidKey) {
wolfSSL 16:8e0d178b1d1e 1896 case PBE_SHA1_RC4_128:
wolfSSL 16:8e0d178b1d1e 1897 algo = 1;
wolfSSL 16:8e0d178b1d1e 1898 break;
wolfSSL 16:8e0d178b1d1e 1899
wolfSSL 16:8e0d178b1d1e 1900 case PBE_SHA1_DES:
wolfSSL 16:8e0d178b1d1e 1901 algo = 2;
wolfSSL 16:8e0d178b1d1e 1902 break;
wolfSSL 16:8e0d178b1d1e 1903
wolfSSL 16:8e0d178b1d1e 1904 case PBE_SHA1_DES3:
wolfSSL 16:8e0d178b1d1e 1905 algo = 3;
wolfSSL 16:8e0d178b1d1e 1906 break;
wolfSSL 16:8e0d178b1d1e 1907
wolfSSL 16:8e0d178b1d1e 1908 /* no encryption */
wolfSSL 16:8e0d178b1d1e 1909 case -1:
wolfSSL 16:8e0d178b1d1e 1910 algo = -1;
wolfSSL 16:8e0d178b1d1e 1911 break;
wolfSSL 16:8e0d178b1d1e 1912
wolfSSL 16:8e0d178b1d1e 1913 default:
wolfSSL 16:8e0d178b1d1e 1914 WOLFSSL_MSG("Unknown/Unsupported key encryption");
wolfSSL 16:8e0d178b1d1e 1915 return NULL;
wolfSSL 16:8e0d178b1d1e 1916 }
wolfSSL 16:8e0d178b1d1e 1917
wolfSSL 16:8e0d178b1d1e 1918 /* get max size for key bag */
wolfSSL 16:8e0d178b1d1e 1919 ret = wc_PKCS12_create_key_bag(pkcs12, rng, NULL, &keyBufSz, key, keySz,
wolfSSL 16:8e0d178b1d1e 1920 algo, iter, pass, passSz);
wolfSSL 16:8e0d178b1d1e 1921 if (ret != LENGTH_ONLY_E && ret < 0) {
wolfSSL 16:8e0d178b1d1e 1922 WOLFSSL_MSG("Error getting key bag size");
wolfSSL 16:8e0d178b1d1e 1923 return NULL;
wolfSSL 16:8e0d178b1d1e 1924 }
wolfSSL 16:8e0d178b1d1e 1925
wolfSSL 16:8e0d178b1d1e 1926 /* account for sequence around bag */
wolfSSL 16:8e0d178b1d1e 1927 keyBufSz += MAX_SEQ_SZ;
wolfSSL 16:8e0d178b1d1e 1928 keyBuf = (byte*)XMALLOC(keyBufSz, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 1929 if (keyBuf == NULL) {
wolfSSL 16:8e0d178b1d1e 1930 WOLFSSL_MSG("Memory error creating keyBuf buffer");
wolfSSL 16:8e0d178b1d1e 1931 return NULL;
wolfSSL 16:8e0d178b1d1e 1932 }
wolfSSL 16:8e0d178b1d1e 1933
wolfSSL 16:8e0d178b1d1e 1934 ret = wc_PKCS12_create_key_bag(pkcs12, rng, keyBuf + MAX_SEQ_SZ, &keyBufSz,
wolfSSL 16:8e0d178b1d1e 1935 key, keySz, algo, iter, pass, passSz);
wolfSSL 16:8e0d178b1d1e 1936 if (ret < 0) {
wolfSSL 16:8e0d178b1d1e 1937 XFREE(keyBuf, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 1938 WOLFSSL_MSG("Error creating key bag");
wolfSSL 16:8e0d178b1d1e 1939 return NULL;
wolfSSL 16:8e0d178b1d1e 1940 }
wolfSSL 16:8e0d178b1d1e 1941 keyBufSz = ret;
wolfSSL 16:8e0d178b1d1e 1942
wolfSSL 16:8e0d178b1d1e 1943 tmpSz = SetSequence(keyBufSz, keyBuf);
wolfSSL 16:8e0d178b1d1e 1944 XMEMMOVE(keyBuf + tmpSz, keyBuf + MAX_SEQ_SZ, keyBufSz);
wolfSSL 16:8e0d178b1d1e 1945 keyBufSz += tmpSz;
wolfSSL 16:8e0d178b1d1e 1946
wolfSSL 16:8e0d178b1d1e 1947 #ifdef WOLFSSL_DEBUG_PKCS12
wolfSSL 16:8e0d178b1d1e 1948 {
wolfSSL 16:8e0d178b1d1e 1949 word32 i;
wolfSSL 16:8e0d178b1d1e 1950 printf("(size %u) Key Bag = ", keyBufSz);
wolfSSL 16:8e0d178b1d1e 1951 for (i = 0; i < keyBufSz; i++)
wolfSSL 16:8e0d178b1d1e 1952 printf("%02X", keyBuf[i]);
wolfSSL 16:8e0d178b1d1e 1953 printf("\n");
wolfSSL 16:8e0d178b1d1e 1954 }
wolfSSL 16:8e0d178b1d1e 1955 #endif
wolfSSL 16:8e0d178b1d1e 1956 ret = wc_PKCS12_encrypt_content(pkcs12, rng, NULL, keyCiSz,
wolfSSL 16:8e0d178b1d1e 1957 NULL, keyBufSz, algo, pass, passSz, iter, WC_PKCS12_DATA);
wolfSSL 16:8e0d178b1d1e 1958 if (ret != LENGTH_ONLY_E) {
wolfSSL 16:8e0d178b1d1e 1959 XFREE(keyBuf, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 1960 WOLFSSL_MSG("Error getting key encrypt content size");
wolfSSL 16:8e0d178b1d1e 1961 return NULL;
wolfSSL 16:8e0d178b1d1e 1962 }
wolfSSL 16:8e0d178b1d1e 1963 keyCi = (byte*)XMALLOC(*keyCiSz, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 1964 if (keyCi == NULL) {
wolfSSL 16:8e0d178b1d1e 1965 XFREE(keyBuf, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 1966 return NULL;
wolfSSL 16:8e0d178b1d1e 1967 }
wolfSSL 16:8e0d178b1d1e 1968
wolfSSL 16:8e0d178b1d1e 1969 ret = wc_PKCS12_encrypt_content(pkcs12, rng, keyCi, keyCiSz,
wolfSSL 16:8e0d178b1d1e 1970 keyBuf, keyBufSz, algo, pass, passSz, iter, WC_PKCS12_DATA);
wolfSSL 16:8e0d178b1d1e 1971 XFREE(keyBuf, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 1972 if (ret < 0 ) {
wolfSSL 16:8e0d178b1d1e 1973 XFREE(keyCi, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 1974 WOLFSSL_MSG("Error creating key encrypt content");
wolfSSL 16:8e0d178b1d1e 1975 return NULL;
wolfSSL 16:8e0d178b1d1e 1976 }
wolfSSL 16:8e0d178b1d1e 1977 *keyCiSz = ret;
wolfSSL 16:8e0d178b1d1e 1978
wolfSSL 16:8e0d178b1d1e 1979 #ifdef WOLFSSL_DEBUG_PKCS12
wolfSSL 16:8e0d178b1d1e 1980 {
wolfSSL 16:8e0d178b1d1e 1981 word32 i;
wolfSSL 16:8e0d178b1d1e 1982 printf("(size %u) Key Content Info = ", *keyCiSz);
wolfSSL 16:8e0d178b1d1e 1983 for (i = 0; i < *keyCiSz; i++)
wolfSSL 16:8e0d178b1d1e 1984 printf("%02X", keyCi[i]);
wolfSSL 16:8e0d178b1d1e 1985 printf("\n");
wolfSSL 16:8e0d178b1d1e 1986 }
wolfSSL 16:8e0d178b1d1e 1987 #endif
wolfSSL 16:8e0d178b1d1e 1988
wolfSSL 16:8e0d178b1d1e 1989 (void)heap;
wolfSSL 16:8e0d178b1d1e 1990 return keyCi;
wolfSSL 16:8e0d178b1d1e 1991 }
wolfSSL 16:8e0d178b1d1e 1992
wolfSSL 16:8e0d178b1d1e 1993
wolfSSL 16:8e0d178b1d1e 1994 /* helper function to create the PKCS12 certificate content
wolfSSL 16:8e0d178b1d1e 1995 * certCiSz is output buffer size
wolfSSL 16:8e0d178b1d1e 1996 * returns a pointer to be free'd by caller on success and NULL on failure */
wolfSSL 16:8e0d178b1d1e 1997 static byte* PKCS12_create_cert_content(WC_PKCS12* pkcs12, int nidCert,
wolfSSL 16:8e0d178b1d1e 1998 WC_DerCertList* ca, byte* cert, word32 certSz, word32* certCiSz,
wolfSSL 16:8e0d178b1d1e 1999 WC_RNG* rng, char* pass, word32 passSz, int iter)
wolfSSL 16:8e0d178b1d1e 2000 {
wolfSSL 16:8e0d178b1d1e 2001 int algo;
wolfSSL 16:8e0d178b1d1e 2002 int ret;
wolfSSL 16:8e0d178b1d1e 2003 int type;
wolfSSL 16:8e0d178b1d1e 2004
wolfSSL 16:8e0d178b1d1e 2005 byte* certBuf = NULL;
wolfSSL 16:8e0d178b1d1e 2006 word32 certBufSz;
wolfSSL 16:8e0d178b1d1e 2007 word32 idx;
wolfSSL 16:8e0d178b1d1e 2008 word32 sz;
wolfSSL 16:8e0d178b1d1e 2009 word32 tmpSz;
wolfSSL 16:8e0d178b1d1e 2010
wolfSSL 16:8e0d178b1d1e 2011 byte* certCi;
wolfSSL 16:8e0d178b1d1e 2012 void* heap;
wolfSSL 16:8e0d178b1d1e 2013
wolfSSL 16:8e0d178b1d1e 2014 heap = wc_PKCS12_GetHeap(pkcs12);
wolfSSL 16:8e0d178b1d1e 2015 switch (nidCert) {
wolfSSL 16:8e0d178b1d1e 2016 case PBE_SHA1_RC4_128:
wolfSSL 16:8e0d178b1d1e 2017 type = WC_PKCS12_ENCRYPTED_DATA;
wolfSSL 16:8e0d178b1d1e 2018 algo = 1;
wolfSSL 16:8e0d178b1d1e 2019 break;
wolfSSL 16:8e0d178b1d1e 2020
wolfSSL 16:8e0d178b1d1e 2021 case PBE_SHA1_DES:
wolfSSL 16:8e0d178b1d1e 2022 type = WC_PKCS12_ENCRYPTED_DATA;
wolfSSL 16:8e0d178b1d1e 2023 algo = 2;
wolfSSL 16:8e0d178b1d1e 2024 break;
wolfSSL 16:8e0d178b1d1e 2025
wolfSSL 16:8e0d178b1d1e 2026 case PBE_SHA1_DES3:
wolfSSL 16:8e0d178b1d1e 2027 type = WC_PKCS12_ENCRYPTED_DATA;
wolfSSL 16:8e0d178b1d1e 2028 algo = 3;
wolfSSL 16:8e0d178b1d1e 2029 break;
wolfSSL 16:8e0d178b1d1e 2030
wolfSSL 16:8e0d178b1d1e 2031 case -1:
wolfSSL 16:8e0d178b1d1e 2032 type = WC_PKCS12_DATA;
wolfSSL 16:8e0d178b1d1e 2033 algo = -1;
wolfSSL 16:8e0d178b1d1e 2034 break;
wolfSSL 16:8e0d178b1d1e 2035
wolfSSL 16:8e0d178b1d1e 2036 default:
wolfSSL 16:8e0d178b1d1e 2037 WOLFSSL_MSG("Unknown/Unsupported certificate encryption");
wolfSSL 16:8e0d178b1d1e 2038 return NULL;
wolfSSL 16:8e0d178b1d1e 2039 }
wolfSSL 16:8e0d178b1d1e 2040
wolfSSL 16:8e0d178b1d1e 2041 /* get max size of buffer needed */
wolfSSL 16:8e0d178b1d1e 2042 ret = wc_PKCS12_create_cert_bag(pkcs12, NULL, &certBufSz, cert, certSz);
wolfSSL 16:8e0d178b1d1e 2043 if (ret != LENGTH_ONLY_E) {
wolfSSL 16:8e0d178b1d1e 2044 return NULL;
wolfSSL 16:8e0d178b1d1e 2045 }
wolfSSL 16:8e0d178b1d1e 2046
wolfSSL 16:8e0d178b1d1e 2047 if (ca != NULL) {
wolfSSL 16:8e0d178b1d1e 2048 WC_DerCertList* current = ca;
wolfSSL 16:8e0d178b1d1e 2049 word32 curBufSz = 0;
wolfSSL 16:8e0d178b1d1e 2050
wolfSSL 16:8e0d178b1d1e 2051 /* get max buffer size */
wolfSSL 16:8e0d178b1d1e 2052 while (current != NULL) {
wolfSSL 16:8e0d178b1d1e 2053 ret = wc_PKCS12_create_cert_bag(pkcs12, NULL, &curBufSz,
wolfSSL 16:8e0d178b1d1e 2054 current->buffer, current->bufferSz);
wolfSSL 16:8e0d178b1d1e 2055 if (ret != LENGTH_ONLY_E) {
wolfSSL 16:8e0d178b1d1e 2056 return NULL;
wolfSSL 16:8e0d178b1d1e 2057 }
wolfSSL 16:8e0d178b1d1e 2058 certBufSz += curBufSz;
wolfSSL 16:8e0d178b1d1e 2059 current = current->next;
wolfSSL 16:8e0d178b1d1e 2060 }
wolfSSL 16:8e0d178b1d1e 2061 }
wolfSSL 16:8e0d178b1d1e 2062
wolfSSL 16:8e0d178b1d1e 2063 /* account for Sequence that holds all certificate bags */
wolfSSL 16:8e0d178b1d1e 2064 certBufSz += MAX_SEQ_SZ;
wolfSSL 16:8e0d178b1d1e 2065
wolfSSL 16:8e0d178b1d1e 2066 /* completed getting max size, now create buffer and start adding bags */
wolfSSL 16:8e0d178b1d1e 2067 certBuf = (byte*)XMALLOC(certBufSz, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 2068 if (certBuf == NULL) {
wolfSSL 16:8e0d178b1d1e 2069 WOLFSSL_MSG("Memory error creating certificate bags");
wolfSSL 16:8e0d178b1d1e 2070 return NULL;
wolfSSL 16:8e0d178b1d1e 2071 }
wolfSSL 16:8e0d178b1d1e 2072
wolfSSL 16:8e0d178b1d1e 2073 idx = 0;
wolfSSL 16:8e0d178b1d1e 2074 idx += MAX_SEQ_SZ;
wolfSSL 16:8e0d178b1d1e 2075
wolfSSL 16:8e0d178b1d1e 2076 sz = certBufSz - idx;
wolfSSL 16:8e0d178b1d1e 2077 if ((ret = wc_PKCS12_create_cert_bag(pkcs12, certBuf + idx, &sz,
wolfSSL 16:8e0d178b1d1e 2078 cert, certSz)) < 0) {
wolfSSL 16:8e0d178b1d1e 2079 XFREE(certBuf, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 2080 return NULL;
wolfSSL 16:8e0d178b1d1e 2081 }
wolfSSL 16:8e0d178b1d1e 2082 idx += ret;
wolfSSL 16:8e0d178b1d1e 2083
wolfSSL 16:8e0d178b1d1e 2084 if (ca != NULL) {
wolfSSL 16:8e0d178b1d1e 2085 WC_DerCertList* current = ca;
wolfSSL 16:8e0d178b1d1e 2086
wolfSSL 16:8e0d178b1d1e 2087 while (current != NULL) {
wolfSSL 16:8e0d178b1d1e 2088 sz = certBufSz - idx;
wolfSSL 16:8e0d178b1d1e 2089 if ((ret = wc_PKCS12_create_cert_bag(pkcs12, certBuf + idx, &sz,
wolfSSL 16:8e0d178b1d1e 2090 current->buffer, current->bufferSz)) < 0) {
wolfSSL 16:8e0d178b1d1e 2091 XFREE(certBuf, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 2092 return NULL;
wolfSSL 16:8e0d178b1d1e 2093 }
wolfSSL 16:8e0d178b1d1e 2094 idx += ret;
wolfSSL 16:8e0d178b1d1e 2095 current = current->next;
wolfSSL 16:8e0d178b1d1e 2096 }
wolfSSL 16:8e0d178b1d1e 2097 }
wolfSSL 16:8e0d178b1d1e 2098
wolfSSL 16:8e0d178b1d1e 2099 /* set sequence and create encrypted content with all certificate bags */
wolfSSL 16:8e0d178b1d1e 2100 tmpSz = SetSequence(idx - MAX_SEQ_SZ, certBuf);
wolfSSL 16:8e0d178b1d1e 2101 XMEMMOVE(certBuf + tmpSz, certBuf + MAX_SEQ_SZ, idx - MAX_SEQ_SZ);
wolfSSL 16:8e0d178b1d1e 2102 certBufSz = tmpSz + (idx - MAX_SEQ_SZ);
wolfSSL 16:8e0d178b1d1e 2103
wolfSSL 16:8e0d178b1d1e 2104 /* get buffer size needed for content info */
wolfSSL 16:8e0d178b1d1e 2105 ret = wc_PKCS12_encrypt_content(pkcs12, rng, NULL, certCiSz,
wolfSSL 16:8e0d178b1d1e 2106 NULL, certBufSz, algo, pass, passSz, iter, type);
wolfSSL 16:8e0d178b1d1e 2107 if (ret != LENGTH_ONLY_E) {
wolfSSL 16:8e0d178b1d1e 2108 XFREE(certBuf, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 2109 WOLFSSL_LEAVE("wc_PKCS12_create()", ret);
wolfSSL 16:8e0d178b1d1e 2110 return NULL;
wolfSSL 16:8e0d178b1d1e 2111 }
wolfSSL 16:8e0d178b1d1e 2112 certCi = (byte*)XMALLOC(*certCiSz, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 2113 if (certCi == NULL) {
wolfSSL 16:8e0d178b1d1e 2114 XFREE(certBuf, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 2115 return NULL;
wolfSSL 16:8e0d178b1d1e 2116 }
wolfSSL 16:8e0d178b1d1e 2117
wolfSSL 16:8e0d178b1d1e 2118 ret = wc_PKCS12_encrypt_content(pkcs12, rng, certCi, certCiSz,
wolfSSL 16:8e0d178b1d1e 2119 certBuf, certBufSz, algo, pass, passSz, iter, type);
wolfSSL 16:8e0d178b1d1e 2120 XFREE(certBuf, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 2121 if (ret < 0) {
wolfSSL 16:8e0d178b1d1e 2122 WOLFSSL_LEAVE("wc_PKCS12_create()", ret);
wolfSSL 16:8e0d178b1d1e 2123 return NULL;
wolfSSL 16:8e0d178b1d1e 2124 }
wolfSSL 16:8e0d178b1d1e 2125 *certCiSz = ret;
wolfSSL 16:8e0d178b1d1e 2126
wolfSSL 16:8e0d178b1d1e 2127 #ifdef WOLFSSL_DEBUG_PKCS12
wolfSSL 16:8e0d178b1d1e 2128 {
wolfSSL 16:8e0d178b1d1e 2129 word32 i;
wolfSSL 16:8e0d178b1d1e 2130 printf("(size %u) Encrypted Certificate Content Info = ", *certCiSz);
wolfSSL 16:8e0d178b1d1e 2131 for (i = 0; i < *certCiSz; i++)
wolfSSL 16:8e0d178b1d1e 2132 printf("%02X", certCi[i]);
wolfSSL 16:8e0d178b1d1e 2133 printf("\n");
wolfSSL 16:8e0d178b1d1e 2134 }
wolfSSL 16:8e0d178b1d1e 2135 #endif
wolfSSL 16:8e0d178b1d1e 2136
wolfSSL 16:8e0d178b1d1e 2137 (void)heap;
wolfSSL 16:8e0d178b1d1e 2138 return certCi;
wolfSSL 16:8e0d178b1d1e 2139 }
wolfSSL 16:8e0d178b1d1e 2140
wolfSSL 16:8e0d178b1d1e 2141
wolfSSL 16:8e0d178b1d1e 2142 /* helper function to create the PKCS12 safe
wolfSSL 16:8e0d178b1d1e 2143 * returns 0 on success */
wolfSSL 16:8e0d178b1d1e 2144 static int PKCS12_create_safe(WC_PKCS12* pkcs12, byte* certCi, word32 certCiSz,
wolfSSL 16:8e0d178b1d1e 2145 byte* keyCi, word32 keyCiSz, WC_RNG* rng, char* pass, word32 passSz,
wolfSSL 16:8e0d178b1d1e 2146 int iter)
wolfSSL 16:8e0d178b1d1e 2147 {
wolfSSL 16:8e0d178b1d1e 2148 int length;
wolfSSL 16:8e0d178b1d1e 2149 int ret;
wolfSSL 16:8e0d178b1d1e 2150 byte seq[MAX_SEQ_SZ];
wolfSSL 16:8e0d178b1d1e 2151 word32 safeDataSz;
wolfSSL 16:8e0d178b1d1e 2152 word32 innerDataSz;
wolfSSL 16:8e0d178b1d1e 2153 byte *innerData = NULL;
wolfSSL 16:8e0d178b1d1e 2154 byte *safeData = NULL;
wolfSSL 16:8e0d178b1d1e 2155 word32 idx;
wolfSSL 16:8e0d178b1d1e 2156
wolfSSL 16:8e0d178b1d1e 2157 innerDataSz = certCiSz + keyCiSz+SetSequence(certCiSz + keyCiSz, seq);
wolfSSL 16:8e0d178b1d1e 2158
wolfSSL 16:8e0d178b1d1e 2159 /* add Content Info structs to safe, key first then cert */
wolfSSL 16:8e0d178b1d1e 2160 ret = wc_PKCS12_encrypt_content(pkcs12, rng, NULL, &safeDataSz,
wolfSSL 16:8e0d178b1d1e 2161 NULL, innerDataSz, 0, NULL, 0, 0, WC_PKCS12_DATA);
wolfSSL 16:8e0d178b1d1e 2162 if (ret != LENGTH_ONLY_E) {
wolfSSL 16:8e0d178b1d1e 2163 return ret;
wolfSSL 16:8e0d178b1d1e 2164 }
wolfSSL 16:8e0d178b1d1e 2165
wolfSSL 16:8e0d178b1d1e 2166 safeData = (byte*)XMALLOC(safeDataSz, pkcs12->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 2167 if (safeData == NULL) {
wolfSSL 16:8e0d178b1d1e 2168 WOLFSSL_MSG("Error malloc'ing safe data buffer");
wolfSSL 16:8e0d178b1d1e 2169 return MEMORY_E;
wolfSSL 16:8e0d178b1d1e 2170 }
wolfSSL 16:8e0d178b1d1e 2171
wolfSSL 16:8e0d178b1d1e 2172 /* create sequence of inner data */
wolfSSL 16:8e0d178b1d1e 2173 innerData = (byte*)XMALLOC(innerDataSz, pkcs12->heap, DYNAMIC_TYPE_PKCS);
wolfSSL 16:8e0d178b1d1e 2174 if (innerData == NULL) {
wolfSSL 16:8e0d178b1d1e 2175 WOLFSSL_MSG("Error malloc'ing inner data buffer");
wolfSSL 16:8e0d178b1d1e 2176 XFREE(safeData, pkcs12->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 2177 return MEMORY_E;
wolfSSL 16:8e0d178b1d1e 2178 }
wolfSSL 16:8e0d178b1d1e 2179 idx = 0;
wolfSSL 16:8e0d178b1d1e 2180 idx += SetSequence(certCiSz + keyCiSz, innerData);
wolfSSL 16:8e0d178b1d1e 2181 XMEMCPY(innerData + idx, certCi, certCiSz);
wolfSSL 16:8e0d178b1d1e 2182 XMEMCPY(innerData + idx + certCiSz, keyCi, keyCiSz);
wolfSSL 16:8e0d178b1d1e 2183
wolfSSL 16:8e0d178b1d1e 2184 ret = wc_PKCS12_encrypt_content(pkcs12, rng, safeData, &safeDataSz,
wolfSSL 16:8e0d178b1d1e 2185 innerData, innerDataSz, 0, pass, passSz, iter, WC_PKCS12_DATA);
wolfSSL 16:8e0d178b1d1e 2186 XFREE(innerData, pkcs12->heap, DYNAMIC_TYPE_PKCS);
wolfSSL 16:8e0d178b1d1e 2187 if (ret < 0 ) {
wolfSSL 16:8e0d178b1d1e 2188 WOLFSSL_MSG("Error setting data type for safe contents");
wolfSSL 16:8e0d178b1d1e 2189 XFREE(safeData, pkcs12->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 2190 return ret;
wolfSSL 16:8e0d178b1d1e 2191 }
wolfSSL 16:8e0d178b1d1e 2192 idx = 0;
wolfSSL 16:8e0d178b1d1e 2193
wolfSSL 16:8e0d178b1d1e 2194 ret = GetSequence(safeData, &idx, &length, safeDataSz);
wolfSSL 16:8e0d178b1d1e 2195 if (ret < 0) {
wolfSSL 16:8e0d178b1d1e 2196 WOLFSSL_MSG("Error getting first sequence of safe");
wolfSSL 16:8e0d178b1d1e 2197 XFREE(safeData, pkcs12->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 2198 return ret;
wolfSSL 16:8e0d178b1d1e 2199 }
wolfSSL 16:8e0d178b1d1e 2200
wolfSSL 16:8e0d178b1d1e 2201 ret = GetSafeContent(pkcs12, safeData, &idx, safeDataSz);
wolfSSL 16:8e0d178b1d1e 2202 XFREE(safeData, pkcs12->heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 2203 if (ret < 0) {
wolfSSL 16:8e0d178b1d1e 2204 WOLFSSL_MSG("Unable to create safe contents");
wolfSSL 16:8e0d178b1d1e 2205 return ret;
wolfSSL 16:8e0d178b1d1e 2206 }
wolfSSL 16:8e0d178b1d1e 2207 return 0;
wolfSSL 16:8e0d178b1d1e 2208 }
wolfSSL 16:8e0d178b1d1e 2209
wolfSSL 16:8e0d178b1d1e 2210
wolfSSL 15:117db924cf7c 2211 /*
wolfSSL 15:117db924cf7c 2212 * pass : password to use with encryption
wolfSSL 15:117db924cf7c 2213 * passSz : size of the password buffer
wolfSSL 15:117db924cf7c 2214 * name : friendlyName to use
wolfSSL 15:117db924cf7c 2215 * key : DER format of key
wolfSSL 15:117db924cf7c 2216 * keySz : size of key buffer
wolfSSL 15:117db924cf7c 2217 * cert : DER format of certificate
wolfSSL 15:117db924cf7c 2218 * certSz : size of the certificate buffer
wolfSSL 15:117db924cf7c 2219 * ca : a list of extra certificates
wolfSSL 15:117db924cf7c 2220 * nidKey : type of encryption to use on the key (-1 means no encryption)
wolfSSL 15:117db924cf7c 2221 * nidCert : type of encryption to use on the certificate
wolfSSL 15:117db924cf7c 2222 * (-1 means no encryption)
wolfSSL 15:117db924cf7c 2223 * iter : number of iterations with encryption
wolfSSL 15:117db924cf7c 2224 * macIter : number of iterations when creating MAC
wolfSSL 15:117db924cf7c 2225 * keyType : flag for signature and/or encryption key
wolfSSL 15:117db924cf7c 2226 * heap : pointer to allocate from memory
wolfSSL 15:117db924cf7c 2227 *
wolfSSL 15:117db924cf7c 2228 * returns a pointer to a new WC_PKCS12 structure on success and NULL if failed
wolfSSL 15:117db924cf7c 2229 */
wolfSSL 15:117db924cf7c 2230 WC_PKCS12* wc_PKCS12_create(char* pass, word32 passSz, char* name,
wolfSSL 15:117db924cf7c 2231 byte* key, word32 keySz, byte* cert, word32 certSz, WC_DerCertList* ca,
wolfSSL 15:117db924cf7c 2232 int nidKey, int nidCert, int iter, int macIter, int keyType, void* heap)
wolfSSL 15:117db924cf7c 2233 {
wolfSSL 16:8e0d178b1d1e 2234 WC_PKCS12* pkcs12;
wolfSSL 16:8e0d178b1d1e 2235 WC_RNG rng;
wolfSSL 15:117db924cf7c 2236 int ret;
wolfSSL 15:117db924cf7c 2237
wolfSSL 15:117db924cf7c 2238 byte* certCi = NULL;
wolfSSL 16:8e0d178b1d1e 2239 byte* keyCi = NULL;
wolfSSL 15:117db924cf7c 2240 word32 certCiSz;
wolfSSL 15:117db924cf7c 2241 word32 keyCiSz;
wolfSSL 15:117db924cf7c 2242
wolfSSL 15:117db924cf7c 2243 WOLFSSL_ENTER("wc_PKCS12_create()");
wolfSSL 15:117db924cf7c 2244
wolfSSL 15:117db924cf7c 2245 if ((ret = wc_InitRng_ex(&rng, heap, INVALID_DEVID)) != 0) {
wolfSSL 15:117db924cf7c 2246 return NULL;
wolfSSL 15:117db924cf7c 2247 }
wolfSSL 15:117db924cf7c 2248
wolfSSL 15:117db924cf7c 2249 if ((pkcs12 = wc_PKCS12_new()) == NULL) {
wolfSSL 15:117db924cf7c 2250 wc_FreeRng(&rng);
wolfSSL 15:117db924cf7c 2251 WOLFSSL_LEAVE("wc_PKCS12_create", MEMORY_E);
wolfSSL 15:117db924cf7c 2252 return NULL;
wolfSSL 15:117db924cf7c 2253 }
wolfSSL 15:117db924cf7c 2254
wolfSSL 15:117db924cf7c 2255 if ((ret = wc_PKCS12_SetHeap(pkcs12, heap)) != 0) {
wolfSSL 15:117db924cf7c 2256 wc_PKCS12_free(pkcs12);
wolfSSL 15:117db924cf7c 2257 wc_FreeRng(&rng);
wolfSSL 15:117db924cf7c 2258 WOLFSSL_LEAVE("wc_PKCS12_create", ret);
wolfSSL 15:117db924cf7c 2259 return NULL;
wolfSSL 15:117db924cf7c 2260 }
wolfSSL 15:117db924cf7c 2261
wolfSSL 15:117db924cf7c 2262 if (iter <= 0) {
wolfSSL 15:117db924cf7c 2263 iter = WC_PKCS12_ITT_DEFAULT;
wolfSSL 15:117db924cf7c 2264 }
wolfSSL 15:117db924cf7c 2265
wolfSSL 15:117db924cf7c 2266 /**** add private key bag ****/
wolfSSL 16:8e0d178b1d1e 2267 keyCi = PKCS12_create_key_content(pkcs12, nidKey, &keyCiSz, &rng,
wolfSSL 16:8e0d178b1d1e 2268 pass, passSz, key, keySz, iter);
wolfSSL 16:8e0d178b1d1e 2269 if (keyCi == NULL) {
wolfSSL 15:117db924cf7c 2270 wc_PKCS12_free(pkcs12);
wolfSSL 15:117db924cf7c 2271 wc_FreeRng(&rng);
wolfSSL 15:117db924cf7c 2272 return NULL;
wolfSSL 15:117db924cf7c 2273 }
wolfSSL 15:117db924cf7c 2274
wolfSSL 15:117db924cf7c 2275 /**** add main certificate bag and extras ****/
wolfSSL 16:8e0d178b1d1e 2276 certCi = PKCS12_create_cert_content(pkcs12, nidCert, ca, cert, certSz,
wolfSSL 16:8e0d178b1d1e 2277 &certCiSz, &rng, pass, passSz, iter);
wolfSSL 16:8e0d178b1d1e 2278 if (certCi == NULL) {
wolfSSL 15:117db924cf7c 2279 XFREE(keyCi, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 2280 wc_PKCS12_free(pkcs12);
wolfSSL 15:117db924cf7c 2281 wc_FreeRng(&rng);
wolfSSL 15:117db924cf7c 2282 return NULL;
wolfSSL 15:117db924cf7c 2283 }
wolfSSL 15:117db924cf7c 2284
wolfSSL 16:8e0d178b1d1e 2285 /**** create safe and Content Info ****/
wolfSSL 16:8e0d178b1d1e 2286 ret = PKCS12_create_safe(pkcs12, certCi, certCiSz, keyCi, keyCiSz, &rng,
wolfSSL 16:8e0d178b1d1e 2287 pass, passSz, iter);
wolfSSL 16:8e0d178b1d1e 2288 XFREE(keyCi, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 2289 XFREE(certCi, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 2290 if (ret != 0) {
wolfSSL 16:8e0d178b1d1e 2291 WOLFSSL_MSG("Unable to create PKCS12 safe");
wolfSSL 15:117db924cf7c 2292 wc_PKCS12_free(pkcs12);
wolfSSL 15:117db924cf7c 2293 wc_FreeRng(&rng);
wolfSSL 15:117db924cf7c 2294 return NULL;
wolfSSL 15:117db924cf7c 2295 }
wolfSSL 15:117db924cf7c 2296
wolfSSL 15:117db924cf7c 2297 /* create MAC */
wolfSSL 15:117db924cf7c 2298 if (macIter > 0) {
wolfSSL 15:117db924cf7c 2299 MacData* mac;
wolfSSL 15:117db924cf7c 2300 byte digest[WC_MAX_DIGEST_SIZE]; /* for MAC */
wolfSSL 15:117db924cf7c 2301
wolfSSL 15:117db924cf7c 2302 mac = (MacData*)XMALLOC(sizeof(MacData), heap, DYNAMIC_TYPE_PKCS);
wolfSSL 15:117db924cf7c 2303 if (mac == NULL) {
wolfSSL 15:117db924cf7c 2304 wc_PKCS12_free(pkcs12);
wolfSSL 15:117db924cf7c 2305 wc_FreeRng(&rng);
wolfSSL 16:8e0d178b1d1e 2306 WOLFSSL_MSG("Error malloc'ing mac data buffer");
wolfSSL 15:117db924cf7c 2307 return NULL;
wolfSSL 15:117db924cf7c 2308 }
wolfSSL 15:117db924cf7c 2309 XMEMSET(mac, 0, sizeof(MacData));
wolfSSL 15:117db924cf7c 2310 pkcs12->signData = mac; /* now wc_PKCS12_free will free all mac too */
wolfSSL 15:117db924cf7c 2311
wolfSSL 15:117db924cf7c 2312 #ifndef NO_SHA256
wolfSSL 15:117db924cf7c 2313 mac->oid = SHA256h;
wolfSSL 15:117db924cf7c 2314 #elif !defined(NO_SHA)
wolfSSL 15:117db924cf7c 2315 mac->oid = SHA;
wolfSSL 15:117db924cf7c 2316 #elif defined(WOLFSSL_SHA384)
wolfSSL 15:117db924cf7c 2317 mac->oid = SHA384;
wolfSSL 15:117db924cf7c 2318 #elif defined(WOLFSSL_SHA512)
wolfSSL 15:117db924cf7c 2319 mac->oid = SHA512;
wolfSSL 15:117db924cf7c 2320 #else
wolfSSL 15:117db924cf7c 2321 WOLFSSL_MSG("No supported hash algorithm compiled in!");
wolfSSL 15:117db924cf7c 2322 wc_PKCS12_free(pkcs12);
wolfSSL 15:117db924cf7c 2323 wc_FreeRng(&rng);
wolfSSL 15:117db924cf7c 2324 return NULL;
wolfSSL 15:117db924cf7c 2325 #endif
wolfSSL 15:117db924cf7c 2326
wolfSSL 15:117db924cf7c 2327 /* store number of iterations */
wolfSSL 15:117db924cf7c 2328 mac->itt = macIter;
wolfSSL 15:117db924cf7c 2329
wolfSSL 15:117db924cf7c 2330 /* set mac salt */
wolfSSL 15:117db924cf7c 2331 mac->saltSz = 8;
wolfSSL 15:117db924cf7c 2332 mac->salt = (byte*)XMALLOC(mac->saltSz, heap, DYNAMIC_TYPE_PKCS);
wolfSSL 15:117db924cf7c 2333 if (mac->salt == NULL) {
wolfSSL 15:117db924cf7c 2334 wc_PKCS12_free(pkcs12);
wolfSSL 15:117db924cf7c 2335 wc_FreeRng(&rng);
wolfSSL 16:8e0d178b1d1e 2336 WOLFSSL_MSG("Error malloc'ing salt data buffer");
wolfSSL 15:117db924cf7c 2337 return NULL;
wolfSSL 15:117db924cf7c 2338 }
wolfSSL 15:117db924cf7c 2339
wolfSSL 15:117db924cf7c 2340 if ((ret = wc_RNG_GenerateBlock(&rng, mac->salt, mac->saltSz)) != 0) {
wolfSSL 15:117db924cf7c 2341 WOLFSSL_MSG("Error generating random salt");
wolfSSL 15:117db924cf7c 2342 wc_PKCS12_free(pkcs12);
wolfSSL 15:117db924cf7c 2343 wc_FreeRng(&rng);
wolfSSL 15:117db924cf7c 2344 return NULL;
wolfSSL 15:117db924cf7c 2345 }
wolfSSL 16:8e0d178b1d1e 2346 ret = wc_PKCS12_create_mac(pkcs12, pkcs12->safe->data,
wolfSSL 16:8e0d178b1d1e 2347 pkcs12->safe->dataSz, (const byte*)pass, passSz, digest,
wolfSSL 16:8e0d178b1d1e 2348 WC_MAX_DIGEST_SIZE);
wolfSSL 15:117db924cf7c 2349 if (ret < 0) {
wolfSSL 15:117db924cf7c 2350 wc_PKCS12_free(pkcs12);
wolfSSL 15:117db924cf7c 2351 wc_FreeRng(&rng);
wolfSSL 16:8e0d178b1d1e 2352 WOLFSSL_MSG("Error creating mac");
wolfSSL 16:8e0d178b1d1e 2353 WOLFSSL_LEAVE("wc_PKCS12_create", ret);
wolfSSL 15:117db924cf7c 2354 return NULL;
wolfSSL 15:117db924cf7c 2355 }
wolfSSL 15:117db924cf7c 2356
wolfSSL 15:117db924cf7c 2357 mac->digestSz = ret;
wolfSSL 15:117db924cf7c 2358 mac->digest = (byte*)XMALLOC(ret, heap, DYNAMIC_TYPE_PKCS);
wolfSSL 15:117db924cf7c 2359 if (mac->digest == NULL) {
wolfSSL 16:8e0d178b1d1e 2360 WOLFSSL_MSG("Error malloc'ing mac digest buffer");
wolfSSL 15:117db924cf7c 2361 wc_PKCS12_free(pkcs12);
wolfSSL 15:117db924cf7c 2362 wc_FreeRng(&rng);
wolfSSL 15:117db924cf7c 2363 return NULL;
wolfSSL 15:117db924cf7c 2364 }
wolfSSL 15:117db924cf7c 2365 XMEMCPY(mac->digest, digest, mac->digestSz);
wolfSSL 15:117db924cf7c 2366 }
wolfSSL 15:117db924cf7c 2367 else {
wolfSSL 15:117db924cf7c 2368 pkcs12->signData = NULL;
wolfSSL 15:117db924cf7c 2369 }
wolfSSL 15:117db924cf7c 2370
wolfSSL 15:117db924cf7c 2371 wc_FreeRng(&rng);
wolfSSL 15:117db924cf7c 2372 (void)name;
wolfSSL 15:117db924cf7c 2373 (void)keyType;
wolfSSL 15:117db924cf7c 2374
wolfSSL 15:117db924cf7c 2375 return pkcs12;
wolfSSL 15:117db924cf7c 2376 }
wolfSSL 15:117db924cf7c 2377
wolfSSL 15:117db924cf7c 2378
wolfSSL 15:117db924cf7c 2379 /* if using a specific memory heap */
wolfSSL 15:117db924cf7c 2380 int wc_PKCS12_SetHeap(WC_PKCS12* pkcs12, void* heap)
wolfSSL 15:117db924cf7c 2381 {
wolfSSL 15:117db924cf7c 2382 if (pkcs12 == NULL) {
wolfSSL 15:117db924cf7c 2383 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 2384 }
wolfSSL 15:117db924cf7c 2385 pkcs12->heap = heap;
wolfSSL 15:117db924cf7c 2386
wolfSSL 15:117db924cf7c 2387 return 0;
wolfSSL 15:117db924cf7c 2388 }
wolfSSL 15:117db924cf7c 2389
wolfSSL 15:117db924cf7c 2390
wolfSSL 15:117db924cf7c 2391 /* getter for heap */
wolfSSL 15:117db924cf7c 2392 void* wc_PKCS12_GetHeap(WC_PKCS12* pkcs12)
wolfSSL 15:117db924cf7c 2393 {
wolfSSL 15:117db924cf7c 2394 if (pkcs12 == NULL) {
wolfSSL 15:117db924cf7c 2395 return NULL;
wolfSSL 15:117db924cf7c 2396 }
wolfSSL 15:117db924cf7c 2397
wolfSSL 15:117db924cf7c 2398 return pkcs12->heap;
wolfSSL 15:117db924cf7c 2399 }
wolfSSL 15:117db924cf7c 2400
wolfSSL 15:117db924cf7c 2401 #undef ERROR_OUT
wolfSSL 15:117db924cf7c 2402
wolfSSL 16:8e0d178b1d1e 2403 #endif /* !NO_ASN && !NO_PWDBASED && HAVE_PKCS12 */
wolfSSL 15:117db924cf7c 2404