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

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

Committer:
wolfSSL
Date:
Tue Aug 22 10:48:22 2017 +0000
Revision:
13:f67a6c6013ca
wolfSSL3.12.0 with TLS1.3

Who changed what in which revision?

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