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

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

Committer:
wolfSSL
Date:
Tue May 02 08:44:26 2017 +0000
Revision:
6:fa3bd0ca5896
wolfSSL3.10.2;

Who changed what in which revision?

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