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