Xuyi Wang / wolfSSL

Dependents:   OS

Committer:
wolfSSL
Date:
Sat Aug 18 22:20:43 2018 +0000
Revision:
15:117db924cf7c
wolfSSL 3.15.3

Who changed what in which revision?

UserRevisionLine numberNew contents of line
wolfSSL 15:117db924cf7c 1 /* pkcs12.c
wolfSSL 15:117db924cf7c 2 *
wolfSSL 15:117db924cf7c 3 * Copyright (C) 2006-2017 wolfSSL Inc.
wolfSSL 15:117db924cf7c 4 *
wolfSSL 15:117db924cf7c 5 * This file is part of wolfSSL.
wolfSSL 15:117db924cf7c 6 *
wolfSSL 15:117db924cf7c 7 * wolfSSL is free software; you can redistribute it and/or modify
wolfSSL 15:117db924cf7c 8 * it under the terms of the GNU General Public License as published by
wolfSSL 15:117db924cf7c 9 * the Free Software Foundation; either version 2 of the License, or
wolfSSL 15:117db924cf7c 10 * (at your option) any later version.
wolfSSL 15:117db924cf7c 11 *
wolfSSL 15:117db924cf7c 12 * wolfSSL is distributed in the hope that it will be useful,
wolfSSL 15:117db924cf7c 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
wolfSSL 15:117db924cf7c 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
wolfSSL 15:117db924cf7c 15 * GNU General Public License for more details.
wolfSSL 15:117db924cf7c 16 *
wolfSSL 15:117db924cf7c 17 * You should have received a copy of the GNU General Public License
wolfSSL 15:117db924cf7c 18 * along with this program; if not, write to the Free Software
wolfSSL 15:117db924cf7c 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
wolfSSL 15:117db924cf7c 20 */
wolfSSL 15:117db924cf7c 21
wolfSSL 15:117db924cf7c 22
wolfSSL 15:117db924cf7c 23 #ifdef HAVE_CONFIG_H
wolfSSL 15:117db924cf7c 24 #include <config.h>
wolfSSL 15:117db924cf7c 25 #endif
wolfSSL 15:117db924cf7c 26
wolfSSL 15:117db924cf7c 27 #include <wolfssl/wolfcrypt/settings.h>
wolfSSL 15:117db924cf7c 28
wolfSSL 15:117db924cf7c 29 #if !defined(NO_ASN) && !defined(NO_PWDBASED)
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 15:117db924cf7c 63 /* static const byte WC_PKCS12_ENCRYPTED_OID[] =
wolfSSL 15:117db924cf7c 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 15:117db924cf7c 82 int type; /* DATA / encrypted / envelpoed */
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 15:117db924cf7c 101 int itt; /* number of itterations 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 15:117db924cf7c 201
wolfSSL 15:117db924cf7c 202 safe = (AuthenticatedSafe*)XMALLOC(sizeof(AuthenticatedSafe), pkcs12->heap,
wolfSSL 15:117db924cf7c 203 DYNAMIC_TYPE_PKCS);
wolfSSL 15:117db924cf7c 204 if (safe == NULL) {
wolfSSL 15:117db924cf7c 205 return MEMORY_E;
wolfSSL 15:117db924cf7c 206 }
wolfSSL 15:117db924cf7c 207 XMEMSET(safe, 0, sizeof(AuthenticatedSafe));
wolfSSL 15:117db924cf7c 208
wolfSSL 15:117db924cf7c 209 ret = GetObjectId(input, &localIdx, &oid, oidIgnoreType, maxIdx);
wolfSSL 15:117db924cf7c 210 if (ret < 0) {
wolfSSL 15:117db924cf7c 211 WOLFSSL_LEAVE("Get object id failed", ret);
wolfSSL 15:117db924cf7c 212 freeSafe(safe, pkcs12->heap);
wolfSSL 15:117db924cf7c 213 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 214 }
wolfSSL 15:117db924cf7c 215
wolfSSL 15:117db924cf7c 216 safe->oid = oid;
wolfSSL 15:117db924cf7c 217 /* check tag, length */
wolfSSL 15:117db924cf7c 218 if (input[localIdx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) {
wolfSSL 15:117db924cf7c 219 WOLFSSL_MSG("Unexpected tag in PKCS12 DER");
wolfSSL 15:117db924cf7c 220 freeSafe(safe, pkcs12->heap);
wolfSSL 15:117db924cf7c 221 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 222 }
wolfSSL 15:117db924cf7c 223 if ((ret = GetLength(input, &localIdx, &size, maxIdx)) <= 0) {
wolfSSL 15:117db924cf7c 224 freeSafe(safe, pkcs12->heap);
wolfSSL 15:117db924cf7c 225 return ret;
wolfSSL 15:117db924cf7c 226 }
wolfSSL 15:117db924cf7c 227
wolfSSL 15:117db924cf7c 228 switch (oid) {
wolfSSL 15:117db924cf7c 229 case WC_PKCS12_ENCRYPTED_DATA:
wolfSSL 15:117db924cf7c 230 WOLFSSL_MSG("Found PKCS12 OBJECT: ENCRYPTED DATA\n");
wolfSSL 15:117db924cf7c 231 break;
wolfSSL 15:117db924cf7c 232
wolfSSL 15:117db924cf7c 233 case WC_PKCS12_DATA:
wolfSSL 15:117db924cf7c 234 WOLFSSL_MSG("Found PKCS12 OBJECT: DATA");
wolfSSL 15:117db924cf7c 235 /* get octets holding contents */
wolfSSL 15:117db924cf7c 236 if (input[localIdx++] != ASN_OCTET_STRING) {
wolfSSL 15:117db924cf7c 237 WOLFSSL_MSG("Wrong tag with content PKCS12 type DATA");
wolfSSL 15:117db924cf7c 238 freeSafe(safe, pkcs12->heap);
wolfSSL 15:117db924cf7c 239 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 240 }
wolfSSL 15:117db924cf7c 241 if ((ret = GetLength(input, &localIdx, &size, maxIdx)) <= 0) {
wolfSSL 15:117db924cf7c 242 freeSafe(safe, pkcs12->heap);
wolfSSL 15:117db924cf7c 243 return ret;
wolfSSL 15:117db924cf7c 244 }
wolfSSL 15:117db924cf7c 245
wolfSSL 15:117db924cf7c 246 break;
wolfSSL 15:117db924cf7c 247 }
wolfSSL 15:117db924cf7c 248
wolfSSL 15:117db924cf7c 249 safe->dataSz = size;
wolfSSL 15:117db924cf7c 250 safe->data = (byte*)XMALLOC(size, pkcs12->heap, DYNAMIC_TYPE_PKCS);
wolfSSL 15:117db924cf7c 251 if (safe->data == NULL) {
wolfSSL 15:117db924cf7c 252 freeSafe(safe, pkcs12->heap);
wolfSSL 15:117db924cf7c 253 return MEMORY_E;
wolfSSL 15:117db924cf7c 254 }
wolfSSL 15:117db924cf7c 255 XMEMCPY(safe->data, input + localIdx, size);
wolfSSL 15:117db924cf7c 256 *idx = localIdx;
wolfSSL 15:117db924cf7c 257
wolfSSL 15:117db924cf7c 258 /* an instance of AuthenticatedSafe is created from
wolfSSL 15:117db924cf7c 259 * ContentInfo's strung together in a SEQUENCE. Here we itterate
wolfSSL 15:117db924cf7c 260 * through the ContentInfo's and add them to our
wolfSSL 15:117db924cf7c 261 * AuthenticatedSafe struct */
wolfSSL 15:117db924cf7c 262 localIdx = 0;
wolfSSL 15:117db924cf7c 263 input = safe->data;
wolfSSL 15:117db924cf7c 264 {
wolfSSL 15:117db924cf7c 265 int CISz;
wolfSSL 15:117db924cf7c 266 ret = GetSequence(input, &localIdx, &CISz, safe->dataSz);
wolfSSL 15:117db924cf7c 267 if (ret < 0) {
wolfSSL 15:117db924cf7c 268 freeSafe(safe, pkcs12->heap);
wolfSSL 15:117db924cf7c 269 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 270 }
wolfSSL 15:117db924cf7c 271 CISz += localIdx;
wolfSSL 15:117db924cf7c 272 while ((int)localIdx < CISz) {
wolfSSL 15:117db924cf7c 273 int curSz = 0;
wolfSSL 15:117db924cf7c 274 word32 curIdx;
wolfSSL 15:117db924cf7c 275 ContentInfo* ci = NULL;
wolfSSL 15:117db924cf7c 276
wolfSSL 15:117db924cf7c 277 #ifdef WOLFSSL_DEBUG_PKCS12
wolfSSL 15:117db924cf7c 278 printf("\t\tlooking for Content Info.... ");
wolfSSL 15:117db924cf7c 279 #endif
wolfSSL 15:117db924cf7c 280
wolfSSL 15:117db924cf7c 281 if ((ret = GetSequence(input, &localIdx, &curSz, safe->dataSz))
wolfSSL 15:117db924cf7c 282 < 0) {
wolfSSL 15:117db924cf7c 283 freeSafe(safe, pkcs12->heap);
wolfSSL 15:117db924cf7c 284 return ret;
wolfSSL 15:117db924cf7c 285 }
wolfSSL 15:117db924cf7c 286
wolfSSL 15:117db924cf7c 287 if (curSz > CISz) {
wolfSSL 15:117db924cf7c 288 /* subset should not be larger than universe */
wolfSSL 15:117db924cf7c 289 freeSafe(safe, pkcs12->heap);
wolfSSL 15:117db924cf7c 290 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 291 }
wolfSSL 15:117db924cf7c 292
wolfSSL 15:117db924cf7c 293 curIdx = localIdx;
wolfSSL 15:117db924cf7c 294 if ((ret = GetObjectId(input, &localIdx, &oid, oidIgnoreType,
wolfSSL 15:117db924cf7c 295 safe->dataSz)) < 0) {
wolfSSL 15:117db924cf7c 296 WOLFSSL_LEAVE("Get object id failed", ret);
wolfSSL 15:117db924cf7c 297 freeSafe(safe, pkcs12->heap);
wolfSSL 15:117db924cf7c 298 return ret;
wolfSSL 15:117db924cf7c 299 }
wolfSSL 15:117db924cf7c 300
wolfSSL 15:117db924cf7c 301 /* create new content info struct ... possible OID sanity check? */
wolfSSL 15:117db924cf7c 302 ci = (ContentInfo*)XMALLOC(sizeof(ContentInfo), pkcs12->heap,
wolfSSL 15:117db924cf7c 303 DYNAMIC_TYPE_PKCS);
wolfSSL 15:117db924cf7c 304 if (ci == NULL) {
wolfSSL 15:117db924cf7c 305 freeSafe(safe, pkcs12->heap);
wolfSSL 15:117db924cf7c 306 return MEMORY_E;
wolfSSL 15:117db924cf7c 307 }
wolfSSL 15:117db924cf7c 308
wolfSSL 15:117db924cf7c 309 ci->type = oid;
wolfSSL 15:117db924cf7c 310 ci->dataSz = curSz - (localIdx-curIdx);
wolfSSL 15:117db924cf7c 311 ci->data = (byte*)input + localIdx;
wolfSSL 15:117db924cf7c 312 localIdx += ci->dataSz;
wolfSSL 15:117db924cf7c 313
wolfSSL 15:117db924cf7c 314 #ifdef WOLFSSL_DEBUG_PKCS12
wolfSSL 15:117db924cf7c 315 switch (oid) {
wolfSSL 15:117db924cf7c 316 case WC_PKCS12_ENCRYPTED_DATA:
wolfSSL 15:117db924cf7c 317 printf("CONTENT INFO: ENCRYPTED DATA, size = %d\n", ci->dataSz);
wolfSSL 15:117db924cf7c 318 break;
wolfSSL 15:117db924cf7c 319
wolfSSL 15:117db924cf7c 320 case WC_PKCS12_DATA:
wolfSSL 15:117db924cf7c 321 printf("CONTENT INFO: DATA, size = %d\n", ci->dataSz);
wolfSSL 15:117db924cf7c 322 break;
wolfSSL 15:117db924cf7c 323 default:
wolfSSL 15:117db924cf7c 324 printf("CONTENT INFO: UNKNOWN, size = %d\n", ci->dataSz);
wolfSSL 15:117db924cf7c 325 }
wolfSSL 15:117db924cf7c 326 #endif
wolfSSL 15:117db924cf7c 327
wolfSSL 15:117db924cf7c 328 /* insert to head of list */
wolfSSL 15:117db924cf7c 329 ci->next = safe->CI;
wolfSSL 15:117db924cf7c 330 safe->CI = ci;
wolfSSL 15:117db924cf7c 331 safe->numCI += 1;
wolfSSL 15:117db924cf7c 332 }
wolfSSL 15:117db924cf7c 333 }
wolfSSL 15:117db924cf7c 334
wolfSSL 15:117db924cf7c 335 pkcs12->safe = safe;
wolfSSL 15:117db924cf7c 336 *idx += localIdx;
wolfSSL 15:117db924cf7c 337
wolfSSL 15:117db924cf7c 338 return ret;
wolfSSL 15:117db924cf7c 339 }
wolfSSL 15:117db924cf7c 340
wolfSSL 15:117db924cf7c 341
wolfSSL 15:117db924cf7c 342 /* optional mac data */
wolfSSL 15:117db924cf7c 343 static int GetSignData(WC_PKCS12* pkcs12, const byte* mem, word32* idx,
wolfSSL 15:117db924cf7c 344 word32 totalSz)
wolfSSL 15:117db924cf7c 345 {
wolfSSL 15:117db924cf7c 346 MacData* mac;
wolfSSL 15:117db924cf7c 347 word32 curIdx = *idx;
wolfSSL 15:117db924cf7c 348 word32 oid = 0;
wolfSSL 15:117db924cf7c 349 int size, ret;
wolfSSL 15:117db924cf7c 350
wolfSSL 15:117db924cf7c 351 /* Digest Info : Sequence
wolfSSL 15:117db924cf7c 352 * DigestAlgorithmIdentifier
wolfSSL 15:117db924cf7c 353 * Digest
wolfSSL 15:117db924cf7c 354 */
wolfSSL 15:117db924cf7c 355 if ((ret = GetSequence(mem, &curIdx, &size, totalSz)) <= 0) {
wolfSSL 15:117db924cf7c 356 WOLFSSL_MSG("Failed to get PKCS12 sequence");
wolfSSL 15:117db924cf7c 357 return ret;
wolfSSL 15:117db924cf7c 358 }
wolfSSL 15:117db924cf7c 359
wolfSSL 15:117db924cf7c 360 #ifdef WOLFSSL_DEBUG_PKCS12
wolfSSL 15:117db924cf7c 361 printf("\t\tSEQUENCE: DigestInfo size = %d\n", size);
wolfSSL 15:117db924cf7c 362 #endif
wolfSSL 15:117db924cf7c 363
wolfSSL 15:117db924cf7c 364 mac = (MacData*)XMALLOC(sizeof(MacData), pkcs12->heap, DYNAMIC_TYPE_PKCS);
wolfSSL 15:117db924cf7c 365 if (mac == NULL) {
wolfSSL 15:117db924cf7c 366 return MEMORY_E;
wolfSSL 15:117db924cf7c 367 }
wolfSSL 15:117db924cf7c 368 XMEMSET(mac, 0, sizeof(MacData));
wolfSSL 15:117db924cf7c 369
wolfSSL 15:117db924cf7c 370 /* DigestAlgorithmIdentifier */
wolfSSL 15:117db924cf7c 371 if ((ret = GetAlgoId(mem, &curIdx, &oid, oidIgnoreType, totalSz)) < 0) {
wolfSSL 15:117db924cf7c 372 WOLFSSL_MSG("Failed to get PKCS12 sequence");
wolfSSL 15:117db924cf7c 373 XFREE(mac, pkcs12->heap, DYNAMIC_TYPE_PKCS);
wolfSSL 15:117db924cf7c 374 return ret;
wolfSSL 15:117db924cf7c 375 }
wolfSSL 15:117db924cf7c 376 mac->oid = oid;
wolfSSL 15:117db924cf7c 377
wolfSSL 15:117db924cf7c 378 #ifdef WOLFSSL_DEBUG_PKCS12
wolfSSL 15:117db924cf7c 379 printf("\t\tALGO ID = %d\n", oid);
wolfSSL 15:117db924cf7c 380 #endif
wolfSSL 15:117db924cf7c 381
wolfSSL 15:117db924cf7c 382 /* Digest: should be octet type holding digest */
wolfSSL 15:117db924cf7c 383 if (mem[curIdx++] != ASN_OCTET_STRING) {
wolfSSL 15:117db924cf7c 384 WOLFSSL_MSG("Failed to get digest");
wolfSSL 15:117db924cf7c 385 XFREE(mac, pkcs12->heap, DYNAMIC_TYPE_PKCS);
wolfSSL 15:117db924cf7c 386 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 387 }
wolfSSL 15:117db924cf7c 388
wolfSSL 15:117db924cf7c 389 if ((ret = GetLength(mem, &curIdx, &size, totalSz)) <= 0) {
wolfSSL 15:117db924cf7c 390 XFREE(mac, pkcs12->heap, DYNAMIC_TYPE_PKCS);
wolfSSL 15:117db924cf7c 391 return ret;
wolfSSL 15:117db924cf7c 392 }
wolfSSL 15:117db924cf7c 393 mac->digestSz = size;
wolfSSL 15:117db924cf7c 394 mac->digest = (byte*)XMALLOC(mac->digestSz, pkcs12->heap,
wolfSSL 15:117db924cf7c 395 DYNAMIC_TYPE_DIGEST);
wolfSSL 15:117db924cf7c 396 if (mac->digest == NULL || mac->digestSz + curIdx > totalSz) {
wolfSSL 15:117db924cf7c 397 ERROR_OUT(MEMORY_E, exit_gsd);
wolfSSL 15:117db924cf7c 398 }
wolfSSL 15:117db924cf7c 399 XMEMCPY(mac->digest, mem + curIdx, mac->digestSz);
wolfSSL 15:117db924cf7c 400
wolfSSL 15:117db924cf7c 401 #ifdef WOLFSSL_DEBUG_PKCS12
wolfSSL 15:117db924cf7c 402 {
wolfSSL 15:117db924cf7c 403 byte* p;
wolfSSL 15:117db924cf7c 404 for (printf("\t\tDigest = "), p = (byte*)mem+curIdx;
wolfSSL 15:117db924cf7c 405 p < (byte*)mem + curIdx + mac->digestSz;
wolfSSL 15:117db924cf7c 406 printf("%02X", *p), p++);
wolfSSL 15:117db924cf7c 407 printf(" : size = %d\n", mac->digestSz);
wolfSSL 15:117db924cf7c 408 }
wolfSSL 15:117db924cf7c 409 #endif
wolfSSL 15:117db924cf7c 410
wolfSSL 15:117db924cf7c 411 curIdx += mac->digestSz;
wolfSSL 15:117db924cf7c 412
wolfSSL 15:117db924cf7c 413 /* get salt, should be octet string */
wolfSSL 15:117db924cf7c 414 if (mem[curIdx++] != ASN_OCTET_STRING) {
wolfSSL 15:117db924cf7c 415 WOLFSSL_MSG("Failed to get salt");
wolfSSL 15:117db924cf7c 416 ERROR_OUT(ASN_PARSE_E, exit_gsd);
wolfSSL 15:117db924cf7c 417 }
wolfSSL 15:117db924cf7c 418
wolfSSL 15:117db924cf7c 419 if ((ret = GetLength(mem, &curIdx, &size, totalSz)) <= 0) {
wolfSSL 15:117db924cf7c 420 goto exit_gsd;
wolfSSL 15:117db924cf7c 421 }
wolfSSL 15:117db924cf7c 422 mac->saltSz = size;
wolfSSL 15:117db924cf7c 423 mac->salt = (byte*)XMALLOC(mac->saltSz, pkcs12->heap, DYNAMIC_TYPE_SALT);
wolfSSL 15:117db924cf7c 424 if (mac->salt == NULL || mac->saltSz + curIdx > totalSz) {
wolfSSL 15:117db924cf7c 425 ERROR_OUT(MEMORY_E, exit_gsd);
wolfSSL 15:117db924cf7c 426 }
wolfSSL 15:117db924cf7c 427 XMEMCPY(mac->salt, mem + curIdx, mac->saltSz);
wolfSSL 15:117db924cf7c 428
wolfSSL 15:117db924cf7c 429 #ifdef WOLFSSL_DEBUG_PKCS12
wolfSSL 15:117db924cf7c 430 {
wolfSSL 15:117db924cf7c 431 byte* p;
wolfSSL 15:117db924cf7c 432 for (printf("\t\tSalt = "), p = (byte*)mem + curIdx;
wolfSSL 15:117db924cf7c 433 p < (byte*)mem + curIdx + mac->saltSz;
wolfSSL 15:117db924cf7c 434 printf("%02X", *p), p++);
wolfSSL 15:117db924cf7c 435 printf(" : size = %d\n", mac->saltSz);
wolfSSL 15:117db924cf7c 436 }
wolfSSL 15:117db924cf7c 437 #endif
wolfSSL 15:117db924cf7c 438
wolfSSL 15:117db924cf7c 439 curIdx += mac->saltSz;
wolfSSL 15:117db924cf7c 440
wolfSSL 15:117db924cf7c 441 /* check for MAC iterations, default to 1 */
wolfSSL 15:117db924cf7c 442 mac->itt = WC_PKCS12_MAC_DEFAULT;
wolfSSL 15:117db924cf7c 443 if (curIdx < totalSz) {
wolfSSL 15:117db924cf7c 444 int number = 0;
wolfSSL 15:117db924cf7c 445 if ((ret = GetShortInt(mem, &curIdx, &number, totalSz)) >= 0) {
wolfSSL 15:117db924cf7c 446 /* found a iteration value */
wolfSSL 15:117db924cf7c 447 mac->itt = number;
wolfSSL 15:117db924cf7c 448 }
wolfSSL 15:117db924cf7c 449 }
wolfSSL 15:117db924cf7c 450
wolfSSL 15:117db924cf7c 451 #ifdef WOLFSSL_DEBUG_PKCS12
wolfSSL 15:117db924cf7c 452 printf("\t\tITTERATIONS : %d\n", mac->itt);
wolfSSL 15:117db924cf7c 453 #endif
wolfSSL 15:117db924cf7c 454
wolfSSL 15:117db924cf7c 455 *idx = curIdx;
wolfSSL 15:117db924cf7c 456 pkcs12->signData = mac;
wolfSSL 15:117db924cf7c 457 ret = 0; /* success */
wolfSSL 15:117db924cf7c 458
wolfSSL 15:117db924cf7c 459 exit_gsd:
wolfSSL 15:117db924cf7c 460
wolfSSL 15:117db924cf7c 461 /* failure cleanup */
wolfSSL 15:117db924cf7c 462 if (ret != 0) {
wolfSSL 15:117db924cf7c 463 if (mac) {
wolfSSL 15:117db924cf7c 464 if (mac->digest)
wolfSSL 15:117db924cf7c 465 XFREE(mac->digest, pkcs12->heap, DYNAMIC_TYPE_DIGEST);
wolfSSL 15:117db924cf7c 466 XFREE(mac, pkcs12->heap, DYNAMIC_TYPE_PKCS);
wolfSSL 15:117db924cf7c 467 }
wolfSSL 15:117db924cf7c 468 }
wolfSSL 15:117db924cf7c 469
wolfSSL 15:117db924cf7c 470 return ret;
wolfSSL 15:117db924cf7c 471 }
wolfSSL 15:117db924cf7c 472
wolfSSL 15:117db924cf7c 473
wolfSSL 15:117db924cf7c 474 /* expects PKCS12 signData to be set up with OID
wolfSSL 15:117db924cf7c 475 *
wolfSSL 15:117db924cf7c 476 * returns the size of mac created on success. A negative value will be returned
wolfSSL 15:117db924cf7c 477 * in the case that an error happened.
wolfSSL 15:117db924cf7c 478 */
wolfSSL 15:117db924cf7c 479 static int wc_PKCS12_create_mac(WC_PKCS12* pkcs12, byte* data, word32 dataSz,
wolfSSL 15:117db924cf7c 480 const byte* psw, word32 pswSz, byte* out, word32 outSz)
wolfSSL 15:117db924cf7c 481 {
wolfSSL 15:117db924cf7c 482 Hmac hmac;
wolfSSL 15:117db924cf7c 483 MacData* mac;
wolfSSL 15:117db924cf7c 484 int ret, kLen;
wolfSSL 15:117db924cf7c 485 enum wc_HashType hashT;
wolfSSL 15:117db924cf7c 486 int idx = 0;
wolfSSL 15:117db924cf7c 487 int id = 3; /* value from RFC 7292 indicating key is used for MAC */
wolfSSL 15:117db924cf7c 488 word32 i;
wolfSSL 15:117db924cf7c 489 byte unicodePasswd[MAX_UNICODE_SZ];
wolfSSL 15:117db924cf7c 490 byte key[MAX_KEY_SIZE];
wolfSSL 15:117db924cf7c 491
wolfSSL 15:117db924cf7c 492 if (pkcs12 == NULL || pkcs12->signData == NULL || data == NULL ||
wolfSSL 15:117db924cf7c 493 out == NULL) {
wolfSSL 15:117db924cf7c 494 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 495 }
wolfSSL 15:117db924cf7c 496
wolfSSL 15:117db924cf7c 497 mac = pkcs12->signData;
wolfSSL 15:117db924cf7c 498
wolfSSL 15:117db924cf7c 499 /* unicode set up from asn.c */
wolfSSL 15:117db924cf7c 500 if ((pswSz * 2 + 2) > (int)sizeof(unicodePasswd)) {
wolfSSL 15:117db924cf7c 501 WOLFSSL_MSG("PKCS12 max unicode size too small");
wolfSSL 15:117db924cf7c 502 return UNICODE_SIZE_E;
wolfSSL 15:117db924cf7c 503 }
wolfSSL 15:117db924cf7c 504
wolfSSL 15:117db924cf7c 505 for (i = 0; i < pswSz; i++) {
wolfSSL 15:117db924cf7c 506 unicodePasswd[idx++] = 0x00;
wolfSSL 15:117db924cf7c 507 unicodePasswd[idx++] = (byte)psw[i];
wolfSSL 15:117db924cf7c 508 }
wolfSSL 15:117db924cf7c 509 /* add trailing NULL */
wolfSSL 15:117db924cf7c 510 unicodePasswd[idx++] = 0x00;
wolfSSL 15:117db924cf7c 511 unicodePasswd[idx++] = 0x00;
wolfSSL 15:117db924cf7c 512
wolfSSL 15:117db924cf7c 513 /* get hash type used and resulting size of HMAC key */
wolfSSL 15:117db924cf7c 514 hashT = wc_OidGetHash(mac->oid);
wolfSSL 15:117db924cf7c 515 if (hashT == WC_HASH_TYPE_NONE) {
wolfSSL 15:117db924cf7c 516 WOLFSSL_MSG("Unsupported hash used");
wolfSSL 15:117db924cf7c 517 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 518 }
wolfSSL 15:117db924cf7c 519 kLen = wc_HashGetDigestSize(hashT);
wolfSSL 15:117db924cf7c 520
wolfSSL 15:117db924cf7c 521 /* check out buffer is large enough */
wolfSSL 15:117db924cf7c 522 if (kLen < 0 || outSz < (word32)kLen) {
wolfSSL 15:117db924cf7c 523 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 524 }
wolfSSL 15:117db924cf7c 525
wolfSSL 15:117db924cf7c 526 /* idx contains size of unicodePasswd */
wolfSSL 15:117db924cf7c 527 if ((ret = wc_PKCS12_PBKDF_ex(key, unicodePasswd, idx, mac->salt,
wolfSSL 15:117db924cf7c 528 mac->saltSz, mac->itt, kLen, (int)hashT, id, pkcs12->heap)) < 0) {
wolfSSL 15:117db924cf7c 529 return ret;
wolfSSL 15:117db924cf7c 530 }
wolfSSL 15:117db924cf7c 531
wolfSSL 15:117db924cf7c 532 /* now that key has been created use it to get HMAC hash on data */
wolfSSL 15:117db924cf7c 533 if ((ret = wc_HmacInit(&hmac, pkcs12->heap, INVALID_DEVID)) != 0) {
wolfSSL 15:117db924cf7c 534 return ret;
wolfSSL 15:117db924cf7c 535 }
wolfSSL 15:117db924cf7c 536 ret = wc_HmacSetKey(&hmac, (int)hashT, key, kLen);
wolfSSL 15:117db924cf7c 537 if (ret == 0)
wolfSSL 15:117db924cf7c 538 ret = wc_HmacUpdate(&hmac, data, dataSz);
wolfSSL 15:117db924cf7c 539 if (ret == 0)
wolfSSL 15:117db924cf7c 540 ret = wc_HmacFinal(&hmac, out);
wolfSSL 15:117db924cf7c 541 wc_HmacFree(&hmac);
wolfSSL 15:117db924cf7c 542
wolfSSL 15:117db924cf7c 543 if (ret != 0)
wolfSSL 15:117db924cf7c 544 return ret;
wolfSSL 15:117db924cf7c 545
wolfSSL 15:117db924cf7c 546 return kLen; /* same as digest size */
wolfSSL 15:117db924cf7c 547 }
wolfSSL 15:117db924cf7c 548
wolfSSL 15:117db924cf7c 549
wolfSSL 15:117db924cf7c 550 /* check mac on pkcs12, pkcs12->mac has been sanity checked before entering *
wolfSSL 15:117db924cf7c 551 * returns the result of comparison, success is 0 */
wolfSSL 15:117db924cf7c 552 static int wc_PKCS12_verify(WC_PKCS12* pkcs12, byte* data, word32 dataSz,
wolfSSL 15:117db924cf7c 553 const byte* psw, word32 pswSz)
wolfSSL 15:117db924cf7c 554 {
wolfSSL 15:117db924cf7c 555 MacData* mac;
wolfSSL 15:117db924cf7c 556 int ret;
wolfSSL 15:117db924cf7c 557 byte digest[WC_MAX_DIGEST_SIZE];
wolfSSL 15:117db924cf7c 558
wolfSSL 15:117db924cf7c 559 if (pkcs12 == NULL || pkcs12->signData == NULL || data == NULL) {
wolfSSL 15:117db924cf7c 560 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 561 }
wolfSSL 15:117db924cf7c 562
wolfSSL 15:117db924cf7c 563 mac = pkcs12->signData;
wolfSSL 15:117db924cf7c 564
wolfSSL 15:117db924cf7c 565 #ifdef WOLFSSL_DEBUG_PKCS12
wolfSSL 15:117db924cf7c 566 printf("Verifying MAC with OID = %d\n", mac->oid);
wolfSSL 15:117db924cf7c 567 #endif
wolfSSL 15:117db924cf7c 568
wolfSSL 15:117db924cf7c 569 /* check if this builds digest size is too small */
wolfSSL 15:117db924cf7c 570 if (mac->digestSz > WC_MAX_DIGEST_SIZE) {
wolfSSL 15:117db924cf7c 571 WOLFSSL_MSG("PKCS12 max digest size too small");
wolfSSL 15:117db924cf7c 572 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 573 }
wolfSSL 15:117db924cf7c 574
wolfSSL 15:117db924cf7c 575 if ((ret = wc_PKCS12_create_mac(pkcs12, data, dataSz, psw, pswSz,
wolfSSL 15:117db924cf7c 576 digest, WC_MAX_DIGEST_SIZE)) < 0) {
wolfSSL 15:117db924cf7c 577 return ret;
wolfSSL 15:117db924cf7c 578 }
wolfSSL 15:117db924cf7c 579
wolfSSL 15:117db924cf7c 580 #ifdef WOLFSSL_DEBUG_PKCS12
wolfSSL 15:117db924cf7c 581 {
wolfSSL 15:117db924cf7c 582 byte* p;
wolfSSL 15:117db924cf7c 583 for (printf("\t\tHash = "), p = (byte*)digest;
wolfSSL 15:117db924cf7c 584 p < (byte*)digest + mac->digestSz;
wolfSSL 15:117db924cf7c 585 printf("%02X", *p), p++);
wolfSSL 15:117db924cf7c 586 printf(" : size = %d\n", mac->digestSz);
wolfSSL 15:117db924cf7c 587 }
wolfSSL 15:117db924cf7c 588 #endif
wolfSSL 15:117db924cf7c 589
wolfSSL 15:117db924cf7c 590 return XMEMCMP(digest, mac->digest, mac->digestSz);
wolfSSL 15:117db924cf7c 591 }
wolfSSL 15:117db924cf7c 592
wolfSSL 15:117db924cf7c 593
wolfSSL 15:117db924cf7c 594 /* Convert DER format stored in der buffer to WC_PKCS12 struct
wolfSSL 15:117db924cf7c 595 * Puts the raw contents of Content Info into structure without completly
wolfSSL 15:117db924cf7c 596 * parsing or decoding.
wolfSSL 15:117db924cf7c 597 * der : pointer to der buffer holding PKCS12
wolfSSL 15:117db924cf7c 598 * derSz : size of der buffer
wolfSSL 15:117db924cf7c 599 * pkcs12 : non-null pkcs12 pointer
wolfSSL 15:117db924cf7c 600 * return 0 on success and negative on failure.
wolfSSL 15:117db924cf7c 601 */
wolfSSL 15:117db924cf7c 602 int wc_d2i_PKCS12(const byte* der, word32 derSz, WC_PKCS12* pkcs12)
wolfSSL 15:117db924cf7c 603 {
wolfSSL 15:117db924cf7c 604 word32 idx = 0;
wolfSSL 15:117db924cf7c 605 word32 totalSz = 0;
wolfSSL 15:117db924cf7c 606 int ret;
wolfSSL 15:117db924cf7c 607 int size = 0;
wolfSSL 15:117db924cf7c 608 int version = 0;
wolfSSL 15:117db924cf7c 609
wolfSSL 15:117db924cf7c 610 WOLFSSL_ENTER("wolfSSL_d2i_PKCS12_bio");
wolfSSL 15:117db924cf7c 611
wolfSSL 15:117db924cf7c 612 if (der == NULL || pkcs12 == NULL) {
wolfSSL 15:117db924cf7c 613 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 614 }
wolfSSL 15:117db924cf7c 615
wolfSSL 15:117db924cf7c 616 totalSz = derSz;
wolfSSL 15:117db924cf7c 617 if ((ret = GetSequence(der, &idx, &size, totalSz)) <= 0) {
wolfSSL 15:117db924cf7c 618 WOLFSSL_MSG("Failed to get PKCS12 sequence");
wolfSSL 15:117db924cf7c 619 return ret;
wolfSSL 15:117db924cf7c 620 }
wolfSSL 15:117db924cf7c 621
wolfSSL 15:117db924cf7c 622 /* get version */
wolfSSL 15:117db924cf7c 623 if ((ret = GetMyVersion(der, &idx, &version, totalSz)) < 0) {
wolfSSL 15:117db924cf7c 624 return ret;
wolfSSL 15:117db924cf7c 625 }
wolfSSL 15:117db924cf7c 626
wolfSSL 15:117db924cf7c 627 #ifdef WOLFSSL_DEBUG_PKCS12
wolfSSL 15:117db924cf7c 628 printf("\nBEGIN: PKCS12 size = %d\n", totalSz);
wolfSSL 15:117db924cf7c 629 printf("version = %d\n", version);
wolfSSL 15:117db924cf7c 630 #endif
wolfSSL 15:117db924cf7c 631
wolfSSL 15:117db924cf7c 632 if (version != 3) {
wolfSSL 15:117db924cf7c 633 WOLFSSL_MSG("PKCS12 unsupported version!");
wolfSSL 15:117db924cf7c 634 return ASN_VERSION_E;
wolfSSL 15:117db924cf7c 635 }
wolfSSL 15:117db924cf7c 636
wolfSSL 15:117db924cf7c 637 if ((ret = GetSequence(der, &idx, &size, totalSz)) < 0) {
wolfSSL 15:117db924cf7c 638 return ret;
wolfSSL 15:117db924cf7c 639 }
wolfSSL 15:117db924cf7c 640
wolfSSL 15:117db924cf7c 641 #ifdef WOLFSSL_DEBUG_PKCS12
wolfSSL 15:117db924cf7c 642 printf("\tSEQUENCE: AuthenticatedSafe size = %d\n", size);
wolfSSL 15:117db924cf7c 643 #endif
wolfSSL 15:117db924cf7c 644
wolfSSL 15:117db924cf7c 645 if ((ret = GetSafeContent(pkcs12, der, &idx, size + idx)) < 0) {
wolfSSL 15:117db924cf7c 646 WOLFSSL_MSG("GetSafeContent error");
wolfSSL 15:117db924cf7c 647 return ret;
wolfSSL 15:117db924cf7c 648 }
wolfSSL 15:117db924cf7c 649
wolfSSL 15:117db924cf7c 650 /* if more buffer left check for MAC data */
wolfSSL 15:117db924cf7c 651 if (idx < totalSz) {
wolfSSL 15:117db924cf7c 652 if ((ret = GetSequence(der, &idx, &size, totalSz)) < 0) {
wolfSSL 15:117db924cf7c 653 WOLFSSL_MSG("Ignoring unknown data at end of PKCS12 DER buffer");
wolfSSL 15:117db924cf7c 654 }
wolfSSL 15:117db924cf7c 655 else {
wolfSSL 15:117db924cf7c 656 #ifdef WOLFSSL_DEBUG_PKCS12
wolfSSL 15:117db924cf7c 657 printf("\tSEQUENCE: Signature size = %d\n", size);
wolfSSL 15:117db924cf7c 658 #endif
wolfSSL 15:117db924cf7c 659
wolfSSL 15:117db924cf7c 660 if ((ret = GetSignData(pkcs12, der, &idx, totalSz)) < 0) {
wolfSSL 15:117db924cf7c 661 return ASN_PARSE_E;
wolfSSL 15:117db924cf7c 662 }
wolfSSL 15:117db924cf7c 663 }
wolfSSL 15:117db924cf7c 664 }
wolfSSL 15:117db924cf7c 665
wolfSSL 15:117db924cf7c 666 #ifdef WOLFSSL_DEBUG_PKCS12
wolfSSL 15:117db924cf7c 667 printf("END: PKCS12\n");
wolfSSL 15:117db924cf7c 668 #endif
wolfSSL 15:117db924cf7c 669
wolfSSL 15:117db924cf7c 670 return ret;
wolfSSL 15:117db924cf7c 671 }
wolfSSL 15:117db924cf7c 672
wolfSSL 15:117db924cf7c 673
wolfSSL 15:117db924cf7c 674 /* helper function to free WC_DerCertList */
wolfSSL 15:117db924cf7c 675 void wc_FreeCertList(WC_DerCertList* list, void* heap)
wolfSSL 15:117db924cf7c 676 {
wolfSSL 15:117db924cf7c 677 WC_DerCertList* current = list;
wolfSSL 15:117db924cf7c 678 WC_DerCertList* next;
wolfSSL 15:117db924cf7c 679
wolfSSL 15:117db924cf7c 680 if (list == NULL) {
wolfSSL 15:117db924cf7c 681 return;
wolfSSL 15:117db924cf7c 682 }
wolfSSL 15:117db924cf7c 683
wolfSSL 15:117db924cf7c 684 while (current != NULL) {
wolfSSL 15:117db924cf7c 685 next = current->next;
wolfSSL 15:117db924cf7c 686 if (current->buffer != NULL) {
wolfSSL 15:117db924cf7c 687 XFREE(current->buffer, heap, DYNAMIC_TYPE_PKCS);
wolfSSL 15:117db924cf7c 688 }
wolfSSL 15:117db924cf7c 689 XFREE(current, heap, DYNAMIC_TYPE_PKCS);
wolfSSL 15:117db924cf7c 690 current = next;
wolfSSL 15:117db924cf7c 691 }
wolfSSL 15:117db924cf7c 692
wolfSSL 15:117db924cf7c 693 (void)heap;
wolfSSL 15:117db924cf7c 694 }
wolfSSL 15:117db924cf7c 695
wolfSSL 15:117db924cf7c 696 static void freeDecCertList(WC_DerCertList** list, byte** pkey, word32* pkeySz,
wolfSSL 15:117db924cf7c 697 byte** cert, word32* certSz, void* heap)
wolfSSL 15:117db924cf7c 698 {
wolfSSL 15:117db924cf7c 699 WC_DerCertList* current = *list;
wolfSSL 15:117db924cf7c 700 WC_DerCertList* previous = NULL;
wolfSSL 15:117db924cf7c 701 DecodedCert DeCert;
wolfSSL 15:117db924cf7c 702
wolfSSL 15:117db924cf7c 703 while (current != NULL) {
wolfSSL 15:117db924cf7c 704
wolfSSL 15:117db924cf7c 705 InitDecodedCert(&DeCert, current->buffer, current->bufferSz, heap);
wolfSSL 15:117db924cf7c 706 if (ParseCertRelative(&DeCert, CERT_TYPE, NO_VERIFY, NULL) == 0) {
wolfSSL 15:117db924cf7c 707 if (wc_CheckPrivateKey(*pkey, *pkeySz, &DeCert) == 1) {
wolfSSL 15:117db924cf7c 708 WOLFSSL_MSG("Key Pair found");
wolfSSL 15:117db924cf7c 709 *cert = current->buffer;
wolfSSL 15:117db924cf7c 710 *certSz = current->bufferSz;
wolfSSL 15:117db924cf7c 711
wolfSSL 15:117db924cf7c 712 if (previous == NULL) {
wolfSSL 15:117db924cf7c 713 *list = current->next;
wolfSSL 15:117db924cf7c 714 }
wolfSSL 15:117db924cf7c 715 else {
wolfSSL 15:117db924cf7c 716 previous->next = current->next;
wolfSSL 15:117db924cf7c 717 }
wolfSSL 15:117db924cf7c 718 FreeDecodedCert(&DeCert);
wolfSSL 15:117db924cf7c 719 XFREE(current, heap, DYNAMIC_TYPE_PKCS);
wolfSSL 15:117db924cf7c 720 break;
wolfSSL 15:117db924cf7c 721 }
wolfSSL 15:117db924cf7c 722 }
wolfSSL 15:117db924cf7c 723 FreeDecodedCert(&DeCert);
wolfSSL 15:117db924cf7c 724
wolfSSL 15:117db924cf7c 725 previous = current;
wolfSSL 15:117db924cf7c 726 current = current->next;
wolfSSL 15:117db924cf7c 727 }
wolfSSL 15:117db924cf7c 728 }
wolfSSL 15:117db924cf7c 729
wolfSSL 15:117db924cf7c 730
wolfSSL 15:117db924cf7c 731 /* return 0 on success and negative on failure.
wolfSSL 15:117db924cf7c 732 * By side effect returns private key, cert, and optionally ca.
wolfSSL 15:117db924cf7c 733 * Parses and decodes the parts of PKCS12
wolfSSL 15:117db924cf7c 734 *
wolfSSL 15:117db924cf7c 735 * NOTE: can parse with USER RSA enabled but may return cert that is not the
wolfSSL 15:117db924cf7c 736 * pair for the key when using RSA key pairs.
wolfSSL 15:117db924cf7c 737 *
wolfSSL 15:117db924cf7c 738 * pkcs12 : non-null WC_PKCS12 struct
wolfSSL 15:117db924cf7c 739 * psw : password to use for PKCS12 decode
wolfSSL 15:117db924cf7c 740 * pkey : Private key returned
wolfSSL 15:117db924cf7c 741 * cert : x509 cert returned
wolfSSL 15:117db924cf7c 742 * ca : optional ca returned
wolfSSL 15:117db924cf7c 743 */
wolfSSL 15:117db924cf7c 744 int wc_PKCS12_parse(WC_PKCS12* pkcs12, const char* psw,
wolfSSL 15:117db924cf7c 745 byte** pkey, word32* pkeySz, byte** cert, word32* certSz,
wolfSSL 15:117db924cf7c 746 WC_DerCertList** ca)
wolfSSL 15:117db924cf7c 747 {
wolfSSL 15:117db924cf7c 748 ContentInfo* ci = NULL;
wolfSSL 15:117db924cf7c 749 WC_DerCertList* certList = NULL;
wolfSSL 15:117db924cf7c 750 WC_DerCertList* tailList = NULL;
wolfSSL 15:117db924cf7c 751 byte* buf = NULL;
wolfSSL 15:117db924cf7c 752 word32 i, oid;
wolfSSL 15:117db924cf7c 753 int ret, pswSz;
wolfSSL 15:117db924cf7c 754
wolfSSL 15:117db924cf7c 755 WOLFSSL_ENTER("wc_PKCS12_parse");
wolfSSL 15:117db924cf7c 756
wolfSSL 15:117db924cf7c 757 if (pkcs12 == NULL || psw == NULL || cert == NULL || certSz == NULL ||
wolfSSL 15:117db924cf7c 758 pkey == NULL || pkeySz == NULL) {
wolfSSL 15:117db924cf7c 759 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 760 }
wolfSSL 15:117db924cf7c 761
wolfSSL 15:117db924cf7c 762 pswSz = (int)XSTRLEN(psw);
wolfSSL 15:117db924cf7c 763 *cert = NULL;
wolfSSL 15:117db924cf7c 764 *pkey = NULL;
wolfSSL 15:117db924cf7c 765 if (ca != NULL)
wolfSSL 15:117db924cf7c 766 *ca = NULL;
wolfSSL 15:117db924cf7c 767
wolfSSL 15:117db924cf7c 768 /* if there is sign data then verify the MAC */
wolfSSL 15:117db924cf7c 769 if (pkcs12->signData != NULL ) {
wolfSSL 15:117db924cf7c 770 if ((ret = wc_PKCS12_verify(pkcs12, pkcs12->safe->data,
wolfSSL 15:117db924cf7c 771 pkcs12->safe->dataSz, (byte*)psw, pswSz)) != 0) {
wolfSSL 15:117db924cf7c 772 WOLFSSL_MSG("PKCS12 Bad MAC on verify");
wolfSSL 15:117db924cf7c 773 WOLFSSL_LEAVE("wc_PKCS12_parse verify ", ret);
wolfSSL 15:117db924cf7c 774 return MAC_CMP_FAILED_E;
wolfSSL 15:117db924cf7c 775 }
wolfSSL 15:117db924cf7c 776 }
wolfSSL 15:117db924cf7c 777
wolfSSL 15:117db924cf7c 778 if (pkcs12->safe == NULL) {
wolfSSL 15:117db924cf7c 779 WOLFSSL_MSG("No PKCS12 safes to parse");
wolfSSL 15:117db924cf7c 780 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 781 }
wolfSSL 15:117db924cf7c 782
wolfSSL 15:117db924cf7c 783 /* Decode content infos */
wolfSSL 15:117db924cf7c 784 ci = pkcs12->safe->CI;
wolfSSL 15:117db924cf7c 785 for (i = 0; i < pkcs12->safe->numCI; i++) {
wolfSSL 15:117db924cf7c 786 byte* data;
wolfSSL 15:117db924cf7c 787 word32 idx = 0;
wolfSSL 15:117db924cf7c 788 int size, totalSz;
wolfSSL 15:117db924cf7c 789
wolfSSL 15:117db924cf7c 790 if (ci->type == WC_PKCS12_ENCRYPTED_DATA) {
wolfSSL 15:117db924cf7c 791 int number;
wolfSSL 15:117db924cf7c 792
wolfSSL 15:117db924cf7c 793 WOLFSSL_MSG("Decrypting PKCS12 Content Info Container");
wolfSSL 15:117db924cf7c 794 data = ci->data;
wolfSSL 15:117db924cf7c 795 if (data[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) {
wolfSSL 15:117db924cf7c 796 ERROR_OUT(ASN_PARSE_E, exit_pk12par);
wolfSSL 15:117db924cf7c 797 }
wolfSSL 15:117db924cf7c 798 if ((ret = GetLength(data, &idx, &size, ci->dataSz)) < 0) {
wolfSSL 15:117db924cf7c 799 goto exit_pk12par;
wolfSSL 15:117db924cf7c 800 }
wolfSSL 15:117db924cf7c 801
wolfSSL 15:117db924cf7c 802 if ((ret = GetSequence(data, &idx, &size, ci->dataSz)) < 0) {
wolfSSL 15:117db924cf7c 803 goto exit_pk12par;
wolfSSL 15:117db924cf7c 804 }
wolfSSL 15:117db924cf7c 805
wolfSSL 15:117db924cf7c 806 if ((ret = GetShortInt(data, &idx, &number, ci->dataSz)) < 0) {
wolfSSL 15:117db924cf7c 807 goto exit_pk12par;
wolfSSL 15:117db924cf7c 808 }
wolfSSL 15:117db924cf7c 809
wolfSSL 15:117db924cf7c 810 if (number != 0) {
wolfSSL 15:117db924cf7c 811 WOLFSSL_MSG("Expecting 0 for Integer with Encrypted PKCS12");
wolfSSL 15:117db924cf7c 812 }
wolfSSL 15:117db924cf7c 813
wolfSSL 15:117db924cf7c 814 if ((ret = GetSequence(data, &idx, &size, ci->dataSz)) < 0) {
wolfSSL 15:117db924cf7c 815 goto exit_pk12par;
wolfSSL 15:117db924cf7c 816 }
wolfSSL 15:117db924cf7c 817
wolfSSL 15:117db924cf7c 818 ret = GetObjectId(data, &idx, &oid, oidIgnoreType, ci->dataSz);
wolfSSL 15:117db924cf7c 819 if (ret < 0 || oid != WC_PKCS12_DATA) {
wolfSSL 15:117db924cf7c 820 WOLFSSL_MSG("Not PKCS12 DATA object or get object parse error");
wolfSSL 15:117db924cf7c 821 ERROR_OUT(ASN_PARSE_E, exit_pk12par);
wolfSSL 15:117db924cf7c 822 }
wolfSSL 15:117db924cf7c 823
wolfSSL 15:117db924cf7c 824 /* decrypted content overwrites input buffer */
wolfSSL 15:117db924cf7c 825 size = ci->dataSz - idx;
wolfSSL 15:117db924cf7c 826 buf = (byte*)XMALLOC(size, pkcs12->heap, DYNAMIC_TYPE_PKCS);
wolfSSL 15:117db924cf7c 827 if (buf == NULL) {
wolfSSL 15:117db924cf7c 828 ERROR_OUT(MEMORY_E, exit_pk12par);
wolfSSL 15:117db924cf7c 829 }
wolfSSL 15:117db924cf7c 830 XMEMCPY(buf, data + idx, size);
wolfSSL 15:117db924cf7c 831
wolfSSL 15:117db924cf7c 832 if ((ret = DecryptContent(buf, size, psw, pswSz)) < 0) {
wolfSSL 15:117db924cf7c 833 WOLFSSL_MSG("Decryption failed, algorithm not compiled in?");
wolfSSL 15:117db924cf7c 834 goto exit_pk12par;
wolfSSL 15:117db924cf7c 835 }
wolfSSL 15:117db924cf7c 836
wolfSSL 15:117db924cf7c 837 data = buf;
wolfSSL 15:117db924cf7c 838 idx = 0;
wolfSSL 15:117db924cf7c 839
wolfSSL 15:117db924cf7c 840 #ifdef WOLFSSL_DEBUG_PKCS12
wolfSSL 15:117db924cf7c 841 {
wolfSSL 15:117db924cf7c 842 byte* p;
wolfSSL 15:117db924cf7c 843 for (printf("\tData = "), p = (byte*)buf;
wolfSSL 15:117db924cf7c 844 p < (byte*)buf + size;
wolfSSL 15:117db924cf7c 845 printf("%02X", *p), p++);
wolfSSL 15:117db924cf7c 846 printf("\n");
wolfSSL 15:117db924cf7c 847 }
wolfSSL 15:117db924cf7c 848 #endif
wolfSSL 15:117db924cf7c 849 }
wolfSSL 15:117db924cf7c 850 else { /* type DATA */
wolfSSL 15:117db924cf7c 851 WOLFSSL_MSG("Parsing PKCS12 DATA Content Info Container");
wolfSSL 15:117db924cf7c 852 data = ci->data;
wolfSSL 15:117db924cf7c 853 if (data[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) {
wolfSSL 15:117db924cf7c 854 ERROR_OUT(ASN_PARSE_E, exit_pk12par);
wolfSSL 15:117db924cf7c 855 }
wolfSSL 15:117db924cf7c 856 if ((ret = GetLength(data, &idx, &size, ci->dataSz)) <= 0) {
wolfSSL 15:117db924cf7c 857 goto exit_pk12par;
wolfSSL 15:117db924cf7c 858 }
wolfSSL 15:117db924cf7c 859 if (data[idx++] != ASN_OCTET_STRING) {
wolfSSL 15:117db924cf7c 860 ERROR_OUT(ASN_PARSE_E, exit_pk12par);
wolfSSL 15:117db924cf7c 861 }
wolfSSL 15:117db924cf7c 862 if ((ret = GetLength(data, &idx, &size, ci->dataSz)) < 0) {
wolfSSL 15:117db924cf7c 863 goto exit_pk12par;
wolfSSL 15:117db924cf7c 864 }
wolfSSL 15:117db924cf7c 865
wolfSSL 15:117db924cf7c 866 }
wolfSSL 15:117db924cf7c 867
wolfSSL 15:117db924cf7c 868 /* parse through bags in ContentInfo */
wolfSSL 15:117db924cf7c 869 if ((ret = GetSequence(data, &idx, &totalSz, ci->dataSz)) < 0) {
wolfSSL 15:117db924cf7c 870 goto exit_pk12par;
wolfSSL 15:117db924cf7c 871 }
wolfSSL 15:117db924cf7c 872 totalSz += idx;
wolfSSL 15:117db924cf7c 873
wolfSSL 15:117db924cf7c 874 while ((int)idx < totalSz) {
wolfSSL 15:117db924cf7c 875 int bagSz;
wolfSSL 15:117db924cf7c 876 if ((ret = GetSequence(data, &idx, &bagSz, ci->dataSz)) < 0) {
wolfSSL 15:117db924cf7c 877 goto exit_pk12par;
wolfSSL 15:117db924cf7c 878 }
wolfSSL 15:117db924cf7c 879 bagSz += idx;
wolfSSL 15:117db924cf7c 880
wolfSSL 15:117db924cf7c 881 if ((ret = GetObjectId(data, &idx, &oid, oidIgnoreType,
wolfSSL 15:117db924cf7c 882 ci->dataSz)) < 0) {
wolfSSL 15:117db924cf7c 883 goto exit_pk12par;
wolfSSL 15:117db924cf7c 884 }
wolfSSL 15:117db924cf7c 885
wolfSSL 15:117db924cf7c 886 switch (oid) {
wolfSSL 15:117db924cf7c 887 case WC_PKCS12_KeyBag: /* 667 */
wolfSSL 15:117db924cf7c 888 WOLFSSL_MSG("PKCS12 Key Bag found");
wolfSSL 15:117db924cf7c 889 if (data[idx++] !=
wolfSSL 15:117db924cf7c 890 (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) {
wolfSSL 15:117db924cf7c 891 ERROR_OUT(ASN_PARSE_E, exit_pk12par);
wolfSSL 15:117db924cf7c 892 }
wolfSSL 15:117db924cf7c 893 if ((ret = GetLength(data, &idx, &size, ci->dataSz)) <= 0) {
wolfSSL 15:117db924cf7c 894 goto exit_pk12par;
wolfSSL 15:117db924cf7c 895 }
wolfSSL 15:117db924cf7c 896 if (*pkey == NULL) {
wolfSSL 15:117db924cf7c 897 *pkey = (byte*)XMALLOC(size, pkcs12->heap,
wolfSSL 15:117db924cf7c 898 DYNAMIC_TYPE_PUBLIC_KEY);
wolfSSL 15:117db924cf7c 899 if (*pkey == NULL) {
wolfSSL 15:117db924cf7c 900 ERROR_OUT(MEMORY_E, exit_pk12par);
wolfSSL 15:117db924cf7c 901 }
wolfSSL 15:117db924cf7c 902 XMEMCPY(*pkey, data + idx, size);
wolfSSL 15:117db924cf7c 903 *pkeySz = ToTraditional(*pkey, size);
wolfSSL 15:117db924cf7c 904 }
wolfSSL 15:117db924cf7c 905
wolfSSL 15:117db924cf7c 906 #ifdef WOLFSSL_DEBUG_PKCS12
wolfSSL 15:117db924cf7c 907 {
wolfSSL 15:117db924cf7c 908 byte* p;
wolfSSL 15:117db924cf7c 909 for (printf("\tKey = "), p = (byte*)*pkey;
wolfSSL 15:117db924cf7c 910 p < (byte*)*pkey + size;
wolfSSL 15:117db924cf7c 911 printf("%02X", *p), p++);
wolfSSL 15:117db924cf7c 912 printf("\n");
wolfSSL 15:117db924cf7c 913 }
wolfSSL 15:117db924cf7c 914 #endif
wolfSSL 15:117db924cf7c 915 idx += size;
wolfSSL 15:117db924cf7c 916 break;
wolfSSL 15:117db924cf7c 917
wolfSSL 15:117db924cf7c 918 case WC_PKCS12_ShroudedKeyBag: /* 668 */
wolfSSL 15:117db924cf7c 919 {
wolfSSL 15:117db924cf7c 920 byte* k;
wolfSSL 15:117db924cf7c 921
wolfSSL 15:117db924cf7c 922 WOLFSSL_MSG("PKCS12 Shrouded Key Bag found");
wolfSSL 15:117db924cf7c 923 if (data[idx++] !=
wolfSSL 15:117db924cf7c 924 (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) {
wolfSSL 15:117db924cf7c 925 ERROR_OUT(ASN_PARSE_E, exit_pk12par);
wolfSSL 15:117db924cf7c 926 }
wolfSSL 15:117db924cf7c 927 if ((ret = GetLength(data, &idx, &size,
wolfSSL 15:117db924cf7c 928 ci->dataSz)) < 0) {
wolfSSL 15:117db924cf7c 929 goto exit_pk12par;
wolfSSL 15:117db924cf7c 930 }
wolfSSL 15:117db924cf7c 931
wolfSSL 15:117db924cf7c 932 k = (byte*)XMALLOC(size, pkcs12->heap,
wolfSSL 15:117db924cf7c 933 DYNAMIC_TYPE_PUBLIC_KEY);
wolfSSL 15:117db924cf7c 934 if (k == NULL) {
wolfSSL 15:117db924cf7c 935 ERROR_OUT(MEMORY_E, exit_pk12par);
wolfSSL 15:117db924cf7c 936 }
wolfSSL 15:117db924cf7c 937 XMEMCPY(k, data + idx, size);
wolfSSL 15:117db924cf7c 938
wolfSSL 15:117db924cf7c 939 /* overwrites input, be warned */
wolfSSL 15:117db924cf7c 940 if ((ret = ToTraditionalEnc(k, size, psw, pswSz)) < 0) {
wolfSSL 15:117db924cf7c 941 XFREE(k, pkcs12->heap, DYNAMIC_TYPE_PUBLIC_KEY);
wolfSSL 15:117db924cf7c 942 goto exit_pk12par;
wolfSSL 15:117db924cf7c 943 }
wolfSSL 15:117db924cf7c 944
wolfSSL 15:117db924cf7c 945 if (ret < size) {
wolfSSL 15:117db924cf7c 946 /* shrink key buffer */
wolfSSL 15:117db924cf7c 947 byte* tmp = (byte*)XMALLOC(ret, pkcs12->heap,
wolfSSL 15:117db924cf7c 948 DYNAMIC_TYPE_PUBLIC_KEY);
wolfSSL 15:117db924cf7c 949 if (tmp == NULL) {
wolfSSL 15:117db924cf7c 950 XFREE(k, pkcs12->heap, DYNAMIC_TYPE_PUBLIC_KEY);
wolfSSL 15:117db924cf7c 951 ERROR_OUT(MEMORY_E, exit_pk12par);
wolfSSL 15:117db924cf7c 952 }
wolfSSL 15:117db924cf7c 953 XMEMCPY(tmp, k, ret);
wolfSSL 15:117db924cf7c 954 XFREE(k, pkcs12->heap, DYNAMIC_TYPE_PUBLIC_KEY);
wolfSSL 15:117db924cf7c 955 k = tmp;
wolfSSL 15:117db924cf7c 956 }
wolfSSL 15:117db924cf7c 957 size = ret;
wolfSSL 15:117db924cf7c 958
wolfSSL 15:117db924cf7c 959 if (*pkey == NULL) {
wolfSSL 15:117db924cf7c 960 *pkey = k;
wolfSSL 15:117db924cf7c 961 *pkeySz = size;
wolfSSL 15:117db924cf7c 962 }
wolfSSL 15:117db924cf7c 963 else { /* only expecting one key */
wolfSSL 15:117db924cf7c 964 XFREE(k, pkcs12->heap, DYNAMIC_TYPE_PUBLIC_KEY);
wolfSSL 15:117db924cf7c 965 }
wolfSSL 15:117db924cf7c 966 idx += size;
wolfSSL 15:117db924cf7c 967
wolfSSL 15:117db924cf7c 968 #ifdef WOLFSSL_DEBUG_PKCS12
wolfSSL 15:117db924cf7c 969 {
wolfSSL 15:117db924cf7c 970 byte* p;
wolfSSL 15:117db924cf7c 971 for (printf("\tKey = "), p = (byte*)k;
wolfSSL 15:117db924cf7c 972 p < (byte*)k + ret;
wolfSSL 15:117db924cf7c 973 printf("%02X", *p), p++);
wolfSSL 15:117db924cf7c 974 printf("\n");
wolfSSL 15:117db924cf7c 975 }
wolfSSL 15:117db924cf7c 976 #endif
wolfSSL 15:117db924cf7c 977 }
wolfSSL 15:117db924cf7c 978 break;
wolfSSL 15:117db924cf7c 979
wolfSSL 15:117db924cf7c 980 case WC_PKCS12_CertBag: /* 669 */
wolfSSL 15:117db924cf7c 981 {
wolfSSL 15:117db924cf7c 982 WC_DerCertList* node;
wolfSSL 15:117db924cf7c 983 WOLFSSL_MSG("PKCS12 Cert Bag found");
wolfSSL 15:117db924cf7c 984 if (data[idx++] !=
wolfSSL 15:117db924cf7c 985 (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) {
wolfSSL 15:117db924cf7c 986 ERROR_OUT(ASN_PARSE_E, exit_pk12par);
wolfSSL 15:117db924cf7c 987 }
wolfSSL 15:117db924cf7c 988 if ((ret = GetLength(data, &idx, &size, ci->dataSz)) < 0) {
wolfSSL 15:117db924cf7c 989 goto exit_pk12par;
wolfSSL 15:117db924cf7c 990 }
wolfSSL 15:117db924cf7c 991
wolfSSL 15:117db924cf7c 992 /* get cert bag type */
wolfSSL 15:117db924cf7c 993 if ((ret = GetSequence(data, &idx, &size, ci->dataSz)) <0) {
wolfSSL 15:117db924cf7c 994 goto exit_pk12par;
wolfSSL 15:117db924cf7c 995 }
wolfSSL 15:117db924cf7c 996
wolfSSL 15:117db924cf7c 997 if ((ret = GetObjectId(data, &idx, &oid, oidIgnoreType,
wolfSSL 15:117db924cf7c 998 ci->dataSz)) < 0) {
wolfSSL 15:117db924cf7c 999 goto exit_pk12par;
wolfSSL 15:117db924cf7c 1000 }
wolfSSL 15:117db924cf7c 1001
wolfSSL 15:117db924cf7c 1002 switch (oid) {
wolfSSL 15:117db924cf7c 1003 case WC_PKCS12_CertBag_Type1: /* 675 */
wolfSSL 15:117db924cf7c 1004 /* type 1 */
wolfSSL 15:117db924cf7c 1005 WOLFSSL_MSG("PKCS12 cert bag type 1");
wolfSSL 15:117db924cf7c 1006 if (data[idx++] !=
wolfSSL 15:117db924cf7c 1007 (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) {
wolfSSL 15:117db924cf7c 1008 ERROR_OUT(ASN_PARSE_E, exit_pk12par);
wolfSSL 15:117db924cf7c 1009 }
wolfSSL 15:117db924cf7c 1010 if ((ret = GetLength(data, &idx, &size, ci->dataSz))
wolfSSL 15:117db924cf7c 1011 <= 0) {
wolfSSL 15:117db924cf7c 1012 goto exit_pk12par;
wolfSSL 15:117db924cf7c 1013 }
wolfSSL 15:117db924cf7c 1014 if (data[idx++] != ASN_OCTET_STRING) {
wolfSSL 15:117db924cf7c 1015 ERROR_OUT(ASN_PARSE_E, exit_pk12par);
wolfSSL 15:117db924cf7c 1016
wolfSSL 15:117db924cf7c 1017 }
wolfSSL 15:117db924cf7c 1018 if ((ret = GetLength(data, &idx, &size, ci->dataSz))
wolfSSL 15:117db924cf7c 1019 < 0) {
wolfSSL 15:117db924cf7c 1020 goto exit_pk12par;
wolfSSL 15:117db924cf7c 1021 }
wolfSSL 15:117db924cf7c 1022 break;
wolfSSL 15:117db924cf7c 1023 default:
wolfSSL 15:117db924cf7c 1024 WOLFSSL_MSG("Unknown PKCS12 cert bag type");
wolfSSL 15:117db924cf7c 1025 }
wolfSSL 15:117db924cf7c 1026
wolfSSL 15:117db924cf7c 1027 if (size + idx > (word32)bagSz) {
wolfSSL 15:117db924cf7c 1028 ERROR_OUT(ASN_PARSE_E, exit_pk12par);
wolfSSL 15:117db924cf7c 1029 }
wolfSSL 15:117db924cf7c 1030
wolfSSL 15:117db924cf7c 1031 /* list to hold all certs found */
wolfSSL 15:117db924cf7c 1032 node = (WC_DerCertList*)XMALLOC(sizeof(WC_DerCertList),
wolfSSL 15:117db924cf7c 1033 pkcs12->heap, DYNAMIC_TYPE_PKCS);
wolfSSL 15:117db924cf7c 1034 if (node == NULL) {
wolfSSL 15:117db924cf7c 1035 ERROR_OUT(MEMORY_E, exit_pk12par);
wolfSSL 15:117db924cf7c 1036 }
wolfSSL 15:117db924cf7c 1037 XMEMSET(node, 0, sizeof(WC_DerCertList));
wolfSSL 15:117db924cf7c 1038
wolfSSL 15:117db924cf7c 1039 node->buffer = (byte*)XMALLOC(size, pkcs12->heap,
wolfSSL 15:117db924cf7c 1040 DYNAMIC_TYPE_PKCS);
wolfSSL 15:117db924cf7c 1041 if (node->buffer == NULL) {
wolfSSL 15:117db924cf7c 1042 XFREE(node, pkcs12->heap, DYNAMIC_TYPE_PKCS);
wolfSSL 15:117db924cf7c 1043 ERROR_OUT(MEMORY_E, exit_pk12par);
wolfSSL 15:117db924cf7c 1044 }
wolfSSL 15:117db924cf7c 1045 XMEMCPY(node->buffer, data + idx, size);
wolfSSL 15:117db924cf7c 1046 node->bufferSz = size;
wolfSSL 15:117db924cf7c 1047
wolfSSL 15:117db924cf7c 1048 /* put the new node into the list */
wolfSSL 15:117db924cf7c 1049 if (certList != NULL) {
wolfSSL 15:117db924cf7c 1050 WOLFSSL_MSG("Pushing new cert onto queue");
wolfSSL 15:117db924cf7c 1051 tailList->next = node;
wolfSSL 15:117db924cf7c 1052 tailList = node;
wolfSSL 15:117db924cf7c 1053 }
wolfSSL 15:117db924cf7c 1054 else {
wolfSSL 15:117db924cf7c 1055 certList = node;
wolfSSL 15:117db924cf7c 1056 tailList = node;
wolfSSL 15:117db924cf7c 1057 }
wolfSSL 15:117db924cf7c 1058
wolfSSL 15:117db924cf7c 1059 /* on to next */
wolfSSL 15:117db924cf7c 1060 idx += size;
wolfSSL 15:117db924cf7c 1061 }
wolfSSL 15:117db924cf7c 1062 break;
wolfSSL 15:117db924cf7c 1063
wolfSSL 15:117db924cf7c 1064 case WC_PKCS12_CrlBag: /* 670 */
wolfSSL 15:117db924cf7c 1065 WOLFSSL_MSG("PKCS12 CRL BAG not yet supported");
wolfSSL 15:117db924cf7c 1066 break;
wolfSSL 15:117db924cf7c 1067
wolfSSL 15:117db924cf7c 1068 case WC_PKCS12_SecretBag: /* 671 */
wolfSSL 15:117db924cf7c 1069 WOLFSSL_MSG("PKCS12 Secret BAG not yet supported");
wolfSSL 15:117db924cf7c 1070 break;
wolfSSL 15:117db924cf7c 1071
wolfSSL 15:117db924cf7c 1072 case WC_PKCS12_SafeContentsBag: /* 672 */
wolfSSL 15:117db924cf7c 1073 WOLFSSL_MSG("PKCS12 Safe Contents BAG not yet supported");
wolfSSL 15:117db924cf7c 1074 break;
wolfSSL 15:117db924cf7c 1075
wolfSSL 15:117db924cf7c 1076 default:
wolfSSL 15:117db924cf7c 1077 WOLFSSL_MSG("Unknown PKCS12 BAG type found");
wolfSSL 15:117db924cf7c 1078 }
wolfSSL 15:117db924cf7c 1079
wolfSSL 15:117db924cf7c 1080 /* Attribute, unknown bag or unsupported */
wolfSSL 15:117db924cf7c 1081 if ((int)idx < bagSz) {
wolfSSL 15:117db924cf7c 1082 idx = bagSz; /* skip for now */
wolfSSL 15:117db924cf7c 1083 }
wolfSSL 15:117db924cf7c 1084 }
wolfSSL 15:117db924cf7c 1085
wolfSSL 15:117db924cf7c 1086 /* free temporary buffer */
wolfSSL 15:117db924cf7c 1087 if (buf != NULL) {
wolfSSL 15:117db924cf7c 1088 XFREE(buf, pkcs12->heap, DYNAMIC_TYPE_PKCS);
wolfSSL 15:117db924cf7c 1089 buf = NULL;
wolfSSL 15:117db924cf7c 1090 }
wolfSSL 15:117db924cf7c 1091
wolfSSL 15:117db924cf7c 1092 ci = ci->next;
wolfSSL 15:117db924cf7c 1093 WOLFSSL_MSG("Done Parsing PKCS12 Content Info Container");
wolfSSL 15:117db924cf7c 1094 }
wolfSSL 15:117db924cf7c 1095
wolfSSL 15:117db924cf7c 1096 /* check if key pair, remove from list */
wolfSSL 15:117db924cf7c 1097 if (*pkey != NULL) {
wolfSSL 15:117db924cf7c 1098 freeDecCertList(&certList, pkey, pkeySz, cert, certSz, pkcs12->heap);
wolfSSL 15:117db924cf7c 1099 }
wolfSSL 15:117db924cf7c 1100
wolfSSL 15:117db924cf7c 1101 /* if ca arg provided return certList, otherwise free it */
wolfSSL 15:117db924cf7c 1102 if (ca != NULL) {
wolfSSL 15:117db924cf7c 1103 *ca = certList;
wolfSSL 15:117db924cf7c 1104 }
wolfSSL 15:117db924cf7c 1105 else {
wolfSSL 15:117db924cf7c 1106 /* free list, not wanted */
wolfSSL 15:117db924cf7c 1107 wc_FreeCertList(certList, pkcs12->heap);
wolfSSL 15:117db924cf7c 1108 }
wolfSSL 15:117db924cf7c 1109
wolfSSL 15:117db924cf7c 1110 ret = 0; /* success */
wolfSSL 15:117db924cf7c 1111
wolfSSL 15:117db924cf7c 1112 exit_pk12par:
wolfSSL 15:117db924cf7c 1113
wolfSSL 15:117db924cf7c 1114 if (ret != 0) {
wolfSSL 15:117db924cf7c 1115 /* failure cleanup */
wolfSSL 15:117db924cf7c 1116 if (*pkey) {
wolfSSL 15:117db924cf7c 1117 XFREE(*pkey, pkcs12->heap, DYNAMIC_TYPE_PUBLIC_KEY);
wolfSSL 15:117db924cf7c 1118 *pkey = NULL;
wolfSSL 15:117db924cf7c 1119 }
wolfSSL 15:117db924cf7c 1120 if (buf) {
wolfSSL 15:117db924cf7c 1121 XFREE(buf, pkcs12->heap, DYNAMIC_TYPE_PKCS);
wolfSSL 15:117db924cf7c 1122 buf = NULL;
wolfSSL 15:117db924cf7c 1123 }
wolfSSL 15:117db924cf7c 1124
wolfSSL 15:117db924cf7c 1125 wc_FreeCertList(certList, pkcs12->heap);
wolfSSL 15:117db924cf7c 1126 }
wolfSSL 15:117db924cf7c 1127
wolfSSL 15:117db924cf7c 1128 return ret;
wolfSSL 15:117db924cf7c 1129 }
wolfSSL 15:117db924cf7c 1130
wolfSSL 15:117db924cf7c 1131
wolfSSL 15:117db924cf7c 1132 /* Helper function to shroud keys.
wolfSSL 15:117db924cf7c 1133 *
wolfSSL 15:117db924cf7c 1134 * pkcs12 structure to use with shrouding key
wolfSSL 15:117db924cf7c 1135 * rng random number generator used
wolfSSL 15:117db924cf7c 1136 * out buffer to hold results
wolfSSL 15:117db924cf7c 1137 * outSz size of out buffer
wolfSSL 15:117db924cf7c 1138 * key key that is going to be shrouded
wolfSSL 15:117db924cf7c 1139 * keySz size of key buffer
wolfSSL 15:117db924cf7c 1140 * vAlgo algorithm version
wolfSSL 15:117db924cf7c 1141 * pass password to use
wolfSSL 15:117db924cf7c 1142 * passSz size of pass buffer
wolfSSL 15:117db924cf7c 1143 * itt number of iterations
wolfSSL 15:117db924cf7c 1144 *
wolfSSL 15:117db924cf7c 1145 * returns the size of the shrouded key on success
wolfSSL 15:117db924cf7c 1146 */
wolfSSL 15:117db924cf7c 1147 static int wc_PKCS12_shroud_key(WC_PKCS12* pkcs12, WC_RNG* rng,
wolfSSL 15:117db924cf7c 1148 byte* out, word32* outSz, byte* key, word32 keySz, int vAlgo,
wolfSSL 15:117db924cf7c 1149 const char* pass, int passSz, int itt)
wolfSSL 15:117db924cf7c 1150 {
wolfSSL 15:117db924cf7c 1151 void* heap;
wolfSSL 15:117db924cf7c 1152 word32 tmpIdx = 0;
wolfSSL 15:117db924cf7c 1153 int vPKCS = 1; /* PKCS#12 default set to 1 */
wolfSSL 15:117db924cf7c 1154 word32 sz;
wolfSSL 15:117db924cf7c 1155 word32 totalSz = 0;
wolfSSL 15:117db924cf7c 1156 int ret;
wolfSSL 15:117db924cf7c 1157
wolfSSL 15:117db924cf7c 1158
wolfSSL 15:117db924cf7c 1159 if (outSz == NULL || pkcs12 == NULL || rng == NULL || key == NULL ||
wolfSSL 15:117db924cf7c 1160 pass == NULL) {
wolfSSL 15:117db924cf7c 1161 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 1162 }
wolfSSL 15:117db924cf7c 1163
wolfSSL 15:117db924cf7c 1164 heap = wc_PKCS12_GetHeap(pkcs12);
wolfSSL 15:117db924cf7c 1165
wolfSSL 15:117db924cf7c 1166 /* check if trying to get size */
wolfSSL 15:117db924cf7c 1167 if (out != NULL) {
wolfSSL 15:117db924cf7c 1168 tmpIdx += MAX_LENGTH_SZ + 1; /* save room for length and tag (+1) */
wolfSSL 15:117db924cf7c 1169 sz = *outSz - tmpIdx;
wolfSSL 15:117db924cf7c 1170 }
wolfSSL 15:117db924cf7c 1171
wolfSSL 15:117db924cf7c 1172 /* case of no encryption */
wolfSSL 15:117db924cf7c 1173 if (vAlgo < 0) {
wolfSSL 15:117db924cf7c 1174 const byte* curveOID = NULL;
wolfSSL 15:117db924cf7c 1175 word32 oidSz = 0;
wolfSSL 15:117db924cf7c 1176 int algoID;
wolfSSL 15:117db924cf7c 1177
wolfSSL 15:117db924cf7c 1178 WOLFSSL_MSG("creating PKCS12 Key Bag");
wolfSSL 15:117db924cf7c 1179
wolfSSL 15:117db924cf7c 1180 /* check key type and get OID if ECC */
wolfSSL 15:117db924cf7c 1181 if ((ret = wc_GetKeyOID(key, keySz, &curveOID, &oidSz, &algoID, heap))
wolfSSL 15:117db924cf7c 1182 < 0) {
wolfSSL 15:117db924cf7c 1183 return ret;
wolfSSL 15:117db924cf7c 1184 }
wolfSSL 15:117db924cf7c 1185
wolfSSL 15:117db924cf7c 1186 /* PKCS#8 wrapping around key */
wolfSSL 15:117db924cf7c 1187 ret = wc_CreatePKCS8Key(out + tmpIdx, &sz, key, keySz, algoID,
wolfSSL 15:117db924cf7c 1188 curveOID, oidSz);
wolfSSL 15:117db924cf7c 1189 }
wolfSSL 15:117db924cf7c 1190 else {
wolfSSL 15:117db924cf7c 1191 WOLFSSL_MSG("creating PKCS12 Shrouded Key Bag");
wolfSSL 15:117db924cf7c 1192
wolfSSL 15:117db924cf7c 1193 if (vAlgo == PBE_SHA1_DES) {
wolfSSL 15:117db924cf7c 1194 vPKCS = PKCS5;
wolfSSL 15:117db924cf7c 1195 vAlgo = 10;
wolfSSL 15:117db924cf7c 1196 }
wolfSSL 15:117db924cf7c 1197
wolfSSL 15:117db924cf7c 1198 ret = UnTraditionalEnc(key, keySz, out + tmpIdx, &sz, pass, passSz,
wolfSSL 15:117db924cf7c 1199 vPKCS, vAlgo, NULL, 0, itt, rng, heap);
wolfSSL 15:117db924cf7c 1200 }
wolfSSL 15:117db924cf7c 1201 if (ret == LENGTH_ONLY_E) {
wolfSSL 15:117db924cf7c 1202 *outSz = sz + MAX_LENGTH_SZ + 1;
wolfSSL 15:117db924cf7c 1203 return LENGTH_ONLY_E;
wolfSSL 15:117db924cf7c 1204 }
wolfSSL 15:117db924cf7c 1205 if (ret < 0) {
wolfSSL 15:117db924cf7c 1206 return ret;
wolfSSL 15:117db924cf7c 1207 }
wolfSSL 15:117db924cf7c 1208
wolfSSL 15:117db924cf7c 1209 totalSz += ret;
wolfSSL 15:117db924cf7c 1210
wolfSSL 15:117db924cf7c 1211 /* out should not be null at this point but check before writing */
wolfSSL 15:117db924cf7c 1212 if (out == NULL) {
wolfSSL 15:117db924cf7c 1213 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 1214 }
wolfSSL 15:117db924cf7c 1215
wolfSSL 15:117db924cf7c 1216 /* rewind index and set tag and length */
wolfSSL 15:117db924cf7c 1217 tmpIdx -= MAX_LENGTH_SZ + 1;
wolfSSL 15:117db924cf7c 1218 sz = SetExplicit(0, ret, out + tmpIdx);
wolfSSL 15:117db924cf7c 1219 tmpIdx += sz; totalSz += sz;
wolfSSL 15:117db924cf7c 1220 XMEMMOVE(out + tmpIdx, out + MAX_LENGTH_SZ + 1, ret);
wolfSSL 15:117db924cf7c 1221
wolfSSL 15:117db924cf7c 1222 return totalSz;
wolfSSL 15:117db924cf7c 1223 }
wolfSSL 15:117db924cf7c 1224
wolfSSL 15:117db924cf7c 1225
wolfSSL 15:117db924cf7c 1226 /* Helper function to create key bag.
wolfSSL 15:117db924cf7c 1227 *
wolfSSL 15:117db924cf7c 1228 * pkcs12 structure to use with key bag
wolfSSL 15:117db924cf7c 1229 * rng random number generator used
wolfSSL 15:117db924cf7c 1230 * out buffer to hold results
wolfSSL 15:117db924cf7c 1231 * outSz size of out buffer
wolfSSL 15:117db924cf7c 1232 * key key that is going into key bag
wolfSSL 15:117db924cf7c 1233 * keySz size of key buffer
wolfSSL 15:117db924cf7c 1234 * algo algorithm version
wolfSSL 15:117db924cf7c 1235 * iter number of iterations
wolfSSL 15:117db924cf7c 1236 * pass password to use
wolfSSL 15:117db924cf7c 1237 * passSz size of pass buffer
wolfSSL 15:117db924cf7c 1238 *
wolfSSL 15:117db924cf7c 1239 * returns the size of the key bag on success
wolfSSL 15:117db924cf7c 1240 */
wolfSSL 15:117db924cf7c 1241 static int wc_PKCS12_create_key_bag(WC_PKCS12* pkcs12, WC_RNG* rng,
wolfSSL 15:117db924cf7c 1242 byte* out, word32* outSz, byte* key, word32 keySz, int algo, int iter,
wolfSSL 15:117db924cf7c 1243 char* pass, int passSz)
wolfSSL 15:117db924cf7c 1244 {
wolfSSL 15:117db924cf7c 1245 void* heap;
wolfSSL 15:117db924cf7c 1246 byte* tmp;
wolfSSL 15:117db924cf7c 1247 word32 length = 0;
wolfSSL 15:117db924cf7c 1248 word32 idx = 0;
wolfSSL 15:117db924cf7c 1249 word32 totalSz = 0;
wolfSSL 15:117db924cf7c 1250 word32 sz;
wolfSSL 15:117db924cf7c 1251 word32 i;
wolfSSL 15:117db924cf7c 1252 word32 tmpSz;
wolfSSL 15:117db924cf7c 1253 int ret;
wolfSSL 15:117db924cf7c 1254
wolfSSL 15:117db924cf7c 1255 /* get max size for shrouded key */
wolfSSL 15:117db924cf7c 1256 ret = wc_PKCS12_shroud_key(pkcs12, rng, NULL, &length, key, keySz,
wolfSSL 15:117db924cf7c 1257 algo, pass, passSz, iter);
wolfSSL 15:117db924cf7c 1258 if (ret != LENGTH_ONLY_E && ret < 0) {
wolfSSL 15:117db924cf7c 1259 return ret;
wolfSSL 15:117db924cf7c 1260 }
wolfSSL 15:117db924cf7c 1261
wolfSSL 15:117db924cf7c 1262 if (out == NULL) {
wolfSSL 15:117db924cf7c 1263 *outSz = MAX_SEQ_SZ + WC_PKCS12_DATA_OBJ_SZ + 1 + MAX_LENGTH_SZ +
wolfSSL 15:117db924cf7c 1264 length;
wolfSSL 15:117db924cf7c 1265 return LENGTH_ONLY_E;
wolfSSL 15:117db924cf7c 1266 }
wolfSSL 15:117db924cf7c 1267
wolfSSL 15:117db924cf7c 1268 heap = wc_PKCS12_GetHeap(pkcs12);
wolfSSL 15:117db924cf7c 1269
wolfSSL 15:117db924cf7c 1270 /* leave room for sequence */
wolfSSL 15:117db924cf7c 1271 idx += MAX_SEQ_SZ;
wolfSSL 15:117db924cf7c 1272
wolfSSL 15:117db924cf7c 1273 if (algo < 0) { /* not encrypted */
wolfSSL 15:117db924cf7c 1274 out[idx++] = ASN_OBJECT_ID; totalSz++;
wolfSSL 15:117db924cf7c 1275 sz = SetLength(sizeof(WC_PKCS12_KeyBag_OID), out + idx);
wolfSSL 15:117db924cf7c 1276 idx += sz; totalSz += sz;
wolfSSL 15:117db924cf7c 1277 for (i = 0; i < sizeof(WC_PKCS12_KeyBag_OID); i++) {
wolfSSL 15:117db924cf7c 1278 out[idx++] = WC_PKCS12_KeyBag_OID[i]; totalSz++;
wolfSSL 15:117db924cf7c 1279 }
wolfSSL 15:117db924cf7c 1280 }
wolfSSL 15:117db924cf7c 1281 else { /* encrypted */
wolfSSL 15:117db924cf7c 1282 out[idx++] = ASN_OBJECT_ID; totalSz++;
wolfSSL 15:117db924cf7c 1283 sz = SetLength(sizeof(WC_PKCS12_ShroudedKeyBag_OID), out + idx);
wolfSSL 15:117db924cf7c 1284 idx += sz; totalSz += sz;
wolfSSL 15:117db924cf7c 1285 for (i = 0; i < sizeof(WC_PKCS12_ShroudedKeyBag_OID); i++) {
wolfSSL 15:117db924cf7c 1286 out[idx++] = WC_PKCS12_ShroudedKeyBag_OID[i]; totalSz++;
wolfSSL 15:117db924cf7c 1287 }
wolfSSL 15:117db924cf7c 1288 }
wolfSSL 15:117db924cf7c 1289
wolfSSL 15:117db924cf7c 1290 /* shroud key */
wolfSSL 15:117db924cf7c 1291 tmp = (byte*)XMALLOC(length, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1292 if (tmp == NULL) {
wolfSSL 15:117db924cf7c 1293 return MEMORY_E;
wolfSSL 15:117db924cf7c 1294 }
wolfSSL 15:117db924cf7c 1295
wolfSSL 15:117db924cf7c 1296 ret = wc_PKCS12_shroud_key(pkcs12, rng, tmp, &length, key, keySz,
wolfSSL 15:117db924cf7c 1297 algo, pass, passSz, iter);
wolfSSL 15:117db924cf7c 1298 if (ret < 0) {
wolfSSL 15:117db924cf7c 1299 XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1300 return ret;
wolfSSL 15:117db924cf7c 1301 }
wolfSSL 15:117db924cf7c 1302 length = ret;
wolfSSL 15:117db924cf7c 1303 XMEMCPY(out + idx, tmp, length);
wolfSSL 15:117db924cf7c 1304 XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1305 totalSz += length;
wolfSSL 15:117db924cf7c 1306
wolfSSL 15:117db924cf7c 1307 /* set begining sequence */
wolfSSL 15:117db924cf7c 1308 tmpSz = SetSequence(totalSz, out);
wolfSSL 15:117db924cf7c 1309 XMEMMOVE(out + tmpSz, out + MAX_SEQ_SZ, totalSz);
wolfSSL 15:117db924cf7c 1310
wolfSSL 15:117db924cf7c 1311 (void)heap;
wolfSSL 15:117db924cf7c 1312 return totalSz + tmpSz;
wolfSSL 15:117db924cf7c 1313 }
wolfSSL 15:117db924cf7c 1314
wolfSSL 15:117db924cf7c 1315
wolfSSL 15:117db924cf7c 1316 /* Helper function to create cert bag.
wolfSSL 15:117db924cf7c 1317 *
wolfSSL 15:117db924cf7c 1318 * pkcs12 structure to use with cert bag
wolfSSL 15:117db924cf7c 1319 * out buffer to hold results
wolfSSL 15:117db924cf7c 1320 * outSz size of out buffer
wolfSSL 15:117db924cf7c 1321 * cert cert that is going into cert bag
wolfSSL 15:117db924cf7c 1322 * certSz size of cert buffer
wolfSSL 15:117db924cf7c 1323 *
wolfSSL 15:117db924cf7c 1324 * returns the size of the cert bag on success
wolfSSL 15:117db924cf7c 1325 */
wolfSSL 15:117db924cf7c 1326 static int wc_PKCS12_create_cert_bag(WC_PKCS12* pkcs12,
wolfSSL 15:117db924cf7c 1327 byte* out, word32* outSz, byte* cert, word32 certSz)
wolfSSL 15:117db924cf7c 1328 {
wolfSSL 15:117db924cf7c 1329 word32 length = 0;
wolfSSL 15:117db924cf7c 1330 word32 idx = 0;
wolfSSL 15:117db924cf7c 1331 word32 totalSz = 0;
wolfSSL 15:117db924cf7c 1332 word32 sz;
wolfSSL 15:117db924cf7c 1333 int WC_CERTBAG_OBJECT_ID = 13;
wolfSSL 15:117db924cf7c 1334 int WC_CERTBAG1_OBJECT_ID = 12;
wolfSSL 15:117db924cf7c 1335 word32 i;
wolfSSL 15:117db924cf7c 1336 word32 tmpSz;
wolfSSL 15:117db924cf7c 1337
wolfSSL 15:117db924cf7c 1338 if (out == NULL) {
wolfSSL 15:117db924cf7c 1339 *outSz = MAX_SEQ_SZ + WC_CERTBAG_OBJECT_ID + 1 + MAX_LENGTH_SZ +
wolfSSL 15:117db924cf7c 1340 MAX_SEQ_SZ + WC_CERTBAG1_OBJECT_ID + 1 + MAX_LENGTH_SZ + 1 +
wolfSSL 15:117db924cf7c 1341 MAX_LENGTH_SZ + certSz;
wolfSSL 15:117db924cf7c 1342 return LENGTH_ONLY_E;
wolfSSL 15:117db924cf7c 1343 }
wolfSSL 15:117db924cf7c 1344
wolfSSL 15:117db924cf7c 1345 /* check buffer size able to handle max size */
wolfSSL 15:117db924cf7c 1346 if (*outSz < (MAX_SEQ_SZ + WC_CERTBAG_OBJECT_ID + 1 + MAX_LENGTH_SZ +
wolfSSL 15:117db924cf7c 1347 MAX_SEQ_SZ + WC_CERTBAG1_OBJECT_ID + 1 + MAX_LENGTH_SZ + 1 +
wolfSSL 15:117db924cf7c 1348 MAX_LENGTH_SZ + certSz)) {
wolfSSL 15:117db924cf7c 1349 return BUFFER_E;
wolfSSL 15:117db924cf7c 1350 }
wolfSSL 15:117db924cf7c 1351
wolfSSL 15:117db924cf7c 1352 /* save room for sequence */
wolfSSL 15:117db924cf7c 1353 idx += MAX_SEQ_SZ;
wolfSSL 15:117db924cf7c 1354
wolfSSL 15:117db924cf7c 1355 /* objectId WC_PKCS12_CertBag */
wolfSSL 15:117db924cf7c 1356 out[idx++] = ASN_OBJECT_ID; totalSz++;
wolfSSL 15:117db924cf7c 1357 sz = SetLength(sizeof(WC_PKCS12_CertBag_OID), out + idx);
wolfSSL 15:117db924cf7c 1358 idx += sz; totalSz += sz;
wolfSSL 15:117db924cf7c 1359 for (i = 0; i < sizeof(WC_PKCS12_CertBag_OID); i++) {
wolfSSL 15:117db924cf7c 1360 out[idx++] = WC_PKCS12_CertBag_OID[i]; totalSz++;
wolfSSL 15:117db924cf7c 1361 }
wolfSSL 15:117db924cf7c 1362
wolfSSL 15:117db924cf7c 1363 /**** Cert Bag type 1 ****/
wolfSSL 15:117db924cf7c 1364 out[idx++] = (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC); totalSz++;
wolfSSL 15:117db924cf7c 1365
wolfSSL 15:117db924cf7c 1366 /* save room for length and sequence */
wolfSSL 15:117db924cf7c 1367 idx += MAX_LENGTH_SZ;
wolfSSL 15:117db924cf7c 1368 idx += MAX_SEQ_SZ;
wolfSSL 15:117db924cf7c 1369
wolfSSL 15:117db924cf7c 1370 /* object id WC_PKCS12_CertBag_Type1 */
wolfSSL 15:117db924cf7c 1371 out[idx++] = ASN_OBJECT_ID; length++;
wolfSSL 15:117db924cf7c 1372 sz = SetLength(sizeof(WC_PKCS12_CertBag_Type1_OID), out + idx);
wolfSSL 15:117db924cf7c 1373 idx += sz; length += sz;
wolfSSL 15:117db924cf7c 1374 for (i = 0; i < sizeof(WC_PKCS12_CertBag_Type1_OID); i++) {
wolfSSL 15:117db924cf7c 1375 out[idx++] = WC_PKCS12_CertBag_Type1_OID[i]; length++;
wolfSSL 15:117db924cf7c 1376 }
wolfSSL 15:117db924cf7c 1377
wolfSSL 15:117db924cf7c 1378 out[idx++] = (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC); length++;
wolfSSL 15:117db924cf7c 1379 sz = 0;
wolfSSL 15:117db924cf7c 1380 idx += MAX_LENGTH_SZ; /* save room for length */
wolfSSL 15:117db924cf7c 1381
wolfSSL 15:117db924cf7c 1382 /* place the cert in the buffer */
wolfSSL 15:117db924cf7c 1383 out[idx++] = ASN_OCTET_STRING; sz++;
wolfSSL 15:117db924cf7c 1384 tmpSz = SetLength(certSz, out + idx);
wolfSSL 15:117db924cf7c 1385 idx += tmpSz; sz += tmpSz;
wolfSSL 15:117db924cf7c 1386 XMEMCPY(out + idx, cert, certSz);
wolfSSL 15:117db924cf7c 1387 idx += certSz; sz += certSz;
wolfSSL 15:117db924cf7c 1388
wolfSSL 15:117db924cf7c 1389 /* rewind idx and place length */
wolfSSL 15:117db924cf7c 1390 idx -= (sz + MAX_LENGTH_SZ);
wolfSSL 15:117db924cf7c 1391 tmpSz = SetLength(sz, out + idx);
wolfSSL 15:117db924cf7c 1392 XMEMMOVE(out + idx + tmpSz, out + idx + MAX_LENGTH_SZ, sz);
wolfSSL 15:117db924cf7c 1393 idx += tmpSz + sz; length += tmpSz + sz;
wolfSSL 15:117db924cf7c 1394
wolfSSL 15:117db924cf7c 1395 /* rewind idx and set sequence */
wolfSSL 15:117db924cf7c 1396 idx -= (length + MAX_SEQ_SZ);
wolfSSL 15:117db924cf7c 1397 tmpSz = SetSequence(length, out + idx);
wolfSSL 15:117db924cf7c 1398 XMEMMOVE(out + idx + tmpSz, out + idx + MAX_SEQ_SZ, length);
wolfSSL 15:117db924cf7c 1399 length += tmpSz;
wolfSSL 15:117db924cf7c 1400
wolfSSL 15:117db924cf7c 1401 /* place final length */
wolfSSL 15:117db924cf7c 1402 idx -= MAX_LENGTH_SZ;
wolfSSL 15:117db924cf7c 1403 tmpSz = SetLength(length, out + idx);
wolfSSL 15:117db924cf7c 1404 XMEMMOVE(out + idx + tmpSz, out + idx + MAX_LENGTH_SZ, length);
wolfSSL 15:117db924cf7c 1405 length += tmpSz;
wolfSSL 15:117db924cf7c 1406
wolfSSL 15:117db924cf7c 1407 /* place final sequence */
wolfSSL 15:117db924cf7c 1408 totalSz += length;
wolfSSL 15:117db924cf7c 1409 tmpSz = SetSequence(totalSz, out);
wolfSSL 15:117db924cf7c 1410 XMEMMOVE(out + tmpSz, out + MAX_SEQ_SZ, totalSz);
wolfSSL 15:117db924cf7c 1411
wolfSSL 15:117db924cf7c 1412 (void)pkcs12;
wolfSSL 15:117db924cf7c 1413
wolfSSL 15:117db924cf7c 1414 return totalSz + tmpSz;
wolfSSL 15:117db924cf7c 1415 }
wolfSSL 15:117db924cf7c 1416
wolfSSL 15:117db924cf7c 1417
wolfSSL 15:117db924cf7c 1418 /* Helper function to encrypt content.
wolfSSL 15:117db924cf7c 1419 *
wolfSSL 15:117db924cf7c 1420 * pkcs12 structure to use with key bag
wolfSSL 15:117db924cf7c 1421 * rng random number generator used
wolfSSL 15:117db924cf7c 1422 * out buffer to hold results
wolfSSL 15:117db924cf7c 1423 * outSz size of out buffer
wolfSSL 15:117db924cf7c 1424 * content content to encrypt
wolfSSL 15:117db924cf7c 1425 * contentSz size of content buffer
wolfSSL 15:117db924cf7c 1426 * vAlgo algorithm version
wolfSSL 15:117db924cf7c 1427 * pass password to use
wolfSSL 15:117db924cf7c 1428 * passSz size of pass buffer
wolfSSL 15:117db924cf7c 1429 * iter number of iterations
wolfSSL 15:117db924cf7c 1430 * type content type i.e WC_PKCS12_ENCRYPTED_DATA or WC_PKCS12_DATA
wolfSSL 15:117db924cf7c 1431 *
wolfSSL 15:117db924cf7c 1432 * returns the size of result on success
wolfSSL 15:117db924cf7c 1433 */
wolfSSL 15:117db924cf7c 1434 static int wc_PKCS12_encrypt_content(WC_PKCS12* pkcs12, WC_RNG* rng,
wolfSSL 15:117db924cf7c 1435 byte* out, word32* outSz, byte* content, word32 contentSz, int vAlgo,
wolfSSL 15:117db924cf7c 1436 const char* pass, int passSz, int iter, int type)
wolfSSL 15:117db924cf7c 1437 {
wolfSSL 15:117db924cf7c 1438 void* heap;
wolfSSL 15:117db924cf7c 1439 int vPKCS = 1; /* PKCS#12 is always set to 1 */
wolfSSL 15:117db924cf7c 1440 int ret;
wolfSSL 15:117db924cf7c 1441 byte* tmp;
wolfSSL 15:117db924cf7c 1442 word32 idx = 0;
wolfSSL 15:117db924cf7c 1443 word32 totalSz = 0;
wolfSSL 15:117db924cf7c 1444 word32 length = 0;
wolfSSL 15:117db924cf7c 1445 word32 tmpSz;
wolfSSL 15:117db924cf7c 1446 word32 encSz;
wolfSSL 15:117db924cf7c 1447 word32 i;
wolfSSL 15:117db924cf7c 1448
wolfSSL 15:117db924cf7c 1449 WOLFSSL_MSG("encrypting PKCS12 content");
wolfSSL 15:117db924cf7c 1450
wolfSSL 15:117db924cf7c 1451 heap = wc_PKCS12_GetHeap(pkcs12);
wolfSSL 15:117db924cf7c 1452
wolfSSL 15:117db924cf7c 1453 /* ENCRYPTED DATA
wolfSSL 15:117db924cf7c 1454 * ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC
wolfSSL 15:117db924cf7c 1455 * length
wolfSSL 15:117db924cf7c 1456 * sequence
wolfSSL 15:117db924cf7c 1457 * short int
wolfSSL 15:117db924cf7c 1458 * sequence
wolfSSL 15:117db924cf7c 1459 * get object id */
wolfSSL 15:117db924cf7c 1460 if (type == WC_PKCS12_ENCRYPTED_DATA) {
wolfSSL 15:117db924cf7c 1461 if (out == NULL) {
wolfSSL 15:117db924cf7c 1462 *outSz = 1 + MAX_LENGTH_SZ + MAX_SEQ_SZ + MAX_VERSION_SZ +
wolfSSL 15:117db924cf7c 1463 MAX_SEQ_SZ + WC_PKCS12_DATA_OBJ_SZ;
wolfSSL 15:117db924cf7c 1464 ret = EncryptContent(NULL, contentSz + MAX_SEQ_SZ, NULL, &encSz,
wolfSSL 15:117db924cf7c 1465 pass, passSz, vPKCS, vAlgo, NULL, 0, iter, rng, heap);
wolfSSL 15:117db924cf7c 1466 if (ret != LENGTH_ONLY_E) {
wolfSSL 15:117db924cf7c 1467 return ret;
wolfSSL 15:117db924cf7c 1468 }
wolfSSL 15:117db924cf7c 1469
wolfSSL 15:117db924cf7c 1470 *outSz += encSz;
wolfSSL 15:117db924cf7c 1471 return LENGTH_ONLY_E;
wolfSSL 15:117db924cf7c 1472 }
wolfSSL 15:117db924cf7c 1473
wolfSSL 15:117db924cf7c 1474 if (*outSz < (1 + MAX_LENGTH_SZ + MAX_SEQ_SZ + MAX_VERSION_SZ)) {
wolfSSL 15:117db924cf7c 1475 return BUFFER_E;
wolfSSL 15:117db924cf7c 1476 }
wolfSSL 15:117db924cf7c 1477 out[idx++] = (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC); totalSz++;
wolfSSL 15:117db924cf7c 1478
wolfSSL 15:117db924cf7c 1479 /* save room for length and sequence */
wolfSSL 15:117db924cf7c 1480 idx += MAX_LENGTH_SZ;
wolfSSL 15:117db924cf7c 1481 idx += MAX_SEQ_SZ;
wolfSSL 15:117db924cf7c 1482
wolfSSL 15:117db924cf7c 1483 tmpSz = SetMyVersion(0, out + idx, 0);
wolfSSL 15:117db924cf7c 1484 idx += tmpSz; length += tmpSz;
wolfSSL 15:117db924cf7c 1485
wolfSSL 15:117db924cf7c 1486 encSz = contentSz;
wolfSSL 15:117db924cf7c 1487 if ((ret = EncryptContent(NULL, contentSz, NULL, &encSz,
wolfSSL 15:117db924cf7c 1488 pass, passSz, vPKCS, vAlgo, NULL, 0, iter, rng, heap)) < 0) {
wolfSSL 15:117db924cf7c 1489 if (ret != LENGTH_ONLY_E) {
wolfSSL 15:117db924cf7c 1490 return ret;
wolfSSL 15:117db924cf7c 1491 }
wolfSSL 15:117db924cf7c 1492 }
wolfSSL 15:117db924cf7c 1493
wolfSSL 15:117db924cf7c 1494 if (*outSz < (idx + MAX_SEQ_SZ + WC_PKCS12_DATA_OBJ_SZ + encSz)) {
wolfSSL 15:117db924cf7c 1495 return BUFFER_E;
wolfSSL 15:117db924cf7c 1496 }
wolfSSL 15:117db924cf7c 1497 tmp = (byte*)XMALLOC(encSz, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1498 if (tmp == NULL) {
wolfSSL 15:117db924cf7c 1499 return MEMORY_E;
wolfSSL 15:117db924cf7c 1500 }
wolfSSL 15:117db924cf7c 1501
wolfSSL 15:117db924cf7c 1502 if ((ret = EncryptContent(content, contentSz, tmp, &encSz,
wolfSSL 15:117db924cf7c 1503 pass, passSz, vPKCS, vAlgo, NULL, 0, iter, rng, heap)) < 0) {
wolfSSL 15:117db924cf7c 1504 XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1505 return ret;
wolfSSL 15:117db924cf7c 1506 }
wolfSSL 15:117db924cf7c 1507 encSz = ret;
wolfSSL 15:117db924cf7c 1508
wolfSSL 15:117db924cf7c 1509 #ifdef WOLFSSL_DEBUG_PKCS12
wolfSSL 15:117db924cf7c 1510 {
wolfSSL 15:117db924cf7c 1511 byte* p;
wolfSSL 15:117db924cf7c 1512 for (printf("(size %u) Encrypted Content = ", encSz),
wolfSSL 15:117db924cf7c 1513 p = (byte*)tmp;
wolfSSL 15:117db924cf7c 1514 p < (byte*)tmp + encSz;
wolfSSL 15:117db924cf7c 1515 printf("%02X", *p), p++);
wolfSSL 15:117db924cf7c 1516 printf("\n");
wolfSSL 15:117db924cf7c 1517 }
wolfSSL 15:117db924cf7c 1518 #endif
wolfSSL 15:117db924cf7c 1519
wolfSSL 15:117db924cf7c 1520 tmpSz = SetSequence(WC_PKCS12_DATA_OBJ_SZ + encSz, out + idx);
wolfSSL 15:117db924cf7c 1521 idx += tmpSz; length += tmpSz;
wolfSSL 15:117db924cf7c 1522
wolfSSL 15:117db924cf7c 1523 out[idx++] = ASN_OBJECT_ID; length++;
wolfSSL 15:117db924cf7c 1524 tmpSz = SetLength(sizeof(WC_PKCS12_DATA_OID), out + idx);
wolfSSL 15:117db924cf7c 1525 idx += tmpSz; length += tmpSz;
wolfSSL 15:117db924cf7c 1526 for (i = 0; i < sizeof(WC_PKCS12_DATA_OID); i++) {
wolfSSL 15:117db924cf7c 1527 out[idx++] = WC_PKCS12_DATA_OID[i]; length++;
wolfSSL 15:117db924cf7c 1528 }
wolfSSL 15:117db924cf7c 1529
wolfSSL 15:117db924cf7c 1530 /* copy over encrypted data */
wolfSSL 15:117db924cf7c 1531 XMEMCPY(out + idx, tmp, encSz);
wolfSSL 15:117db924cf7c 1532 XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1533 idx += encSz; length += encSz;
wolfSSL 15:117db924cf7c 1534
wolfSSL 15:117db924cf7c 1535 /* rewind and place sequence */
wolfSSL 15:117db924cf7c 1536 idx -= (length + MAX_SEQ_SZ);
wolfSSL 15:117db924cf7c 1537 tmpSz = SetSequence(length, out + idx);
wolfSSL 15:117db924cf7c 1538 XMEMMOVE(out + idx + tmpSz, out + idx + MAX_SEQ_SZ, length);
wolfSSL 15:117db924cf7c 1539 length += tmpSz;
wolfSSL 15:117db924cf7c 1540
wolfSSL 15:117db924cf7c 1541 /* now place length */
wolfSSL 15:117db924cf7c 1542 idx -= MAX_LENGTH_SZ;
wolfSSL 15:117db924cf7c 1543 tmpSz = SetLength(length, out + idx);
wolfSSL 15:117db924cf7c 1544 XMEMMOVE(out + idx + tmpSz, out + idx + MAX_LENGTH_SZ, length);
wolfSSL 15:117db924cf7c 1545 totalSz += length + tmpSz;
wolfSSL 15:117db924cf7c 1546
wolfSSL 15:117db924cf7c 1547 return totalSz;
wolfSSL 15:117db924cf7c 1548 }
wolfSSL 15:117db924cf7c 1549
wolfSSL 15:117db924cf7c 1550 /* DATA
wolfSSL 15:117db924cf7c 1551 * ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC
wolfSSL 15:117db924cf7c 1552 * length
wolfSSL 15:117db924cf7c 1553 * ASN_OCTET_STRING
wolfSSL 15:117db924cf7c 1554 * length
wolfSSL 15:117db924cf7c 1555 * sequence containing all bags */
wolfSSL 15:117db924cf7c 1556 if (type == WC_PKCS12_DATA) {
wolfSSL 15:117db924cf7c 1557 if (out == NULL) {
wolfSSL 15:117db924cf7c 1558 *outSz = 1 + MAX_LENGTH_SZ + 1 + MAX_LENGTH_SZ + contentSz;
wolfSSL 15:117db924cf7c 1559 return LENGTH_ONLY_E;
wolfSSL 15:117db924cf7c 1560 }
wolfSSL 15:117db924cf7c 1561
wolfSSL 15:117db924cf7c 1562 if (*outSz < (1 + MAX_LENGTH_SZ + 1 + MAX_LENGTH_SZ + contentSz)) {
wolfSSL 15:117db924cf7c 1563 return BUFFER_E;
wolfSSL 15:117db924cf7c 1564 }
wolfSSL 15:117db924cf7c 1565
wolfSSL 15:117db924cf7c 1566 out[idx++] = (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC);
wolfSSL 15:117db924cf7c 1567 totalSz++;
wolfSSL 15:117db924cf7c 1568
wolfSSL 15:117db924cf7c 1569 /* save room for length */
wolfSSL 15:117db924cf7c 1570 idx += MAX_LENGTH_SZ;
wolfSSL 15:117db924cf7c 1571
wolfSSL 15:117db924cf7c 1572 out[idx++] = ASN_OCTET_STRING; length++;
wolfSSL 15:117db924cf7c 1573 tmpSz = SetLength(contentSz, out + idx);
wolfSSL 15:117db924cf7c 1574 idx += tmpSz; length += tmpSz;
wolfSSL 15:117db924cf7c 1575
wolfSSL 15:117db924cf7c 1576 /* sequence containing all bags */
wolfSSL 15:117db924cf7c 1577 XMEMCPY(out + idx, content, contentSz);
wolfSSL 15:117db924cf7c 1578 idx += contentSz; length += contentSz;
wolfSSL 15:117db924cf7c 1579
wolfSSL 15:117db924cf7c 1580 idx -= (MAX_LENGTH_SZ + length);
wolfSSL 15:117db924cf7c 1581 tmpSz = SetLength(length, out + idx);
wolfSSL 15:117db924cf7c 1582 XMEMMOVE(out + idx + tmpSz, out + idx + MAX_LENGTH_SZ, length);
wolfSSL 15:117db924cf7c 1583 totalSz += length + tmpSz;
wolfSSL 15:117db924cf7c 1584
wolfSSL 15:117db924cf7c 1585 return totalSz;
wolfSSL 15:117db924cf7c 1586 }
wolfSSL 15:117db924cf7c 1587
wolfSSL 15:117db924cf7c 1588 WOLFSSL_MSG("Unknown/Unsupported content type");
wolfSSL 15:117db924cf7c 1589 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 1590 }
wolfSSL 15:117db924cf7c 1591
wolfSSL 15:117db924cf7c 1592
wolfSSL 15:117db924cf7c 1593 /*
wolfSSL 15:117db924cf7c 1594 * pass : password to use with encryption
wolfSSL 15:117db924cf7c 1595 * passSz : size of the password buffer
wolfSSL 15:117db924cf7c 1596 * name : friendlyName to use
wolfSSL 15:117db924cf7c 1597 * key : DER format of key
wolfSSL 15:117db924cf7c 1598 * keySz : size of key buffer
wolfSSL 15:117db924cf7c 1599 * cert : DER format of certificate
wolfSSL 15:117db924cf7c 1600 * certSz : size of the certificate buffer
wolfSSL 15:117db924cf7c 1601 * ca : a list of extra certificates
wolfSSL 15:117db924cf7c 1602 * nidKey : type of encryption to use on the key (-1 means no encryption)
wolfSSL 15:117db924cf7c 1603 * nidCert : type of encryption to use on the certificate
wolfSSL 15:117db924cf7c 1604 * (-1 means no encryption)
wolfSSL 15:117db924cf7c 1605 * iter : number of iterations with encryption
wolfSSL 15:117db924cf7c 1606 * macIter : number of iterations when creating MAC
wolfSSL 15:117db924cf7c 1607 * keyType : flag for signature and/or encryption key
wolfSSL 15:117db924cf7c 1608 * heap : pointer to allocate from memory
wolfSSL 15:117db924cf7c 1609 *
wolfSSL 15:117db924cf7c 1610 * returns a pointer to a new WC_PKCS12 structure on success and NULL if failed
wolfSSL 15:117db924cf7c 1611 */
wolfSSL 15:117db924cf7c 1612 WC_PKCS12* wc_PKCS12_create(char* pass, word32 passSz, char* name,
wolfSSL 15:117db924cf7c 1613 byte* key, word32 keySz, byte* cert, word32 certSz, WC_DerCertList* ca,
wolfSSL 15:117db924cf7c 1614 int nidKey, int nidCert, int iter, int macIter, int keyType, void* heap)
wolfSSL 15:117db924cf7c 1615 {
wolfSSL 15:117db924cf7c 1616 WC_PKCS12* pkcs12;
wolfSSL 15:117db924cf7c 1617 AuthenticatedSafe* safe;
wolfSSL 15:117db924cf7c 1618 ContentInfo* ci;
wolfSSL 15:117db924cf7c 1619 WC_RNG rng;
wolfSSL 15:117db924cf7c 1620 int algo;
wolfSSL 15:117db924cf7c 1621 int ret;
wolfSSL 15:117db924cf7c 1622 int type;
wolfSSL 15:117db924cf7c 1623 word32 idx;
wolfSSL 15:117db924cf7c 1624 word32 sz;
wolfSSL 15:117db924cf7c 1625 word32 tmpSz;
wolfSSL 15:117db924cf7c 1626
wolfSSL 15:117db924cf7c 1627 byte* certCi = NULL;
wolfSSL 15:117db924cf7c 1628 word32 certCiSz;
wolfSSL 15:117db924cf7c 1629 byte* keyCi;
wolfSSL 15:117db924cf7c 1630 word32 keyCiSz;
wolfSSL 15:117db924cf7c 1631
wolfSSL 15:117db924cf7c 1632 byte* certBuf = NULL;
wolfSSL 15:117db924cf7c 1633 word32 certBufSz;
wolfSSL 15:117db924cf7c 1634 byte* keyBuf;
wolfSSL 15:117db924cf7c 1635 word32 keyBufSz = 0;
wolfSSL 15:117db924cf7c 1636
wolfSSL 15:117db924cf7c 1637 WOLFSSL_ENTER("wc_PKCS12_create()");
wolfSSL 15:117db924cf7c 1638
wolfSSL 15:117db924cf7c 1639 if ((ret = wc_InitRng_ex(&rng, heap, INVALID_DEVID)) != 0) {
wolfSSL 15:117db924cf7c 1640 return NULL;
wolfSSL 15:117db924cf7c 1641 }
wolfSSL 15:117db924cf7c 1642
wolfSSL 15:117db924cf7c 1643 if ((pkcs12 = wc_PKCS12_new()) == NULL) {
wolfSSL 15:117db924cf7c 1644 wc_FreeRng(&rng);
wolfSSL 15:117db924cf7c 1645 WOLFSSL_LEAVE("wc_PKCS12_create", MEMORY_E);
wolfSSL 15:117db924cf7c 1646 return NULL;
wolfSSL 15:117db924cf7c 1647 }
wolfSSL 15:117db924cf7c 1648
wolfSSL 15:117db924cf7c 1649 if ((ret = wc_PKCS12_SetHeap(pkcs12, heap)) != 0) {
wolfSSL 15:117db924cf7c 1650 wc_PKCS12_free(pkcs12);
wolfSSL 15:117db924cf7c 1651 wc_FreeRng(&rng);
wolfSSL 15:117db924cf7c 1652 WOLFSSL_LEAVE("wc_PKCS12_create", ret);
wolfSSL 15:117db924cf7c 1653 return NULL;
wolfSSL 15:117db924cf7c 1654 }
wolfSSL 15:117db924cf7c 1655
wolfSSL 15:117db924cf7c 1656 if (iter <= 0) {
wolfSSL 15:117db924cf7c 1657 iter = WC_PKCS12_ITT_DEFAULT;
wolfSSL 15:117db924cf7c 1658 }
wolfSSL 15:117db924cf7c 1659
wolfSSL 15:117db924cf7c 1660 /**** add private key bag ****/
wolfSSL 15:117db924cf7c 1661 switch (nidKey) {
wolfSSL 15:117db924cf7c 1662 case PBE_SHA1_RC4_128:
wolfSSL 15:117db924cf7c 1663 algo = 1;
wolfSSL 15:117db924cf7c 1664 break;
wolfSSL 15:117db924cf7c 1665
wolfSSL 15:117db924cf7c 1666 case PBE_SHA1_DES:
wolfSSL 15:117db924cf7c 1667 algo = 2;
wolfSSL 15:117db924cf7c 1668 break;
wolfSSL 15:117db924cf7c 1669
wolfSSL 15:117db924cf7c 1670 case PBE_SHA1_DES3:
wolfSSL 15:117db924cf7c 1671 algo = 3;
wolfSSL 15:117db924cf7c 1672 break;
wolfSSL 15:117db924cf7c 1673
wolfSSL 15:117db924cf7c 1674 /* no encryption */
wolfSSL 15:117db924cf7c 1675 case -1:
wolfSSL 15:117db924cf7c 1676 algo = -1;
wolfSSL 15:117db924cf7c 1677 break;
wolfSSL 15:117db924cf7c 1678
wolfSSL 15:117db924cf7c 1679 default:
wolfSSL 15:117db924cf7c 1680 WOLFSSL_MSG("Unknown/Unsupported key encryption");
wolfSSL 15:117db924cf7c 1681 wc_PKCS12_free(pkcs12);
wolfSSL 15:117db924cf7c 1682 wc_FreeRng(&rng);
wolfSSL 15:117db924cf7c 1683 return NULL;
wolfSSL 15:117db924cf7c 1684 }
wolfSSL 15:117db924cf7c 1685
wolfSSL 15:117db924cf7c 1686 /* get max size for key bag */
wolfSSL 15:117db924cf7c 1687 ret = wc_PKCS12_create_key_bag(pkcs12, &rng, NULL, &keyBufSz, key, keySz,
wolfSSL 15:117db924cf7c 1688 algo, iter, pass, passSz);
wolfSSL 15:117db924cf7c 1689 if (ret != LENGTH_ONLY_E && ret < 0) {
wolfSSL 15:117db924cf7c 1690 wc_PKCS12_free(pkcs12);
wolfSSL 15:117db924cf7c 1691 wc_FreeRng(&rng);
wolfSSL 15:117db924cf7c 1692 WOLFSSL_LEAVE("wc_PKCS12_create", ret);
wolfSSL 15:117db924cf7c 1693 return NULL;
wolfSSL 15:117db924cf7c 1694 }
wolfSSL 15:117db924cf7c 1695
wolfSSL 15:117db924cf7c 1696 /* account for sequence around bag */
wolfSSL 15:117db924cf7c 1697 keyBufSz += MAX_SEQ_SZ;
wolfSSL 15:117db924cf7c 1698
wolfSSL 15:117db924cf7c 1699 keyBuf = (byte*)XMALLOC(keyBufSz, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1700 if (keyBuf == NULL) {
wolfSSL 15:117db924cf7c 1701 wc_PKCS12_free(pkcs12);
wolfSSL 15:117db924cf7c 1702 wc_FreeRng(&rng);
wolfSSL 15:117db924cf7c 1703 WOLFSSL_LEAVE("wc_PKCS12_create", MEMORY_E);
wolfSSL 15:117db924cf7c 1704 return NULL;
wolfSSL 15:117db924cf7c 1705 }
wolfSSL 15:117db924cf7c 1706
wolfSSL 15:117db924cf7c 1707 ret = wc_PKCS12_create_key_bag(pkcs12, &rng, keyBuf + MAX_SEQ_SZ, &keyBufSz,
wolfSSL 15:117db924cf7c 1708 key, keySz, algo, iter, pass, passSz);
wolfSSL 15:117db924cf7c 1709 if (ret < 0) {
wolfSSL 15:117db924cf7c 1710 wc_PKCS12_free(pkcs12);
wolfSSL 15:117db924cf7c 1711 wc_FreeRng(&rng);
wolfSSL 15:117db924cf7c 1712 XFREE(keyBuf, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1713 WOLFSSL_LEAVE("wc_PKCS12_create", ret);
wolfSSL 15:117db924cf7c 1714 return NULL;
wolfSSL 15:117db924cf7c 1715 }
wolfSSL 15:117db924cf7c 1716 keyBufSz = ret;
wolfSSL 15:117db924cf7c 1717
wolfSSL 15:117db924cf7c 1718 tmpSz = SetSequence(keyBufSz, keyBuf);
wolfSSL 15:117db924cf7c 1719 XMEMMOVE(keyBuf + tmpSz, keyBuf + MAX_SEQ_SZ, keyBufSz);
wolfSSL 15:117db924cf7c 1720 keyBufSz += tmpSz;
wolfSSL 15:117db924cf7c 1721
wolfSSL 15:117db924cf7c 1722 ret = wc_PKCS12_encrypt_content(pkcs12, &rng, NULL, &keyCiSz,
wolfSSL 15:117db924cf7c 1723 NULL, keyBufSz, algo, pass, passSz, iter, WC_PKCS12_DATA);
wolfSSL 15:117db924cf7c 1724 if (ret != LENGTH_ONLY_E) {
wolfSSL 15:117db924cf7c 1725 wc_PKCS12_free(pkcs12);
wolfSSL 15:117db924cf7c 1726 wc_FreeRng(&rng);
wolfSSL 15:117db924cf7c 1727 XFREE(keyBuf, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1728 WOLFSSL_LEAVE("wc_PKCS12_create", ret);
wolfSSL 15:117db924cf7c 1729 return NULL;
wolfSSL 15:117db924cf7c 1730 }
wolfSSL 15:117db924cf7c 1731 keyCi = (byte*)XMALLOC(keyCiSz, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1732 if (keyCi == NULL) {
wolfSSL 15:117db924cf7c 1733 wc_PKCS12_free(pkcs12);
wolfSSL 15:117db924cf7c 1734 wc_FreeRng(&rng);
wolfSSL 15:117db924cf7c 1735 XFREE(keyBuf, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1736 return NULL;
wolfSSL 15:117db924cf7c 1737 }
wolfSSL 15:117db924cf7c 1738
wolfSSL 15:117db924cf7c 1739 ret = wc_PKCS12_encrypt_content(pkcs12, &rng, keyCi, &keyCiSz,
wolfSSL 15:117db924cf7c 1740 keyBuf, keyBufSz, algo, pass, passSz, iter, WC_PKCS12_DATA);
wolfSSL 15:117db924cf7c 1741 if (ret < 0 ) {
wolfSSL 15:117db924cf7c 1742 wc_PKCS12_free(pkcs12);
wolfSSL 15:117db924cf7c 1743 wc_FreeRng(&rng);
wolfSSL 15:117db924cf7c 1744 XFREE(keyBuf, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1745 XFREE(keyCi, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1746 WOLFSSL_LEAVE("wc_PKCS12_create", ret);
wolfSSL 15:117db924cf7c 1747 return NULL;
wolfSSL 15:117db924cf7c 1748 }
wolfSSL 15:117db924cf7c 1749 keyCiSz = ret;
wolfSSL 15:117db924cf7c 1750 XFREE(keyBuf, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1751
wolfSSL 15:117db924cf7c 1752 #ifdef WOLFSSL_DEBUG_PKCS12
wolfSSL 15:117db924cf7c 1753 {
wolfSSL 15:117db924cf7c 1754 byte* p;
wolfSSL 15:117db924cf7c 1755 for (printf("(size %u) Key Content Info = ", keyCiSz), p = (byte*)keyCi;
wolfSSL 15:117db924cf7c 1756 p < (byte*)keyCi + keyCiSz;
wolfSSL 15:117db924cf7c 1757 printf("%02X", *p), p++);
wolfSSL 15:117db924cf7c 1758 printf("\n");
wolfSSL 15:117db924cf7c 1759 }
wolfSSL 15:117db924cf7c 1760 #endif
wolfSSL 15:117db924cf7c 1761
wolfSSL 15:117db924cf7c 1762
wolfSSL 15:117db924cf7c 1763 /**** add main certificate bag and extras ****/
wolfSSL 15:117db924cf7c 1764 switch (nidCert) {
wolfSSL 15:117db924cf7c 1765 case PBE_SHA1_RC4_128:
wolfSSL 15:117db924cf7c 1766 type = WC_PKCS12_ENCRYPTED_DATA;
wolfSSL 15:117db924cf7c 1767 algo = 1;
wolfSSL 15:117db924cf7c 1768 break;
wolfSSL 15:117db924cf7c 1769
wolfSSL 15:117db924cf7c 1770 case PBE_SHA1_DES:
wolfSSL 15:117db924cf7c 1771 type = WC_PKCS12_ENCRYPTED_DATA;
wolfSSL 15:117db924cf7c 1772 algo = 2;
wolfSSL 15:117db924cf7c 1773 break;
wolfSSL 15:117db924cf7c 1774
wolfSSL 15:117db924cf7c 1775 case PBE_SHA1_DES3:
wolfSSL 15:117db924cf7c 1776 type = WC_PKCS12_ENCRYPTED_DATA;
wolfSSL 15:117db924cf7c 1777 algo = 3;
wolfSSL 15:117db924cf7c 1778 break;
wolfSSL 15:117db924cf7c 1779
wolfSSL 15:117db924cf7c 1780 case -1:
wolfSSL 15:117db924cf7c 1781 type = WC_PKCS12_DATA;
wolfSSL 15:117db924cf7c 1782 algo = -1;
wolfSSL 15:117db924cf7c 1783 break;
wolfSSL 15:117db924cf7c 1784
wolfSSL 15:117db924cf7c 1785 default:
wolfSSL 15:117db924cf7c 1786 WOLFSSL_MSG("Unknown/Unsupported certificate encryption");
wolfSSL 15:117db924cf7c 1787 XFREE(keyCi, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1788 wc_PKCS12_free(pkcs12);
wolfSSL 15:117db924cf7c 1789 wc_FreeRng(&rng);
wolfSSL 15:117db924cf7c 1790 return NULL;
wolfSSL 15:117db924cf7c 1791 }
wolfSSL 15:117db924cf7c 1792
wolfSSL 15:117db924cf7c 1793 /* get max size of buffer needed */
wolfSSL 15:117db924cf7c 1794 ret = wc_PKCS12_create_cert_bag(pkcs12, NULL, &certBufSz, cert, certSz);
wolfSSL 15:117db924cf7c 1795 if (ret != LENGTH_ONLY_E) {
wolfSSL 15:117db924cf7c 1796 XFREE(keyCi, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1797 wc_PKCS12_free(pkcs12);
wolfSSL 15:117db924cf7c 1798 wc_FreeRng(&rng);
wolfSSL 15:117db924cf7c 1799 return NULL;
wolfSSL 15:117db924cf7c 1800 }
wolfSSL 15:117db924cf7c 1801
wolfSSL 15:117db924cf7c 1802 if (ca != NULL) {
wolfSSL 15:117db924cf7c 1803 WC_DerCertList* current = ca;
wolfSSL 15:117db924cf7c 1804 word32 curBufSz = 0;
wolfSSL 15:117db924cf7c 1805
wolfSSL 15:117db924cf7c 1806 /* get max buffer size */
wolfSSL 15:117db924cf7c 1807 while (current != NULL) {
wolfSSL 15:117db924cf7c 1808 ret = wc_PKCS12_create_cert_bag(pkcs12, NULL, &curBufSz,
wolfSSL 15:117db924cf7c 1809 current->buffer, current->bufferSz);
wolfSSL 15:117db924cf7c 1810 if (ret != LENGTH_ONLY_E) {
wolfSSL 15:117db924cf7c 1811 XFREE(keyCi, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1812 wc_PKCS12_free(pkcs12);
wolfSSL 15:117db924cf7c 1813 wc_FreeRng(&rng);
wolfSSL 15:117db924cf7c 1814 return NULL;
wolfSSL 15:117db924cf7c 1815 }
wolfSSL 15:117db924cf7c 1816 certBufSz += curBufSz;
wolfSSL 15:117db924cf7c 1817 current = current->next;
wolfSSL 15:117db924cf7c 1818 }
wolfSSL 15:117db924cf7c 1819 }
wolfSSL 15:117db924cf7c 1820
wolfSSL 15:117db924cf7c 1821 /* account for Sequence that holds all certificate bags */
wolfSSL 15:117db924cf7c 1822 certBufSz += MAX_SEQ_SZ;
wolfSSL 15:117db924cf7c 1823
wolfSSL 15:117db924cf7c 1824 /* completed getting max size, now create buffer and start adding bags */
wolfSSL 15:117db924cf7c 1825 certBuf = (byte*)XMALLOC(certBufSz, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1826 if (certBuf == NULL) {
wolfSSL 15:117db924cf7c 1827 XFREE(keyCi, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1828 wc_PKCS12_free(pkcs12);
wolfSSL 15:117db924cf7c 1829 wc_FreeRng(&rng);
wolfSSL 15:117db924cf7c 1830 WOLFSSL_MSG("Memory error creating certificate bags");
wolfSSL 15:117db924cf7c 1831 return NULL;
wolfSSL 15:117db924cf7c 1832 }
wolfSSL 15:117db924cf7c 1833
wolfSSL 15:117db924cf7c 1834 idx = 0;
wolfSSL 15:117db924cf7c 1835 idx += MAX_SEQ_SZ;
wolfSSL 15:117db924cf7c 1836
wolfSSL 15:117db924cf7c 1837 sz = certBufSz - idx;
wolfSSL 15:117db924cf7c 1838 if ((ret = wc_PKCS12_create_cert_bag(pkcs12, certBuf + idx, &sz,
wolfSSL 15:117db924cf7c 1839 cert, certSz)) < 0) {
wolfSSL 15:117db924cf7c 1840 XFREE(keyCi, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1841 XFREE(certBuf, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1842 wc_PKCS12_free(pkcs12);
wolfSSL 15:117db924cf7c 1843 wc_FreeRng(&rng);
wolfSSL 15:117db924cf7c 1844 return NULL;
wolfSSL 15:117db924cf7c 1845 }
wolfSSL 15:117db924cf7c 1846 idx += ret;
wolfSSL 15:117db924cf7c 1847
wolfSSL 15:117db924cf7c 1848 if (ca != NULL) {
wolfSSL 15:117db924cf7c 1849 WC_DerCertList* current = ca;
wolfSSL 15:117db924cf7c 1850
wolfSSL 15:117db924cf7c 1851 while (current != NULL) {
wolfSSL 15:117db924cf7c 1852 sz = certBufSz - idx;
wolfSSL 15:117db924cf7c 1853 if ((ret = wc_PKCS12_create_cert_bag(pkcs12, certBuf + idx, &sz,
wolfSSL 15:117db924cf7c 1854 current->buffer, current->bufferSz)) < 0) {
wolfSSL 15:117db924cf7c 1855 XFREE(keyCi, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1856 XFREE(certBuf, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1857 wc_PKCS12_free(pkcs12);
wolfSSL 15:117db924cf7c 1858 wc_FreeRng(&rng);
wolfSSL 15:117db924cf7c 1859 return NULL;
wolfSSL 15:117db924cf7c 1860 }
wolfSSL 15:117db924cf7c 1861 idx += ret;
wolfSSL 15:117db924cf7c 1862 current = current->next;
wolfSSL 15:117db924cf7c 1863 }
wolfSSL 15:117db924cf7c 1864 }
wolfSSL 15:117db924cf7c 1865
wolfSSL 15:117db924cf7c 1866 /* set sequence and create encrypted content with all certificate bags */
wolfSSL 15:117db924cf7c 1867 tmpSz = SetSequence(idx - MAX_SEQ_SZ, certBuf);
wolfSSL 15:117db924cf7c 1868 XMEMMOVE(certBuf + tmpSz, certBuf + MAX_SEQ_SZ, idx - MAX_SEQ_SZ);
wolfSSL 15:117db924cf7c 1869 certBufSz = tmpSz + (idx - MAX_SEQ_SZ);
wolfSSL 15:117db924cf7c 1870
wolfSSL 15:117db924cf7c 1871 /* get buffer size needed for content info */
wolfSSL 15:117db924cf7c 1872 ret = wc_PKCS12_encrypt_content(pkcs12, &rng, NULL, &certCiSz,
wolfSSL 15:117db924cf7c 1873 NULL, certBufSz, algo, pass, passSz, iter, type);
wolfSSL 15:117db924cf7c 1874 if (ret != LENGTH_ONLY_E) {
wolfSSL 15:117db924cf7c 1875 XFREE(keyCi, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1876 XFREE(certBuf, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1877 wc_PKCS12_free(pkcs12);
wolfSSL 15:117db924cf7c 1878 wc_FreeRng(&rng);
wolfSSL 15:117db924cf7c 1879 WOLFSSL_LEAVE("wc_PKCS12_create()", ret);
wolfSSL 15:117db924cf7c 1880 return NULL;
wolfSSL 15:117db924cf7c 1881 }
wolfSSL 15:117db924cf7c 1882 certCi = (byte*)XMALLOC(certCiSz, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1883 if (certCi == NULL) {
wolfSSL 15:117db924cf7c 1884 XFREE(keyCi, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1885 XFREE(certBuf, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1886 wc_PKCS12_free(pkcs12);
wolfSSL 15:117db924cf7c 1887 wc_FreeRng(&rng);
wolfSSL 15:117db924cf7c 1888 return NULL;
wolfSSL 15:117db924cf7c 1889 }
wolfSSL 15:117db924cf7c 1890
wolfSSL 15:117db924cf7c 1891 ret = wc_PKCS12_encrypt_content(pkcs12, &rng, certCi, &certCiSz,
wolfSSL 15:117db924cf7c 1892 certBuf, certBufSz, algo, pass, passSz, iter, type);
wolfSSL 15:117db924cf7c 1893 if (ret < 0) {
wolfSSL 15:117db924cf7c 1894 XFREE(keyCi, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1895 XFREE(certBuf, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1896 XFREE(certCi, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1897 wc_PKCS12_free(pkcs12);
wolfSSL 15:117db924cf7c 1898 wc_FreeRng(&rng);
wolfSSL 15:117db924cf7c 1899 WOLFSSL_LEAVE("wc_PKCS12_create()", ret);
wolfSSL 15:117db924cf7c 1900 return NULL;
wolfSSL 15:117db924cf7c 1901 }
wolfSSL 15:117db924cf7c 1902 certCiSz = ret;
wolfSSL 15:117db924cf7c 1903 XFREE(certBuf, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1904
wolfSSL 15:117db924cf7c 1905 #ifdef WOLFSSL_DEBUG_PKCS12
wolfSSL 15:117db924cf7c 1906 {
wolfSSL 15:117db924cf7c 1907 byte* p;
wolfSSL 15:117db924cf7c 1908 for (printf("(size %u) Encrypted Certificate Content Info = ",certCiSz),
wolfSSL 15:117db924cf7c 1909 p = (byte*)certCi;
wolfSSL 15:117db924cf7c 1910 p < (byte*)certCi + certCiSz;
wolfSSL 15:117db924cf7c 1911 printf("%02X", *p), p++);
wolfSSL 15:117db924cf7c 1912 printf("\n");
wolfSSL 15:117db924cf7c 1913 }
wolfSSL 15:117db924cf7c 1914 #endif
wolfSSL 15:117db924cf7c 1915
wolfSSL 15:117db924cf7c 1916 /**** create safe and and Content Info ****/
wolfSSL 15:117db924cf7c 1917 safe = (AuthenticatedSafe*)XMALLOC(sizeof(AuthenticatedSafe), heap,
wolfSSL 15:117db924cf7c 1918 DYNAMIC_TYPE_PKCS);
wolfSSL 15:117db924cf7c 1919 if (safe == NULL) {
wolfSSL 15:117db924cf7c 1920 XFREE(keyCi, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1921 XFREE(certCi, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1922 wc_PKCS12_free(pkcs12);
wolfSSL 15:117db924cf7c 1923 wc_FreeRng(&rng);
wolfSSL 15:117db924cf7c 1924 return NULL;
wolfSSL 15:117db924cf7c 1925 }
wolfSSL 15:117db924cf7c 1926 pkcs12->safe = safe; /* set so all of safe is free'd with wc_PKCS12_free */
wolfSSL 15:117db924cf7c 1927 XMEMSET(safe, 0, sizeof(AuthenticatedSafe));
wolfSSL 15:117db924cf7c 1928
wolfSSL 15:117db924cf7c 1929 safe->dataSz = certCiSz + keyCiSz;
wolfSSL 15:117db924cf7c 1930 safe->data = (byte*)XMALLOC(safe->dataSz, heap, DYNAMIC_TYPE_PKCS);
wolfSSL 15:117db924cf7c 1931 if (safe->data == NULL) {
wolfSSL 15:117db924cf7c 1932 XFREE(keyCi, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1933 XFREE(certCi, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1934 wc_PKCS12_free(pkcs12);
wolfSSL 15:117db924cf7c 1935 wc_FreeRng(&rng);
wolfSSL 15:117db924cf7c 1936 return NULL;
wolfSSL 15:117db924cf7c 1937 }
wolfSSL 15:117db924cf7c 1938 XMEMCPY(safe->data, certCi, certCiSz);
wolfSSL 15:117db924cf7c 1939 XMEMCPY(safe->data + certCiSz, keyCi, keyCiSz);
wolfSSL 15:117db924cf7c 1940 XFREE(certCi, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1941 XFREE(keyCi, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 1942
wolfSSL 15:117db924cf7c 1943 safe->numCI = 2;
wolfSSL 15:117db924cf7c 1944
wolfSSL 15:117db924cf7c 1945 /* add Content Info structs to safe, key first then cert */
wolfSSL 15:117db924cf7c 1946 ci = (ContentInfo*)XMALLOC(sizeof(ContentInfo), heap, DYNAMIC_TYPE_PKCS);
wolfSSL 15:117db924cf7c 1947 if (ci == NULL) {
wolfSSL 15:117db924cf7c 1948 wc_PKCS12_free(pkcs12);
wolfSSL 15:117db924cf7c 1949 wc_FreeRng(&rng);
wolfSSL 15:117db924cf7c 1950 return NULL;
wolfSSL 15:117db924cf7c 1951 }
wolfSSL 15:117db924cf7c 1952 XMEMSET(ci, 0, sizeof(ContentInfo));
wolfSSL 15:117db924cf7c 1953 safe->CI = ci;
wolfSSL 15:117db924cf7c 1954 ci->data = safe->data + certCiSz;
wolfSSL 15:117db924cf7c 1955 ci->dataSz = keyCiSz;
wolfSSL 15:117db924cf7c 1956 ci->type = WC_PKCS12_DATA;
wolfSSL 15:117db924cf7c 1957
wolfSSL 15:117db924cf7c 1958 ci = (ContentInfo*)XMALLOC(sizeof(ContentInfo), heap, DYNAMIC_TYPE_PKCS);
wolfSSL 15:117db924cf7c 1959 if (ci == NULL) {
wolfSSL 15:117db924cf7c 1960 wc_PKCS12_free(pkcs12);
wolfSSL 15:117db924cf7c 1961 wc_FreeRng(&rng);
wolfSSL 15:117db924cf7c 1962 return NULL;
wolfSSL 15:117db924cf7c 1963 }
wolfSSL 15:117db924cf7c 1964 XMEMSET(ci, 0, sizeof(ContentInfo));
wolfSSL 15:117db924cf7c 1965 ci->next = safe->CI;
wolfSSL 15:117db924cf7c 1966 safe->CI = ci;
wolfSSL 15:117db924cf7c 1967 ci->data = safe->data;
wolfSSL 15:117db924cf7c 1968 ci->dataSz = certCiSz;
wolfSSL 15:117db924cf7c 1969 if (nidCert < 0) {
wolfSSL 15:117db924cf7c 1970 ci->type = WC_PKCS12_DATA;
wolfSSL 15:117db924cf7c 1971 }
wolfSSL 15:117db924cf7c 1972 else {
wolfSSL 15:117db924cf7c 1973 ci->type = WC_PKCS12_ENCRYPTED_DATA;
wolfSSL 15:117db924cf7c 1974 }
wolfSSL 15:117db924cf7c 1975
wolfSSL 15:117db924cf7c 1976 /* create MAC */
wolfSSL 15:117db924cf7c 1977 if (macIter > 0) {
wolfSSL 15:117db924cf7c 1978 MacData* mac;
wolfSSL 15:117db924cf7c 1979 byte digest[WC_MAX_DIGEST_SIZE]; /* for MAC */
wolfSSL 15:117db924cf7c 1980
wolfSSL 15:117db924cf7c 1981 mac = (MacData*)XMALLOC(sizeof(MacData), heap, DYNAMIC_TYPE_PKCS);
wolfSSL 15:117db924cf7c 1982 if (mac == NULL) {
wolfSSL 15:117db924cf7c 1983 wc_PKCS12_free(pkcs12);
wolfSSL 15:117db924cf7c 1984 wc_FreeRng(&rng);
wolfSSL 15:117db924cf7c 1985 return NULL;
wolfSSL 15:117db924cf7c 1986 }
wolfSSL 15:117db924cf7c 1987 XMEMSET(mac, 0, sizeof(MacData));
wolfSSL 15:117db924cf7c 1988 pkcs12->signData = mac; /* now wc_PKCS12_free will free all mac too */
wolfSSL 15:117db924cf7c 1989
wolfSSL 15:117db924cf7c 1990 #ifndef NO_SHA256
wolfSSL 15:117db924cf7c 1991 mac->oid = SHA256h;
wolfSSL 15:117db924cf7c 1992 #elif !defined(NO_SHA)
wolfSSL 15:117db924cf7c 1993 mac->oid = SHA;
wolfSSL 15:117db924cf7c 1994 #elif defined(WOLFSSL_SHA384)
wolfSSL 15:117db924cf7c 1995 mac->oid = SHA384;
wolfSSL 15:117db924cf7c 1996 #elif defined(WOLFSSL_SHA512)
wolfSSL 15:117db924cf7c 1997 mac->oid = SHA512;
wolfSSL 15:117db924cf7c 1998 #else
wolfSSL 15:117db924cf7c 1999 WOLFSSL_MSG("No supported hash algorithm compiled in!");
wolfSSL 15:117db924cf7c 2000 wc_PKCS12_free(pkcs12);
wolfSSL 15:117db924cf7c 2001 wc_FreeRng(&rng);
wolfSSL 15:117db924cf7c 2002 return NULL;
wolfSSL 15:117db924cf7c 2003 #endif
wolfSSL 15:117db924cf7c 2004
wolfSSL 15:117db924cf7c 2005 /* store number of iterations */
wolfSSL 15:117db924cf7c 2006 mac->itt = macIter;
wolfSSL 15:117db924cf7c 2007
wolfSSL 15:117db924cf7c 2008 /* set mac salt */
wolfSSL 15:117db924cf7c 2009 mac->saltSz = 8;
wolfSSL 15:117db924cf7c 2010 mac->salt = (byte*)XMALLOC(mac->saltSz, heap, DYNAMIC_TYPE_PKCS);
wolfSSL 15:117db924cf7c 2011 if (mac->salt == NULL) {
wolfSSL 15:117db924cf7c 2012 wc_PKCS12_free(pkcs12);
wolfSSL 15:117db924cf7c 2013 wc_FreeRng(&rng);
wolfSSL 15:117db924cf7c 2014 return NULL;
wolfSSL 15:117db924cf7c 2015 }
wolfSSL 15:117db924cf7c 2016
wolfSSL 15:117db924cf7c 2017 if ((ret = wc_RNG_GenerateBlock(&rng, mac->salt, mac->saltSz)) != 0) {
wolfSSL 15:117db924cf7c 2018 WOLFSSL_MSG("Error generating random salt");
wolfSSL 15:117db924cf7c 2019 wc_PKCS12_free(pkcs12);
wolfSSL 15:117db924cf7c 2020 wc_FreeRng(&rng);
wolfSSL 15:117db924cf7c 2021 return NULL;
wolfSSL 15:117db924cf7c 2022 }
wolfSSL 15:117db924cf7c 2023 ret = wc_PKCS12_create_mac(pkcs12, safe->data, safe->dataSz,
wolfSSL 15:117db924cf7c 2024 (const byte*)pass, passSz, digest, WC_MAX_DIGEST_SIZE);
wolfSSL 15:117db924cf7c 2025 if (ret < 0) {
wolfSSL 15:117db924cf7c 2026 wc_PKCS12_free(pkcs12);
wolfSSL 15:117db924cf7c 2027 wc_FreeRng(&rng);
wolfSSL 15:117db924cf7c 2028 return NULL;
wolfSSL 15:117db924cf7c 2029 }
wolfSSL 15:117db924cf7c 2030
wolfSSL 15:117db924cf7c 2031 mac->digestSz = ret;
wolfSSL 15:117db924cf7c 2032 mac->digest = (byte*)XMALLOC(ret, heap, DYNAMIC_TYPE_PKCS);
wolfSSL 15:117db924cf7c 2033 if (mac->digest == NULL) {
wolfSSL 15:117db924cf7c 2034 wc_PKCS12_free(pkcs12);
wolfSSL 15:117db924cf7c 2035 wc_FreeRng(&rng);
wolfSSL 15:117db924cf7c 2036 return NULL;
wolfSSL 15:117db924cf7c 2037 }
wolfSSL 15:117db924cf7c 2038 XMEMCPY(mac->digest, digest, mac->digestSz);
wolfSSL 15:117db924cf7c 2039 }
wolfSSL 15:117db924cf7c 2040 else {
wolfSSL 15:117db924cf7c 2041 pkcs12->signData = NULL;
wolfSSL 15:117db924cf7c 2042 }
wolfSSL 15:117db924cf7c 2043
wolfSSL 15:117db924cf7c 2044 wc_FreeRng(&rng);
wolfSSL 15:117db924cf7c 2045 (void)name;
wolfSSL 15:117db924cf7c 2046 (void)keyType;
wolfSSL 15:117db924cf7c 2047
wolfSSL 15:117db924cf7c 2048 return pkcs12;
wolfSSL 15:117db924cf7c 2049 }
wolfSSL 15:117db924cf7c 2050
wolfSSL 15:117db924cf7c 2051
wolfSSL 15:117db924cf7c 2052 /* if using a specific memory heap */
wolfSSL 15:117db924cf7c 2053 int wc_PKCS12_SetHeap(WC_PKCS12* pkcs12, void* heap)
wolfSSL 15:117db924cf7c 2054 {
wolfSSL 15:117db924cf7c 2055 if (pkcs12 == NULL) {
wolfSSL 15:117db924cf7c 2056 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 2057 }
wolfSSL 15:117db924cf7c 2058 pkcs12->heap = heap;
wolfSSL 15:117db924cf7c 2059
wolfSSL 15:117db924cf7c 2060 return 0;
wolfSSL 15:117db924cf7c 2061 }
wolfSSL 15:117db924cf7c 2062
wolfSSL 15:117db924cf7c 2063
wolfSSL 15:117db924cf7c 2064 /* getter for heap */
wolfSSL 15:117db924cf7c 2065 void* wc_PKCS12_GetHeap(WC_PKCS12* pkcs12)
wolfSSL 15:117db924cf7c 2066 {
wolfSSL 15:117db924cf7c 2067 if (pkcs12 == NULL) {
wolfSSL 15:117db924cf7c 2068 return NULL;
wolfSSL 15:117db924cf7c 2069 }
wolfSSL 15:117db924cf7c 2070
wolfSSL 15:117db924cf7c 2071 return pkcs12->heap;
wolfSSL 15:117db924cf7c 2072 }
wolfSSL 15:117db924cf7c 2073
wolfSSL 15:117db924cf7c 2074 #undef ERROR_OUT
wolfSSL 15:117db924cf7c 2075
wolfSSL 15:117db924cf7c 2076 #endif /* !NO_ASN && !NO_PWDBASED */
wolfSSL 15:117db924cf7c 2077