wolfSSL 3.11.1 for TLS1.3 beta

Fork of wolfSSL by wolf SSL

Committer:
wolfSSL
Date:
Tue May 30 06:16:19 2017 +0000
Revision:
13:80fb167dafdf
Parent:
11:cee25a834751
wolfSSL 3.11.1: TLS1.3 Beta

Who changed what in which revision?

UserRevisionLine numberNew contents of line
wolfSSL 11:cee25a834751 1 /* pkcs12.c
wolfSSL 11:cee25a834751 2 *
wolfSSL 11:cee25a834751 3 * Copyright (C) 2006-2016 wolfSSL Inc.
wolfSSL 11:cee25a834751 4 *
wolfSSL 11:cee25a834751 5 * This file is part of wolfSSL.
wolfSSL 11:cee25a834751 6 *
wolfSSL 11:cee25a834751 7 * wolfSSL is free software; you can redistribute it and/or modify
wolfSSL 11:cee25a834751 8 * it under the terms of the GNU General Public License as published by
wolfSSL 11:cee25a834751 9 * the Free Software Foundation; either version 2 of the License, or
wolfSSL 11:cee25a834751 10 * (at your option) any later version.
wolfSSL 11:cee25a834751 11 *
wolfSSL 11:cee25a834751 12 * wolfSSL is distributed in the hope that it will be useful,
wolfSSL 11:cee25a834751 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
wolfSSL 11:cee25a834751 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
wolfSSL 11:cee25a834751 15 * GNU General Public License for more details.
wolfSSL 11:cee25a834751 16 *
wolfSSL 11:cee25a834751 17 * You should have received a copy of the GNU General Public License
wolfSSL 11:cee25a834751 18 * along with this program; if not, write to the Free Software
wolfSSL 11:cee25a834751 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
wolfSSL 11:cee25a834751 20 */
wolfSSL 11:cee25a834751 21
wolfSSL 11:cee25a834751 22
wolfSSL 11:cee25a834751 23 #ifdef HAVE_CONFIG_H
wolfSSL 11:cee25a834751 24 #include <config.h>
wolfSSL 11:cee25a834751 25 #endif
wolfSSL 11:cee25a834751 26
wolfSSL 11:cee25a834751 27 #include <wolfssl/wolfcrypt/settings.h>
wolfSSL 11:cee25a834751 28
wolfSSL 11:cee25a834751 29 #if !defined(NO_ASN) && !defined(NO_PWDBASED)
wolfSSL 11:cee25a834751 30
wolfSSL 11:cee25a834751 31 #include <wolfssl/wolfcrypt/asn.h>
wolfSSL 11:cee25a834751 32 #include <wolfssl/wolfcrypt/asn_public.h>
wolfSSL 11:cee25a834751 33 #include <wolfssl/wolfcrypt/error-crypt.h>
wolfSSL 11:cee25a834751 34 #include <wolfssl/wolfcrypt/hmac.h>
wolfSSL 11:cee25a834751 35 #include <wolfssl/wolfcrypt/logging.h>
wolfSSL 11:cee25a834751 36 #ifdef NO_INLINE
wolfSSL 11:cee25a834751 37 #include <wolfssl/wolfcrypt/misc.h>
wolfSSL 11:cee25a834751 38 #else
wolfSSL 11:cee25a834751 39 #define WOLFSSL_MISC_INCLUDED
wolfSSL 11:cee25a834751 40 #include <wolfcrypt/src/misc.c>
wolfSSL 11:cee25a834751 41 #endif
wolfSSL 11:cee25a834751 42 #include <wolfssl/wolfcrypt/pkcs12.h>
wolfSSL 11:cee25a834751 43 #include <wolfssl/wolfcrypt/pwdbased.h>
wolfSSL 11:cee25a834751 44
wolfSSL 11:cee25a834751 45
wolfSSL 11:cee25a834751 46 enum {
wolfSSL 11:cee25a834751 47 WC_PKCS12_KeyBag = 667,
wolfSSL 11:cee25a834751 48 WC_PKCS12_ShroudedKeyBag = 668,
wolfSSL 11:cee25a834751 49 WC_PKCS12_CertBag = 669,
wolfSSL 11:cee25a834751 50 WC_PKCS12_CertBag_Type1 = 675,
wolfSSL 11:cee25a834751 51 WC_PKCS12_CrlBag = 670,
wolfSSL 11:cee25a834751 52 WC_PKCS12_SecretBag = 671,
wolfSSL 11:cee25a834751 53 WC_PKCS12_SafeContentsBag = 672,
wolfSSL 11:cee25a834751 54 WC_PKCS12_DATA = 651,
wolfSSL 11:cee25a834751 55 WC_PKCS12_ENCRYPTED_DATA = 656,
wolfSSL 11:cee25a834751 56 };
wolfSSL 11:cee25a834751 57
wolfSSL 11:cee25a834751 58 typedef struct ContentInfo {
wolfSSL 11:cee25a834751 59 byte* data;
wolfSSL 11:cee25a834751 60 struct ContentInfo* next;
wolfSSL 11:cee25a834751 61 word32 encC; /* encryptedContent */
wolfSSL 11:cee25a834751 62 word32 dataSz;
wolfSSL 11:cee25a834751 63 int type; /* DATA / encrypted / envelpoed */
wolfSSL 11:cee25a834751 64 } ContentInfo;
wolfSSL 11:cee25a834751 65
wolfSSL 11:cee25a834751 66
wolfSSL 11:cee25a834751 67 typedef struct AuthenticatedSafe {
wolfSSL 11:cee25a834751 68 ContentInfo* CI;
wolfSSL 11:cee25a834751 69 byte* data; /* T contents.... */
wolfSSL 11:cee25a834751 70 word32 oid; /* encrypted or not */
wolfSSL 11:cee25a834751 71 word32 numCI; /* number of Content Info structs */
wolfSSL 11:cee25a834751 72 word32 dataSz;
wolfSSL 11:cee25a834751 73 } AuthenticatedSafe;
wolfSSL 11:cee25a834751 74
wolfSSL 11:cee25a834751 75
wolfSSL 11:cee25a834751 76 typedef struct MacData {
wolfSSL 11:cee25a834751 77 byte* digest;
wolfSSL 11:cee25a834751 78 byte* salt;
wolfSSL 11:cee25a834751 79 word32 oid;
wolfSSL 11:cee25a834751 80 word32 digestSz;
wolfSSL 11:cee25a834751 81 word32 saltSz;
wolfSSL 11:cee25a834751 82 int itt; /* number of itterations when creating HMAC key */
wolfSSL 11:cee25a834751 83 } MacData;
wolfSSL 11:cee25a834751 84
wolfSSL 11:cee25a834751 85
wolfSSL 11:cee25a834751 86 struct WC_PKCS12 {
wolfSSL 11:cee25a834751 87 void* heap;
wolfSSL 11:cee25a834751 88 AuthenticatedSafe* safe;
wolfSSL 11:cee25a834751 89 MacData* signData;
wolfSSL 11:cee25a834751 90 word32 oid; /* DATA / Enveloped DATA ... */
wolfSSL 11:cee25a834751 91 };
wolfSSL 11:cee25a834751 92
wolfSSL 11:cee25a834751 93
wolfSSL 11:cee25a834751 94 /* for friendlyName, localKeyId .... */
wolfSSL 11:cee25a834751 95 typedef struct WC_PKCS12_ATTRIBUTE {
wolfSSL 11:cee25a834751 96 byte* data;
wolfSSL 11:cee25a834751 97 word32 oid;
wolfSSL 11:cee25a834751 98 word32 dataSz;
wolfSSL 11:cee25a834751 99 } WC_PKCS12_ATTRIBUTE;
wolfSSL 11:cee25a834751 100
wolfSSL 11:cee25a834751 101
wolfSSL 11:cee25a834751 102 WC_PKCS12* wc_PKCS12_new(void)
wolfSSL 11:cee25a834751 103 {
wolfSSL 11:cee25a834751 104 WC_PKCS12* pkcs12 = (WC_PKCS12*)XMALLOC(sizeof(WC_PKCS12),
wolfSSL 11:cee25a834751 105 NULL, DYNAMIC_TYPE_PKCS);
wolfSSL 11:cee25a834751 106 if (pkcs12 == NULL) {
wolfSSL 11:cee25a834751 107 WOLFSSL_MSG("Memory issue when creating WC_PKCS12 struct");
wolfSSL 11:cee25a834751 108 return NULL;
wolfSSL 11:cee25a834751 109 }
wolfSSL 11:cee25a834751 110
wolfSSL 11:cee25a834751 111 XMEMSET(pkcs12, 0, sizeof(WC_PKCS12));
wolfSSL 11:cee25a834751 112
wolfSSL 11:cee25a834751 113 return pkcs12;
wolfSSL 11:cee25a834751 114 }
wolfSSL 11:cee25a834751 115
wolfSSL 11:cee25a834751 116
wolfSSL 11:cee25a834751 117 static void freeSafe(AuthenticatedSafe* safe, void* heap)
wolfSSL 11:cee25a834751 118 {
wolfSSL 11:cee25a834751 119 int i;
wolfSSL 11:cee25a834751 120
wolfSSL 11:cee25a834751 121 if (safe == NULL) {
wolfSSL 11:cee25a834751 122 return;
wolfSSL 11:cee25a834751 123 }
wolfSSL 11:cee25a834751 124
wolfSSL 11:cee25a834751 125 /* free content info structs */
wolfSSL 11:cee25a834751 126 for (i = safe->numCI; i > 0; i--) {
wolfSSL 11:cee25a834751 127 ContentInfo* ci = safe->CI;
wolfSSL 11:cee25a834751 128 safe->CI = ci->next;
wolfSSL 11:cee25a834751 129 XFREE(ci, heap, DYNAMIC_TYPE_PKCS);
wolfSSL 11:cee25a834751 130 }
wolfSSL 11:cee25a834751 131 if (safe->data != NULL) {
wolfSSL 11:cee25a834751 132 XFREE(safe->data, heap, DYNAMIC_TYPE_PKCS);
wolfSSL 11:cee25a834751 133 }
wolfSSL 11:cee25a834751 134 XFREE(safe, heap, DYNAMIC_TYPE_PKCS);
wolfSSL 11:cee25a834751 135
wolfSSL 11:cee25a834751 136 (void)heap;
wolfSSL 11:cee25a834751 137 }
wolfSSL 11:cee25a834751 138
wolfSSL 11:cee25a834751 139
wolfSSL 11:cee25a834751 140 void wc_PKCS12_free(WC_PKCS12* pkcs12)
wolfSSL 11:cee25a834751 141 {
wolfSSL 11:cee25a834751 142 void* heap;
wolfSSL 11:cee25a834751 143
wolfSSL 11:cee25a834751 144 /* if null pointer is passed in do nothing */
wolfSSL 11:cee25a834751 145 if (pkcs12 == NULL) {
wolfSSL 11:cee25a834751 146 WOLFSSL_MSG("Trying to free null WC_PKCS12 object");
wolfSSL 11:cee25a834751 147 return;
wolfSSL 11:cee25a834751 148 }
wolfSSL 11:cee25a834751 149
wolfSSL 11:cee25a834751 150 heap = pkcs12->heap;
wolfSSL 11:cee25a834751 151 if (pkcs12->safe != NULL) {
wolfSSL 11:cee25a834751 152 freeSafe(pkcs12->safe, heap);
wolfSSL 11:cee25a834751 153 }
wolfSSL 11:cee25a834751 154
wolfSSL 11:cee25a834751 155 /* free mac data */
wolfSSL 11:cee25a834751 156 if (pkcs12->signData != NULL) {
wolfSSL 11:cee25a834751 157 if (pkcs12->signData->digest != NULL) {
wolfSSL 11:cee25a834751 158 XFREE(pkcs12->signData->digest, heap, DYNAMIC_TYPE_PKCS);
wolfSSL 11:cee25a834751 159 }
wolfSSL 11:cee25a834751 160 if (pkcs12->signData->salt != NULL) {
wolfSSL 11:cee25a834751 161 XFREE(pkcs12->signData->salt, heap, DYNAMIC_TYPE_PKCS);
wolfSSL 11:cee25a834751 162 }
wolfSSL 11:cee25a834751 163 XFREE(pkcs12->signData, heap, DYNAMIC_TYPE_PKCS);
wolfSSL 11:cee25a834751 164 }
wolfSSL 11:cee25a834751 165
wolfSSL 11:cee25a834751 166 XFREE(pkcs12, NULL, DYNAMIC_TYPE_PKCS);
wolfSSL 11:cee25a834751 167 pkcs12 = NULL;
wolfSSL 11:cee25a834751 168
wolfSSL 11:cee25a834751 169 (void)heap;
wolfSSL 11:cee25a834751 170 }
wolfSSL 11:cee25a834751 171
wolfSSL 11:cee25a834751 172
wolfSSL 11:cee25a834751 173 static int GetSafeContent(WC_PKCS12* pkcs12, const byte* input,
wolfSSL 11:cee25a834751 174 word32* idx, int maxIdx)
wolfSSL 11:cee25a834751 175 {
wolfSSL 11:cee25a834751 176 AuthenticatedSafe* safe;
wolfSSL 11:cee25a834751 177 word32 oid;
wolfSSL 11:cee25a834751 178 word32 localIdx = *idx;
wolfSSL 11:cee25a834751 179 int ret;
wolfSSL 11:cee25a834751 180 int size = 0;
wolfSSL 11:cee25a834751 181
wolfSSL 11:cee25a834751 182 safe = (AuthenticatedSafe*)XMALLOC(sizeof(AuthenticatedSafe), pkcs12->heap,
wolfSSL 11:cee25a834751 183 DYNAMIC_TYPE_PKCS);
wolfSSL 11:cee25a834751 184 if (safe == NULL) {
wolfSSL 11:cee25a834751 185 return MEMORY_E;
wolfSSL 11:cee25a834751 186 }
wolfSSL 11:cee25a834751 187 XMEMSET(safe, 0, sizeof(AuthenticatedSafe));
wolfSSL 11:cee25a834751 188
wolfSSL 11:cee25a834751 189 ret = GetObjectId(input, &localIdx, &oid, oidIgnoreType, maxIdx);
wolfSSL 11:cee25a834751 190 if (ret < 0) {
wolfSSL 11:cee25a834751 191 WOLFSSL_LEAVE("Get object id failed", ret);
wolfSSL 11:cee25a834751 192 freeSafe(safe, pkcs12->heap);
wolfSSL 11:cee25a834751 193 return ASN_PARSE_E;
wolfSSL 11:cee25a834751 194 }
wolfSSL 11:cee25a834751 195
wolfSSL 11:cee25a834751 196 safe->oid = oid;
wolfSSL 11:cee25a834751 197 /* check tag, length */
wolfSSL 11:cee25a834751 198 if (input[localIdx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) {
wolfSSL 11:cee25a834751 199 WOLFSSL_MSG("Unexpected tag in PKCS12 DER");
wolfSSL 11:cee25a834751 200 freeSafe(safe, pkcs12->heap);
wolfSSL 11:cee25a834751 201 return ASN_PARSE_E;
wolfSSL 11:cee25a834751 202 }
wolfSSL 11:cee25a834751 203 if ((ret = GetLength(input, &localIdx, &size, maxIdx)) <= 0) {
wolfSSL 11:cee25a834751 204 freeSafe(safe, pkcs12->heap);
wolfSSL 11:cee25a834751 205 return ret;
wolfSSL 11:cee25a834751 206 }
wolfSSL 11:cee25a834751 207
wolfSSL 11:cee25a834751 208 switch (oid) {
wolfSSL 11:cee25a834751 209 case WC_PKCS12_ENCRYPTED_DATA:
wolfSSL 11:cee25a834751 210 WOLFSSL_MSG("Found PKCS12 OBJECT: ENCRYPTED DATA\n");
wolfSSL 11:cee25a834751 211 break;
wolfSSL 11:cee25a834751 212
wolfSSL 11:cee25a834751 213 case WC_PKCS12_DATA:
wolfSSL 11:cee25a834751 214 WOLFSSL_MSG("Found PKCS12 OBJECT: DATA");
wolfSSL 11:cee25a834751 215 /* get octets holding contents */
wolfSSL 11:cee25a834751 216 if (input[localIdx++] != ASN_OCTET_STRING) {
wolfSSL 11:cee25a834751 217 WOLFSSL_MSG("Wrong tag with content PKCS12 type DATA");
wolfSSL 11:cee25a834751 218 freeSafe(safe, pkcs12->heap);
wolfSSL 11:cee25a834751 219 return ASN_PARSE_E;
wolfSSL 11:cee25a834751 220 }
wolfSSL 11:cee25a834751 221 if ((ret = GetLength(input, &localIdx, &size, maxIdx)) <= 0) {
wolfSSL 11:cee25a834751 222 freeSafe(safe, pkcs12->heap);
wolfSSL 11:cee25a834751 223 return ret;
wolfSSL 11:cee25a834751 224 }
wolfSSL 11:cee25a834751 225
wolfSSL 11:cee25a834751 226 break;
wolfSSL 11:cee25a834751 227 }
wolfSSL 11:cee25a834751 228
wolfSSL 11:cee25a834751 229 safe->dataSz = size;
wolfSSL 11:cee25a834751 230 safe->data = (byte*)XMALLOC(size, pkcs12->heap, DYNAMIC_TYPE_PKCS);
wolfSSL 11:cee25a834751 231 if (safe->data == NULL) {
wolfSSL 11:cee25a834751 232 freeSafe(safe, pkcs12->heap);
wolfSSL 11:cee25a834751 233 return MEMORY_E;
wolfSSL 11:cee25a834751 234 }
wolfSSL 11:cee25a834751 235 XMEMCPY(safe->data, input + localIdx, size);
wolfSSL 11:cee25a834751 236 *idx = localIdx;
wolfSSL 11:cee25a834751 237
wolfSSL 11:cee25a834751 238 /* an instance of AuthenticatedSafe is created from
wolfSSL 11:cee25a834751 239 * ContentInfo's strung together in a SEQUENCE. Here we itterate
wolfSSL 11:cee25a834751 240 * through the ContentInfo's and add them to our
wolfSSL 11:cee25a834751 241 * AuthenticatedSafe struct */
wolfSSL 11:cee25a834751 242 localIdx = 0;
wolfSSL 11:cee25a834751 243 input = safe->data;
wolfSSL 11:cee25a834751 244 {
wolfSSL 11:cee25a834751 245 int CISz;
wolfSSL 11:cee25a834751 246 ret = GetSequence(input, &localIdx, &CISz, safe->dataSz);
wolfSSL 11:cee25a834751 247 if (ret < 0) {
wolfSSL 11:cee25a834751 248 freeSafe(safe, pkcs12->heap);
wolfSSL 11:cee25a834751 249 return ASN_PARSE_E;
wolfSSL 11:cee25a834751 250 }
wolfSSL 11:cee25a834751 251 CISz += localIdx;
wolfSSL 11:cee25a834751 252 while ((int)localIdx < CISz) {
wolfSSL 11:cee25a834751 253 int curSz = 0;
wolfSSL 11:cee25a834751 254 word32 curIdx;
wolfSSL 11:cee25a834751 255 ContentInfo* ci = NULL;
wolfSSL 11:cee25a834751 256
wolfSSL 11:cee25a834751 257 #ifdef WOLFSSL_DEBUG_PKCS12
wolfSSL 11:cee25a834751 258 printf("\t\tlooking for Content Info.... ");
wolfSSL 11:cee25a834751 259 #endif
wolfSSL 11:cee25a834751 260
wolfSSL 11:cee25a834751 261 if ((ret = GetSequence(input, &localIdx, &curSz, safe->dataSz))
wolfSSL 11:cee25a834751 262 < 0) {
wolfSSL 11:cee25a834751 263 freeSafe(safe, pkcs12->heap);
wolfSSL 11:cee25a834751 264 return ret;
wolfSSL 11:cee25a834751 265 }
wolfSSL 11:cee25a834751 266
wolfSSL 11:cee25a834751 267 if (curSz > CISz) {
wolfSSL 11:cee25a834751 268 /* subset should not be larger than universe */
wolfSSL 11:cee25a834751 269 freeSafe(safe, pkcs12->heap);
wolfSSL 11:cee25a834751 270 return ASN_PARSE_E;
wolfSSL 11:cee25a834751 271 }
wolfSSL 11:cee25a834751 272
wolfSSL 11:cee25a834751 273 curIdx = localIdx;
wolfSSL 11:cee25a834751 274 if ((ret = GetObjectId(input, &localIdx, &oid, oidIgnoreType,
wolfSSL 11:cee25a834751 275 safe->dataSz)) < 0) {
wolfSSL 11:cee25a834751 276 WOLFSSL_LEAVE("Get object id failed", ret);
wolfSSL 11:cee25a834751 277 freeSafe(safe, pkcs12->heap);
wolfSSL 11:cee25a834751 278 return ret;
wolfSSL 11:cee25a834751 279 }
wolfSSL 11:cee25a834751 280
wolfSSL 11:cee25a834751 281 /* create new content info struct ... possible OID sanity check? */
wolfSSL 11:cee25a834751 282 ci = (ContentInfo*)XMALLOC(sizeof(ContentInfo), pkcs12->heap,
wolfSSL 11:cee25a834751 283 DYNAMIC_TYPE_PKCS);
wolfSSL 11:cee25a834751 284 if (ci == NULL) {
wolfSSL 11:cee25a834751 285 freeSafe(safe, pkcs12->heap);
wolfSSL 11:cee25a834751 286 return MEMORY_E;
wolfSSL 11:cee25a834751 287 }
wolfSSL 11:cee25a834751 288
wolfSSL 11:cee25a834751 289 ci->type = oid;
wolfSSL 11:cee25a834751 290 ci->dataSz = curSz - (localIdx-curIdx);
wolfSSL 11:cee25a834751 291 ci->data = (byte*)input + localIdx;
wolfSSL 11:cee25a834751 292 localIdx += ci->dataSz;
wolfSSL 11:cee25a834751 293
wolfSSL 11:cee25a834751 294 #ifdef WOLFSSL_DEBUG_PKCS12
wolfSSL 11:cee25a834751 295 switch (oid) {
wolfSSL 11:cee25a834751 296 case WC_PKCS12_ENCRYPTED_DATA:
wolfSSL 11:cee25a834751 297 printf("CONTENT INFO: ENCRYPTED DATA, size = %d\n", ci->dataSz);
wolfSSL 11:cee25a834751 298 break;
wolfSSL 11:cee25a834751 299
wolfSSL 11:cee25a834751 300 case WC_PKCS12_DATA:
wolfSSL 11:cee25a834751 301 printf("CONTENT INFO: DATA, size = %d\n", ci->dataSz);
wolfSSL 11:cee25a834751 302 break;
wolfSSL 11:cee25a834751 303 default:
wolfSSL 11:cee25a834751 304 printf("CONTENT INFO: UNKNOWN, size = %d\n", ci->dataSz);
wolfSSL 11:cee25a834751 305 }
wolfSSL 11:cee25a834751 306 #endif
wolfSSL 11:cee25a834751 307
wolfSSL 11:cee25a834751 308 /* insert to head of list */
wolfSSL 11:cee25a834751 309 ci->next = safe->CI;
wolfSSL 11:cee25a834751 310 safe->CI = ci;
wolfSSL 11:cee25a834751 311 safe->numCI += 1;
wolfSSL 11:cee25a834751 312 }
wolfSSL 11:cee25a834751 313 }
wolfSSL 11:cee25a834751 314
wolfSSL 11:cee25a834751 315 pkcs12->safe = safe;
wolfSSL 11:cee25a834751 316 *idx += localIdx;
wolfSSL 11:cee25a834751 317
wolfSSL 11:cee25a834751 318 return 1;
wolfSSL 11:cee25a834751 319 }
wolfSSL 11:cee25a834751 320
wolfSSL 11:cee25a834751 321
wolfSSL 11:cee25a834751 322 /* optional mac data */
wolfSSL 11:cee25a834751 323 static int GetSignData(WC_PKCS12* pkcs12, const byte* mem, word32* idx,
wolfSSL 11:cee25a834751 324 word32 totalSz)
wolfSSL 11:cee25a834751 325 {
wolfSSL 11:cee25a834751 326 MacData* mac;
wolfSSL 11:cee25a834751 327 word32 curIdx = *idx;
wolfSSL 11:cee25a834751 328 word32 oid = 0;
wolfSSL 11:cee25a834751 329 int size, ret;
wolfSSL 11:cee25a834751 330
wolfSSL 11:cee25a834751 331
wolfSSL 11:cee25a834751 332 /* Digest Info : Sequence
wolfSSL 11:cee25a834751 333 * DigestAlgorithmIdentifier
wolfSSL 11:cee25a834751 334 * Digest
wolfSSL 11:cee25a834751 335 */
wolfSSL 11:cee25a834751 336 if ((ret = GetSequence(mem, &curIdx, &size, totalSz)) <= 0) {
wolfSSL 11:cee25a834751 337 WOLFSSL_MSG("Failed to get PKCS12 sequence");
wolfSSL 11:cee25a834751 338 return ret;
wolfSSL 11:cee25a834751 339 }
wolfSSL 11:cee25a834751 340
wolfSSL 11:cee25a834751 341 #ifdef WOLFSSL_DEBUG_PKCS12
wolfSSL 11:cee25a834751 342 printf("\t\tSEQUENCE: DigestInfo size = %d\n", size);
wolfSSL 11:cee25a834751 343 #endif
wolfSSL 11:cee25a834751 344
wolfSSL 11:cee25a834751 345 mac = (MacData*)XMALLOC(sizeof(MacData), pkcs12->heap, DYNAMIC_TYPE_PKCS);
wolfSSL 11:cee25a834751 346 if (mac == NULL) {
wolfSSL 11:cee25a834751 347 return MEMORY_E;
wolfSSL 11:cee25a834751 348 }
wolfSSL 11:cee25a834751 349 XMEMSET(mac, 0, sizeof(MacData));
wolfSSL 11:cee25a834751 350
wolfSSL 11:cee25a834751 351 /* DigestAlgorithmIdentifier */
wolfSSL 11:cee25a834751 352 if ((ret = GetAlgoId(mem, &curIdx, &oid, oidIgnoreType, totalSz)) < 0) {
wolfSSL 11:cee25a834751 353 WOLFSSL_MSG("Failed to get PKCS12 sequence");
wolfSSL 11:cee25a834751 354 XFREE(mac, pkcs12->heap, DYNAMIC_TYPE_PKCS);
wolfSSL 11:cee25a834751 355 return ret;
wolfSSL 11:cee25a834751 356 }
wolfSSL 11:cee25a834751 357 mac->oid = oid;
wolfSSL 11:cee25a834751 358
wolfSSL 11:cee25a834751 359 #ifdef WOLFSSL_DEBUG_PKCS12
wolfSSL 11:cee25a834751 360 printf("\t\tALGO ID = %d\n", oid);
wolfSSL 11:cee25a834751 361 #endif
wolfSSL 11:cee25a834751 362
wolfSSL 11:cee25a834751 363 /* Digest: should be octet type holding digest */
wolfSSL 11:cee25a834751 364 if (mem[curIdx++] != ASN_OCTET_STRING) {
wolfSSL 11:cee25a834751 365 WOLFSSL_MSG("Failed to get digest");
wolfSSL 11:cee25a834751 366 XFREE(mac, pkcs12->heap, DYNAMIC_TYPE_PKCS);
wolfSSL 11:cee25a834751 367 return ASN_PARSE_E;
wolfSSL 11:cee25a834751 368 }
wolfSSL 11:cee25a834751 369
wolfSSL 11:cee25a834751 370 if ((ret = GetLength(mem, &curIdx, &size, totalSz)) <= 0) {
wolfSSL 11:cee25a834751 371 XFREE(mac, pkcs12->heap, DYNAMIC_TYPE_PKCS);
wolfSSL 11:cee25a834751 372 return ret;
wolfSSL 11:cee25a834751 373 }
wolfSSL 11:cee25a834751 374 mac->digestSz = size;
wolfSSL 11:cee25a834751 375 mac->digest = (byte*)XMALLOC(mac->digestSz, pkcs12->heap,
wolfSSL 11:cee25a834751 376 DYNAMIC_TYPE_PKCS);
wolfSSL 11:cee25a834751 377 if (mac->digest == NULL || mac->digestSz + curIdx > totalSz) {
wolfSSL 11:cee25a834751 378 XFREE(mac, pkcs12->heap, DYNAMIC_TYPE_PKCS);
wolfSSL 11:cee25a834751 379 return MEMORY_E;
wolfSSL 11:cee25a834751 380 }
wolfSSL 11:cee25a834751 381 XMEMCPY(mac->digest, mem + curIdx, mac->digestSz);
wolfSSL 11:cee25a834751 382 #ifdef WOLFSSL_DEBUG_PKCS12
wolfSSL 11:cee25a834751 383 {
wolfSSL 11:cee25a834751 384 byte* p;
wolfSSL 11:cee25a834751 385 for (printf("\t\tDigest = "), p = (byte*)mem+curIdx;
wolfSSL 11:cee25a834751 386 p < (byte*)mem + curIdx + mac->digestSz;
wolfSSL 11:cee25a834751 387 printf("%02X", *p), p++);
wolfSSL 11:cee25a834751 388 printf(" : size = %d\n", mac->digestSz);
wolfSSL 11:cee25a834751 389 }
wolfSSL 11:cee25a834751 390 #endif
wolfSSL 11:cee25a834751 391 curIdx += mac->digestSz;
wolfSSL 11:cee25a834751 392
wolfSSL 11:cee25a834751 393 /* get salt, should be octet string */
wolfSSL 11:cee25a834751 394 if (mem[curIdx++] != ASN_OCTET_STRING) {
wolfSSL 11:cee25a834751 395 WOLFSSL_MSG("Failed to get salt");
wolfSSL 11:cee25a834751 396 XFREE(mac->digest, pkcs12->heap, DYNAMIC_TYPE_PKCS);
wolfSSL 11:cee25a834751 397 XFREE(mac, pkcs12->heap, DYNAMIC_TYPE_PKCS);
wolfSSL 11:cee25a834751 398 return ASN_PARSE_E;
wolfSSL 11:cee25a834751 399 }
wolfSSL 11:cee25a834751 400
wolfSSL 11:cee25a834751 401 if ((ret = GetLength(mem, &curIdx, &size, totalSz)) <= 0) {
wolfSSL 11:cee25a834751 402 XFREE(mac->digest, pkcs12->heap, DYNAMIC_TYPE_PKCS);
wolfSSL 11:cee25a834751 403 XFREE(mac, pkcs12->heap, DYNAMIC_TYPE_PKCS);
wolfSSL 11:cee25a834751 404 return ret;
wolfSSL 11:cee25a834751 405 }
wolfSSL 11:cee25a834751 406 mac->saltSz = size;
wolfSSL 11:cee25a834751 407 mac->salt = (byte*)XMALLOC(mac->saltSz, pkcs12->heap,
wolfSSL 11:cee25a834751 408 DYNAMIC_TYPE_PKCS);
wolfSSL 11:cee25a834751 409 if (mac->salt == NULL || mac->saltSz + curIdx > totalSz) {
wolfSSL 11:cee25a834751 410 XFREE(mac->digest, pkcs12->heap, DYNAMIC_TYPE_PKCS);
wolfSSL 11:cee25a834751 411 XFREE(mac, pkcs12->heap, DYNAMIC_TYPE_PKCS);
wolfSSL 11:cee25a834751 412 return MEMORY_E;
wolfSSL 11:cee25a834751 413 }
wolfSSL 11:cee25a834751 414 XMEMCPY(mac->salt, mem + curIdx, mac->saltSz);
wolfSSL 11:cee25a834751 415 #ifdef WOLFSSL_DEBUG_PKCS12
wolfSSL 11:cee25a834751 416 {
wolfSSL 11:cee25a834751 417 byte* p;
wolfSSL 11:cee25a834751 418 for (printf("\t\tSalt = "), p = (byte*)mem + curIdx;
wolfSSL 11:cee25a834751 419 p < (byte*)mem + curIdx + mac->saltSz;
wolfSSL 11:cee25a834751 420 printf("%02X", *p), p++);
wolfSSL 11:cee25a834751 421 printf(" : size = %d\n", mac->saltSz);
wolfSSL 11:cee25a834751 422 }
wolfSSL 11:cee25a834751 423 #endif
wolfSSL 11:cee25a834751 424 curIdx += mac->saltSz;
wolfSSL 11:cee25a834751 425
wolfSSL 11:cee25a834751 426 /* check for MAC itterations, default to 1 */
wolfSSL 11:cee25a834751 427 mac->itt = 1;
wolfSSL 11:cee25a834751 428 if (curIdx < totalSz) {
wolfSSL 11:cee25a834751 429 int number = 0;
wolfSSL 11:cee25a834751 430 if ((ret = GetShortInt(mem, &curIdx, &number, totalSz)) >= 0) {
wolfSSL 11:cee25a834751 431 /* found a itteration value */
wolfSSL 11:cee25a834751 432 mac->itt = number;
wolfSSL 11:cee25a834751 433 }
wolfSSL 11:cee25a834751 434 }
wolfSSL 11:cee25a834751 435
wolfSSL 11:cee25a834751 436 #ifdef WOLFSSL_DEBUG_PKCS12
wolfSSL 11:cee25a834751 437 printf("\t\tITTERATIONS : %d\n", mac->itt);
wolfSSL 11:cee25a834751 438 #endif
wolfSSL 11:cee25a834751 439
wolfSSL 11:cee25a834751 440 *idx = curIdx;
wolfSSL 11:cee25a834751 441 pkcs12->signData = mac;
wolfSSL 11:cee25a834751 442
wolfSSL 11:cee25a834751 443 return 0;
wolfSSL 11:cee25a834751 444 }
wolfSSL 11:cee25a834751 445
wolfSSL 11:cee25a834751 446
wolfSSL 11:cee25a834751 447 /* check mac on pkcs12, pkcs12->mac has been sanity checked before entering *
wolfSSL 11:cee25a834751 448 * returns the result of comparison, success is 0 */
wolfSSL 11:cee25a834751 449 static int wc_PKCS12_verify(WC_PKCS12* pkcs12, byte* data, word32 dataSz,
wolfSSL 11:cee25a834751 450 const byte* psw, word32 pswSz)
wolfSSL 11:cee25a834751 451 {
wolfSSL 11:cee25a834751 452 Hmac hmac;
wolfSSL 11:cee25a834751 453 MacData* mac;
wolfSSL 11:cee25a834751 454 int ret, typeH, kLen;
wolfSSL 11:cee25a834751 455 int idx = 0;
wolfSSL 11:cee25a834751 456 int id = 3; /* value from RFC 7292 indicating key is used for MAC */
wolfSSL 11:cee25a834751 457 word32 i;
wolfSSL 11:cee25a834751 458 byte digest[MAX_DIGEST_SIZE];
wolfSSL 11:cee25a834751 459 byte unicodePasswd[MAX_UNICODE_SZ];
wolfSSL 11:cee25a834751 460 byte key[MAX_KEY_SIZE];
wolfSSL 11:cee25a834751 461
wolfSSL 11:cee25a834751 462 mac = pkcs12->signData;
wolfSSL 11:cee25a834751 463
wolfSSL 11:cee25a834751 464 #ifdef WOLFSSL_DEBUG_PKCS12
wolfSSL 11:cee25a834751 465 printf("Verifying MAC with OID = %d\n", mac->oid);
wolfSSL 11:cee25a834751 466 #endif
wolfSSL 11:cee25a834751 467
wolfSSL 11:cee25a834751 468 /* check if this builds digest size is too small */
wolfSSL 11:cee25a834751 469 if (mac->digestSz > MAX_DIGEST_SIZE) {
wolfSSL 11:cee25a834751 470 WOLFSSL_MSG("PKCS12 max digest size too small");
wolfSSL 11:cee25a834751 471 return BAD_FUNC_ARG;
wolfSSL 11:cee25a834751 472 }
wolfSSL 11:cee25a834751 473
wolfSSL 11:cee25a834751 474 /* unicode set up from asn.c */
wolfSSL 11:cee25a834751 475 if ( (pswSz * 2 + 2) > (int)sizeof(unicodePasswd)) {
wolfSSL 11:cee25a834751 476 WOLFSSL_MSG("PKCS12 max unicode size too small");
wolfSSL 11:cee25a834751 477 return UNICODE_SIZE_E;
wolfSSL 11:cee25a834751 478 }
wolfSSL 11:cee25a834751 479
wolfSSL 11:cee25a834751 480 for (i = 0; i < pswSz; i++) {
wolfSSL 11:cee25a834751 481 unicodePasswd[idx++] = 0x00;
wolfSSL 11:cee25a834751 482 unicodePasswd[idx++] = (byte)psw[i];
wolfSSL 11:cee25a834751 483 }
wolfSSL 11:cee25a834751 484 /* add trailing NULL */
wolfSSL 11:cee25a834751 485 unicodePasswd[idx++] = 0x00;
wolfSSL 11:cee25a834751 486 unicodePasswd[idx++] = 0x00;
wolfSSL 11:cee25a834751 487
wolfSSL 11:cee25a834751 488 /* get hash type used and resulting size of HMAC key */
wolfSSL 11:cee25a834751 489 switch (mac->oid) {
wolfSSL 11:cee25a834751 490 #ifndef NO_SHA
wolfSSL 11:cee25a834751 491 case SHAh: /* 88 */
wolfSSL 11:cee25a834751 492 typeH = SHA;
wolfSSL 11:cee25a834751 493 kLen = SHA_DIGEST_SIZE;
wolfSSL 11:cee25a834751 494 break;
wolfSSL 11:cee25a834751 495 #endif
wolfSSL 11:cee25a834751 496
wolfSSL 11:cee25a834751 497 #ifndef NO_SHA256
wolfSSL 11:cee25a834751 498 case SHA256h: /* 414 */
wolfSSL 11:cee25a834751 499 typeH = SHA256;
wolfSSL 11:cee25a834751 500 kLen = SHA256_DIGEST_SIZE;
wolfSSL 11:cee25a834751 501 break;
wolfSSL 11:cee25a834751 502 #endif
wolfSSL 11:cee25a834751 503
wolfSSL 11:cee25a834751 504 #ifdef WOLFSSL_SHA384
wolfSSL 11:cee25a834751 505 case SHA384h: /* 415 */
wolfSSL 11:cee25a834751 506 typeH = SHA384;
wolfSSL 11:cee25a834751 507 kLen = SHA384_DIGEST_SIZE;
wolfSSL 11:cee25a834751 508 break;
wolfSSL 11:cee25a834751 509 #endif
wolfSSL 11:cee25a834751 510
wolfSSL 11:cee25a834751 511 #ifdef WOLFSSL_SHA512
wolfSSL 11:cee25a834751 512 case SHA512h: /* 416 */
wolfSSL 11:cee25a834751 513 typeH = SHA512;
wolfSSL 11:cee25a834751 514 kLen = SHA512_DIGEST_SIZE;
wolfSSL 11:cee25a834751 515 break;
wolfSSL 11:cee25a834751 516 #endif
wolfSSL 11:cee25a834751 517
wolfSSL 11:cee25a834751 518 default: /* May be SHA224 or was just not built in */
wolfSSL 11:cee25a834751 519 WOLFSSL_MSG("Unsupported hash used");
wolfSSL 11:cee25a834751 520 return BAD_FUNC_ARG;
wolfSSL 11:cee25a834751 521 }
wolfSSL 11:cee25a834751 522
wolfSSL 11:cee25a834751 523 /* idx contains size of unicodePasswd */
wolfSSL 11:cee25a834751 524 if ((ret = wc_PKCS12_PBKDF_ex(key, unicodePasswd, idx, mac->salt,
wolfSSL 11:cee25a834751 525 mac->saltSz, mac->itt, kLen, typeH, id, pkcs12->heap)) < 0) {
wolfSSL 11:cee25a834751 526 return ret;
wolfSSL 11:cee25a834751 527 }
wolfSSL 11:cee25a834751 528
wolfSSL 11:cee25a834751 529 /* now that key has been created use it to get HMAC hash on data */
wolfSSL 11:cee25a834751 530 if ((ret = wc_HmacInit(&hmac, NULL, INVALID_DEVID)) != 0) {
wolfSSL 11:cee25a834751 531 return ret;
wolfSSL 11:cee25a834751 532 }
wolfSSL 11:cee25a834751 533 ret = wc_HmacSetKey(&hmac, typeH, key, kLen);
wolfSSL 11:cee25a834751 534 if (ret == 0)
wolfSSL 11:cee25a834751 535 ret = wc_HmacUpdate(&hmac, data, dataSz);
wolfSSL 11:cee25a834751 536 if (ret == 0)
wolfSSL 11:cee25a834751 537 ret = wc_HmacFinal(&hmac, digest);
wolfSSL 11:cee25a834751 538 wc_HmacFree(&hmac);
wolfSSL 11:cee25a834751 539
wolfSSL 11:cee25a834751 540 if (ret != 0)
wolfSSL 11:cee25a834751 541 return ret;
wolfSSL 11:cee25a834751 542
wolfSSL 11:cee25a834751 543 #ifdef WOLFSSL_DEBUG_PKCS12
wolfSSL 11:cee25a834751 544 {
wolfSSL 11:cee25a834751 545 byte* p;
wolfSSL 11:cee25a834751 546 for (printf("\t\tHash = "), p = (byte*)digest;
wolfSSL 11:cee25a834751 547 p < (byte*)digest + mac->digestSz;
wolfSSL 11:cee25a834751 548 printf("%02X", *p), p++);
wolfSSL 11:cee25a834751 549 printf(" : size = %d\n", mac->digestSz);
wolfSSL 11:cee25a834751 550 }
wolfSSL 11:cee25a834751 551 #endif
wolfSSL 11:cee25a834751 552
wolfSSL 11:cee25a834751 553 return XMEMCMP(digest, mac->digest, mac->digestSz);
wolfSSL 11:cee25a834751 554 }
wolfSSL 11:cee25a834751 555
wolfSSL 11:cee25a834751 556
wolfSSL 11:cee25a834751 557 /* Convert DER format stored in der buffer to WC_PKCS12 struct
wolfSSL 11:cee25a834751 558 * Puts the raw contents of Content Info into structure without completly
wolfSSL 11:cee25a834751 559 * parsing or decoding.
wolfSSL 11:cee25a834751 560 * der : pointer to der buffer holding PKCS12
wolfSSL 11:cee25a834751 561 * derSz : size of der buffer
wolfSSL 11:cee25a834751 562 * pkcs12 : non-null pkcs12 pointer
wolfSSL 11:cee25a834751 563 */
wolfSSL 11:cee25a834751 564 int wc_d2i_PKCS12(const byte* der, word32 derSz, WC_PKCS12* pkcs12)
wolfSSL 11:cee25a834751 565 {
wolfSSL 11:cee25a834751 566 word32 idx = 0;
wolfSSL 11:cee25a834751 567 word32 totalSz = 0;
wolfSSL 11:cee25a834751 568 int ret;
wolfSSL 11:cee25a834751 569 int size = 0;
wolfSSL 11:cee25a834751 570 int version = 0;
wolfSSL 11:cee25a834751 571
wolfSSL 11:cee25a834751 572 WOLFSSL_ENTER("wolfSSL_d2i_PKCS12_bio");
wolfSSL 11:cee25a834751 573
wolfSSL 11:cee25a834751 574 if (der == NULL || pkcs12 == NULL) {
wolfSSL 11:cee25a834751 575 return BAD_FUNC_ARG;
wolfSSL 11:cee25a834751 576 }
wolfSSL 11:cee25a834751 577
wolfSSL 11:cee25a834751 578 totalSz = derSz;
wolfSSL 11:cee25a834751 579 if ((ret = GetSequence(der, &idx, &size, totalSz)) <= 0) {
wolfSSL 11:cee25a834751 580 WOLFSSL_MSG("Failed to get PKCS12 sequence");
wolfSSL 11:cee25a834751 581 return ret;
wolfSSL 11:cee25a834751 582 }
wolfSSL 11:cee25a834751 583
wolfSSL 11:cee25a834751 584 /* get version */
wolfSSL 11:cee25a834751 585 if ((ret = GetMyVersion(der, &idx, &version, totalSz)) < 0) {
wolfSSL 11:cee25a834751 586 return ret;
wolfSSL 11:cee25a834751 587 }
wolfSSL 11:cee25a834751 588
wolfSSL 11:cee25a834751 589 #ifdef WOLFSSL_DEBUG_PKCS12
wolfSSL 11:cee25a834751 590 printf("\nBEGIN: PKCS12 size = %d\n", totalSz);
wolfSSL 11:cee25a834751 591 printf("version = %d\n", version);
wolfSSL 11:cee25a834751 592 #endif
wolfSSL 11:cee25a834751 593
wolfSSL 11:cee25a834751 594 if (version != 3) {
wolfSSL 11:cee25a834751 595 WOLFSSL_MSG("PKCS12 unsupported version!");
wolfSSL 11:cee25a834751 596 return ASN_VERSION_E;
wolfSSL 11:cee25a834751 597 }
wolfSSL 11:cee25a834751 598
wolfSSL 11:cee25a834751 599 if ((ret = GetSequence(der, &idx, &size, totalSz)) < 0) {
wolfSSL 11:cee25a834751 600 return ret;
wolfSSL 11:cee25a834751 601 }
wolfSSL 11:cee25a834751 602
wolfSSL 11:cee25a834751 603 #ifdef WOLFSSL_DEBUG_PKCS12
wolfSSL 11:cee25a834751 604 printf("\tSEQUENCE: AuthenticatedSafe size = %d\n", size);
wolfSSL 11:cee25a834751 605 #endif
wolfSSL 11:cee25a834751 606
wolfSSL 11:cee25a834751 607 if ((ret = GetSafeContent(pkcs12, der, &idx, size + idx)) < 0) {
wolfSSL 11:cee25a834751 608 WOLFSSL_MSG("GetSafeContent error");
wolfSSL 11:cee25a834751 609 return ret;
wolfSSL 11:cee25a834751 610 }
wolfSSL 11:cee25a834751 611
wolfSSL 11:cee25a834751 612 /* if more buffer left check for MAC data */
wolfSSL 11:cee25a834751 613 if (idx < totalSz) {
wolfSSL 11:cee25a834751 614 if ((ret = GetSequence(der, &idx, &size, totalSz)) < 0) {
wolfSSL 11:cee25a834751 615 WOLFSSL_MSG("Ignoring unknown data at end of PKCS12 DER buffer");
wolfSSL 11:cee25a834751 616 }
wolfSSL 11:cee25a834751 617 else {
wolfSSL 11:cee25a834751 618 #ifdef WOLFSSL_DEBUG_PKCS12
wolfSSL 11:cee25a834751 619 printf("\tSEQUENCE: Signature size = %d\n", size);
wolfSSL 11:cee25a834751 620 #endif
wolfSSL 11:cee25a834751 621
wolfSSL 11:cee25a834751 622 if ((ret = GetSignData(pkcs12, der, &idx, totalSz)) < 0) {
wolfSSL 11:cee25a834751 623 return ASN_PARSE_E;
wolfSSL 11:cee25a834751 624 }
wolfSSL 11:cee25a834751 625 }
wolfSSL 11:cee25a834751 626 }
wolfSSL 11:cee25a834751 627
wolfSSL 11:cee25a834751 628 #ifdef WOLFSSL_DEBUG_PKCS12
wolfSSL 11:cee25a834751 629 printf("END: PKCS12\n");
wolfSSL 11:cee25a834751 630 #endif
wolfSSL 11:cee25a834751 631
wolfSSL 11:cee25a834751 632 return 1;
wolfSSL 11:cee25a834751 633 }
wolfSSL 11:cee25a834751 634
wolfSSL 11:cee25a834751 635
wolfSSL 11:cee25a834751 636 /* helper function to free WC_DerCertList */
wolfSSL 11:cee25a834751 637 static void freeCertList(WC_DerCertList* list, void* heap) {
wolfSSL 11:cee25a834751 638 WC_DerCertList* current;
wolfSSL 11:cee25a834751 639
wolfSSL 11:cee25a834751 640 if (list == NULL) {
wolfSSL 11:cee25a834751 641 return;
wolfSSL 11:cee25a834751 642 }
wolfSSL 11:cee25a834751 643
wolfSSL 11:cee25a834751 644 current = list;
wolfSSL 11:cee25a834751 645 while(current != NULL) {
wolfSSL 11:cee25a834751 646 WC_DerCertList* next = current->next;
wolfSSL 11:cee25a834751 647 if (current->buffer != NULL) {
wolfSSL 11:cee25a834751 648 XFREE(current->buffer, heap, DYNAMIC_TYPE_PKCS);
wolfSSL 11:cee25a834751 649 }
wolfSSL 11:cee25a834751 650 XFREE(current, heap, DYNAMIC_TYPE_PKCS);
wolfSSL 11:cee25a834751 651 current = next;
wolfSSL 11:cee25a834751 652 }
wolfSSL 11:cee25a834751 653
wolfSSL 11:cee25a834751 654 (void)heap;
wolfSSL 11:cee25a834751 655 }
wolfSSL 11:cee25a834751 656
wolfSSL 11:cee25a834751 657
wolfSSL 11:cee25a834751 658 static void freeBuffers(byte* a, byte* b, void* heap)
wolfSSL 11:cee25a834751 659 {
wolfSSL 11:cee25a834751 660 if (a != NULL) {
wolfSSL 11:cee25a834751 661 XFREE(a, heap, DYNAMIC_TYPE_PKCS);
wolfSSL 11:cee25a834751 662 }
wolfSSL 11:cee25a834751 663 if (b != NULL) {
wolfSSL 11:cee25a834751 664 XFREE(b, heap, DYNAMIC_TYPE_PKCS);
wolfSSL 11:cee25a834751 665 }
wolfSSL 11:cee25a834751 666 (void)heap;
wolfSSL 11:cee25a834751 667 }
wolfSSL 11:cee25a834751 668
wolfSSL 11:cee25a834751 669
wolfSSL 11:cee25a834751 670 /* return 1 on success and 0 on failure.
wolfSSL 11:cee25a834751 671 * By side effect returns private key, cert, and optionally ca.
wolfSSL 11:cee25a834751 672 * Parses and decodes the parts of PKCS12
wolfSSL 11:cee25a834751 673 *
wolfSSL 11:cee25a834751 674 * NOTE: can parse with USER RSA enabled but may return cert that is not the
wolfSSL 11:cee25a834751 675 * pair for the key when using RSA key pairs.
wolfSSL 11:cee25a834751 676 *
wolfSSL 11:cee25a834751 677 * pkcs12 : non-null WC_PKCS12 struct
wolfSSL 11:cee25a834751 678 * psw : password to use for PKCS12 decode
wolfSSL 11:cee25a834751 679 * pkey : Private key returned
wolfSSL 11:cee25a834751 680 * cert : x509 cert returned
wolfSSL 11:cee25a834751 681 * ca : optional ca returned
wolfSSL 11:cee25a834751 682 */
wolfSSL 11:cee25a834751 683 int wc_PKCS12_parse(WC_PKCS12* pkcs12, const char* psw,
wolfSSL 11:cee25a834751 684 byte** pkey, word32* pkeySz, byte** cert, word32* certSz,
wolfSSL 11:cee25a834751 685 WC_DerCertList** ca)
wolfSSL 11:cee25a834751 686 {
wolfSSL 11:cee25a834751 687 ContentInfo* ci = NULL;
wolfSSL 11:cee25a834751 688 WC_DerCertList* certList = NULL;
wolfSSL 11:cee25a834751 689 byte* buf = NULL;
wolfSSL 11:cee25a834751 690 word32 i, oid;
wolfSSL 11:cee25a834751 691 int ret, pswSz;
wolfSSL 11:cee25a834751 692
wolfSSL 11:cee25a834751 693 WOLFSSL_ENTER("wc_PKCS12_parse");
wolfSSL 11:cee25a834751 694
wolfSSL 11:cee25a834751 695 if (pkcs12 == NULL || psw == NULL || cert == NULL || certSz == NULL ||
wolfSSL 11:cee25a834751 696 pkey == NULL || pkeySz == NULL) {
wolfSSL 11:cee25a834751 697 return BAD_FUNC_ARG;
wolfSSL 11:cee25a834751 698 }
wolfSSL 11:cee25a834751 699 pswSz = (int)XSTRLEN(psw);
wolfSSL 11:cee25a834751 700 *cert = NULL;
wolfSSL 11:cee25a834751 701 *pkey = NULL;
wolfSSL 11:cee25a834751 702 if (ca != NULL) {
wolfSSL 11:cee25a834751 703 *ca = NULL;
wolfSSL 11:cee25a834751 704 }
wolfSSL 11:cee25a834751 705
wolfSSL 11:cee25a834751 706 /* if there is sign data then verify the MAC */
wolfSSL 11:cee25a834751 707 if (pkcs12->signData != NULL ) {
wolfSSL 11:cee25a834751 708 if ((ret = wc_PKCS12_verify(pkcs12, pkcs12->safe->data,
wolfSSL 11:cee25a834751 709 pkcs12->safe->dataSz, (byte*)psw, pswSz)) != 0) {
wolfSSL 11:cee25a834751 710 WOLFSSL_MSG("PKCS12 Bad MAC on verify");
wolfSSL 11:cee25a834751 711 WOLFSSL_LEAVE("wc_PKCS12_parse verify ", ret);
wolfSSL 11:cee25a834751 712 return MAC_CMP_FAILED_E;
wolfSSL 11:cee25a834751 713 }
wolfSSL 11:cee25a834751 714 }
wolfSSL 11:cee25a834751 715
wolfSSL 11:cee25a834751 716 if (pkcs12->safe == NULL) {
wolfSSL 11:cee25a834751 717 WOLFSSL_MSG("No PKCS12 safes to parse");
wolfSSL 11:cee25a834751 718 return BAD_FUNC_ARG;
wolfSSL 11:cee25a834751 719 }
wolfSSL 11:cee25a834751 720
wolfSSL 11:cee25a834751 721 /* Decode content infos */
wolfSSL 11:cee25a834751 722 ci = pkcs12->safe->CI;
wolfSSL 11:cee25a834751 723 for (i = 0; i < pkcs12->safe->numCI; i++) {
wolfSSL 11:cee25a834751 724 byte* data;
wolfSSL 11:cee25a834751 725 word32 idx = 0;
wolfSSL 11:cee25a834751 726 int size, totalSz;
wolfSSL 11:cee25a834751 727
wolfSSL 11:cee25a834751 728 if (ci->type == WC_PKCS12_ENCRYPTED_DATA) {
wolfSSL 11:cee25a834751 729 int number;
wolfSSL 11:cee25a834751 730
wolfSSL 11:cee25a834751 731 WOLFSSL_MSG("Decrypting PKCS12 Content Info Container");
wolfSSL 11:cee25a834751 732 data = ci->data;
wolfSSL 11:cee25a834751 733 if (data[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) {
wolfSSL 11:cee25a834751 734 freeBuffers(*pkey, buf, pkcs12->heap);
wolfSSL 11:cee25a834751 735 freeCertList(certList, pkcs12->heap);
wolfSSL 11:cee25a834751 736 return ASN_PARSE_E;
wolfSSL 11:cee25a834751 737 }
wolfSSL 11:cee25a834751 738 if ((ret = GetLength(data, &idx, &size, ci->dataSz)) < 0) {
wolfSSL 11:cee25a834751 739 freeBuffers(*pkey, buf, pkcs12->heap);
wolfSSL 11:cee25a834751 740 freeCertList(certList, pkcs12->heap);
wolfSSL 11:cee25a834751 741 return ret;
wolfSSL 11:cee25a834751 742 }
wolfSSL 11:cee25a834751 743
wolfSSL 11:cee25a834751 744 if ((ret = GetSequence(data, &idx, &size, ci->dataSz)) < 0) {
wolfSSL 11:cee25a834751 745 freeBuffers(*pkey, buf, pkcs12->heap);
wolfSSL 11:cee25a834751 746 freeCertList(certList, pkcs12->heap);
wolfSSL 11:cee25a834751 747 return ret;
wolfSSL 11:cee25a834751 748 }
wolfSSL 11:cee25a834751 749
wolfSSL 11:cee25a834751 750 if ((ret = GetShortInt(data, &idx, &number, ci->dataSz)) < 0) {
wolfSSL 11:cee25a834751 751 freeBuffers(*pkey, buf, pkcs12->heap);
wolfSSL 11:cee25a834751 752 freeCertList(certList, pkcs12->heap);
wolfSSL 11:cee25a834751 753 return ret;
wolfSSL 11:cee25a834751 754 }
wolfSSL 11:cee25a834751 755
wolfSSL 11:cee25a834751 756 if (number != 0) {
wolfSSL 11:cee25a834751 757 WOLFSSL_MSG("Expecting 0 for Integer with Encrypted PKCS12");
wolfSSL 11:cee25a834751 758 }
wolfSSL 11:cee25a834751 759
wolfSSL 11:cee25a834751 760 if ((ret = GetSequence(data, &idx, &size, ci->dataSz)) < 0) {
wolfSSL 11:cee25a834751 761 freeBuffers(*pkey, buf, pkcs12->heap);
wolfSSL 11:cee25a834751 762 freeCertList(certList, pkcs12->heap);
wolfSSL 11:cee25a834751 763 return ret;
wolfSSL 11:cee25a834751 764 }
wolfSSL 11:cee25a834751 765
wolfSSL 11:cee25a834751 766 ret = GetObjectId(data, &idx, &oid, oidIgnoreType, ci->dataSz);
wolfSSL 11:cee25a834751 767 if (ret < 0 || oid != WC_PKCS12_DATA) {
wolfSSL 11:cee25a834751 768 WOLFSSL_MSG("Not PKCS12 DATA object or get object parse error");
wolfSSL 11:cee25a834751 769 freeBuffers(*pkey, buf, pkcs12->heap);
wolfSSL 11:cee25a834751 770 freeCertList(certList, pkcs12->heap);
wolfSSL 11:cee25a834751 771 return ASN_PARSE_E;
wolfSSL 11:cee25a834751 772 }
wolfSSL 11:cee25a834751 773
wolfSSL 11:cee25a834751 774 /* decrypted content overwrites input buffer */
wolfSSL 11:cee25a834751 775 size = ci->dataSz - idx;
wolfSSL 11:cee25a834751 776 buf = (byte*)XMALLOC(size, pkcs12->heap, DYNAMIC_TYPE_PKCS);
wolfSSL 11:cee25a834751 777 if (buf == NULL) {
wolfSSL 11:cee25a834751 778 freeBuffers(*pkey, buf, pkcs12->heap);
wolfSSL 11:cee25a834751 779 freeCertList(certList, pkcs12->heap);
wolfSSL 11:cee25a834751 780 return MEMORY_E;
wolfSSL 11:cee25a834751 781 }
wolfSSL 11:cee25a834751 782 XMEMCPY(buf, data + idx, size);
wolfSSL 11:cee25a834751 783
wolfSSL 11:cee25a834751 784 if ((ret = DecryptContent(buf, size, psw, pswSz)) < 0) {
wolfSSL 11:cee25a834751 785 freeBuffers(*pkey, buf, pkcs12->heap);
wolfSSL 11:cee25a834751 786 freeCertList(certList, pkcs12->heap);
wolfSSL 11:cee25a834751 787 WOLFSSL_MSG("Decryption failed, algorithm not compiled in?");
wolfSSL 11:cee25a834751 788 return ret;
wolfSSL 11:cee25a834751 789 }
wolfSSL 11:cee25a834751 790
wolfSSL 11:cee25a834751 791 data = buf;
wolfSSL 11:cee25a834751 792 idx = 0;
wolfSSL 11:cee25a834751 793 #ifdef WOLFSSL_DEBUG_PKCS12
wolfSSL 11:cee25a834751 794 {
wolfSSL 11:cee25a834751 795 byte* p;
wolfSSL 11:cee25a834751 796 for (printf("\tData = "), p = (byte*)buf;
wolfSSL 11:cee25a834751 797 p < (byte*)buf + size;
wolfSSL 11:cee25a834751 798 printf("%02X", *p), p++);
wolfSSL 11:cee25a834751 799 printf("\n");
wolfSSL 11:cee25a834751 800 }
wolfSSL 11:cee25a834751 801 #endif
wolfSSL 11:cee25a834751 802 }
wolfSSL 11:cee25a834751 803 else { /* type DATA */
wolfSSL 11:cee25a834751 804 WOLFSSL_MSG("Parsing PKCS12 DATA Content Info Container");
wolfSSL 11:cee25a834751 805 data = ci->data;
wolfSSL 11:cee25a834751 806 if (data[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) {
wolfSSL 11:cee25a834751 807 freeBuffers(*pkey, buf, pkcs12->heap);
wolfSSL 11:cee25a834751 808 freeCertList(certList, pkcs12->heap);
wolfSSL 11:cee25a834751 809 return ASN_PARSE_E;
wolfSSL 11:cee25a834751 810 }
wolfSSL 11:cee25a834751 811 if ((ret = GetLength(data, &idx, &size, ci->dataSz)) <= 0) {
wolfSSL 11:cee25a834751 812 freeBuffers(*pkey, buf, pkcs12->heap);
wolfSSL 11:cee25a834751 813 freeCertList(certList, pkcs12->heap);
wolfSSL 11:cee25a834751 814 return ret;
wolfSSL 11:cee25a834751 815 }
wolfSSL 11:cee25a834751 816 if (data[idx++] != ASN_OCTET_STRING) {
wolfSSL 11:cee25a834751 817 freeBuffers(*pkey, buf, pkcs12->heap);
wolfSSL 11:cee25a834751 818 freeCertList(certList, pkcs12->heap);
wolfSSL 11:cee25a834751 819 return ASN_PARSE_E;
wolfSSL 11:cee25a834751 820 }
wolfSSL 11:cee25a834751 821 if ((ret = GetLength(data, &idx, &size, ci->dataSz)) < 0) {
wolfSSL 11:cee25a834751 822 freeBuffers(*pkey, buf, pkcs12->heap);
wolfSSL 11:cee25a834751 823 freeCertList(certList, pkcs12->heap);
wolfSSL 11:cee25a834751 824 return ret;
wolfSSL 11:cee25a834751 825 }
wolfSSL 11:cee25a834751 826
wolfSSL 11:cee25a834751 827 }
wolfSSL 11:cee25a834751 828
wolfSSL 11:cee25a834751 829 /* parse through bags in ContentInfo */
wolfSSL 11:cee25a834751 830 if ((ret = GetSequence(data, &idx, &totalSz, ci->dataSz)) < 0) {
wolfSSL 11:cee25a834751 831 freeBuffers(*pkey, buf, pkcs12->heap);
wolfSSL 11:cee25a834751 832 freeCertList(certList, pkcs12->heap);
wolfSSL 11:cee25a834751 833 return ret;
wolfSSL 11:cee25a834751 834 }
wolfSSL 11:cee25a834751 835 totalSz += idx;
wolfSSL 11:cee25a834751 836
wolfSSL 11:cee25a834751 837 while ((int)idx < totalSz) {
wolfSSL 11:cee25a834751 838 int bagSz;
wolfSSL 11:cee25a834751 839 if ((ret = GetSequence(data, &idx, &bagSz, ci->dataSz)) < 0) {
wolfSSL 11:cee25a834751 840 freeBuffers(*pkey, buf, pkcs12->heap);
wolfSSL 11:cee25a834751 841 freeCertList(certList, pkcs12->heap);
wolfSSL 11:cee25a834751 842 return ret;
wolfSSL 11:cee25a834751 843 }
wolfSSL 11:cee25a834751 844 bagSz += idx;
wolfSSL 11:cee25a834751 845
wolfSSL 11:cee25a834751 846 if ((ret = GetObjectId(data, &idx, &oid, oidIgnoreType,
wolfSSL 11:cee25a834751 847 ci->dataSz)) < 0) {
wolfSSL 11:cee25a834751 848 freeBuffers(*pkey, buf, pkcs12->heap);
wolfSSL 11:cee25a834751 849 freeCertList(certList, pkcs12->heap);
wolfSSL 11:cee25a834751 850 return ret;
wolfSSL 11:cee25a834751 851 }
wolfSSL 11:cee25a834751 852
wolfSSL 11:cee25a834751 853 switch (oid) {
wolfSSL 11:cee25a834751 854 case WC_PKCS12_KeyBag: /* 667 */
wolfSSL 11:cee25a834751 855 WOLFSSL_MSG("PKCS12 Key Bag found");
wolfSSL 11:cee25a834751 856 if (data[idx++] !=
wolfSSL 11:cee25a834751 857 (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) {
wolfSSL 11:cee25a834751 858 freeBuffers(*pkey, buf, pkcs12->heap);
wolfSSL 11:cee25a834751 859 freeCertList(certList, pkcs12->heap);
wolfSSL 11:cee25a834751 860 return ASN_PARSE_E;
wolfSSL 11:cee25a834751 861 }
wolfSSL 11:cee25a834751 862 if ((ret = GetLength(data, &idx, &size, ci->dataSz)) <= 0) {
wolfSSL 11:cee25a834751 863 freeBuffers(*pkey, buf, pkcs12->heap);
wolfSSL 11:cee25a834751 864 freeCertList(certList, pkcs12->heap);
wolfSSL 11:cee25a834751 865 return ASN_PARSE_E;
wolfSSL 11:cee25a834751 866 }
wolfSSL 11:cee25a834751 867 if (*pkey == NULL) {
wolfSSL 11:cee25a834751 868 *pkey = (byte*)XMALLOC(size, pkcs12->heap,
wolfSSL 11:cee25a834751 869 DYNAMIC_TYPE_PKCS);
wolfSSL 11:cee25a834751 870 if (*pkey == NULL) {
wolfSSL 11:cee25a834751 871 freeBuffers(*pkey, buf, pkcs12->heap);
wolfSSL 11:cee25a834751 872 freeCertList(certList, pkcs12->heap);
wolfSSL 11:cee25a834751 873 return MEMORY_E;
wolfSSL 11:cee25a834751 874 }
wolfSSL 11:cee25a834751 875 XMEMCPY(*pkey, data + idx, size);
wolfSSL 11:cee25a834751 876 *pkeySz = ToTraditional(*pkey, size);
wolfSSL 11:cee25a834751 877 }
wolfSSL 11:cee25a834751 878 #ifdef WOLFSSL_DEBUG_PKCS12
wolfSSL 11:cee25a834751 879 {
wolfSSL 11:cee25a834751 880 byte* p;
wolfSSL 11:cee25a834751 881 for (printf("\tKey = "), p = (byte*)*pkey;
wolfSSL 11:cee25a834751 882 p < (byte*)*pkey + size;
wolfSSL 11:cee25a834751 883 printf("%02X", *p), p++);
wolfSSL 11:cee25a834751 884 printf("\n");
wolfSSL 11:cee25a834751 885 }
wolfSSL 11:cee25a834751 886 #endif
wolfSSL 11:cee25a834751 887 idx += size;
wolfSSL 11:cee25a834751 888 break;
wolfSSL 11:cee25a834751 889
wolfSSL 11:cee25a834751 890 case WC_PKCS12_ShroudedKeyBag: /* 668 */
wolfSSL 11:cee25a834751 891 {
wolfSSL 11:cee25a834751 892 byte* k;
wolfSSL 11:cee25a834751 893 WOLFSSL_MSG("PKCS12 Shrouded Key Bag found");
wolfSSL 11:cee25a834751 894 if (data[idx++] !=
wolfSSL 11:cee25a834751 895 (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) {
wolfSSL 11:cee25a834751 896 freeBuffers(*pkey, buf, pkcs12->heap);
wolfSSL 11:cee25a834751 897 freeCertList(certList, pkcs12->heap);
wolfSSL 11:cee25a834751 898 return ASN_PARSE_E;
wolfSSL 11:cee25a834751 899 }
wolfSSL 11:cee25a834751 900 if ((ret = GetLength(data, &idx, &size,
wolfSSL 11:cee25a834751 901 ci->dataSz)) < 0) {
wolfSSL 11:cee25a834751 902 freeBuffers(*pkey, buf, pkcs12->heap);
wolfSSL 11:cee25a834751 903 freeCertList(certList, pkcs12->heap);
wolfSSL 11:cee25a834751 904 return ASN_PARSE_E;
wolfSSL 11:cee25a834751 905 }
wolfSSL 11:cee25a834751 906
wolfSSL 11:cee25a834751 907 k = (byte*)XMALLOC(size, pkcs12->heap,
wolfSSL 11:cee25a834751 908 DYNAMIC_TYPE_PKCS);
wolfSSL 11:cee25a834751 909 if (k == NULL) {
wolfSSL 11:cee25a834751 910 freeBuffers(*pkey, buf, pkcs12->heap);
wolfSSL 11:cee25a834751 911 freeCertList(certList, pkcs12->heap);
wolfSSL 11:cee25a834751 912 return MEMORY_E;
wolfSSL 11:cee25a834751 913 }
wolfSSL 11:cee25a834751 914 XMEMCPY(k, data + idx, size);
wolfSSL 11:cee25a834751 915
wolfSSL 11:cee25a834751 916 /* overwrites input, be warned */
wolfSSL 11:cee25a834751 917 if ((ret = ToTraditionalEnc(k, size, psw, pswSz)) < 0) {
wolfSSL 11:cee25a834751 918 freeBuffers(k, NULL, pkcs12->heap);
wolfSSL 11:cee25a834751 919 freeBuffers(*pkey, buf, pkcs12->heap);
wolfSSL 11:cee25a834751 920 freeCertList(certList, pkcs12->heap);
wolfSSL 11:cee25a834751 921 return ret;
wolfSSL 11:cee25a834751 922 }
wolfSSL 11:cee25a834751 923
wolfSSL 11:cee25a834751 924 if (ret < size) {
wolfSSL 11:cee25a834751 925 /* shrink key buffer */
wolfSSL 11:cee25a834751 926 k = (byte*)XREALLOC(k, ret, pkcs12->heap,
wolfSSL 11:cee25a834751 927 DYNAMIC_TYPE_PKCS);
wolfSSL 11:cee25a834751 928 if (k == NULL) {
wolfSSL 11:cee25a834751 929 freeBuffers(*pkey, buf, pkcs12->heap);
wolfSSL 11:cee25a834751 930 freeCertList(certList, pkcs12->heap);
wolfSSL 11:cee25a834751 931 return MEMORY_E;
wolfSSL 11:cee25a834751 932 }
wolfSSL 11:cee25a834751 933 }
wolfSSL 11:cee25a834751 934 size = ret;
wolfSSL 11:cee25a834751 935
wolfSSL 11:cee25a834751 936 if (*pkey == NULL) {
wolfSSL 11:cee25a834751 937 *pkey = k;
wolfSSL 11:cee25a834751 938 *pkeySz = size;
wolfSSL 11:cee25a834751 939 }
wolfSSL 11:cee25a834751 940 else { /* only expecting one key */
wolfSSL 11:cee25a834751 941 freeBuffers(k, NULL, pkcs12->heap);
wolfSSL 11:cee25a834751 942 }
wolfSSL 11:cee25a834751 943 idx += size;
wolfSSL 11:cee25a834751 944
wolfSSL 11:cee25a834751 945 #ifdef WOLFSSL_DEBUG_PKCS12
wolfSSL 11:cee25a834751 946 {
wolfSSL 11:cee25a834751 947 byte* p;
wolfSSL 11:cee25a834751 948 for (printf("\tKey = "), p = (byte*)k;
wolfSSL 11:cee25a834751 949 p < (byte*)k + ret;
wolfSSL 11:cee25a834751 950 printf("%02X", *p), p++);
wolfSSL 11:cee25a834751 951 printf("\n");
wolfSSL 11:cee25a834751 952 }
wolfSSL 11:cee25a834751 953 #endif
wolfSSL 11:cee25a834751 954 }
wolfSSL 11:cee25a834751 955 break;
wolfSSL 11:cee25a834751 956
wolfSSL 11:cee25a834751 957 case WC_PKCS12_CertBag: /* 669 */
wolfSSL 11:cee25a834751 958 {
wolfSSL 11:cee25a834751 959 WC_DerCertList* node;
wolfSSL 11:cee25a834751 960 WOLFSSL_MSG("PKCS12 Cert Bag found");
wolfSSL 11:cee25a834751 961 if (data[idx++] !=
wolfSSL 11:cee25a834751 962 (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) {
wolfSSL 11:cee25a834751 963 freeBuffers(*pkey, buf, pkcs12->heap);
wolfSSL 11:cee25a834751 964 freeCertList(certList, pkcs12->heap);
wolfSSL 11:cee25a834751 965 return ASN_PARSE_E;
wolfSSL 11:cee25a834751 966 }
wolfSSL 11:cee25a834751 967 if ((ret = GetLength(data, &idx, &size, ci->dataSz)) < 0) {
wolfSSL 11:cee25a834751 968 freeBuffers(*pkey, buf, pkcs12->heap);
wolfSSL 11:cee25a834751 969 freeCertList(certList, pkcs12->heap);
wolfSSL 11:cee25a834751 970 return ret;
wolfSSL 11:cee25a834751 971 }
wolfSSL 11:cee25a834751 972
wolfSSL 11:cee25a834751 973 /* get cert bag type */
wolfSSL 11:cee25a834751 974 if ((ret = GetSequence(data, &idx, &size, ci->dataSz)) <0) {
wolfSSL 11:cee25a834751 975 freeBuffers(*pkey, buf, pkcs12->heap);
wolfSSL 11:cee25a834751 976 freeCertList(certList, pkcs12->heap);
wolfSSL 11:cee25a834751 977 return ret;
wolfSSL 11:cee25a834751 978 }
wolfSSL 11:cee25a834751 979
wolfSSL 11:cee25a834751 980 if ((ret = GetObjectId(data, &idx, &oid, oidIgnoreType,
wolfSSL 11:cee25a834751 981 ci->dataSz)) < 0) {
wolfSSL 11:cee25a834751 982 freeBuffers(*pkey, buf, pkcs12->heap);
wolfSSL 11:cee25a834751 983 freeCertList(certList, pkcs12->heap);
wolfSSL 11:cee25a834751 984 return ret;
wolfSSL 11:cee25a834751 985 }
wolfSSL 11:cee25a834751 986
wolfSSL 11:cee25a834751 987 switch (oid) {
wolfSSL 11:cee25a834751 988 case WC_PKCS12_CertBag_Type1: /* 675 */
wolfSSL 11:cee25a834751 989 /* type 1 */
wolfSSL 11:cee25a834751 990 WOLFSSL_MSG("PKCS12 cert bag type 1");
wolfSSL 11:cee25a834751 991 if (data[idx++] !=
wolfSSL 11:cee25a834751 992 (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) {
wolfSSL 11:cee25a834751 993 freeBuffers(*pkey, buf, pkcs12->heap);
wolfSSL 11:cee25a834751 994 freeCertList(certList, pkcs12->heap);
wolfSSL 11:cee25a834751 995 return ASN_PARSE_E;
wolfSSL 11:cee25a834751 996 }
wolfSSL 11:cee25a834751 997 if ((ret = GetLength(data, &idx, &size, ci->dataSz))
wolfSSL 11:cee25a834751 998 <= 0) {
wolfSSL 11:cee25a834751 999 freeBuffers(*pkey, buf, pkcs12->heap);
wolfSSL 11:cee25a834751 1000 freeCertList(certList, pkcs12->heap);
wolfSSL 11:cee25a834751 1001 return ret;
wolfSSL 11:cee25a834751 1002 }
wolfSSL 11:cee25a834751 1003 if (data[idx++] != ASN_OCTET_STRING) {
wolfSSL 11:cee25a834751 1004 freeBuffers(*pkey, buf, pkcs12->heap);
wolfSSL 11:cee25a834751 1005 freeCertList(certList, pkcs12->heap);
wolfSSL 11:cee25a834751 1006 return ASN_PARSE_E;
wolfSSL 11:cee25a834751 1007 }
wolfSSL 11:cee25a834751 1008 if ((ret = GetLength(data, &idx, &size, ci->dataSz))
wolfSSL 11:cee25a834751 1009 < 0) {
wolfSSL 11:cee25a834751 1010 freeBuffers(*pkey, buf, pkcs12->heap);
wolfSSL 11:cee25a834751 1011 freeCertList(certList, pkcs12->heap);
wolfSSL 11:cee25a834751 1012 return ret;
wolfSSL 11:cee25a834751 1013 }
wolfSSL 11:cee25a834751 1014 break;
wolfSSL 11:cee25a834751 1015 default:
wolfSSL 11:cee25a834751 1016 WOLFSSL_MSG("Unknown PKCS12 cert bag type");
wolfSSL 11:cee25a834751 1017 }
wolfSSL 11:cee25a834751 1018
wolfSSL 11:cee25a834751 1019 if (size + idx > (word32)bagSz) {
wolfSSL 11:cee25a834751 1020 freeBuffers(*pkey, buf, pkcs12->heap);
wolfSSL 11:cee25a834751 1021 freeCertList(certList, pkcs12->heap);
wolfSSL 11:cee25a834751 1022 return ASN_PARSE_E;
wolfSSL 11:cee25a834751 1023 }
wolfSSL 11:cee25a834751 1024
wolfSSL 11:cee25a834751 1025 /* list to hold all certs found */
wolfSSL 11:cee25a834751 1026 node = (WC_DerCertList*)XMALLOC(sizeof(WC_DerCertList),
wolfSSL 11:cee25a834751 1027 pkcs12->heap, DYNAMIC_TYPE_PKCS);
wolfSSL 11:cee25a834751 1028 if (node == NULL) {
wolfSSL 11:cee25a834751 1029 freeBuffers(*pkey, buf, pkcs12->heap);
wolfSSL 11:cee25a834751 1030 freeCertList(certList, pkcs12->heap);
wolfSSL 11:cee25a834751 1031 return MEMORY_E;
wolfSSL 11:cee25a834751 1032 }
wolfSSL 11:cee25a834751 1033 XMEMSET(node, 0, sizeof(WC_DerCertList));
wolfSSL 11:cee25a834751 1034
wolfSSL 11:cee25a834751 1035 node->buffer = (byte*)XMALLOC(size, pkcs12->heap,
wolfSSL 11:cee25a834751 1036 DYNAMIC_TYPE_PKCS);
wolfSSL 11:cee25a834751 1037 if (node->buffer == NULL) {
wolfSSL 11:cee25a834751 1038 XFREE(node, pkcs12->heap, DYNAMIC_TYPE_PKCS);
wolfSSL 11:cee25a834751 1039 freeBuffers(*pkey, buf, pkcs12->heap);
wolfSSL 11:cee25a834751 1040 freeCertList(certList, pkcs12->heap);
wolfSSL 11:cee25a834751 1041 return MEMORY_E;
wolfSSL 11:cee25a834751 1042 }
wolfSSL 11:cee25a834751 1043 XMEMCPY(node->buffer, data + idx, size);
wolfSSL 11:cee25a834751 1044 node->bufferSz = size;
wolfSSL 11:cee25a834751 1045
wolfSSL 11:cee25a834751 1046 /* put the new node into the list */
wolfSSL 11:cee25a834751 1047 if (certList != NULL) {
wolfSSL 11:cee25a834751 1048 WOLFSSL_MSG("Pushing new cert onto stack");
wolfSSL 11:cee25a834751 1049 node->next = certList;
wolfSSL 11:cee25a834751 1050 certList = node;
wolfSSL 11:cee25a834751 1051 }
wolfSSL 11:cee25a834751 1052 else {
wolfSSL 11:cee25a834751 1053 certList = node;
wolfSSL 11:cee25a834751 1054 }
wolfSSL 11:cee25a834751 1055
wolfSSL 11:cee25a834751 1056 /* on to next */
wolfSSL 11:cee25a834751 1057 idx += size;
wolfSSL 11:cee25a834751 1058 }
wolfSSL 11:cee25a834751 1059 break;
wolfSSL 11:cee25a834751 1060
wolfSSL 11:cee25a834751 1061 case WC_PKCS12_CrlBag: /* 670 */
wolfSSL 11:cee25a834751 1062 WOLFSSL_MSG("PKCS12 CRL BAG not yet supported");
wolfSSL 11:cee25a834751 1063 break;
wolfSSL 11:cee25a834751 1064
wolfSSL 11:cee25a834751 1065 case WC_PKCS12_SecretBag: /* 671 */
wolfSSL 11:cee25a834751 1066 WOLFSSL_MSG("PKCS12 Secret BAG not yet supported");
wolfSSL 11:cee25a834751 1067 break;
wolfSSL 11:cee25a834751 1068
wolfSSL 11:cee25a834751 1069 case WC_PKCS12_SafeContentsBag: /* 672 */
wolfSSL 11:cee25a834751 1070 WOLFSSL_MSG("PKCS12 Safe Contents BAG not yet supported");
wolfSSL 11:cee25a834751 1071 break;
wolfSSL 11:cee25a834751 1072
wolfSSL 11:cee25a834751 1073 default:
wolfSSL 11:cee25a834751 1074 WOLFSSL_MSG("Unknown PKCS12 BAG type found");
wolfSSL 11:cee25a834751 1075 }
wolfSSL 11:cee25a834751 1076
wolfSSL 11:cee25a834751 1077 /* Attribute, unknown bag or unsupported */
wolfSSL 11:cee25a834751 1078 if ((int)idx < bagSz) {
wolfSSL 11:cee25a834751 1079 idx = bagSz; /* skip for now */
wolfSSL 11:cee25a834751 1080 }
wolfSSL 11:cee25a834751 1081 }
wolfSSL 11:cee25a834751 1082
wolfSSL 11:cee25a834751 1083 /* free temporary buffer */
wolfSSL 11:cee25a834751 1084 if (buf != NULL) {
wolfSSL 11:cee25a834751 1085 XFREE(buf, pkcs12->heap, DYNAMIC_TYPE_PKCS);
wolfSSL 11:cee25a834751 1086 buf = NULL;
wolfSSL 11:cee25a834751 1087 }
wolfSSL 11:cee25a834751 1088 ci = ci->next;
wolfSSL 11:cee25a834751 1089 WOLFSSL_MSG("Done Parsing PKCS12 Content Info Container");
wolfSSL 11:cee25a834751 1090 }
wolfSSL 11:cee25a834751 1091
wolfSSL 11:cee25a834751 1092 /* check if key pair, remove from list */
wolfSSL 11:cee25a834751 1093 {
wolfSSL 11:cee25a834751 1094 WC_DerCertList* current = certList;
wolfSSL 11:cee25a834751 1095 WC_DerCertList* previous = NULL;
wolfSSL 11:cee25a834751 1096
wolfSSL 11:cee25a834751 1097 if (*pkey != NULL) {
wolfSSL 11:cee25a834751 1098
wolfSSL 11:cee25a834751 1099 while (current != NULL) {
wolfSSL 11:cee25a834751 1100 DecodedCert DeCert;
wolfSSL 11:cee25a834751 1101 InitDecodedCert(&DeCert, current->buffer, current->bufferSz,
wolfSSL 11:cee25a834751 1102 pkcs12->heap);
wolfSSL 11:cee25a834751 1103 if (ParseCertRelative(&DeCert, CERT_TYPE, NO_VERIFY, NULL) == 0) {
wolfSSL 11:cee25a834751 1104 if (wc_CheckPrivateKey(*pkey, *pkeySz, &DeCert) == 1) {
wolfSSL 11:cee25a834751 1105 WOLFSSL_MSG("Key Pair found");
wolfSSL 11:cee25a834751 1106 *cert = current->buffer;
wolfSSL 11:cee25a834751 1107 *certSz = current->bufferSz;
wolfSSL 11:cee25a834751 1108
wolfSSL 11:cee25a834751 1109 if (previous == NULL) {
wolfSSL 11:cee25a834751 1110 certList = current->next;
wolfSSL 11:cee25a834751 1111 }
wolfSSL 11:cee25a834751 1112 else {
wolfSSL 11:cee25a834751 1113 previous->next = current->next;
wolfSSL 11:cee25a834751 1114 }
wolfSSL 11:cee25a834751 1115 FreeDecodedCert(&DeCert);
wolfSSL 11:cee25a834751 1116 XFREE(current, pkcs12->heap, DYNAMIC_TYPE_PKCS);
wolfSSL 11:cee25a834751 1117 break;
wolfSSL 11:cee25a834751 1118 }
wolfSSL 11:cee25a834751 1119 }
wolfSSL 11:cee25a834751 1120
wolfSSL 11:cee25a834751 1121 FreeDecodedCert(&DeCert);
wolfSSL 11:cee25a834751 1122 previous = current;
wolfSSL 11:cee25a834751 1123 current = current->next;
wolfSSL 11:cee25a834751 1124 }
wolfSSL 11:cee25a834751 1125
wolfSSL 11:cee25a834751 1126 }
wolfSSL 11:cee25a834751 1127 }
wolfSSL 11:cee25a834751 1128
wolfSSL 11:cee25a834751 1129 if (ca != NULL) {
wolfSSL 11:cee25a834751 1130 *ca = certList;
wolfSSL 11:cee25a834751 1131 }
wolfSSL 11:cee25a834751 1132 else {
wolfSSL 11:cee25a834751 1133 /* free list, not wanted */
wolfSSL 11:cee25a834751 1134 freeCertList(certList, pkcs12->heap);
wolfSSL 11:cee25a834751 1135 }
wolfSSL 11:cee25a834751 1136
wolfSSL 11:cee25a834751 1137 return 1;
wolfSSL 11:cee25a834751 1138 }
wolfSSL 11:cee25a834751 1139
wolfSSL 11:cee25a834751 1140
wolfSSL 11:cee25a834751 1141 /* if using a specific memory heap */
wolfSSL 11:cee25a834751 1142 int wc_PKCS12_SetHeap(WC_PKCS12* pkcs12, void* heap)
wolfSSL 11:cee25a834751 1143 {
wolfSSL 11:cee25a834751 1144 if (pkcs12 == NULL) {
wolfSSL 11:cee25a834751 1145 return BAD_FUNC_ARG;
wolfSSL 11:cee25a834751 1146 }
wolfSSL 11:cee25a834751 1147 pkcs12->heap = heap;
wolfSSL 11:cee25a834751 1148
wolfSSL 11:cee25a834751 1149 return 0;
wolfSSL 11:cee25a834751 1150 }
wolfSSL 11:cee25a834751 1151
wolfSSL 11:cee25a834751 1152
wolfSSL 11:cee25a834751 1153 /* getter for heap */
wolfSSL 11:cee25a834751 1154 void* wc_PKCS12_GetHeap(WC_PKCS12* pkcs12)
wolfSSL 11:cee25a834751 1155 {
wolfSSL 11:cee25a834751 1156 if (pkcs12 == NULL) {
wolfSSL 11:cee25a834751 1157 return NULL;
wolfSSL 11:cee25a834751 1158 }
wolfSSL 11:cee25a834751 1159
wolfSSL 11:cee25a834751 1160 return pkcs12->heap;
wolfSSL 11:cee25a834751 1161 }
wolfSSL 11:cee25a834751 1162
wolfSSL 11:cee25a834751 1163 #endif /* !defined(NO_ASN) && !defined(NO_PWDBASED) */
wolfSSL 11:cee25a834751 1164
wolfSSL 11:cee25a834751 1165