Xuyi Wang / wolfSSL

Dependents:   OS

Committer:
sPymbed
Date:
Tue Nov 19 14:32:16 2019 +0000
Revision:
16:048e5e270a58
Parent:
15:117db924cf7c
working ssl

Who changed what in which revision?

UserRevisionLine numberNew contents of line
sPymbed 16:048e5e270a58 1 /* asn.c
sPymbed 16:048e5e270a58 2 *
sPymbed 16:048e5e270a58 3 * Copyright (C) 2006-2017 wolfSSL Inc.
sPymbed 16:048e5e270a58 4 *
sPymbed 16:048e5e270a58 5 * This file is part of wolfSSL.
sPymbed 16:048e5e270a58 6 *
sPymbed 16:048e5e270a58 7 * wolfSSL is free software; you can redistribute it and/or modify
sPymbed 16:048e5e270a58 8 * it under the terms of the GNU General Public License as published by
sPymbed 16:048e5e270a58 9 * the Free Software Foundation; either version 2 of the License, or
sPymbed 16:048e5e270a58 10 * (at your option) any later version.
sPymbed 16:048e5e270a58 11 *
sPymbed 16:048e5e270a58 12 * wolfSSL is distributed in the hope that it will be useful,
sPymbed 16:048e5e270a58 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
sPymbed 16:048e5e270a58 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
sPymbed 16:048e5e270a58 15 * GNU General Public License for more details.
sPymbed 16:048e5e270a58 16 *
sPymbed 16:048e5e270a58 17 * You should have received a copy of the GNU General Public License
sPymbed 16:048e5e270a58 18 * along with this program; if not, write to the Free Software
sPymbed 16:048e5e270a58 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
sPymbed 16:048e5e270a58 20 */
sPymbed 16:048e5e270a58 21
sPymbed 16:048e5e270a58 22
sPymbed 16:048e5e270a58 23 #ifdef HAVE_CONFIG_H
sPymbed 16:048e5e270a58 24 #include <config.h>
sPymbed 16:048e5e270a58 25 #endif
sPymbed 16:048e5e270a58 26
sPymbed 16:048e5e270a58 27 #include <wolfssl/wolfcrypt/settings.h>
sPymbed 16:048e5e270a58 28
sPymbed 16:048e5e270a58 29 /*
sPymbed 16:048e5e270a58 30 ASN Options:
sPymbed 16:048e5e270a58 31 * NO_ASN_TIME: Disables time parts of the ASN code for systems without an RTC
sPymbed 16:048e5e270a58 32 or wishing to save space.
sPymbed 16:048e5e270a58 33 * IGNORE_NAME_CONSTRAINTS: Skip ASN name checks.
sPymbed 16:048e5e270a58 34 * ASN_DUMP_OID: Allows dump of OID information for debugging.
sPymbed 16:048e5e270a58 35 * RSA_DECODE_EXTRA: Decodes extra information in RSA public key.
sPymbed 16:048e5e270a58 36 * WOLFSSL_CERT_GEN: Cert generation. Saves extra certificate info in GetName.
sPymbed 16:048e5e270a58 37 * WOLFSSL_NO_ASN_STRICT: Disable strict RFC compliance checks to
sPymbed 16:048e5e270a58 38 restore 3.13.0 behavior.
sPymbed 16:048e5e270a58 39 * WOLFSSL_NO_OCSP_OPTIONAL_CERTS: Skip optional OCSP certs (responder issuer
sPymbed 16:048e5e270a58 40 must still be trusted)
sPymbed 16:048e5e270a58 41 * WOLFSSL_NO_TRUSTED_CERTS_VERIFY: Workaround for situation where entire cert
sPymbed 16:048e5e270a58 42 chain is not loaded. This only matches on subject and public key and
sPymbed 16:048e5e270a58 43 does not perform a PKI validation, so it is not a secure solution.
sPymbed 16:048e5e270a58 44 Only enabled for OCSP.
sPymbed 16:048e5e270a58 45 * WOLFSSL_NO_OCSP_ISSUER_CHECK: Can be defined for backwards compatibility to
sPymbed 16:048e5e270a58 46 disable checking of OCSP subject hash with issuer hash.
sPymbed 16:048e5e270a58 47 * WOLFSSL_ALT_CERT_CHAINS: Allows matching multiple CA's to validate
sPymbed 16:048e5e270a58 48 chain based on issuer and public key (includes signature confirmation)
sPymbed 16:048e5e270a58 49 */
sPymbed 16:048e5e270a58 50
sPymbed 16:048e5e270a58 51 #ifndef NO_ASN
sPymbed 16:048e5e270a58 52
sPymbed 16:048e5e270a58 53 #include <wolfssl/wolfcrypt/asn.h>
sPymbed 16:048e5e270a58 54 #include <wolfssl/wolfcrypt/coding.h>
sPymbed 16:048e5e270a58 55 #include <wolfssl/wolfcrypt/md2.h>
sPymbed 16:048e5e270a58 56 #include <wolfssl/wolfcrypt/hmac.h>
sPymbed 16:048e5e270a58 57 #include <wolfssl/wolfcrypt/error-crypt.h>
sPymbed 16:048e5e270a58 58 #include <wolfssl/wolfcrypt/pwdbased.h>
sPymbed 16:048e5e270a58 59 #include <wolfssl/wolfcrypt/des3.h>
sPymbed 16:048e5e270a58 60 #include <wolfssl/wolfcrypt/aes.h>
sPymbed 16:048e5e270a58 61 #include <wolfssl/wolfcrypt/wc_encrypt.h>
sPymbed 16:048e5e270a58 62 #include <wolfssl/wolfcrypt/logging.h>
sPymbed 16:048e5e270a58 63
sPymbed 16:048e5e270a58 64 #include <wolfssl/wolfcrypt/random.h>
sPymbed 16:048e5e270a58 65 #include <wolfssl/wolfcrypt/hash.h>
sPymbed 16:048e5e270a58 66 #ifdef NO_INLINE
sPymbed 16:048e5e270a58 67 #include <wolfssl/wolfcrypt/misc.h>
sPymbed 16:048e5e270a58 68 #else
sPymbed 16:048e5e270a58 69 #define WOLFSSL_MISC_INCLUDED
sPymbed 16:048e5e270a58 70 #include <wolfcrypt/src/misc.c>
sPymbed 16:048e5e270a58 71 #endif
sPymbed 16:048e5e270a58 72
sPymbed 16:048e5e270a58 73 #ifndef NO_PWDBASED
sPymbed 16:048e5e270a58 74 #include <wolfssl/wolfcrypt/aes.h>
sPymbed 16:048e5e270a58 75 #endif
sPymbed 16:048e5e270a58 76 #ifndef NO_RC4
sPymbed 16:048e5e270a58 77 #include <wolfssl/wolfcrypt/arc4.h>
sPymbed 16:048e5e270a58 78 #endif
sPymbed 16:048e5e270a58 79
sPymbed 16:048e5e270a58 80 #ifdef HAVE_NTRU
sPymbed 16:048e5e270a58 81 #include "libntruencrypt/ntru_crypto.h"
sPymbed 16:048e5e270a58 82 #endif
sPymbed 16:048e5e270a58 83
sPymbed 16:048e5e270a58 84 #if defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384)
sPymbed 16:048e5e270a58 85 #include <wolfssl/wolfcrypt/sha512.h>
sPymbed 16:048e5e270a58 86 #endif
sPymbed 16:048e5e270a58 87
sPymbed 16:048e5e270a58 88 #ifndef NO_SHA256
sPymbed 16:048e5e270a58 89 #include <wolfssl/wolfcrypt/sha256.h>
sPymbed 16:048e5e270a58 90 #endif
sPymbed 16:048e5e270a58 91
sPymbed 16:048e5e270a58 92 #ifdef HAVE_ECC
sPymbed 16:048e5e270a58 93 #include <wolfssl/wolfcrypt/ecc.h>
sPymbed 16:048e5e270a58 94 #endif
sPymbed 16:048e5e270a58 95
sPymbed 16:048e5e270a58 96 #ifdef HAVE_ED25519
sPymbed 16:048e5e270a58 97 #include <wolfssl/wolfcrypt/ed25519.h>
sPymbed 16:048e5e270a58 98 #endif
sPymbed 16:048e5e270a58 99
sPymbed 16:048e5e270a58 100 #ifndef NO_RSA
sPymbed 16:048e5e270a58 101 #include <wolfssl/wolfcrypt/rsa.h>
sPymbed 16:048e5e270a58 102 #endif
sPymbed 16:048e5e270a58 103
sPymbed 16:048e5e270a58 104 #ifdef WOLFSSL_DEBUG_ENCODING
sPymbed 16:048e5e270a58 105 #if defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX)
sPymbed 16:048e5e270a58 106 #if MQX_USE_IO_OLD
sPymbed 16:048e5e270a58 107 #include <fio.h>
sPymbed 16:048e5e270a58 108 #else
sPymbed 16:048e5e270a58 109 #include <nio.h>
sPymbed 16:048e5e270a58 110 #endif
sPymbed 16:048e5e270a58 111 #else
sPymbed 16:048e5e270a58 112 #include <stdio.h>
sPymbed 16:048e5e270a58 113 #endif
sPymbed 16:048e5e270a58 114 #endif
sPymbed 16:048e5e270a58 115
sPymbed 16:048e5e270a58 116
sPymbed 16:048e5e270a58 117 #ifdef _MSC_VER
sPymbed 16:048e5e270a58 118 /* 4996 warning to use MS extensions e.g., strcpy_s instead of XSTRNCPY */
sPymbed 16:048e5e270a58 119 #pragma warning(disable: 4996)
sPymbed 16:048e5e270a58 120 #endif
sPymbed 16:048e5e270a58 121
sPymbed 16:048e5e270a58 122 #define ERROR_OUT(err, eLabel) { ret = (err); goto eLabel; }
sPymbed 16:048e5e270a58 123
sPymbed 16:048e5e270a58 124 WOLFSSL_LOCAL int GetLength(const byte* input, word32* inOutIdx, int* len,
sPymbed 16:048e5e270a58 125 word32 maxIdx)
sPymbed 16:048e5e270a58 126 {
sPymbed 16:048e5e270a58 127 int length = 0;
sPymbed 16:048e5e270a58 128 word32 idx = *inOutIdx;
sPymbed 16:048e5e270a58 129 byte b;
sPymbed 16:048e5e270a58 130
sPymbed 16:048e5e270a58 131 *len = 0; /* default length */
sPymbed 16:048e5e270a58 132
sPymbed 16:048e5e270a58 133 if ((idx + 1) > maxIdx) { /* for first read */
sPymbed 16:048e5e270a58 134 WOLFSSL_MSG("GetLength bad index on input");
sPymbed 16:048e5e270a58 135 return BUFFER_E;
sPymbed 16:048e5e270a58 136 }
sPymbed 16:048e5e270a58 137
sPymbed 16:048e5e270a58 138 b = input[idx++];
sPymbed 16:048e5e270a58 139 if (b >= ASN_LONG_LENGTH) {
sPymbed 16:048e5e270a58 140 word32 bytes = b & 0x7F;
sPymbed 16:048e5e270a58 141
sPymbed 16:048e5e270a58 142 if ((idx + bytes) > maxIdx) { /* for reading bytes */
sPymbed 16:048e5e270a58 143 WOLFSSL_MSG("GetLength bad long length");
sPymbed 16:048e5e270a58 144 return BUFFER_E;
sPymbed 16:048e5e270a58 145 }
sPymbed 16:048e5e270a58 146
sPymbed 16:048e5e270a58 147 while (bytes--) {
sPymbed 16:048e5e270a58 148 b = input[idx++];
sPymbed 16:048e5e270a58 149 length = (length << 8) | b;
sPymbed 16:048e5e270a58 150 }
sPymbed 16:048e5e270a58 151 }
sPymbed 16:048e5e270a58 152 else
sPymbed 16:048e5e270a58 153 length = b;
sPymbed 16:048e5e270a58 154
sPymbed 16:048e5e270a58 155 if ((idx + length) > maxIdx) { /* for user of length */
sPymbed 16:048e5e270a58 156 WOLFSSL_MSG("GetLength value exceeds buffer length");
sPymbed 16:048e5e270a58 157 return BUFFER_E;
sPymbed 16:048e5e270a58 158 }
sPymbed 16:048e5e270a58 159
sPymbed 16:048e5e270a58 160 *inOutIdx = idx;
sPymbed 16:048e5e270a58 161 if (length > 0)
sPymbed 16:048e5e270a58 162 *len = length;
sPymbed 16:048e5e270a58 163
sPymbed 16:048e5e270a58 164 return length;
sPymbed 16:048e5e270a58 165 }
sPymbed 16:048e5e270a58 166
sPymbed 16:048e5e270a58 167
sPymbed 16:048e5e270a58 168 /* Get the DER/BER encoding of an ASN.1 header.
sPymbed 16:048e5e270a58 169 *
sPymbed 16:048e5e270a58 170 * input Buffer holding DER/BER encoded data.
sPymbed 16:048e5e270a58 171 * tag ASN.1 tag value expected in header.
sPymbed 16:048e5e270a58 172 * inOutIdx Current index into buffer to parse.
sPymbed 16:048e5e270a58 173 * len The number of bytes in the ASN.1 data.
sPymbed 16:048e5e270a58 174 * maxIdx Length of data in buffer.
sPymbed 16:048e5e270a58 175 * returns BUFFER_E when there is not enough data to parse.
sPymbed 16:048e5e270a58 176 * ASN_PARSE_E when the expected tag is not found or length is invalid.
sPymbed 16:048e5e270a58 177 * Otherwise, the number of bytes in the ASN.1 data.
sPymbed 16:048e5e270a58 178 */
sPymbed 16:048e5e270a58 179 static int GetASNHeader(const byte* input, byte tag, word32* inOutIdx, int* len,
sPymbed 16:048e5e270a58 180 word32 maxIdx)
sPymbed 16:048e5e270a58 181 {
sPymbed 16:048e5e270a58 182 word32 idx = *inOutIdx;
sPymbed 16:048e5e270a58 183 byte b;
sPymbed 16:048e5e270a58 184 int length;
sPymbed 16:048e5e270a58 185
sPymbed 16:048e5e270a58 186 if ((idx + 1) > maxIdx)
sPymbed 16:048e5e270a58 187 return BUFFER_E;
sPymbed 16:048e5e270a58 188
sPymbed 16:048e5e270a58 189 b = input[idx++];
sPymbed 16:048e5e270a58 190 if (b != tag)
sPymbed 16:048e5e270a58 191 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 192
sPymbed 16:048e5e270a58 193 if (GetLength(input, &idx, &length, maxIdx) < 0)
sPymbed 16:048e5e270a58 194 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 195
sPymbed 16:048e5e270a58 196 *len = length;
sPymbed 16:048e5e270a58 197 *inOutIdx = idx;
sPymbed 16:048e5e270a58 198 return length;
sPymbed 16:048e5e270a58 199 }
sPymbed 16:048e5e270a58 200
sPymbed 16:048e5e270a58 201 WOLFSSL_LOCAL int GetSequence(const byte* input, word32* inOutIdx, int* len,
sPymbed 16:048e5e270a58 202 word32 maxIdx)
sPymbed 16:048e5e270a58 203 {
sPymbed 16:048e5e270a58 204 return GetASNHeader(input, ASN_SEQUENCE | ASN_CONSTRUCTED, inOutIdx, len,
sPymbed 16:048e5e270a58 205 maxIdx);
sPymbed 16:048e5e270a58 206 }
sPymbed 16:048e5e270a58 207
sPymbed 16:048e5e270a58 208
sPymbed 16:048e5e270a58 209 WOLFSSL_LOCAL int GetSet(const byte* input, word32* inOutIdx, int* len,
sPymbed 16:048e5e270a58 210 word32 maxIdx)
sPymbed 16:048e5e270a58 211 {
sPymbed 16:048e5e270a58 212 return GetASNHeader(input, ASN_SET | ASN_CONSTRUCTED, inOutIdx, len,
sPymbed 16:048e5e270a58 213 maxIdx);
sPymbed 16:048e5e270a58 214 }
sPymbed 16:048e5e270a58 215
sPymbed 16:048e5e270a58 216 /* Get the DER/BER encoded ASN.1 NULL element.
sPymbed 16:048e5e270a58 217 * Ensure that the all fields are as expected and move index past the element.
sPymbed 16:048e5e270a58 218 *
sPymbed 16:048e5e270a58 219 * input Buffer holding DER/BER encoded data.
sPymbed 16:048e5e270a58 220 * inOutIdx Current index into buffer to parse.
sPymbed 16:048e5e270a58 221 * maxIdx Length of data in buffer.
sPymbed 16:048e5e270a58 222 * returns BUFFER_E when there is not enough data to parse.
sPymbed 16:048e5e270a58 223 * ASN_TAG_NULL_E when the NULL tag is not found.
sPymbed 16:048e5e270a58 224 * ASN_EXPECT_0_E when the length is not zero.
sPymbed 16:048e5e270a58 225 * Otherwise, 0 to indicate success.
sPymbed 16:048e5e270a58 226 */
sPymbed 16:048e5e270a58 227 static int GetASNNull(const byte* input, word32* inOutIdx, word32 maxIdx)
sPymbed 16:048e5e270a58 228 {
sPymbed 16:048e5e270a58 229 word32 idx = *inOutIdx;
sPymbed 16:048e5e270a58 230 byte b;
sPymbed 16:048e5e270a58 231
sPymbed 16:048e5e270a58 232 if ((idx + 2) > maxIdx)
sPymbed 16:048e5e270a58 233 return BUFFER_E;
sPymbed 16:048e5e270a58 234
sPymbed 16:048e5e270a58 235 b = input[idx++];
sPymbed 16:048e5e270a58 236 if (b != ASN_TAG_NULL)
sPymbed 16:048e5e270a58 237 return ASN_TAG_NULL_E;
sPymbed 16:048e5e270a58 238
sPymbed 16:048e5e270a58 239 if (input[idx++] != 0)
sPymbed 16:048e5e270a58 240 return ASN_EXPECT_0_E;
sPymbed 16:048e5e270a58 241
sPymbed 16:048e5e270a58 242 *inOutIdx = idx;
sPymbed 16:048e5e270a58 243 return 0;
sPymbed 16:048e5e270a58 244 }
sPymbed 16:048e5e270a58 245
sPymbed 16:048e5e270a58 246 /* Set the DER/BER encoding of the ASN.1 NULL element.
sPymbed 16:048e5e270a58 247 *
sPymbed 16:048e5e270a58 248 * output Buffer to write into.
sPymbed 16:048e5e270a58 249 * returns the number of bytes added to the buffer.
sPymbed 16:048e5e270a58 250 */
sPymbed 16:048e5e270a58 251 static int SetASNNull(byte* output)
sPymbed 16:048e5e270a58 252 {
sPymbed 16:048e5e270a58 253 output[0] = ASN_TAG_NULL;
sPymbed 16:048e5e270a58 254 output[1] = 0;
sPymbed 16:048e5e270a58 255
sPymbed 16:048e5e270a58 256 return 2;
sPymbed 16:048e5e270a58 257 }
sPymbed 16:048e5e270a58 258
sPymbed 16:048e5e270a58 259 /* Get the DER/BER encoding of an ASN.1 BOOLEAN.
sPymbed 16:048e5e270a58 260 *
sPymbed 16:048e5e270a58 261 * input Buffer holding DER/BER encoded data.
sPymbed 16:048e5e270a58 262 * inOutIdx Current index into buffer to parse.
sPymbed 16:048e5e270a58 263 * maxIdx Length of data in buffer.
sPymbed 16:048e5e270a58 264 * returns BUFFER_E when there is not enough data to parse.
sPymbed 16:048e5e270a58 265 * ASN_PARSE_E when the BOOLEAN tag is not found or length is not 1.
sPymbed 16:048e5e270a58 266 * Otherwise, 0 to indicate the value was false and 1 to indicate true.
sPymbed 16:048e5e270a58 267 */
sPymbed 16:048e5e270a58 268 static int GetBoolean(const byte* input, word32* inOutIdx, word32 maxIdx)
sPymbed 16:048e5e270a58 269 {
sPymbed 16:048e5e270a58 270 word32 idx = *inOutIdx;
sPymbed 16:048e5e270a58 271 byte b;
sPymbed 16:048e5e270a58 272
sPymbed 16:048e5e270a58 273 if ((idx + 3) > maxIdx)
sPymbed 16:048e5e270a58 274 return BUFFER_E;
sPymbed 16:048e5e270a58 275
sPymbed 16:048e5e270a58 276 b = input[idx++];
sPymbed 16:048e5e270a58 277 if (b != ASN_BOOLEAN)
sPymbed 16:048e5e270a58 278 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 279
sPymbed 16:048e5e270a58 280 if (input[idx++] != 1)
sPymbed 16:048e5e270a58 281 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 282
sPymbed 16:048e5e270a58 283 b = input[idx++] != 0;
sPymbed 16:048e5e270a58 284
sPymbed 16:048e5e270a58 285 *inOutIdx = idx;
sPymbed 16:048e5e270a58 286 return b;
sPymbed 16:048e5e270a58 287 }
sPymbed 16:048e5e270a58 288
sPymbed 16:048e5e270a58 289 #ifdef ASN1_SET_BOOLEAN
sPymbed 16:048e5e270a58 290 /* Set the DER/BER encoding of the ASN.1 NULL element.
sPymbed 16:048e5e270a58 291 * Note: Function not required as yet.
sPymbed 16:048e5e270a58 292 *
sPymbed 16:048e5e270a58 293 * val Boolean value to encode.
sPymbed 16:048e5e270a58 294 * output Buffer to write into.
sPymbed 16:048e5e270a58 295 * returns the number of bytes added to the buffer.
sPymbed 16:048e5e270a58 296 */
sPymbed 16:048e5e270a58 297 static int SetBoolean(int val, byte* output)
sPymbed 16:048e5e270a58 298 {
sPymbed 16:048e5e270a58 299 output[0] = ASN_BOOLEAN;
sPymbed 16:048e5e270a58 300 output[1] = 1;
sPymbed 16:048e5e270a58 301 output[2] = val ? -1 : 0;
sPymbed 16:048e5e270a58 302
sPymbed 16:048e5e270a58 303 return 3;
sPymbed 16:048e5e270a58 304 }
sPymbed 16:048e5e270a58 305 #endif
sPymbed 16:048e5e270a58 306
sPymbed 16:048e5e270a58 307 /* Get the DER/BER encoding of an ASN.1 OCTET_STRING header.
sPymbed 16:048e5e270a58 308 *
sPymbed 16:048e5e270a58 309 * input Buffer holding DER/BER encoded data.
sPymbed 16:048e5e270a58 310 * inOutIdx Current index into buffer to parse.
sPymbed 16:048e5e270a58 311 * len The number of bytes in the ASN.1 data.
sPymbed 16:048e5e270a58 312 * maxIdx Length of data in buffer.
sPymbed 16:048e5e270a58 313 * returns BUFFER_E when there is not enough data to parse.
sPymbed 16:048e5e270a58 314 * ASN_PARSE_E when the OCTET_STRING tag is not found or length is
sPymbed 16:048e5e270a58 315 * invalid.
sPymbed 16:048e5e270a58 316 * Otherwise, the number of bytes in the ASN.1 data.
sPymbed 16:048e5e270a58 317 */
sPymbed 16:048e5e270a58 318 static int GetOctetString(const byte* input, word32* inOutIdx, int* len,
sPymbed 16:048e5e270a58 319 word32 maxIdx)
sPymbed 16:048e5e270a58 320 {
sPymbed 16:048e5e270a58 321 return GetASNHeader(input, ASN_OCTET_STRING, inOutIdx, len, maxIdx);
sPymbed 16:048e5e270a58 322 }
sPymbed 16:048e5e270a58 323
sPymbed 16:048e5e270a58 324 /* Get the DER/BER encoding of an ASN.1 INTEGER header.
sPymbed 16:048e5e270a58 325 * Removes the leading zero byte when found.
sPymbed 16:048e5e270a58 326 *
sPymbed 16:048e5e270a58 327 * input Buffer holding DER/BER encoded data.
sPymbed 16:048e5e270a58 328 * inOutIdx Current index into buffer to parse.
sPymbed 16:048e5e270a58 329 * len The number of bytes in the ASN.1 data (excluding any leading zero).
sPymbed 16:048e5e270a58 330 * maxIdx Length of data in buffer.
sPymbed 16:048e5e270a58 331 * returns BUFFER_E when there is not enough data to parse.
sPymbed 16:048e5e270a58 332 * ASN_PARSE_E when the INTEGER tag is not found, length is invalid,
sPymbed 16:048e5e270a58 333 * or invalid use of or missing leading zero.
sPymbed 16:048e5e270a58 334 * Otherwise, 0 to indicate success.
sPymbed 16:048e5e270a58 335 */
sPymbed 16:048e5e270a58 336 static int GetASNInt(const byte* input, word32* inOutIdx, int* len,
sPymbed 16:048e5e270a58 337 word32 maxIdx)
sPymbed 16:048e5e270a58 338 {
sPymbed 16:048e5e270a58 339 int ret;
sPymbed 16:048e5e270a58 340
sPymbed 16:048e5e270a58 341 ret = GetASNHeader(input, ASN_INTEGER, inOutIdx, len, maxIdx);
sPymbed 16:048e5e270a58 342 if (ret < 0)
sPymbed 16:048e5e270a58 343 return ret;
sPymbed 16:048e5e270a58 344
sPymbed 16:048e5e270a58 345 if (*len > 0) {
sPymbed 16:048e5e270a58 346 /* remove leading zero, unless there is only one 0x00 byte */
sPymbed 16:048e5e270a58 347 if ((input[*inOutIdx] == 0x00) && (*len > 1)) {
sPymbed 16:048e5e270a58 348 (*inOutIdx)++;
sPymbed 16:048e5e270a58 349 (*len)--;
sPymbed 16:048e5e270a58 350
sPymbed 16:048e5e270a58 351 if (*len > 0 && (input[*inOutIdx] & 0x80) == 0)
sPymbed 16:048e5e270a58 352 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 353 }
sPymbed 16:048e5e270a58 354 }
sPymbed 16:048e5e270a58 355
sPymbed 16:048e5e270a58 356 return 0;
sPymbed 16:048e5e270a58 357 }
sPymbed 16:048e5e270a58 358
sPymbed 16:048e5e270a58 359 /* Get the DER/BER encoding of an ASN.1 INTEGER that has a value of no more than
sPymbed 16:048e5e270a58 360 * 7 bits.
sPymbed 16:048e5e270a58 361 *
sPymbed 16:048e5e270a58 362 * input Buffer holding DER/BER encoded data.
sPymbed 16:048e5e270a58 363 * inOutIdx Current index into buffer to parse.
sPymbed 16:048e5e270a58 364 * maxIdx Length of data in buffer.
sPymbed 16:048e5e270a58 365 * returns BUFFER_E when there is not enough data to parse.
sPymbed 16:048e5e270a58 366 * ASN_PARSE_E when the INTEGER tag is not found or length is invalid.
sPymbed 16:048e5e270a58 367 * Otherwise, the 7-bit value.
sPymbed 16:048e5e270a58 368 */
sPymbed 16:048e5e270a58 369 static int GetInteger7Bit(const byte* input, word32* inOutIdx, word32 maxIdx)
sPymbed 16:048e5e270a58 370 {
sPymbed 16:048e5e270a58 371 word32 idx = *inOutIdx;
sPymbed 16:048e5e270a58 372 byte b;
sPymbed 16:048e5e270a58 373
sPymbed 16:048e5e270a58 374 if ((idx + 3) > maxIdx)
sPymbed 16:048e5e270a58 375 return BUFFER_E;
sPymbed 16:048e5e270a58 376
sPymbed 16:048e5e270a58 377 if (input[idx++] != ASN_INTEGER)
sPymbed 16:048e5e270a58 378 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 379 if (input[idx++] != 1)
sPymbed 16:048e5e270a58 380 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 381 b = input[idx++];
sPymbed 16:048e5e270a58 382
sPymbed 16:048e5e270a58 383 *inOutIdx = idx;
sPymbed 16:048e5e270a58 384 return b;
sPymbed 16:048e5e270a58 385 }
sPymbed 16:048e5e270a58 386
sPymbed 16:048e5e270a58 387
sPymbed 16:048e5e270a58 388 #if !defined(NO_DSA) && !defined(NO_SHA)
sPymbed 16:048e5e270a58 389 static char sigSha1wDsaName[] = "SHAwDSA";
sPymbed 16:048e5e270a58 390 #endif /* NO_DSA */
sPymbed 16:048e5e270a58 391 #ifndef NO_RSA
sPymbed 16:048e5e270a58 392 #ifdef WOLFSSL_MD2
sPymbed 16:048e5e270a58 393 static char sigMd2wRsaName[] = "MD2wRSA";
sPymbed 16:048e5e270a58 394 #endif
sPymbed 16:048e5e270a58 395 #ifndef NO_MD5
sPymbed 16:048e5e270a58 396 static char sigMd5wRsaName[] = "MD5wRSA";
sPymbed 16:048e5e270a58 397 #endif
sPymbed 16:048e5e270a58 398 #ifndef NO_SHA
sPymbed 16:048e5e270a58 399 static char sigSha1wRsaName[] = "SHAwRSA";
sPymbed 16:048e5e270a58 400 #endif
sPymbed 16:048e5e270a58 401 #ifdef WOLFSSL_SHA224
sPymbed 16:048e5e270a58 402 static char sigSha224wRsaName[] = "SHA224wRSA";
sPymbed 16:048e5e270a58 403 #endif
sPymbed 16:048e5e270a58 404 #ifndef NO_SHA256
sPymbed 16:048e5e270a58 405 static char sigSha256wRsaName[] = "SHA256wRSA";
sPymbed 16:048e5e270a58 406 #endif
sPymbed 16:048e5e270a58 407 #ifdef WOLFSSL_SHA384
sPymbed 16:048e5e270a58 408 static char sigSha384wRsaName[] = "SHA384wRSA";
sPymbed 16:048e5e270a58 409 #endif
sPymbed 16:048e5e270a58 410 #ifdef WOLFSSL_SHA512
sPymbed 16:048e5e270a58 411 static char sigSha512wRsaName[] = "SHA512wRSA";
sPymbed 16:048e5e270a58 412 #endif
sPymbed 16:048e5e270a58 413 #endif /* NO_RSA */
sPymbed 16:048e5e270a58 414 #ifdef HAVE_ECC
sPymbed 16:048e5e270a58 415 #ifndef NO_SHA
sPymbed 16:048e5e270a58 416 static char sigSha1wEcdsaName[] = "SHAwECDSA";
sPymbed 16:048e5e270a58 417 #endif
sPymbed 16:048e5e270a58 418 #ifdef WOLFSSL_SHA224
sPymbed 16:048e5e270a58 419 static char sigSha224wEcdsaName[] = "SHA224wECDSA";
sPymbed 16:048e5e270a58 420 #endif
sPymbed 16:048e5e270a58 421 #ifndef NO_SHA256
sPymbed 16:048e5e270a58 422 static char sigSha256wEcdsaName[] = "SHA256wECDSA";
sPymbed 16:048e5e270a58 423 #endif
sPymbed 16:048e5e270a58 424 #ifdef WOLFSSL_SHA384
sPymbed 16:048e5e270a58 425 static char sigSha384wEcdsaName[] = "SHA384wECDSA";
sPymbed 16:048e5e270a58 426 #endif
sPymbed 16:048e5e270a58 427 #ifdef WOLFSSL_SHA512
sPymbed 16:048e5e270a58 428 static char sigSha512wEcdsaName[] = "SHA512wECDSA";
sPymbed 16:048e5e270a58 429 #endif
sPymbed 16:048e5e270a58 430 #endif /* HAVE_ECC */
sPymbed 16:048e5e270a58 431 static char sigUnknownName[] = "Unknown";
sPymbed 16:048e5e270a58 432
sPymbed 16:048e5e270a58 433
sPymbed 16:048e5e270a58 434 /* Get the human readable string for a signature type
sPymbed 16:048e5e270a58 435 *
sPymbed 16:048e5e270a58 436 * oid Oid value for signature
sPymbed 16:048e5e270a58 437 */
sPymbed 16:048e5e270a58 438 char* GetSigName(int oid) {
sPymbed 16:048e5e270a58 439 switch (oid) {
sPymbed 16:048e5e270a58 440 #if !defined(NO_DSA) && !defined(NO_SHA)
sPymbed 16:048e5e270a58 441 case CTC_SHAwDSA:
sPymbed 16:048e5e270a58 442 return sigSha1wDsaName;
sPymbed 16:048e5e270a58 443 #endif /* NO_DSA && NO_SHA */
sPymbed 16:048e5e270a58 444 #ifndef NO_RSA
sPymbed 16:048e5e270a58 445 #ifdef WOLFSSL_MD2
sPymbed 16:048e5e270a58 446 case CTC_MD2wRSA:
sPymbed 16:048e5e270a58 447 return sigMd2wRsaName;
sPymbed 16:048e5e270a58 448 #endif
sPymbed 16:048e5e270a58 449 #ifndef NO_MD5
sPymbed 16:048e5e270a58 450 case CTC_MD5wRSA:
sPymbed 16:048e5e270a58 451 return sigMd5wRsaName;
sPymbed 16:048e5e270a58 452 #endif
sPymbed 16:048e5e270a58 453 #ifndef NO_SHA
sPymbed 16:048e5e270a58 454 case CTC_SHAwRSA:
sPymbed 16:048e5e270a58 455 return sigSha1wRsaName;
sPymbed 16:048e5e270a58 456 #endif
sPymbed 16:048e5e270a58 457 #ifdef WOLFSSL_SHA224
sPymbed 16:048e5e270a58 458 case CTC_SHA224wRSA:
sPymbed 16:048e5e270a58 459 return sigSha224wRsaName;
sPymbed 16:048e5e270a58 460 #endif
sPymbed 16:048e5e270a58 461 #ifndef NO_SHA256
sPymbed 16:048e5e270a58 462 case CTC_SHA256wRSA:
sPymbed 16:048e5e270a58 463 return sigSha256wRsaName;
sPymbed 16:048e5e270a58 464 #endif
sPymbed 16:048e5e270a58 465 #ifdef WOLFSSL_SHA384
sPymbed 16:048e5e270a58 466 case CTC_SHA384wRSA:
sPymbed 16:048e5e270a58 467 return sigSha384wRsaName;
sPymbed 16:048e5e270a58 468 #endif
sPymbed 16:048e5e270a58 469 #ifdef WOLFSSL_SHA512
sPymbed 16:048e5e270a58 470 case CTC_SHA512wRSA:
sPymbed 16:048e5e270a58 471 return sigSha512wRsaName;
sPymbed 16:048e5e270a58 472 #endif
sPymbed 16:048e5e270a58 473 #endif /* NO_RSA */
sPymbed 16:048e5e270a58 474 #ifdef HAVE_ECC
sPymbed 16:048e5e270a58 475 #ifndef NO_SHA
sPymbed 16:048e5e270a58 476 case CTC_SHAwECDSA:
sPymbed 16:048e5e270a58 477 return sigSha1wEcdsaName;
sPymbed 16:048e5e270a58 478 #endif
sPymbed 16:048e5e270a58 479 #ifdef WOLFSSL_SHA224
sPymbed 16:048e5e270a58 480 case CTC_SHA224wECDSA:
sPymbed 16:048e5e270a58 481 return sigSha224wEcdsaName;
sPymbed 16:048e5e270a58 482 #endif
sPymbed 16:048e5e270a58 483 #ifndef NO_SHA256
sPymbed 16:048e5e270a58 484 case CTC_SHA256wECDSA:
sPymbed 16:048e5e270a58 485 return sigSha256wEcdsaName;
sPymbed 16:048e5e270a58 486 #endif
sPymbed 16:048e5e270a58 487 #ifdef WOLFSSL_SHA384
sPymbed 16:048e5e270a58 488 case CTC_SHA384wECDSA:
sPymbed 16:048e5e270a58 489 return sigSha384wEcdsaName;
sPymbed 16:048e5e270a58 490 #endif
sPymbed 16:048e5e270a58 491 #ifdef WOLFSSL_SHA512
sPymbed 16:048e5e270a58 492 case CTC_SHA512wECDSA:
sPymbed 16:048e5e270a58 493 return sigSha512wEcdsaName;
sPymbed 16:048e5e270a58 494 #endif
sPymbed 16:048e5e270a58 495 #endif /* HAVE_ECC */
sPymbed 16:048e5e270a58 496 default:
sPymbed 16:048e5e270a58 497 return sigUnknownName;
sPymbed 16:048e5e270a58 498 }
sPymbed 16:048e5e270a58 499 }
sPymbed 16:048e5e270a58 500
sPymbed 16:048e5e270a58 501
sPymbed 16:048e5e270a58 502 #if !defined(NO_DSA) || defined(HAVE_ECC) || \
sPymbed 16:048e5e270a58 503 (!defined(NO_RSA) && \
sPymbed 16:048e5e270a58 504 (defined(WOLFSSL_CERT_GEN) || \
sPymbed 16:048e5e270a58 505 ((defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)) && !defined(HAVE_USER_RSA))))
sPymbed 16:048e5e270a58 506 /* Set the DER/BER encoding of the ASN.1 INTEGER header.
sPymbed 16:048e5e270a58 507 *
sPymbed 16:048e5e270a58 508 * len Length of data to encode.
sPymbed 16:048e5e270a58 509 * firstByte First byte of data, most significant byte of integer, to encode.
sPymbed 16:048e5e270a58 510 * output Buffer to write into.
sPymbed 16:048e5e270a58 511 * returns the number of bytes added to the buffer.
sPymbed 16:048e5e270a58 512 */
sPymbed 16:048e5e270a58 513 static int SetASNInt(int len, byte firstByte, byte* output)
sPymbed 16:048e5e270a58 514 {
sPymbed 16:048e5e270a58 515 word32 idx = 0;
sPymbed 16:048e5e270a58 516
sPymbed 16:048e5e270a58 517 output[idx++] = ASN_INTEGER;
sPymbed 16:048e5e270a58 518 if (firstByte & 0x80)
sPymbed 16:048e5e270a58 519 len++;
sPymbed 16:048e5e270a58 520 idx += SetLength(len, output + idx);
sPymbed 16:048e5e270a58 521 if (firstByte & 0x80)
sPymbed 16:048e5e270a58 522 output[idx++] = 0x00;
sPymbed 16:048e5e270a58 523
sPymbed 16:048e5e270a58 524 return idx;
sPymbed 16:048e5e270a58 525 }
sPymbed 16:048e5e270a58 526 #endif
sPymbed 16:048e5e270a58 527
sPymbed 16:048e5e270a58 528 #if !defined(NO_DSA) || defined(HAVE_ECC) || defined(WOLFSSL_CERT_GEN) || \
sPymbed 16:048e5e270a58 529 ((defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)) && !defined(NO_RSA) && !defined(HAVE_USER_RSA))
sPymbed 16:048e5e270a58 530 /* Set the DER/BER encoding of the ASN.1 INTEGER element with an mp_int.
sPymbed 16:048e5e270a58 531 * The number is assumed to be positive.
sPymbed 16:048e5e270a58 532 *
sPymbed 16:048e5e270a58 533 * n Multi-precision integer to encode.
sPymbed 16:048e5e270a58 534 * maxSz Maximum size of the encoded integer.
sPymbed 16:048e5e270a58 535 * A negative value indicates no check of length requested.
sPymbed 16:048e5e270a58 536 * output Buffer to write into.
sPymbed 16:048e5e270a58 537 * returns BUFFER_E when the data is too long for the buffer.
sPymbed 16:048e5e270a58 538 * MP_TO_E when encoding the integer fails.
sPymbed 16:048e5e270a58 539 * Otherwise, the number of bytes added to the buffer.
sPymbed 16:048e5e270a58 540 */
sPymbed 16:048e5e270a58 541 static int SetASNIntMP(mp_int* n, int maxSz, byte* output)
sPymbed 16:048e5e270a58 542 {
sPymbed 16:048e5e270a58 543 int idx = 0;
sPymbed 16:048e5e270a58 544 int leadingBit;
sPymbed 16:048e5e270a58 545 int length;
sPymbed 16:048e5e270a58 546 int err;
sPymbed 16:048e5e270a58 547
sPymbed 16:048e5e270a58 548 leadingBit = mp_leading_bit(n);
sPymbed 16:048e5e270a58 549 length = mp_unsigned_bin_size(n);
sPymbed 16:048e5e270a58 550 idx = SetASNInt(length, leadingBit ? 0x80 : 0x00, output);
sPymbed 16:048e5e270a58 551 if (maxSz >= 0 && (idx + length) > maxSz)
sPymbed 16:048e5e270a58 552 return BUFFER_E;
sPymbed 16:048e5e270a58 553
sPymbed 16:048e5e270a58 554 err = mp_to_unsigned_bin(n, output + idx);
sPymbed 16:048e5e270a58 555 if (err != MP_OKAY)
sPymbed 16:048e5e270a58 556 return MP_TO_E;
sPymbed 16:048e5e270a58 557 idx += length;
sPymbed 16:048e5e270a58 558
sPymbed 16:048e5e270a58 559 return idx;
sPymbed 16:048e5e270a58 560 }
sPymbed 16:048e5e270a58 561 #endif
sPymbed 16:048e5e270a58 562
sPymbed 16:048e5e270a58 563 #if !defined(NO_RSA) && defined(HAVE_USER_RSA) && defined(WOLFSSL_CERT_GEN)
sPymbed 16:048e5e270a58 564 /* Set the DER/BER encoding of the ASN.1 INTEGER element with an mp_int from
sPymbed 16:048e5e270a58 565 * an RSA key.
sPymbed 16:048e5e270a58 566 * The number is assumed to be positive.
sPymbed 16:048e5e270a58 567 *
sPymbed 16:048e5e270a58 568 * n Multi-precision integer to encode.
sPymbed 16:048e5e270a58 569 * output Buffer to write into.
sPymbed 16:048e5e270a58 570 * returns BUFFER_E when the data is too long for the buffer.
sPymbed 16:048e5e270a58 571 * MP_TO_E when encoding the integer fails.
sPymbed 16:048e5e270a58 572 * Otherwise, the number of bytes added to the buffer.
sPymbed 16:048e5e270a58 573 */
sPymbed 16:048e5e270a58 574 static int SetASNIntRSA(mp_int* n, byte* output)
sPymbed 16:048e5e270a58 575 {
sPymbed 16:048e5e270a58 576 int idx = 0;
sPymbed 16:048e5e270a58 577 int leadingBit;
sPymbed 16:048e5e270a58 578 int length;
sPymbed 16:048e5e270a58 579 int err;
sPymbed 16:048e5e270a58 580
sPymbed 16:048e5e270a58 581 leadingBit = wc_Rsa_leading_bit(n);
sPymbed 16:048e5e270a58 582 length = wc_Rsa_unsigned_bin_size(n);
sPymbed 16:048e5e270a58 583 idx = SetASNInt(length, leadingBit ? 0x80 : 0x00, output);
sPymbed 16:048e5e270a58 584 if ((idx + length) > MAX_RSA_INT_SZ)
sPymbed 16:048e5e270a58 585 return BUFFER_E;
sPymbed 16:048e5e270a58 586
sPymbed 16:048e5e270a58 587 err = wc_Rsa_to_unsigned_bin(n, output + idx, length);
sPymbed 16:048e5e270a58 588 if (err != MP_OKAY)
sPymbed 16:048e5e270a58 589 return MP_TO_E;
sPymbed 16:048e5e270a58 590 idx += length;
sPymbed 16:048e5e270a58 591
sPymbed 16:048e5e270a58 592 return idx;
sPymbed 16:048e5e270a58 593 }
sPymbed 16:048e5e270a58 594 #endif /* !NO_RSA && HAVE_USER_RSA && WOLFSSL_CERT_GEN */
sPymbed 16:048e5e270a58 595
sPymbed 16:048e5e270a58 596 /* Windows header clash for WinCE using GetVersion */
sPymbed 16:048e5e270a58 597 WOLFSSL_LOCAL int GetMyVersion(const byte* input, word32* inOutIdx,
sPymbed 16:048e5e270a58 598 int* version, word32 maxIdx)
sPymbed 16:048e5e270a58 599 {
sPymbed 16:048e5e270a58 600 word32 idx = *inOutIdx;
sPymbed 16:048e5e270a58 601
sPymbed 16:048e5e270a58 602 if ((idx + MIN_VERSION_SZ) > maxIdx)
sPymbed 16:048e5e270a58 603 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 604
sPymbed 16:048e5e270a58 605 if (input[idx++] != ASN_INTEGER)
sPymbed 16:048e5e270a58 606 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 607
sPymbed 16:048e5e270a58 608 if (input[idx++] != 0x01)
sPymbed 16:048e5e270a58 609 return ASN_VERSION_E;
sPymbed 16:048e5e270a58 610
sPymbed 16:048e5e270a58 611 *version = input[idx++];
sPymbed 16:048e5e270a58 612 *inOutIdx = idx;
sPymbed 16:048e5e270a58 613
sPymbed 16:048e5e270a58 614 return *version;
sPymbed 16:048e5e270a58 615 }
sPymbed 16:048e5e270a58 616
sPymbed 16:048e5e270a58 617
sPymbed 16:048e5e270a58 618 #ifndef NO_PWDBASED
sPymbed 16:048e5e270a58 619 /* Get small count integer, 32 bits or less */
sPymbed 16:048e5e270a58 620 int GetShortInt(const byte* input, word32* inOutIdx, int* number, word32 maxIdx)
sPymbed 16:048e5e270a58 621 {
sPymbed 16:048e5e270a58 622 word32 idx = *inOutIdx;
sPymbed 16:048e5e270a58 623 word32 len;
sPymbed 16:048e5e270a58 624
sPymbed 16:048e5e270a58 625 *number = 0;
sPymbed 16:048e5e270a58 626
sPymbed 16:048e5e270a58 627 /* check for type and length bytes */
sPymbed 16:048e5e270a58 628 if ((idx + 2) > maxIdx)
sPymbed 16:048e5e270a58 629 return BUFFER_E;
sPymbed 16:048e5e270a58 630
sPymbed 16:048e5e270a58 631 if (input[idx++] != ASN_INTEGER)
sPymbed 16:048e5e270a58 632 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 633
sPymbed 16:048e5e270a58 634 len = input[idx++];
sPymbed 16:048e5e270a58 635 if (len > 4)
sPymbed 16:048e5e270a58 636 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 637
sPymbed 16:048e5e270a58 638 if (len + idx > maxIdx)
sPymbed 16:048e5e270a58 639 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 640
sPymbed 16:048e5e270a58 641 while (len--) {
sPymbed 16:048e5e270a58 642 *number = *number << 8 | input[idx++];
sPymbed 16:048e5e270a58 643 }
sPymbed 16:048e5e270a58 644
sPymbed 16:048e5e270a58 645 *inOutIdx = idx;
sPymbed 16:048e5e270a58 646
sPymbed 16:048e5e270a58 647 return *number;
sPymbed 16:048e5e270a58 648 }
sPymbed 16:048e5e270a58 649
sPymbed 16:048e5e270a58 650
sPymbed 16:048e5e270a58 651 /* Set small integer, 32 bits or less. DER encoding with no leading 0s
sPymbed 16:048e5e270a58 652 * returns total amount written including ASN tag and length byte on success */
sPymbed 16:048e5e270a58 653 static int SetShortInt(byte* input, word32* inOutIdx, word32 number,
sPymbed 16:048e5e270a58 654 word32 maxIdx)
sPymbed 16:048e5e270a58 655 {
sPymbed 16:048e5e270a58 656 word32 idx = *inOutIdx;
sPymbed 16:048e5e270a58 657 word32 len = 0;
sPymbed 16:048e5e270a58 658 int i;
sPymbed 16:048e5e270a58 659 byte ar[MAX_LENGTH_SZ];
sPymbed 16:048e5e270a58 660
sPymbed 16:048e5e270a58 661 /* check for room for type and length bytes */
sPymbed 16:048e5e270a58 662 if ((idx + 2) > maxIdx)
sPymbed 16:048e5e270a58 663 return BUFFER_E;
sPymbed 16:048e5e270a58 664
sPymbed 16:048e5e270a58 665 input[idx++] = ASN_INTEGER;
sPymbed 16:048e5e270a58 666 idx++; /* place holder for length byte */
sPymbed 16:048e5e270a58 667 if (MAX_LENGTH_SZ + idx > maxIdx)
sPymbed 16:048e5e270a58 668 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 669
sPymbed 16:048e5e270a58 670 /* find first non zero byte */
sPymbed 16:048e5e270a58 671 XMEMSET(ar, 0, MAX_LENGTH_SZ);
sPymbed 16:048e5e270a58 672 c32toa(number, ar);
sPymbed 16:048e5e270a58 673 for (i = 0; i < MAX_LENGTH_SZ; i++) {
sPymbed 16:048e5e270a58 674 if (ar[i] != 0) {
sPymbed 16:048e5e270a58 675 break;
sPymbed 16:048e5e270a58 676 }
sPymbed 16:048e5e270a58 677 }
sPymbed 16:048e5e270a58 678
sPymbed 16:048e5e270a58 679 /* handle case of 0 */
sPymbed 16:048e5e270a58 680 if (i == MAX_LENGTH_SZ) {
sPymbed 16:048e5e270a58 681 input[idx++] = 0; len++;
sPymbed 16:048e5e270a58 682 }
sPymbed 16:048e5e270a58 683
sPymbed 16:048e5e270a58 684 for (; i < MAX_LENGTH_SZ && idx < maxIdx; i++) {
sPymbed 16:048e5e270a58 685 input[idx++] = ar[i]; len++;
sPymbed 16:048e5e270a58 686 }
sPymbed 16:048e5e270a58 687
sPymbed 16:048e5e270a58 688 /* jump back to beginning of input buffer using unaltered inOutIdx value
sPymbed 16:048e5e270a58 689 * and set number of bytes for integer, then update the index value */
sPymbed 16:048e5e270a58 690 input[*inOutIdx + 1] = (byte)len;
sPymbed 16:048e5e270a58 691 *inOutIdx = idx;
sPymbed 16:048e5e270a58 692
sPymbed 16:048e5e270a58 693 return len + 2; /* size of integer bytes plus ASN TAG and length byte */
sPymbed 16:048e5e270a58 694 }
sPymbed 16:048e5e270a58 695 #endif /* !NO_PWDBASED */
sPymbed 16:048e5e270a58 696
sPymbed 16:048e5e270a58 697 /* May not have one, not an error */
sPymbed 16:048e5e270a58 698 static int GetExplicitVersion(const byte* input, word32* inOutIdx, int* version,
sPymbed 16:048e5e270a58 699 word32 maxIdx)
sPymbed 16:048e5e270a58 700 {
sPymbed 16:048e5e270a58 701 word32 idx = *inOutIdx;
sPymbed 16:048e5e270a58 702
sPymbed 16:048e5e270a58 703 WOLFSSL_ENTER("GetExplicitVersion");
sPymbed 16:048e5e270a58 704
sPymbed 16:048e5e270a58 705 if ((idx + 1) > maxIdx)
sPymbed 16:048e5e270a58 706 return BUFFER_E;
sPymbed 16:048e5e270a58 707
sPymbed 16:048e5e270a58 708 if (input[idx++] == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) {
sPymbed 16:048e5e270a58 709 *inOutIdx = ++idx; /* skip header */
sPymbed 16:048e5e270a58 710 return GetMyVersion(input, inOutIdx, version, maxIdx);
sPymbed 16:048e5e270a58 711 }
sPymbed 16:048e5e270a58 712
sPymbed 16:048e5e270a58 713 /* go back as is */
sPymbed 16:048e5e270a58 714 *version = 0;
sPymbed 16:048e5e270a58 715
sPymbed 16:048e5e270a58 716 return 0;
sPymbed 16:048e5e270a58 717 }
sPymbed 16:048e5e270a58 718
sPymbed 16:048e5e270a58 719 int GetInt(mp_int* mpi, const byte* input, word32* inOutIdx, word32 maxIdx)
sPymbed 16:048e5e270a58 720 {
sPymbed 16:048e5e270a58 721 word32 idx = *inOutIdx;
sPymbed 16:048e5e270a58 722 int ret;
sPymbed 16:048e5e270a58 723 int length;
sPymbed 16:048e5e270a58 724
sPymbed 16:048e5e270a58 725 ret = GetASNInt(input, &idx, &length, maxIdx);
sPymbed 16:048e5e270a58 726 if (ret != 0)
sPymbed 16:048e5e270a58 727 return ret;
sPymbed 16:048e5e270a58 728
sPymbed 16:048e5e270a58 729 if (mp_init(mpi) != MP_OKAY)
sPymbed 16:048e5e270a58 730 return MP_INIT_E;
sPymbed 16:048e5e270a58 731
sPymbed 16:048e5e270a58 732 if (mp_read_unsigned_bin(mpi, (byte*)input + idx, length) != 0) {
sPymbed 16:048e5e270a58 733 mp_clear(mpi);
sPymbed 16:048e5e270a58 734 return ASN_GETINT_E;
sPymbed 16:048e5e270a58 735 }
sPymbed 16:048e5e270a58 736
sPymbed 16:048e5e270a58 737 #ifdef HAVE_WOLF_BIGINT
sPymbed 16:048e5e270a58 738 if (wc_bigint_from_unsigned_bin(&mpi->raw, input + idx, length) != 0) {
sPymbed 16:048e5e270a58 739 mp_clear(mpi);
sPymbed 16:048e5e270a58 740 return ASN_GETINT_E;
sPymbed 16:048e5e270a58 741 }
sPymbed 16:048e5e270a58 742 #endif /* HAVE_WOLF_BIGINT */
sPymbed 16:048e5e270a58 743
sPymbed 16:048e5e270a58 744 *inOutIdx = idx + length;
sPymbed 16:048e5e270a58 745
sPymbed 16:048e5e270a58 746 return 0;
sPymbed 16:048e5e270a58 747 }
sPymbed 16:048e5e270a58 748
sPymbed 16:048e5e270a58 749 #if !defined(WOLFSSL_KEY_GEN) && !defined(OPENSSL_EXTRA) && defined(RSA_LOW_MEM)
sPymbed 16:048e5e270a58 750 #if !defined(NO_RSA) && !defined(HAVE_USER_RSA)
sPymbed 16:048e5e270a58 751 static int SkipInt(const byte* input, word32* inOutIdx, word32 maxIdx)
sPymbed 16:048e5e270a58 752 {
sPymbed 16:048e5e270a58 753 word32 idx = *inOutIdx;
sPymbed 16:048e5e270a58 754 int ret;
sPymbed 16:048e5e270a58 755 int length;
sPymbed 16:048e5e270a58 756
sPymbed 16:048e5e270a58 757 ret = GetASNInt(input, &idx, &length, maxIdx);
sPymbed 16:048e5e270a58 758 if (ret != 0)
sPymbed 16:048e5e270a58 759 return ret;
sPymbed 16:048e5e270a58 760
sPymbed 16:048e5e270a58 761 *inOutIdx = idx + length;
sPymbed 16:048e5e270a58 762
sPymbed 16:048e5e270a58 763 return 0;
sPymbed 16:048e5e270a58 764 }
sPymbed 16:048e5e270a58 765 #endif
sPymbed 16:048e5e270a58 766 #endif
sPymbed 16:048e5e270a58 767
sPymbed 16:048e5e270a58 768 static int CheckBitString(const byte* input, word32* inOutIdx, int* len,
sPymbed 16:048e5e270a58 769 word32 maxIdx, int zeroBits, byte* unusedBits)
sPymbed 16:048e5e270a58 770 {
sPymbed 16:048e5e270a58 771 word32 idx = *inOutIdx;
sPymbed 16:048e5e270a58 772 int length;
sPymbed 16:048e5e270a58 773 byte b;
sPymbed 16:048e5e270a58 774
sPymbed 16:048e5e270a58 775 if ((idx + 1) > maxIdx)
sPymbed 16:048e5e270a58 776 return BUFFER_E;
sPymbed 16:048e5e270a58 777
sPymbed 16:048e5e270a58 778 if (input[idx++] != ASN_BIT_STRING)
sPymbed 16:048e5e270a58 779 return ASN_BITSTR_E;
sPymbed 16:048e5e270a58 780
sPymbed 16:048e5e270a58 781 if (GetLength(input, &idx, &length, maxIdx) < 0)
sPymbed 16:048e5e270a58 782 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 783
sPymbed 16:048e5e270a58 784 /* extra sanity check that length is greater than 0 */
sPymbed 16:048e5e270a58 785 if (length <= 0) {
sPymbed 16:048e5e270a58 786 WOLFSSL_MSG("Error length was 0 in CheckBitString");
sPymbed 16:048e5e270a58 787 return BUFFER_E;
sPymbed 16:048e5e270a58 788 }
sPymbed 16:048e5e270a58 789
sPymbed 16:048e5e270a58 790 if (idx + 1 > maxIdx) {
sPymbed 16:048e5e270a58 791 WOLFSSL_MSG("Attempted buffer read larger than input buffer");
sPymbed 16:048e5e270a58 792 return BUFFER_E;
sPymbed 16:048e5e270a58 793 }
sPymbed 16:048e5e270a58 794
sPymbed 16:048e5e270a58 795 b = input[idx];
sPymbed 16:048e5e270a58 796 if (zeroBits && b != 0x00)
sPymbed 16:048e5e270a58 797 return ASN_EXPECT_0_E;
sPymbed 16:048e5e270a58 798 if (b >= 0x08)
sPymbed 16:048e5e270a58 799 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 800 if (b != 0) {
sPymbed 16:048e5e270a58 801 if ((byte)(input[idx + length - 1] << (8 - b)) != 0)
sPymbed 16:048e5e270a58 802 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 803 }
sPymbed 16:048e5e270a58 804 idx++;
sPymbed 16:048e5e270a58 805 length--; /* length has been checked for greater than 0 */
sPymbed 16:048e5e270a58 806
sPymbed 16:048e5e270a58 807 *inOutIdx = idx;
sPymbed 16:048e5e270a58 808 if (len != NULL)
sPymbed 16:048e5e270a58 809 *len = length;
sPymbed 16:048e5e270a58 810 if (unusedBits != NULL)
sPymbed 16:048e5e270a58 811 *unusedBits = b;
sPymbed 16:048e5e270a58 812
sPymbed 16:048e5e270a58 813 return 0;
sPymbed 16:048e5e270a58 814 }
sPymbed 16:048e5e270a58 815
sPymbed 16:048e5e270a58 816 /* RSA (with CertGen or KeyGen) OR ECC OR ED25519 (with CertGen or KeyGen) */
sPymbed 16:048e5e270a58 817 #if (!defined(NO_RSA) && !defined(HAVE_USER_RSA) && \
sPymbed 16:048e5e270a58 818 (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA))) || \
sPymbed 16:048e5e270a58 819 defined(HAVE_ECC) || \
sPymbed 16:048e5e270a58 820 (defined(HAVE_ED25519) && \
sPymbed 16:048e5e270a58 821 (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)))
sPymbed 16:048e5e270a58 822
sPymbed 16:048e5e270a58 823 /* Set the DER/BER encoding of the ASN.1 BIT_STRING header.
sPymbed 16:048e5e270a58 824 *
sPymbed 16:048e5e270a58 825 * len Length of data to encode.
sPymbed 16:048e5e270a58 826 * unusedBits The number of unused bits in the last byte of data.
sPymbed 16:048e5e270a58 827 * That is, the number of least significant zero bits before a one.
sPymbed 16:048e5e270a58 828 * The last byte is the most-significant non-zero byte of a number.
sPymbed 16:048e5e270a58 829 * output Buffer to write into.
sPymbed 16:048e5e270a58 830 * returns the number of bytes added to the buffer.
sPymbed 16:048e5e270a58 831 */
sPymbed 16:048e5e270a58 832 static word32 SetBitString(word32 len, byte unusedBits, byte* output)
sPymbed 16:048e5e270a58 833 {
sPymbed 16:048e5e270a58 834 word32 idx = 0;
sPymbed 16:048e5e270a58 835
sPymbed 16:048e5e270a58 836 output[idx++] = ASN_BIT_STRING;
sPymbed 16:048e5e270a58 837 idx += SetLength(len + 1, output + idx);
sPymbed 16:048e5e270a58 838 output[idx++] = unusedBits;
sPymbed 16:048e5e270a58 839
sPymbed 16:048e5e270a58 840 return idx;
sPymbed 16:048e5e270a58 841 }
sPymbed 16:048e5e270a58 842 #endif /* !NO_RSA || HAVE_ECC || HAVE_ED25519 */
sPymbed 16:048e5e270a58 843
sPymbed 16:048e5e270a58 844 #ifdef ASN_BER_TO_DER
sPymbed 16:048e5e270a58 845 /* Convert a BER encoding with indefinite length items to DER.
sPymbed 16:048e5e270a58 846 *
sPymbed 16:048e5e270a58 847 * ber BER encoded data.
sPymbed 16:048e5e270a58 848 * berSz Length of BER encoded data.
sPymbed 16:048e5e270a58 849 * der Buffer to hold DER encoded version of data.
sPymbed 16:048e5e270a58 850 * NULL indicates only the length is required.
sPymbed 16:048e5e270a58 851 * derSz The size of the buffer to hold the DER encoded data.
sPymbed 16:048e5e270a58 852 * Will be set if der is NULL, otherwise the value is checked as der is
sPymbed 16:048e5e270a58 853 * filled.
sPymbed 16:048e5e270a58 854 * returns ASN_PARSE_E if the BER data is invalid and BAD_FUNC_ARG if ber or
sPymbed 16:048e5e270a58 855 * derSz are NULL.
sPymbed 16:048e5e270a58 856 */
sPymbed 16:048e5e270a58 857 int wc_BerToDer(const byte* ber, word32 berSz, byte* der, word32* derSz)
sPymbed 16:048e5e270a58 858 {
sPymbed 16:048e5e270a58 859 int ret;
sPymbed 16:048e5e270a58 860 word32 i, j, k;
sPymbed 16:048e5e270a58 861 int len, l;
sPymbed 16:048e5e270a58 862 int indef;
sPymbed 16:048e5e270a58 863 int depth = 0;
sPymbed 16:048e5e270a58 864 byte type;
sPymbed 16:048e5e270a58 865 word32 cnt, sz;
sPymbed 16:048e5e270a58 866 word32 outSz;
sPymbed 16:048e5e270a58 867 byte lenBytes[4];
sPymbed 16:048e5e270a58 868
sPymbed 16:048e5e270a58 869 if (ber == NULL || derSz == NULL)
sPymbed 16:048e5e270a58 870 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 871
sPymbed 16:048e5e270a58 872 outSz = *derSz;
sPymbed 16:048e5e270a58 873
sPymbed 16:048e5e270a58 874 for (i = 0, j = 0; i < berSz; ) {
sPymbed 16:048e5e270a58 875 /* Check that there is data for an ASN item to parse. */
sPymbed 16:048e5e270a58 876 if (i + 2 > berSz)
sPymbed 16:048e5e270a58 877 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 878
sPymbed 16:048e5e270a58 879 /* End Of Content (EOC) mark end of indefinite length items.
sPymbed 16:048e5e270a58 880 * EOCs are not encoded in DER.
sPymbed 16:048e5e270a58 881 * Keep track of no. indefinite length items that have not been
sPymbed 16:048e5e270a58 882 * terminated in depth.
sPymbed 16:048e5e270a58 883 */
sPymbed 16:048e5e270a58 884 if (ber[i] == 0 && ber[i+1] == 0) {
sPymbed 16:048e5e270a58 885 if (depth == 0)
sPymbed 16:048e5e270a58 886 break;
sPymbed 16:048e5e270a58 887 if (--depth == 0)
sPymbed 16:048e5e270a58 888 break;
sPymbed 16:048e5e270a58 889
sPymbed 16:048e5e270a58 890 i += 2;
sPymbed 16:048e5e270a58 891 continue;
sPymbed 16:048e5e270a58 892 }
sPymbed 16:048e5e270a58 893
sPymbed 16:048e5e270a58 894 /* Indefinite length is encoded as: 0x80 */
sPymbed 16:048e5e270a58 895 type = ber[i];
sPymbed 16:048e5e270a58 896 indef = ber[i+1] == ASN_INDEF_LENGTH;
sPymbed 16:048e5e270a58 897 if (indef && (type & 0xC0) == 0 &&
sPymbed 16:048e5e270a58 898 ber[i] != (ASN_SEQUENCE | ASN_CONSTRUCTED) &&
sPymbed 16:048e5e270a58 899 ber[i] != (ASN_SET | ASN_CONSTRUCTED)) {
sPymbed 16:048e5e270a58 900 /* Indefinite length OCTET STRING or other simple type.
sPymbed 16:048e5e270a58 901 * Put all the data into one entry.
sPymbed 16:048e5e270a58 902 */
sPymbed 16:048e5e270a58 903
sPymbed 16:048e5e270a58 904 /* Type no longer constructed. */
sPymbed 16:048e5e270a58 905 type &= ~ASN_CONSTRUCTED;
sPymbed 16:048e5e270a58 906 if (der != NULL) {
sPymbed 16:048e5e270a58 907 /* Ensure space for type. */
sPymbed 16:048e5e270a58 908 if (j + 1 >= outSz)
sPymbed 16:048e5e270a58 909 return BUFFER_E;
sPymbed 16:048e5e270a58 910 der[j] = type;
sPymbed 16:048e5e270a58 911 }
sPymbed 16:048e5e270a58 912 i++; j++;
sPymbed 16:048e5e270a58 913 /* Skip indefinite length. */
sPymbed 16:048e5e270a58 914 i++;
sPymbed 16:048e5e270a58 915
sPymbed 16:048e5e270a58 916 /* There must be further ASN1 items to combine. */
sPymbed 16:048e5e270a58 917 if (i + 2 > berSz)
sPymbed 16:048e5e270a58 918 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 919
sPymbed 16:048e5e270a58 920 /* Calculate length of combined data. */
sPymbed 16:048e5e270a58 921 len = 0;
sPymbed 16:048e5e270a58 922 k = i;
sPymbed 16:048e5e270a58 923 while (ber[k] != 0x00) {
sPymbed 16:048e5e270a58 924 /* Each ASN item must be the same type as the constructed. */
sPymbed 16:048e5e270a58 925 if (ber[k] != type)
sPymbed 16:048e5e270a58 926 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 927 k++;
sPymbed 16:048e5e270a58 928
sPymbed 16:048e5e270a58 929 ret = GetLength(ber, &k, &l, berSz);
sPymbed 16:048e5e270a58 930 if (ret < 0)
sPymbed 16:048e5e270a58 931 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 932 k += l;
sPymbed 16:048e5e270a58 933 len += l;
sPymbed 16:048e5e270a58 934
sPymbed 16:048e5e270a58 935 /* Must at least have terminating EOC. */
sPymbed 16:048e5e270a58 936 if (k + 2 > berSz)
sPymbed 16:048e5e270a58 937 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 938 }
sPymbed 16:048e5e270a58 939 /* Ensure a valid EOC ASN item. */
sPymbed 16:048e5e270a58 940 if (ber[k+1] != 0x00)
sPymbed 16:048e5e270a58 941 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 942
sPymbed 16:048e5e270a58 943 if (der == NULL) {
sPymbed 16:048e5e270a58 944 /* Add length of ASN item length encoding and data. */
sPymbed 16:048e5e270a58 945 j += SetLength(len, lenBytes);
sPymbed 16:048e5e270a58 946 j += len;
sPymbed 16:048e5e270a58 947 }
sPymbed 16:048e5e270a58 948 else {
sPymbed 16:048e5e270a58 949 /* Check space for encoded length. */
sPymbed 16:048e5e270a58 950 if (SetLength(len, lenBytes) > outSz - j)
sPymbed 16:048e5e270a58 951 return BUFFER_E;
sPymbed 16:048e5e270a58 952 /* Encode new length. */
sPymbed 16:048e5e270a58 953 j += SetLength(len, der + j);
sPymbed 16:048e5e270a58 954
sPymbed 16:048e5e270a58 955 /* Encode data in single item. */
sPymbed 16:048e5e270a58 956 k = i;
sPymbed 16:048e5e270a58 957 while (ber[k] != 0x00) {
sPymbed 16:048e5e270a58 958 /* Skip ASN type. */
sPymbed 16:048e5e270a58 959 k++;
sPymbed 16:048e5e270a58 960
sPymbed 16:048e5e270a58 961 /* Find length of data in ASN item. */
sPymbed 16:048e5e270a58 962 ret = GetLength(ber, &k, &l, berSz);
sPymbed 16:048e5e270a58 963 if (ret < 0)
sPymbed 16:048e5e270a58 964 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 965
sPymbed 16:048e5e270a58 966 /* Ensure space for data and copy in. */
sPymbed 16:048e5e270a58 967 if (j + l > outSz)
sPymbed 16:048e5e270a58 968 return BUFFER_E;
sPymbed 16:048e5e270a58 969 XMEMCPY(der + j, ber + k, l);
sPymbed 16:048e5e270a58 970 k += l; j += l;
sPymbed 16:048e5e270a58 971 }
sPymbed 16:048e5e270a58 972 }
sPymbed 16:048e5e270a58 973 /* Continue conversion after EOC. */
sPymbed 16:048e5e270a58 974 i = k + 2;
sPymbed 16:048e5e270a58 975
sPymbed 16:048e5e270a58 976 continue;
sPymbed 16:048e5e270a58 977 }
sPymbed 16:048e5e270a58 978
sPymbed 16:048e5e270a58 979 if (der != NULL) {
sPymbed 16:048e5e270a58 980 /* Ensure space for type and at least one byte of length. */
sPymbed 16:048e5e270a58 981 if (j + 1 >= outSz)
sPymbed 16:048e5e270a58 982 return BUFFER_E;
sPymbed 16:048e5e270a58 983 /* Put in type. */
sPymbed 16:048e5e270a58 984 der[j] = ber[i];
sPymbed 16:048e5e270a58 985 }
sPymbed 16:048e5e270a58 986 i++; j++;
sPymbed 16:048e5e270a58 987
sPymbed 16:048e5e270a58 988 if (indef) {
sPymbed 16:048e5e270a58 989 /* Skip indefinite length. */
sPymbed 16:048e5e270a58 990 i++;
sPymbed 16:048e5e270a58 991 /* Calculate the size of the data inside constructed. */
sPymbed 16:048e5e270a58 992 ret = wc_BerToDer(ber + i, berSz - i, NULL, &sz);
sPymbed 16:048e5e270a58 993 if (ret != LENGTH_ONLY_E)
sPymbed 16:048e5e270a58 994 return ret;
sPymbed 16:048e5e270a58 995
sPymbed 16:048e5e270a58 996 if (der != NULL) {
sPymbed 16:048e5e270a58 997 /* Ensure space for encoded length. */
sPymbed 16:048e5e270a58 998 if (SetLength(sz, lenBytes) > outSz - j)
sPymbed 16:048e5e270a58 999 return BUFFER_E;
sPymbed 16:048e5e270a58 1000 /* Encode real length. */
sPymbed 16:048e5e270a58 1001 j += SetLength(sz, der + j);
sPymbed 16:048e5e270a58 1002 }
sPymbed 16:048e5e270a58 1003 else {
sPymbed 16:048e5e270a58 1004 /* Add size of encoded length. */
sPymbed 16:048e5e270a58 1005 j += SetLength(sz, lenBytes);
sPymbed 16:048e5e270a58 1006 }
sPymbed 16:048e5e270a58 1007
sPymbed 16:048e5e270a58 1008 /* Another EOC to find. */
sPymbed 16:048e5e270a58 1009 depth++;
sPymbed 16:048e5e270a58 1010 }
sPymbed 16:048e5e270a58 1011 else {
sPymbed 16:048e5e270a58 1012 /* Get the size of the encode length and length value. */
sPymbed 16:048e5e270a58 1013 cnt = i;
sPymbed 16:048e5e270a58 1014 ret = GetLength(ber, &cnt, &len, berSz);
sPymbed 16:048e5e270a58 1015 if (ret < 0)
sPymbed 16:048e5e270a58 1016 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 1017 cnt -= i;
sPymbed 16:048e5e270a58 1018
sPymbed 16:048e5e270a58 1019 /* Check there is enough data to copy out. */
sPymbed 16:048e5e270a58 1020 if (i + cnt + len > berSz)
sPymbed 16:048e5e270a58 1021 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 1022
sPymbed 16:048e5e270a58 1023 if (der != NULL) {
sPymbed 16:048e5e270a58 1024 /* Ensure space in DER buffer. */
sPymbed 16:048e5e270a58 1025 if (j + cnt + len > outSz)
sPymbed 16:048e5e270a58 1026 return BUFFER_E;
sPymbed 16:048e5e270a58 1027 /* Copy length and data into DER buffer. */
sPymbed 16:048e5e270a58 1028 XMEMCPY(der + j, ber + i, cnt + len);
sPymbed 16:048e5e270a58 1029 }
sPymbed 16:048e5e270a58 1030 /* Continue conversion after this ASN item. */
sPymbed 16:048e5e270a58 1031 i += cnt + len;
sPymbed 16:048e5e270a58 1032 j += cnt + len;
sPymbed 16:048e5e270a58 1033 }
sPymbed 16:048e5e270a58 1034 }
sPymbed 16:048e5e270a58 1035
sPymbed 16:048e5e270a58 1036 if (depth >= 1)
sPymbed 16:048e5e270a58 1037 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 1038
sPymbed 16:048e5e270a58 1039 /* Return length if no buffer to write to. */
sPymbed 16:048e5e270a58 1040 if (der == NULL) {
sPymbed 16:048e5e270a58 1041 *derSz = j;
sPymbed 16:048e5e270a58 1042 return LENGTH_ONLY_E;
sPymbed 16:048e5e270a58 1043 }
sPymbed 16:048e5e270a58 1044
sPymbed 16:048e5e270a58 1045 return 0;
sPymbed 16:048e5e270a58 1046 }
sPymbed 16:048e5e270a58 1047 #endif
sPymbed 16:048e5e270a58 1048
sPymbed 16:048e5e270a58 1049 #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN)
sPymbed 16:048e5e270a58 1050
sPymbed 16:048e5e270a58 1051 #if (!defined(NO_RSA) && !defined(HAVE_USER_RSA)) || \
sPymbed 16:048e5e270a58 1052 defined(HAVE_ECC) || defined(HAVE_ED25519)
sPymbed 16:048e5e270a58 1053
sPymbed 16:048e5e270a58 1054 #ifdef WOLFSSL_CERT_EXT
sPymbed 16:048e5e270a58 1055 /* Set the DER/BER encoding of the ASN.1 BIT_STRING with a 16-bit value.
sPymbed 16:048e5e270a58 1056 *
sPymbed 16:048e5e270a58 1057 * val 16-bit value to encode.
sPymbed 16:048e5e270a58 1058 * output Buffer to write into.
sPymbed 16:048e5e270a58 1059 * returns the number of bytes added to the buffer.
sPymbed 16:048e5e270a58 1060 */
sPymbed 16:048e5e270a58 1061 static word32 SetBitString16Bit(word16 val, byte* output)
sPymbed 16:048e5e270a58 1062 {
sPymbed 16:048e5e270a58 1063 word32 idx;
sPymbed 16:048e5e270a58 1064 int len;
sPymbed 16:048e5e270a58 1065 byte lastByte;
sPymbed 16:048e5e270a58 1066 byte unusedBits = 0;
sPymbed 16:048e5e270a58 1067
sPymbed 16:048e5e270a58 1068 if ((val >> 8) != 0) {
sPymbed 16:048e5e270a58 1069 len = 2;
sPymbed 16:048e5e270a58 1070 lastByte = (byte)(val >> 8);
sPymbed 16:048e5e270a58 1071 }
sPymbed 16:048e5e270a58 1072 else {
sPymbed 16:048e5e270a58 1073 len = 1;
sPymbed 16:048e5e270a58 1074 lastByte = (byte)val;
sPymbed 16:048e5e270a58 1075 }
sPymbed 16:048e5e270a58 1076
sPymbed 16:048e5e270a58 1077 while (((lastByte >> unusedBits) & 0x01) == 0x00)
sPymbed 16:048e5e270a58 1078 unusedBits++;
sPymbed 16:048e5e270a58 1079
sPymbed 16:048e5e270a58 1080 idx = SetBitString(len, unusedBits, output);
sPymbed 16:048e5e270a58 1081 output[idx++] = (byte)val;
sPymbed 16:048e5e270a58 1082 if (len > 1)
sPymbed 16:048e5e270a58 1083 output[idx++] = (byte)(val >> 8);
sPymbed 16:048e5e270a58 1084
sPymbed 16:048e5e270a58 1085 return idx;
sPymbed 16:048e5e270a58 1086 }
sPymbed 16:048e5e270a58 1087 #endif /* WOLFSSL_CERT_EXT */
sPymbed 16:048e5e270a58 1088 #endif /* !NO_RSA || HAVE_ECC || HAVE_ED25519 */
sPymbed 16:048e5e270a58 1089 #endif /* WOLFSSL_CERT_GEN || WOLFSSL_KEY_GEN */
sPymbed 16:048e5e270a58 1090
sPymbed 16:048e5e270a58 1091
sPymbed 16:048e5e270a58 1092
sPymbed 16:048e5e270a58 1093 /* hashType */
sPymbed 16:048e5e270a58 1094 #ifdef WOLFSSL_MD2
sPymbed 16:048e5e270a58 1095 static const byte hashMd2hOid[] = {42, 134, 72, 134, 247, 13, 2, 2};
sPymbed 16:048e5e270a58 1096 #endif
sPymbed 16:048e5e270a58 1097 #ifndef NO_MD5
sPymbed 16:048e5e270a58 1098 static const byte hashMd5hOid[] = {42, 134, 72, 134, 247, 13, 2, 5};
sPymbed 16:048e5e270a58 1099 #endif
sPymbed 16:048e5e270a58 1100 #ifndef NO_SHA
sPymbed 16:048e5e270a58 1101 static const byte hashSha1hOid[] = {43, 14, 3, 2, 26};
sPymbed 16:048e5e270a58 1102 #endif
sPymbed 16:048e5e270a58 1103 #ifdef WOLFSSL_SHA224
sPymbed 16:048e5e270a58 1104 static const byte hashSha224hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 4};
sPymbed 16:048e5e270a58 1105 #endif
sPymbed 16:048e5e270a58 1106 #ifndef NO_SHA256
sPymbed 16:048e5e270a58 1107 static const byte hashSha256hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 1};
sPymbed 16:048e5e270a58 1108 #endif
sPymbed 16:048e5e270a58 1109 #ifdef WOLFSSL_SHA384
sPymbed 16:048e5e270a58 1110 static const byte hashSha384hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 2};
sPymbed 16:048e5e270a58 1111 #endif
sPymbed 16:048e5e270a58 1112 #ifdef WOLFSSL_SHA512
sPymbed 16:048e5e270a58 1113 static const byte hashSha512hOid[] = {96, 134, 72, 1, 101, 3, 4, 2, 3};
sPymbed 16:048e5e270a58 1114 #endif
sPymbed 16:048e5e270a58 1115
sPymbed 16:048e5e270a58 1116 /* hmacType */
sPymbed 16:048e5e270a58 1117 #ifndef NO_HMAC
sPymbed 16:048e5e270a58 1118 #ifdef WOLFSSL_SHA224
sPymbed 16:048e5e270a58 1119 static const byte hmacSha224Oid[] = {42, 134, 72, 134, 247, 13, 2, 8};
sPymbed 16:048e5e270a58 1120 #endif
sPymbed 16:048e5e270a58 1121 #ifndef NO_SHA256
sPymbed 16:048e5e270a58 1122 static const byte hmacSha256Oid[] = {42, 134, 72, 134, 247, 13, 2, 9};
sPymbed 16:048e5e270a58 1123 #endif
sPymbed 16:048e5e270a58 1124 #ifdef WOLFSSL_SHA384
sPymbed 16:048e5e270a58 1125 static const byte hmacSha384Oid[] = {42, 134, 72, 134, 247, 13, 2, 10};
sPymbed 16:048e5e270a58 1126 #endif
sPymbed 16:048e5e270a58 1127 #ifdef WOLFSSL_SHA512
sPymbed 16:048e5e270a58 1128 static const byte hmacSha512Oid[] = {42, 134, 72, 134, 247, 13, 2, 11};
sPymbed 16:048e5e270a58 1129 #endif
sPymbed 16:048e5e270a58 1130 #endif
sPymbed 16:048e5e270a58 1131
sPymbed 16:048e5e270a58 1132 /* sigType */
sPymbed 16:048e5e270a58 1133 #if !defined(NO_DSA) && !defined(NO_SHA)
sPymbed 16:048e5e270a58 1134 static const byte sigSha1wDsaOid[] = {42, 134, 72, 206, 56, 4, 3};
sPymbed 16:048e5e270a58 1135 #endif /* NO_DSA */
sPymbed 16:048e5e270a58 1136 #ifndef NO_RSA
sPymbed 16:048e5e270a58 1137 #ifdef WOLFSSL_MD2
sPymbed 16:048e5e270a58 1138 static const byte sigMd2wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1, 2};
sPymbed 16:048e5e270a58 1139 #endif
sPymbed 16:048e5e270a58 1140 #ifndef NO_MD5
sPymbed 16:048e5e270a58 1141 static const byte sigMd5wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1, 4};
sPymbed 16:048e5e270a58 1142 #endif
sPymbed 16:048e5e270a58 1143 #ifndef NO_SHA
sPymbed 16:048e5e270a58 1144 static const byte sigSha1wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1, 5};
sPymbed 16:048e5e270a58 1145 #endif
sPymbed 16:048e5e270a58 1146 #ifdef WOLFSSL_SHA224
sPymbed 16:048e5e270a58 1147 static const byte sigSha224wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1,14};
sPymbed 16:048e5e270a58 1148 #endif
sPymbed 16:048e5e270a58 1149 #ifndef NO_SHA256
sPymbed 16:048e5e270a58 1150 static const byte sigSha256wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1,11};
sPymbed 16:048e5e270a58 1151 #endif
sPymbed 16:048e5e270a58 1152 #ifdef WOLFSSL_SHA384
sPymbed 16:048e5e270a58 1153 static const byte sigSha384wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1,12};
sPymbed 16:048e5e270a58 1154 #endif
sPymbed 16:048e5e270a58 1155 #ifdef WOLFSSL_SHA512
sPymbed 16:048e5e270a58 1156 static const byte sigSha512wRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1,13};
sPymbed 16:048e5e270a58 1157 #endif
sPymbed 16:048e5e270a58 1158 #endif /* NO_RSA */
sPymbed 16:048e5e270a58 1159 #ifdef HAVE_ECC
sPymbed 16:048e5e270a58 1160 #ifndef NO_SHA
sPymbed 16:048e5e270a58 1161 static const byte sigSha1wEcdsaOid[] = {42, 134, 72, 206, 61, 4, 1};
sPymbed 16:048e5e270a58 1162 #endif
sPymbed 16:048e5e270a58 1163 #ifdef WOLFSSL_SHA224
sPymbed 16:048e5e270a58 1164 static const byte sigSha224wEcdsaOid[] = {42, 134, 72, 206, 61, 4, 3, 1};
sPymbed 16:048e5e270a58 1165 #endif
sPymbed 16:048e5e270a58 1166 #ifndef NO_SHA256
sPymbed 16:048e5e270a58 1167 static const byte sigSha256wEcdsaOid[] = {42, 134, 72, 206, 61, 4, 3, 2};
sPymbed 16:048e5e270a58 1168 #endif
sPymbed 16:048e5e270a58 1169 #ifdef WOLFSSL_SHA384
sPymbed 16:048e5e270a58 1170 static const byte sigSha384wEcdsaOid[] = {42, 134, 72, 206, 61, 4, 3, 3};
sPymbed 16:048e5e270a58 1171 #endif
sPymbed 16:048e5e270a58 1172 #ifdef WOLFSSL_SHA512
sPymbed 16:048e5e270a58 1173 static const byte sigSha512wEcdsaOid[] = {42, 134, 72, 206, 61, 4, 3, 4};
sPymbed 16:048e5e270a58 1174 #endif
sPymbed 16:048e5e270a58 1175 #endif /* HAVE_ECC */
sPymbed 16:048e5e270a58 1176 #ifdef HAVE_ED25519
sPymbed 16:048e5e270a58 1177 static const byte sigEd25519Oid[] = {43, 101, 112};
sPymbed 16:048e5e270a58 1178 #endif /* HAVE_ED25519 */
sPymbed 16:048e5e270a58 1179
sPymbed 16:048e5e270a58 1180 /* keyType */
sPymbed 16:048e5e270a58 1181 #ifndef NO_DSA
sPymbed 16:048e5e270a58 1182 static const byte keyDsaOid[] = {42, 134, 72, 206, 56, 4, 1};
sPymbed 16:048e5e270a58 1183 #endif /* NO_DSA */
sPymbed 16:048e5e270a58 1184 #ifndef NO_RSA
sPymbed 16:048e5e270a58 1185 static const byte keyRsaOid[] = {42, 134, 72, 134, 247, 13, 1, 1, 1};
sPymbed 16:048e5e270a58 1186 #endif /* NO_RSA */
sPymbed 16:048e5e270a58 1187 #ifdef HAVE_NTRU
sPymbed 16:048e5e270a58 1188 static const byte keyNtruOid[] = {43, 6, 1, 4, 1, 193, 22, 1, 1, 1, 1};
sPymbed 16:048e5e270a58 1189 #endif /* HAVE_NTRU */
sPymbed 16:048e5e270a58 1190 #ifdef HAVE_ECC
sPymbed 16:048e5e270a58 1191 static const byte keyEcdsaOid[] = {42, 134, 72, 206, 61, 2, 1};
sPymbed 16:048e5e270a58 1192 #endif /* HAVE_ECC */
sPymbed 16:048e5e270a58 1193 #ifdef HAVE_ED25519
sPymbed 16:048e5e270a58 1194 static const byte keyEd25519Oid[] = {43, 101, 112};
sPymbed 16:048e5e270a58 1195 #endif /* HAVE_ED25519 */
sPymbed 16:048e5e270a58 1196
sPymbed 16:048e5e270a58 1197 /* curveType */
sPymbed 16:048e5e270a58 1198 #ifdef HAVE_ECC
sPymbed 16:048e5e270a58 1199 /* See "ecc_sets" table in ecc.c */
sPymbed 16:048e5e270a58 1200 #endif /* HAVE_ECC */
sPymbed 16:048e5e270a58 1201
sPymbed 16:048e5e270a58 1202 #ifdef HAVE_AES_CBC
sPymbed 16:048e5e270a58 1203 /* blkType */
sPymbed 16:048e5e270a58 1204 #ifdef WOLFSSL_AES_128
sPymbed 16:048e5e270a58 1205 static const byte blkAes128CbcOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 2};
sPymbed 16:048e5e270a58 1206 #endif
sPymbed 16:048e5e270a58 1207 #ifdef WOLFSSL_AES_192
sPymbed 16:048e5e270a58 1208 static const byte blkAes192CbcOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 22};
sPymbed 16:048e5e270a58 1209 #endif
sPymbed 16:048e5e270a58 1210 #ifdef WOLFSSL_AES_256
sPymbed 16:048e5e270a58 1211 static const byte blkAes256CbcOid[] = {96, 134, 72, 1, 101, 3, 4, 1, 42};
sPymbed 16:048e5e270a58 1212 #endif
sPymbed 16:048e5e270a58 1213 #endif /* HAVE_AES_CBC */
sPymbed 16:048e5e270a58 1214
sPymbed 16:048e5e270a58 1215 #ifndef NO_DES3
sPymbed 16:048e5e270a58 1216 static const byte blkDesCbcOid[] = {43, 14, 3, 2, 7};
sPymbed 16:048e5e270a58 1217 static const byte blkDes3CbcOid[] = {42, 134, 72, 134, 247, 13, 3, 7};
sPymbed 16:048e5e270a58 1218 #endif
sPymbed 16:048e5e270a58 1219
sPymbed 16:048e5e270a58 1220 /* keyWrapType */
sPymbed 16:048e5e270a58 1221 #ifdef WOLFSSL_AES_128
sPymbed 16:048e5e270a58 1222 static const byte wrapAes128Oid[] = {96, 134, 72, 1, 101, 3, 4, 1, 5};
sPymbed 16:048e5e270a58 1223 #endif
sPymbed 16:048e5e270a58 1224 #ifdef WOLFSSL_AES_192
sPymbed 16:048e5e270a58 1225 static const byte wrapAes192Oid[] = {96, 134, 72, 1, 101, 3, 4, 1, 25};
sPymbed 16:048e5e270a58 1226 #endif
sPymbed 16:048e5e270a58 1227 #ifdef WOLFSSL_AES_256
sPymbed 16:048e5e270a58 1228 static const byte wrapAes256Oid[] = {96, 134, 72, 1, 101, 3, 4, 1, 45};
sPymbed 16:048e5e270a58 1229 #endif
sPymbed 16:048e5e270a58 1230
sPymbed 16:048e5e270a58 1231 /* cmsKeyAgreeType */
sPymbed 16:048e5e270a58 1232 #ifndef NO_SHA
sPymbed 16:048e5e270a58 1233 static const byte dhSinglePass_stdDH_sha1kdf_Oid[] =
sPymbed 16:048e5e270a58 1234 {43, 129, 5, 16, 134, 72, 63, 0, 2};
sPymbed 16:048e5e270a58 1235 #endif
sPymbed 16:048e5e270a58 1236 #ifdef WOLFSSL_SHA224
sPymbed 16:048e5e270a58 1237 static const byte dhSinglePass_stdDH_sha224kdf_Oid[] = {43, 129, 4, 1, 11, 0};
sPymbed 16:048e5e270a58 1238 #endif
sPymbed 16:048e5e270a58 1239 #ifndef NO_SHA256
sPymbed 16:048e5e270a58 1240 static const byte dhSinglePass_stdDH_sha256kdf_Oid[] = {43, 129, 4, 1, 11, 1};
sPymbed 16:048e5e270a58 1241 #endif
sPymbed 16:048e5e270a58 1242 #ifdef WOLFSSL_SHA384
sPymbed 16:048e5e270a58 1243 static const byte dhSinglePass_stdDH_sha384kdf_Oid[] = {43, 129, 4, 1, 11, 2};
sPymbed 16:048e5e270a58 1244 #endif
sPymbed 16:048e5e270a58 1245 #ifdef WOLFSSL_SHA512
sPymbed 16:048e5e270a58 1246 static const byte dhSinglePass_stdDH_sha512kdf_Oid[] = {43, 129, 4, 1, 11, 3};
sPymbed 16:048e5e270a58 1247 #endif
sPymbed 16:048e5e270a58 1248
sPymbed 16:048e5e270a58 1249 /* ocspType */
sPymbed 16:048e5e270a58 1250 #ifdef HAVE_OCSP
sPymbed 16:048e5e270a58 1251 static const byte ocspBasicOid[] = {43, 6, 1, 5, 5, 7, 48, 1, 1};
sPymbed 16:048e5e270a58 1252 static const byte ocspNonceOid[] = {43, 6, 1, 5, 5, 7, 48, 1, 2};
sPymbed 16:048e5e270a58 1253 #endif /* HAVE_OCSP */
sPymbed 16:048e5e270a58 1254
sPymbed 16:048e5e270a58 1255 /* certExtType */
sPymbed 16:048e5e270a58 1256 static const byte extBasicCaOid[] = {85, 29, 19};
sPymbed 16:048e5e270a58 1257 static const byte extAltNamesOid[] = {85, 29, 17};
sPymbed 16:048e5e270a58 1258 static const byte extCrlDistOid[] = {85, 29, 31};
sPymbed 16:048e5e270a58 1259 static const byte extAuthInfoOid[] = {43, 6, 1, 5, 5, 7, 1, 1};
sPymbed 16:048e5e270a58 1260 static const byte extAuthKeyOid[] = {85, 29, 35};
sPymbed 16:048e5e270a58 1261 static const byte extSubjKeyOid[] = {85, 29, 14};
sPymbed 16:048e5e270a58 1262 static const byte extCertPolicyOid[] = {85, 29, 32};
sPymbed 16:048e5e270a58 1263 static const byte extKeyUsageOid[] = {85, 29, 15};
sPymbed 16:048e5e270a58 1264 static const byte extInhibitAnyOid[] = {85, 29, 54};
sPymbed 16:048e5e270a58 1265 static const byte extExtKeyUsageOid[] = {85, 29, 37};
sPymbed 16:048e5e270a58 1266 #ifndef IGNORE_NAME_CONSTRAINTS
sPymbed 16:048e5e270a58 1267 static const byte extNameConsOid[] = {85, 29, 30};
sPymbed 16:048e5e270a58 1268 #endif
sPymbed 16:048e5e270a58 1269
sPymbed 16:048e5e270a58 1270 /* certAuthInfoType */
sPymbed 16:048e5e270a58 1271 #ifdef HAVE_OCSP
sPymbed 16:048e5e270a58 1272 static const byte extAuthInfoOcspOid[] = {43, 6, 1, 5, 5, 7, 48, 1};
sPymbed 16:048e5e270a58 1273 #endif
sPymbed 16:048e5e270a58 1274 static const byte extAuthInfoCaIssuerOid[] = {43, 6, 1, 5, 5, 7, 48, 2};
sPymbed 16:048e5e270a58 1275
sPymbed 16:048e5e270a58 1276 /* certPolicyType */
sPymbed 16:048e5e270a58 1277 static const byte extCertPolicyAnyOid[] = {85, 29, 32, 0};
sPymbed 16:048e5e270a58 1278
sPymbed 16:048e5e270a58 1279 /* certKeyUseType */
sPymbed 16:048e5e270a58 1280 static const byte extAltNamesHwNameOid[] = {43, 6, 1, 5, 5, 7, 8, 4};
sPymbed 16:048e5e270a58 1281
sPymbed 16:048e5e270a58 1282 /* certKeyUseType */
sPymbed 16:048e5e270a58 1283 static const byte extExtKeyUsageAnyOid[] = {85, 29, 37, 0};
sPymbed 16:048e5e270a58 1284 static const byte extExtKeyUsageServerAuthOid[] = {43, 6, 1, 5, 5, 7, 3, 1};
sPymbed 16:048e5e270a58 1285 static const byte extExtKeyUsageClientAuthOid[] = {43, 6, 1, 5, 5, 7, 3, 2};
sPymbed 16:048e5e270a58 1286 static const byte extExtKeyUsageCodeSigningOid[] = {43, 6, 1, 5, 5, 7, 3, 3};
sPymbed 16:048e5e270a58 1287 static const byte extExtKeyUsageEmailProtectOid[] = {43, 6, 1, 5, 5, 7, 3, 4};
sPymbed 16:048e5e270a58 1288 static const byte extExtKeyUsageTimestampOid[] = {43, 6, 1, 5, 5, 7, 3, 8};
sPymbed 16:048e5e270a58 1289 static const byte extExtKeyUsageOcspSignOid[] = {43, 6, 1, 5, 5, 7, 3, 9};
sPymbed 16:048e5e270a58 1290
sPymbed 16:048e5e270a58 1291 /* kdfType */
sPymbed 16:048e5e270a58 1292 static const byte pbkdf2Oid[] = {42, 134, 72, 134, 247, 13, 1, 5, 12};
sPymbed 16:048e5e270a58 1293
sPymbed 16:048e5e270a58 1294 /* PKCS5 */
sPymbed 16:048e5e270a58 1295 #if !defined(NO_DES3) && !defined(NO_SHA)
sPymbed 16:048e5e270a58 1296 static const byte pbeSha1Des[] = {42, 134, 72, 134, 247, 13, 1, 5, 10};
sPymbed 16:048e5e270a58 1297 #endif
sPymbed 16:048e5e270a58 1298
sPymbed 16:048e5e270a58 1299 /* PKCS12 */
sPymbed 16:048e5e270a58 1300 #if !defined(NO_RC4) && !defined(NO_SHA)
sPymbed 16:048e5e270a58 1301 static const byte pbeSha1RC4128[] = {42, 134, 72, 134, 247, 13, 1, 12, 1, 1};
sPymbed 16:048e5e270a58 1302 #endif
sPymbed 16:048e5e270a58 1303 #if !defined(NO_DES3) && !defined(NO_SHA)
sPymbed 16:048e5e270a58 1304 static const byte pbeSha1Des3[] = {42, 134, 72, 134, 247, 13, 1, 12, 1, 3};
sPymbed 16:048e5e270a58 1305 #endif
sPymbed 16:048e5e270a58 1306
sPymbed 16:048e5e270a58 1307
sPymbed 16:048e5e270a58 1308 /* returns a pointer to the OID string on success and NULL on fail */
sPymbed 16:048e5e270a58 1309 const byte* OidFromId(word32 id, word32 type, word32* oidSz)
sPymbed 16:048e5e270a58 1310 {
sPymbed 16:048e5e270a58 1311 const byte* oid = NULL;
sPymbed 16:048e5e270a58 1312
sPymbed 16:048e5e270a58 1313 *oidSz = 0;
sPymbed 16:048e5e270a58 1314
sPymbed 16:048e5e270a58 1315 switch (type) {
sPymbed 16:048e5e270a58 1316
sPymbed 16:048e5e270a58 1317 case oidHashType:
sPymbed 16:048e5e270a58 1318 switch (id) {
sPymbed 16:048e5e270a58 1319 #ifdef WOLFSSL_MD2
sPymbed 16:048e5e270a58 1320 case MD2h:
sPymbed 16:048e5e270a58 1321 oid = hashMd2hOid;
sPymbed 16:048e5e270a58 1322 *oidSz = sizeof(hashMd2hOid);
sPymbed 16:048e5e270a58 1323 break;
sPymbed 16:048e5e270a58 1324 #endif
sPymbed 16:048e5e270a58 1325 #ifndef NO_MD5
sPymbed 16:048e5e270a58 1326 case MD5h:
sPymbed 16:048e5e270a58 1327 oid = hashMd5hOid;
sPymbed 16:048e5e270a58 1328 *oidSz = sizeof(hashMd5hOid);
sPymbed 16:048e5e270a58 1329 break;
sPymbed 16:048e5e270a58 1330 #endif
sPymbed 16:048e5e270a58 1331 #ifndef NO_SHA
sPymbed 16:048e5e270a58 1332 case SHAh:
sPymbed 16:048e5e270a58 1333 oid = hashSha1hOid;
sPymbed 16:048e5e270a58 1334 *oidSz = sizeof(hashSha1hOid);
sPymbed 16:048e5e270a58 1335 break;
sPymbed 16:048e5e270a58 1336 #endif
sPymbed 16:048e5e270a58 1337 #ifdef WOLFSSL_SHA224
sPymbed 16:048e5e270a58 1338 case SHA224h:
sPymbed 16:048e5e270a58 1339 oid = hashSha224hOid;
sPymbed 16:048e5e270a58 1340 *oidSz = sizeof(hashSha224hOid);
sPymbed 16:048e5e270a58 1341 break;
sPymbed 16:048e5e270a58 1342 #endif
sPymbed 16:048e5e270a58 1343 #ifndef NO_SHA256
sPymbed 16:048e5e270a58 1344 case SHA256h:
sPymbed 16:048e5e270a58 1345 oid = hashSha256hOid;
sPymbed 16:048e5e270a58 1346 *oidSz = sizeof(hashSha256hOid);
sPymbed 16:048e5e270a58 1347 break;
sPymbed 16:048e5e270a58 1348 #endif
sPymbed 16:048e5e270a58 1349 #ifdef WOLFSSL_SHA384
sPymbed 16:048e5e270a58 1350 case SHA384h:
sPymbed 16:048e5e270a58 1351 oid = hashSha384hOid;
sPymbed 16:048e5e270a58 1352 *oidSz = sizeof(hashSha384hOid);
sPymbed 16:048e5e270a58 1353 break;
sPymbed 16:048e5e270a58 1354 #endif
sPymbed 16:048e5e270a58 1355 #ifdef WOLFSSL_SHA512
sPymbed 16:048e5e270a58 1356 case SHA512h:
sPymbed 16:048e5e270a58 1357 oid = hashSha512hOid;
sPymbed 16:048e5e270a58 1358 *oidSz = sizeof(hashSha512hOid);
sPymbed 16:048e5e270a58 1359 break;
sPymbed 16:048e5e270a58 1360 #endif
sPymbed 16:048e5e270a58 1361 }
sPymbed 16:048e5e270a58 1362 break;
sPymbed 16:048e5e270a58 1363
sPymbed 16:048e5e270a58 1364 case oidSigType:
sPymbed 16:048e5e270a58 1365 switch (id) {
sPymbed 16:048e5e270a58 1366 #if !defined(NO_DSA) && !defined(NO_SHA)
sPymbed 16:048e5e270a58 1367 case CTC_SHAwDSA:
sPymbed 16:048e5e270a58 1368 oid = sigSha1wDsaOid;
sPymbed 16:048e5e270a58 1369 *oidSz = sizeof(sigSha1wDsaOid);
sPymbed 16:048e5e270a58 1370 break;
sPymbed 16:048e5e270a58 1371 #endif /* NO_DSA */
sPymbed 16:048e5e270a58 1372 #ifndef NO_RSA
sPymbed 16:048e5e270a58 1373 #ifdef WOLFSSL_MD2
sPymbed 16:048e5e270a58 1374 case CTC_MD2wRSA:
sPymbed 16:048e5e270a58 1375 oid = sigMd2wRsaOid;
sPymbed 16:048e5e270a58 1376 *oidSz = sizeof(sigMd2wRsaOid);
sPymbed 16:048e5e270a58 1377 break;
sPymbed 16:048e5e270a58 1378 #endif
sPymbed 16:048e5e270a58 1379 #ifndef NO_MD5
sPymbed 16:048e5e270a58 1380 case CTC_MD5wRSA:
sPymbed 16:048e5e270a58 1381 oid = sigMd5wRsaOid;
sPymbed 16:048e5e270a58 1382 *oidSz = sizeof(sigMd5wRsaOid);
sPymbed 16:048e5e270a58 1383 break;
sPymbed 16:048e5e270a58 1384 #endif
sPymbed 16:048e5e270a58 1385 #ifndef NO_SHA
sPymbed 16:048e5e270a58 1386 case CTC_SHAwRSA:
sPymbed 16:048e5e270a58 1387 oid = sigSha1wRsaOid;
sPymbed 16:048e5e270a58 1388 *oidSz = sizeof(sigSha1wRsaOid);
sPymbed 16:048e5e270a58 1389 break;
sPymbed 16:048e5e270a58 1390 #endif
sPymbed 16:048e5e270a58 1391 #ifdef WOLFSSL_SHA224
sPymbed 16:048e5e270a58 1392 case CTC_SHA224wRSA:
sPymbed 16:048e5e270a58 1393 oid = sigSha224wRsaOid;
sPymbed 16:048e5e270a58 1394 *oidSz = sizeof(sigSha224wRsaOid);
sPymbed 16:048e5e270a58 1395 break;
sPymbed 16:048e5e270a58 1396 #endif
sPymbed 16:048e5e270a58 1397 #ifndef NO_SHA256
sPymbed 16:048e5e270a58 1398 case CTC_SHA256wRSA:
sPymbed 16:048e5e270a58 1399 oid = sigSha256wRsaOid;
sPymbed 16:048e5e270a58 1400 *oidSz = sizeof(sigSha256wRsaOid);
sPymbed 16:048e5e270a58 1401 break;
sPymbed 16:048e5e270a58 1402 #endif
sPymbed 16:048e5e270a58 1403 #ifdef WOLFSSL_SHA384
sPymbed 16:048e5e270a58 1404 case CTC_SHA384wRSA:
sPymbed 16:048e5e270a58 1405 oid = sigSha384wRsaOid;
sPymbed 16:048e5e270a58 1406 *oidSz = sizeof(sigSha384wRsaOid);
sPymbed 16:048e5e270a58 1407 break;
sPymbed 16:048e5e270a58 1408 #endif
sPymbed 16:048e5e270a58 1409 #ifdef WOLFSSL_SHA512
sPymbed 16:048e5e270a58 1410 case CTC_SHA512wRSA:
sPymbed 16:048e5e270a58 1411 oid = sigSha512wRsaOid;
sPymbed 16:048e5e270a58 1412 *oidSz = sizeof(sigSha512wRsaOid);
sPymbed 16:048e5e270a58 1413 break;
sPymbed 16:048e5e270a58 1414 #endif /* WOLFSSL_SHA512 */
sPymbed 16:048e5e270a58 1415 #endif /* NO_RSA */
sPymbed 16:048e5e270a58 1416 #ifdef HAVE_ECC
sPymbed 16:048e5e270a58 1417 #ifndef NO_SHA
sPymbed 16:048e5e270a58 1418 case CTC_SHAwECDSA:
sPymbed 16:048e5e270a58 1419 oid = sigSha1wEcdsaOid;
sPymbed 16:048e5e270a58 1420 *oidSz = sizeof(sigSha1wEcdsaOid);
sPymbed 16:048e5e270a58 1421 break;
sPymbed 16:048e5e270a58 1422 #endif
sPymbed 16:048e5e270a58 1423 #ifdef WOLFSSL_SHA224
sPymbed 16:048e5e270a58 1424 case CTC_SHA224wECDSA:
sPymbed 16:048e5e270a58 1425 oid = sigSha224wEcdsaOid;
sPymbed 16:048e5e270a58 1426 *oidSz = sizeof(sigSha224wEcdsaOid);
sPymbed 16:048e5e270a58 1427 break;
sPymbed 16:048e5e270a58 1428 #endif
sPymbed 16:048e5e270a58 1429 #ifndef NO_SHA256
sPymbed 16:048e5e270a58 1430 case CTC_SHA256wECDSA:
sPymbed 16:048e5e270a58 1431 oid = sigSha256wEcdsaOid;
sPymbed 16:048e5e270a58 1432 *oidSz = sizeof(sigSha256wEcdsaOid);
sPymbed 16:048e5e270a58 1433 break;
sPymbed 16:048e5e270a58 1434 #endif
sPymbed 16:048e5e270a58 1435 #ifdef WOLFSSL_SHA384
sPymbed 16:048e5e270a58 1436 case CTC_SHA384wECDSA:
sPymbed 16:048e5e270a58 1437 oid = sigSha384wEcdsaOid;
sPymbed 16:048e5e270a58 1438 *oidSz = sizeof(sigSha384wEcdsaOid);
sPymbed 16:048e5e270a58 1439 break;
sPymbed 16:048e5e270a58 1440 #endif
sPymbed 16:048e5e270a58 1441 #ifdef WOLFSSL_SHA512
sPymbed 16:048e5e270a58 1442 case CTC_SHA512wECDSA:
sPymbed 16:048e5e270a58 1443 oid = sigSha512wEcdsaOid;
sPymbed 16:048e5e270a58 1444 *oidSz = sizeof(sigSha512wEcdsaOid);
sPymbed 16:048e5e270a58 1445 break;
sPymbed 16:048e5e270a58 1446 #endif
sPymbed 16:048e5e270a58 1447 #endif /* HAVE_ECC */
sPymbed 16:048e5e270a58 1448 #ifdef HAVE_ED25519
sPymbed 16:048e5e270a58 1449 case CTC_ED25519:
sPymbed 16:048e5e270a58 1450 oid = sigEd25519Oid;
sPymbed 16:048e5e270a58 1451 *oidSz = sizeof(sigEd25519Oid);
sPymbed 16:048e5e270a58 1452 break;
sPymbed 16:048e5e270a58 1453 #endif
sPymbed 16:048e5e270a58 1454 default:
sPymbed 16:048e5e270a58 1455 break;
sPymbed 16:048e5e270a58 1456 }
sPymbed 16:048e5e270a58 1457 break;
sPymbed 16:048e5e270a58 1458
sPymbed 16:048e5e270a58 1459 case oidKeyType:
sPymbed 16:048e5e270a58 1460 switch (id) {
sPymbed 16:048e5e270a58 1461 #ifndef NO_DSA
sPymbed 16:048e5e270a58 1462 case DSAk:
sPymbed 16:048e5e270a58 1463 oid = keyDsaOid;
sPymbed 16:048e5e270a58 1464 *oidSz = sizeof(keyDsaOid);
sPymbed 16:048e5e270a58 1465 break;
sPymbed 16:048e5e270a58 1466 #endif /* NO_DSA */
sPymbed 16:048e5e270a58 1467 #ifndef NO_RSA
sPymbed 16:048e5e270a58 1468 case RSAk:
sPymbed 16:048e5e270a58 1469 oid = keyRsaOid;
sPymbed 16:048e5e270a58 1470 *oidSz = sizeof(keyRsaOid);
sPymbed 16:048e5e270a58 1471 break;
sPymbed 16:048e5e270a58 1472 #endif /* NO_RSA */
sPymbed 16:048e5e270a58 1473 #ifdef HAVE_NTRU
sPymbed 16:048e5e270a58 1474 case NTRUk:
sPymbed 16:048e5e270a58 1475 oid = keyNtruOid;
sPymbed 16:048e5e270a58 1476 *oidSz = sizeof(keyNtruOid);
sPymbed 16:048e5e270a58 1477 break;
sPymbed 16:048e5e270a58 1478 #endif /* HAVE_NTRU */
sPymbed 16:048e5e270a58 1479 #ifdef HAVE_ECC
sPymbed 16:048e5e270a58 1480 case ECDSAk:
sPymbed 16:048e5e270a58 1481 oid = keyEcdsaOid;
sPymbed 16:048e5e270a58 1482 *oidSz = sizeof(keyEcdsaOid);
sPymbed 16:048e5e270a58 1483 break;
sPymbed 16:048e5e270a58 1484 #endif /* HAVE_ECC */
sPymbed 16:048e5e270a58 1485 #ifdef HAVE_ED25519
sPymbed 16:048e5e270a58 1486 case ED25519k:
sPymbed 16:048e5e270a58 1487 oid = keyEd25519Oid;
sPymbed 16:048e5e270a58 1488 *oidSz = sizeof(keyEd25519Oid);
sPymbed 16:048e5e270a58 1489 break;
sPymbed 16:048e5e270a58 1490 #endif /* HAVE_ED25519 */
sPymbed 16:048e5e270a58 1491 default:
sPymbed 16:048e5e270a58 1492 break;
sPymbed 16:048e5e270a58 1493 }
sPymbed 16:048e5e270a58 1494 break;
sPymbed 16:048e5e270a58 1495
sPymbed 16:048e5e270a58 1496 #ifdef HAVE_ECC
sPymbed 16:048e5e270a58 1497 case oidCurveType:
sPymbed 16:048e5e270a58 1498 if (wc_ecc_get_oid(id, &oid, oidSz) < 0) {
sPymbed 16:048e5e270a58 1499 WOLFSSL_MSG("ECC OID not found");
sPymbed 16:048e5e270a58 1500 }
sPymbed 16:048e5e270a58 1501 break;
sPymbed 16:048e5e270a58 1502 #endif /* HAVE_ECC */
sPymbed 16:048e5e270a58 1503
sPymbed 16:048e5e270a58 1504 case oidBlkType:
sPymbed 16:048e5e270a58 1505 switch (id) {
sPymbed 16:048e5e270a58 1506 #ifdef HAVE_AES_CBC
sPymbed 16:048e5e270a58 1507 #ifdef WOLFSSL_AES_128
sPymbed 16:048e5e270a58 1508 case AES128CBCb:
sPymbed 16:048e5e270a58 1509 oid = blkAes128CbcOid;
sPymbed 16:048e5e270a58 1510 *oidSz = sizeof(blkAes128CbcOid);
sPymbed 16:048e5e270a58 1511 break;
sPymbed 16:048e5e270a58 1512 #endif
sPymbed 16:048e5e270a58 1513 #ifdef WOLFSSL_AES_192
sPymbed 16:048e5e270a58 1514 case AES192CBCb:
sPymbed 16:048e5e270a58 1515 oid = blkAes192CbcOid;
sPymbed 16:048e5e270a58 1516 *oidSz = sizeof(blkAes192CbcOid);
sPymbed 16:048e5e270a58 1517 break;
sPymbed 16:048e5e270a58 1518 #endif
sPymbed 16:048e5e270a58 1519 #ifdef WOLFSSL_AES_256
sPymbed 16:048e5e270a58 1520 case AES256CBCb:
sPymbed 16:048e5e270a58 1521 oid = blkAes256CbcOid;
sPymbed 16:048e5e270a58 1522 *oidSz = sizeof(blkAes256CbcOid);
sPymbed 16:048e5e270a58 1523 break;
sPymbed 16:048e5e270a58 1524 #endif
sPymbed 16:048e5e270a58 1525 #endif /* HAVE_AES_CBC */
sPymbed 16:048e5e270a58 1526 #ifndef NO_DES3
sPymbed 16:048e5e270a58 1527 case DESb:
sPymbed 16:048e5e270a58 1528 oid = blkDesCbcOid;
sPymbed 16:048e5e270a58 1529 *oidSz = sizeof(blkDesCbcOid);
sPymbed 16:048e5e270a58 1530 break;
sPymbed 16:048e5e270a58 1531 case DES3b:
sPymbed 16:048e5e270a58 1532 oid = blkDes3CbcOid;
sPymbed 16:048e5e270a58 1533 *oidSz = sizeof(blkDes3CbcOid);
sPymbed 16:048e5e270a58 1534 break;
sPymbed 16:048e5e270a58 1535 #endif /* !NO_DES3 */
sPymbed 16:048e5e270a58 1536 }
sPymbed 16:048e5e270a58 1537 break;
sPymbed 16:048e5e270a58 1538
sPymbed 16:048e5e270a58 1539 #ifdef HAVE_OCSP
sPymbed 16:048e5e270a58 1540 case oidOcspType:
sPymbed 16:048e5e270a58 1541 switch (id) {
sPymbed 16:048e5e270a58 1542 case OCSP_BASIC_OID:
sPymbed 16:048e5e270a58 1543 oid = ocspBasicOid;
sPymbed 16:048e5e270a58 1544 *oidSz = sizeof(ocspBasicOid);
sPymbed 16:048e5e270a58 1545 break;
sPymbed 16:048e5e270a58 1546 case OCSP_NONCE_OID:
sPymbed 16:048e5e270a58 1547 oid = ocspNonceOid;
sPymbed 16:048e5e270a58 1548 *oidSz = sizeof(ocspNonceOid);
sPymbed 16:048e5e270a58 1549 break;
sPymbed 16:048e5e270a58 1550 }
sPymbed 16:048e5e270a58 1551 break;
sPymbed 16:048e5e270a58 1552 #endif /* HAVE_OCSP */
sPymbed 16:048e5e270a58 1553
sPymbed 16:048e5e270a58 1554 case oidCertExtType:
sPymbed 16:048e5e270a58 1555 switch (id) {
sPymbed 16:048e5e270a58 1556 case BASIC_CA_OID:
sPymbed 16:048e5e270a58 1557 oid = extBasicCaOid;
sPymbed 16:048e5e270a58 1558 *oidSz = sizeof(extBasicCaOid);
sPymbed 16:048e5e270a58 1559 break;
sPymbed 16:048e5e270a58 1560 case ALT_NAMES_OID:
sPymbed 16:048e5e270a58 1561 oid = extAltNamesOid;
sPymbed 16:048e5e270a58 1562 *oidSz = sizeof(extAltNamesOid);
sPymbed 16:048e5e270a58 1563 break;
sPymbed 16:048e5e270a58 1564 case CRL_DIST_OID:
sPymbed 16:048e5e270a58 1565 oid = extCrlDistOid;
sPymbed 16:048e5e270a58 1566 *oidSz = sizeof(extCrlDistOid);
sPymbed 16:048e5e270a58 1567 break;
sPymbed 16:048e5e270a58 1568 case AUTH_INFO_OID:
sPymbed 16:048e5e270a58 1569 oid = extAuthInfoOid;
sPymbed 16:048e5e270a58 1570 *oidSz = sizeof(extAuthInfoOid);
sPymbed 16:048e5e270a58 1571 break;
sPymbed 16:048e5e270a58 1572 case AUTH_KEY_OID:
sPymbed 16:048e5e270a58 1573 oid = extAuthKeyOid;
sPymbed 16:048e5e270a58 1574 *oidSz = sizeof(extAuthKeyOid);
sPymbed 16:048e5e270a58 1575 break;
sPymbed 16:048e5e270a58 1576 case SUBJ_KEY_OID:
sPymbed 16:048e5e270a58 1577 oid = extSubjKeyOid;
sPymbed 16:048e5e270a58 1578 *oidSz = sizeof(extSubjKeyOid);
sPymbed 16:048e5e270a58 1579 break;
sPymbed 16:048e5e270a58 1580 case CERT_POLICY_OID:
sPymbed 16:048e5e270a58 1581 oid = extCertPolicyOid;
sPymbed 16:048e5e270a58 1582 *oidSz = sizeof(extCertPolicyOid);
sPymbed 16:048e5e270a58 1583 break;
sPymbed 16:048e5e270a58 1584 case KEY_USAGE_OID:
sPymbed 16:048e5e270a58 1585 oid = extKeyUsageOid;
sPymbed 16:048e5e270a58 1586 *oidSz = sizeof(extKeyUsageOid);
sPymbed 16:048e5e270a58 1587 break;
sPymbed 16:048e5e270a58 1588 case INHIBIT_ANY_OID:
sPymbed 16:048e5e270a58 1589 oid = extInhibitAnyOid;
sPymbed 16:048e5e270a58 1590 *oidSz = sizeof(extInhibitAnyOid);
sPymbed 16:048e5e270a58 1591 break;
sPymbed 16:048e5e270a58 1592 case EXT_KEY_USAGE_OID:
sPymbed 16:048e5e270a58 1593 oid = extExtKeyUsageOid;
sPymbed 16:048e5e270a58 1594 *oidSz = sizeof(extExtKeyUsageOid);
sPymbed 16:048e5e270a58 1595 break;
sPymbed 16:048e5e270a58 1596 #ifndef IGNORE_NAME_CONSTRAINTS
sPymbed 16:048e5e270a58 1597 case NAME_CONS_OID:
sPymbed 16:048e5e270a58 1598 oid = extNameConsOid;
sPymbed 16:048e5e270a58 1599 *oidSz = sizeof(extNameConsOid);
sPymbed 16:048e5e270a58 1600 break;
sPymbed 16:048e5e270a58 1601 #endif
sPymbed 16:048e5e270a58 1602 }
sPymbed 16:048e5e270a58 1603 break;
sPymbed 16:048e5e270a58 1604
sPymbed 16:048e5e270a58 1605 case oidCertAuthInfoType:
sPymbed 16:048e5e270a58 1606 switch (id) {
sPymbed 16:048e5e270a58 1607 #ifdef HAVE_OCSP
sPymbed 16:048e5e270a58 1608 case AIA_OCSP_OID:
sPymbed 16:048e5e270a58 1609 oid = extAuthInfoOcspOid;
sPymbed 16:048e5e270a58 1610 *oidSz = sizeof(extAuthInfoOcspOid);
sPymbed 16:048e5e270a58 1611 break;
sPymbed 16:048e5e270a58 1612 #endif
sPymbed 16:048e5e270a58 1613 case AIA_CA_ISSUER_OID:
sPymbed 16:048e5e270a58 1614 oid = extAuthInfoCaIssuerOid;
sPymbed 16:048e5e270a58 1615 *oidSz = sizeof(extAuthInfoCaIssuerOid);
sPymbed 16:048e5e270a58 1616 break;
sPymbed 16:048e5e270a58 1617 }
sPymbed 16:048e5e270a58 1618 break;
sPymbed 16:048e5e270a58 1619
sPymbed 16:048e5e270a58 1620 case oidCertPolicyType:
sPymbed 16:048e5e270a58 1621 switch (id) {
sPymbed 16:048e5e270a58 1622 case CP_ANY_OID:
sPymbed 16:048e5e270a58 1623 oid = extCertPolicyAnyOid;
sPymbed 16:048e5e270a58 1624 *oidSz = sizeof(extCertPolicyAnyOid);
sPymbed 16:048e5e270a58 1625 break;
sPymbed 16:048e5e270a58 1626 }
sPymbed 16:048e5e270a58 1627 break;
sPymbed 16:048e5e270a58 1628
sPymbed 16:048e5e270a58 1629 case oidCertAltNameType:
sPymbed 16:048e5e270a58 1630 switch (id) {
sPymbed 16:048e5e270a58 1631 case HW_NAME_OID:
sPymbed 16:048e5e270a58 1632 oid = extAltNamesHwNameOid;
sPymbed 16:048e5e270a58 1633 *oidSz = sizeof(extAltNamesHwNameOid);
sPymbed 16:048e5e270a58 1634 break;
sPymbed 16:048e5e270a58 1635 }
sPymbed 16:048e5e270a58 1636 break;
sPymbed 16:048e5e270a58 1637
sPymbed 16:048e5e270a58 1638 case oidCertKeyUseType:
sPymbed 16:048e5e270a58 1639 switch (id) {
sPymbed 16:048e5e270a58 1640 case EKU_ANY_OID:
sPymbed 16:048e5e270a58 1641 oid = extExtKeyUsageAnyOid;
sPymbed 16:048e5e270a58 1642 *oidSz = sizeof(extExtKeyUsageAnyOid);
sPymbed 16:048e5e270a58 1643 break;
sPymbed 16:048e5e270a58 1644 case EKU_SERVER_AUTH_OID:
sPymbed 16:048e5e270a58 1645 oid = extExtKeyUsageServerAuthOid;
sPymbed 16:048e5e270a58 1646 *oidSz = sizeof(extExtKeyUsageServerAuthOid);
sPymbed 16:048e5e270a58 1647 break;
sPymbed 16:048e5e270a58 1648 case EKU_CLIENT_AUTH_OID:
sPymbed 16:048e5e270a58 1649 oid = extExtKeyUsageClientAuthOid;
sPymbed 16:048e5e270a58 1650 *oidSz = sizeof(extExtKeyUsageClientAuthOid);
sPymbed 16:048e5e270a58 1651 break;
sPymbed 16:048e5e270a58 1652 case EKU_CODESIGNING_OID:
sPymbed 16:048e5e270a58 1653 oid = extExtKeyUsageCodeSigningOid;
sPymbed 16:048e5e270a58 1654 *oidSz = sizeof(extExtKeyUsageCodeSigningOid);
sPymbed 16:048e5e270a58 1655 break;
sPymbed 16:048e5e270a58 1656 case EKU_EMAILPROTECT_OID:
sPymbed 16:048e5e270a58 1657 oid = extExtKeyUsageEmailProtectOid;
sPymbed 16:048e5e270a58 1658 *oidSz = sizeof(extExtKeyUsageEmailProtectOid);
sPymbed 16:048e5e270a58 1659 break;
sPymbed 16:048e5e270a58 1660 case EKU_TIMESTAMP_OID:
sPymbed 16:048e5e270a58 1661 oid = extExtKeyUsageTimestampOid;
sPymbed 16:048e5e270a58 1662 *oidSz = sizeof(extExtKeyUsageTimestampOid);
sPymbed 16:048e5e270a58 1663 break;
sPymbed 16:048e5e270a58 1664 case EKU_OCSP_SIGN_OID:
sPymbed 16:048e5e270a58 1665 oid = extExtKeyUsageOcspSignOid;
sPymbed 16:048e5e270a58 1666 *oidSz = sizeof(extExtKeyUsageOcspSignOid);
sPymbed 16:048e5e270a58 1667 break;
sPymbed 16:048e5e270a58 1668 }
sPymbed 16:048e5e270a58 1669 break;
sPymbed 16:048e5e270a58 1670
sPymbed 16:048e5e270a58 1671 case oidKdfType:
sPymbed 16:048e5e270a58 1672 switch (id) {
sPymbed 16:048e5e270a58 1673 case PBKDF2_OID:
sPymbed 16:048e5e270a58 1674 oid = pbkdf2Oid;
sPymbed 16:048e5e270a58 1675 *oidSz = sizeof(pbkdf2Oid);
sPymbed 16:048e5e270a58 1676 break;
sPymbed 16:048e5e270a58 1677 }
sPymbed 16:048e5e270a58 1678 break;
sPymbed 16:048e5e270a58 1679
sPymbed 16:048e5e270a58 1680 case oidPBEType:
sPymbed 16:048e5e270a58 1681 switch (id) {
sPymbed 16:048e5e270a58 1682 #if !defined(NO_SHA) && !defined(NO_RC4)
sPymbed 16:048e5e270a58 1683 case PBE_SHA1_RC4_128:
sPymbed 16:048e5e270a58 1684 oid = pbeSha1RC4128;
sPymbed 16:048e5e270a58 1685 *oidSz = sizeof(pbeSha1RC4128);
sPymbed 16:048e5e270a58 1686 break;
sPymbed 16:048e5e270a58 1687 #endif
sPymbed 16:048e5e270a58 1688 #if !defined(NO_SHA) && !defined(NO_DES3)
sPymbed 16:048e5e270a58 1689 case PBE_SHA1_DES:
sPymbed 16:048e5e270a58 1690 oid = pbeSha1Des;
sPymbed 16:048e5e270a58 1691 *oidSz = sizeof(pbeSha1Des);
sPymbed 16:048e5e270a58 1692 break;
sPymbed 16:048e5e270a58 1693
sPymbed 16:048e5e270a58 1694 #endif
sPymbed 16:048e5e270a58 1695 #if !defined(NO_SHA) && !defined(NO_DES3)
sPymbed 16:048e5e270a58 1696 case PBE_SHA1_DES3:
sPymbed 16:048e5e270a58 1697 oid = pbeSha1Des3;
sPymbed 16:048e5e270a58 1698 *oidSz = sizeof(pbeSha1Des3);
sPymbed 16:048e5e270a58 1699 break;
sPymbed 16:048e5e270a58 1700 #endif
sPymbed 16:048e5e270a58 1701 }
sPymbed 16:048e5e270a58 1702 break;
sPymbed 16:048e5e270a58 1703
sPymbed 16:048e5e270a58 1704 case oidKeyWrapType:
sPymbed 16:048e5e270a58 1705 switch (id) {
sPymbed 16:048e5e270a58 1706 #ifdef WOLFSSL_AES_128
sPymbed 16:048e5e270a58 1707 case AES128_WRAP:
sPymbed 16:048e5e270a58 1708 oid = wrapAes128Oid;
sPymbed 16:048e5e270a58 1709 *oidSz = sizeof(wrapAes128Oid);
sPymbed 16:048e5e270a58 1710 break;
sPymbed 16:048e5e270a58 1711 #endif
sPymbed 16:048e5e270a58 1712 #ifdef WOLFSSL_AES_192
sPymbed 16:048e5e270a58 1713 case AES192_WRAP:
sPymbed 16:048e5e270a58 1714 oid = wrapAes192Oid;
sPymbed 16:048e5e270a58 1715 *oidSz = sizeof(wrapAes192Oid);
sPymbed 16:048e5e270a58 1716 break;
sPymbed 16:048e5e270a58 1717 #endif
sPymbed 16:048e5e270a58 1718 #ifdef WOLFSSL_AES_256
sPymbed 16:048e5e270a58 1719 case AES256_WRAP:
sPymbed 16:048e5e270a58 1720 oid = wrapAes256Oid;
sPymbed 16:048e5e270a58 1721 *oidSz = sizeof(wrapAes256Oid);
sPymbed 16:048e5e270a58 1722 break;
sPymbed 16:048e5e270a58 1723 #endif
sPymbed 16:048e5e270a58 1724 }
sPymbed 16:048e5e270a58 1725 break;
sPymbed 16:048e5e270a58 1726
sPymbed 16:048e5e270a58 1727 case oidCmsKeyAgreeType:
sPymbed 16:048e5e270a58 1728 switch (id) {
sPymbed 16:048e5e270a58 1729 #ifndef NO_SHA
sPymbed 16:048e5e270a58 1730 case dhSinglePass_stdDH_sha1kdf_scheme:
sPymbed 16:048e5e270a58 1731 oid = dhSinglePass_stdDH_sha1kdf_Oid;
sPymbed 16:048e5e270a58 1732 *oidSz = sizeof(dhSinglePass_stdDH_sha1kdf_Oid);
sPymbed 16:048e5e270a58 1733 break;
sPymbed 16:048e5e270a58 1734 #endif
sPymbed 16:048e5e270a58 1735 #ifdef WOLFSSL_SHA224
sPymbed 16:048e5e270a58 1736 case dhSinglePass_stdDH_sha224kdf_scheme:
sPymbed 16:048e5e270a58 1737 oid = dhSinglePass_stdDH_sha224kdf_Oid;
sPymbed 16:048e5e270a58 1738 *oidSz = sizeof(dhSinglePass_stdDH_sha224kdf_Oid);
sPymbed 16:048e5e270a58 1739 break;
sPymbed 16:048e5e270a58 1740 #endif
sPymbed 16:048e5e270a58 1741 #ifndef NO_SHA256
sPymbed 16:048e5e270a58 1742 case dhSinglePass_stdDH_sha256kdf_scheme:
sPymbed 16:048e5e270a58 1743 oid = dhSinglePass_stdDH_sha256kdf_Oid;
sPymbed 16:048e5e270a58 1744 *oidSz = sizeof(dhSinglePass_stdDH_sha256kdf_Oid);
sPymbed 16:048e5e270a58 1745 break;
sPymbed 16:048e5e270a58 1746 #endif
sPymbed 16:048e5e270a58 1747 #ifdef WOLFSSL_SHA384
sPymbed 16:048e5e270a58 1748 case dhSinglePass_stdDH_sha384kdf_scheme:
sPymbed 16:048e5e270a58 1749 oid = dhSinglePass_stdDH_sha384kdf_Oid;
sPymbed 16:048e5e270a58 1750 *oidSz = sizeof(dhSinglePass_stdDH_sha384kdf_Oid);
sPymbed 16:048e5e270a58 1751 break;
sPymbed 16:048e5e270a58 1752 #endif
sPymbed 16:048e5e270a58 1753 #ifdef WOLFSSL_SHA512
sPymbed 16:048e5e270a58 1754 case dhSinglePass_stdDH_sha512kdf_scheme:
sPymbed 16:048e5e270a58 1755 oid = dhSinglePass_stdDH_sha512kdf_Oid;
sPymbed 16:048e5e270a58 1756 *oidSz = sizeof(dhSinglePass_stdDH_sha512kdf_Oid);
sPymbed 16:048e5e270a58 1757 break;
sPymbed 16:048e5e270a58 1758 #endif
sPymbed 16:048e5e270a58 1759 }
sPymbed 16:048e5e270a58 1760 break;
sPymbed 16:048e5e270a58 1761
sPymbed 16:048e5e270a58 1762 #ifndef NO_HMAC
sPymbed 16:048e5e270a58 1763 case oidHmacType:
sPymbed 16:048e5e270a58 1764 switch (id) {
sPymbed 16:048e5e270a58 1765 #ifdef WOLFSSL_SHA224
sPymbed 16:048e5e270a58 1766 case HMAC_SHA224_OID:
sPymbed 16:048e5e270a58 1767 oid = hmacSha224Oid;
sPymbed 16:048e5e270a58 1768 *oidSz = sizeof(hmacSha224Oid);
sPymbed 16:048e5e270a58 1769 break;
sPymbed 16:048e5e270a58 1770 #endif
sPymbed 16:048e5e270a58 1771 #ifndef NO_SHA256
sPymbed 16:048e5e270a58 1772 case HMAC_SHA256_OID:
sPymbed 16:048e5e270a58 1773 oid = hmacSha256Oid;
sPymbed 16:048e5e270a58 1774 *oidSz = sizeof(hmacSha256Oid);
sPymbed 16:048e5e270a58 1775 break;
sPymbed 16:048e5e270a58 1776 #endif
sPymbed 16:048e5e270a58 1777 #ifdef WOLFSSL_SHA384
sPymbed 16:048e5e270a58 1778 case HMAC_SHA384_OID:
sPymbed 16:048e5e270a58 1779 oid = hmacSha384Oid;
sPymbed 16:048e5e270a58 1780 *oidSz = sizeof(hmacSha384Oid);
sPymbed 16:048e5e270a58 1781 break;
sPymbed 16:048e5e270a58 1782 #endif
sPymbed 16:048e5e270a58 1783 #ifdef WOLFSSL_SHA512
sPymbed 16:048e5e270a58 1784 case HMAC_SHA512_OID:
sPymbed 16:048e5e270a58 1785 oid = hmacSha512Oid;
sPymbed 16:048e5e270a58 1786 *oidSz = sizeof(hmacSha512Oid);
sPymbed 16:048e5e270a58 1787 break;
sPymbed 16:048e5e270a58 1788 #endif
sPymbed 16:048e5e270a58 1789 }
sPymbed 16:048e5e270a58 1790 break;
sPymbed 16:048e5e270a58 1791 #endif /* !NO_HMAC */
sPymbed 16:048e5e270a58 1792
sPymbed 16:048e5e270a58 1793 case oidIgnoreType:
sPymbed 16:048e5e270a58 1794 default:
sPymbed 16:048e5e270a58 1795 break;
sPymbed 16:048e5e270a58 1796 }
sPymbed 16:048e5e270a58 1797
sPymbed 16:048e5e270a58 1798 return oid;
sPymbed 16:048e5e270a58 1799 }
sPymbed 16:048e5e270a58 1800
sPymbed 16:048e5e270a58 1801 #ifdef HAVE_OID_ENCODING
sPymbed 16:048e5e270a58 1802 int EncodeObjectId(const word16* in, word32 inSz, byte* out, word32* outSz)
sPymbed 16:048e5e270a58 1803 {
sPymbed 16:048e5e270a58 1804 int i, x, len;
sPymbed 16:048e5e270a58 1805 word32 d, t;
sPymbed 16:048e5e270a58 1806
sPymbed 16:048e5e270a58 1807 /* check args */
sPymbed 16:048e5e270a58 1808 if (in == NULL || outSz == NULL) {
sPymbed 16:048e5e270a58 1809 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 1810 }
sPymbed 16:048e5e270a58 1811
sPymbed 16:048e5e270a58 1812 /* compute length of encoded OID */
sPymbed 16:048e5e270a58 1813 d = (in[0] * 40) + in[1];
sPymbed 16:048e5e270a58 1814 len = 0;
sPymbed 16:048e5e270a58 1815 for (i = 1; i < (int)inSz; i++) {
sPymbed 16:048e5e270a58 1816 x = 0;
sPymbed 16:048e5e270a58 1817 t = d;
sPymbed 16:048e5e270a58 1818 while (t) {
sPymbed 16:048e5e270a58 1819 x++;
sPymbed 16:048e5e270a58 1820 t >>= 1;
sPymbed 16:048e5e270a58 1821 }
sPymbed 16:048e5e270a58 1822 len += (x / 7) + ((x % 7) ? 1 : 0) + (d == 0 ? 1 : 0);
sPymbed 16:048e5e270a58 1823
sPymbed 16:048e5e270a58 1824 if (i < (int)inSz - 1) {
sPymbed 16:048e5e270a58 1825 d = in[i + 1];
sPymbed 16:048e5e270a58 1826 }
sPymbed 16:048e5e270a58 1827 }
sPymbed 16:048e5e270a58 1828
sPymbed 16:048e5e270a58 1829 if (out) {
sPymbed 16:048e5e270a58 1830 /* verify length */
sPymbed 16:048e5e270a58 1831 if ((int)*outSz < len) {
sPymbed 16:048e5e270a58 1832 return BUFFER_E; /* buffer provided is not large enough */
sPymbed 16:048e5e270a58 1833 }
sPymbed 16:048e5e270a58 1834
sPymbed 16:048e5e270a58 1835 /* calc first byte */
sPymbed 16:048e5e270a58 1836 d = (in[0] * 40) + in[1];
sPymbed 16:048e5e270a58 1837
sPymbed 16:048e5e270a58 1838 /* encode bytes */
sPymbed 16:048e5e270a58 1839 x = 0;
sPymbed 16:048e5e270a58 1840 for (i = 1; i < (int)inSz; i++) {
sPymbed 16:048e5e270a58 1841 if (d) {
sPymbed 16:048e5e270a58 1842 int y = x, z;
sPymbed 16:048e5e270a58 1843 byte mask = 0;
sPymbed 16:048e5e270a58 1844 while (d) {
sPymbed 16:048e5e270a58 1845 out[x++] = (byte)((d & 0x7F) | mask);
sPymbed 16:048e5e270a58 1846 d >>= 7;
sPymbed 16:048e5e270a58 1847 mask |= 0x80; /* upper bit is set on all but the last byte */
sPymbed 16:048e5e270a58 1848 }
sPymbed 16:048e5e270a58 1849 /* now swap bytes y...x-1 */
sPymbed 16:048e5e270a58 1850 z = x - 1;
sPymbed 16:048e5e270a58 1851 while (y < z) {
sPymbed 16:048e5e270a58 1852 mask = out[y];
sPymbed 16:048e5e270a58 1853 out[y] = out[z];
sPymbed 16:048e5e270a58 1854 out[z] = mask;
sPymbed 16:048e5e270a58 1855 ++y;
sPymbed 16:048e5e270a58 1856 --z;
sPymbed 16:048e5e270a58 1857 }
sPymbed 16:048e5e270a58 1858 }
sPymbed 16:048e5e270a58 1859 else {
sPymbed 16:048e5e270a58 1860 out[x++] = 0x00; /* zero value */
sPymbed 16:048e5e270a58 1861 }
sPymbed 16:048e5e270a58 1862
sPymbed 16:048e5e270a58 1863 /* next word */
sPymbed 16:048e5e270a58 1864 if (i < (int)inSz - 1) {
sPymbed 16:048e5e270a58 1865 d = in[i + 1];
sPymbed 16:048e5e270a58 1866 }
sPymbed 16:048e5e270a58 1867 }
sPymbed 16:048e5e270a58 1868 }
sPymbed 16:048e5e270a58 1869
sPymbed 16:048e5e270a58 1870 /* return length */
sPymbed 16:048e5e270a58 1871 *outSz = len;
sPymbed 16:048e5e270a58 1872
sPymbed 16:048e5e270a58 1873 return 0;
sPymbed 16:048e5e270a58 1874 }
sPymbed 16:048e5e270a58 1875 #endif /* HAVE_OID_ENCODING */
sPymbed 16:048e5e270a58 1876
sPymbed 16:048e5e270a58 1877 #ifdef HAVE_OID_DECODING
sPymbed 16:048e5e270a58 1878 int DecodeObjectId(const byte* in, word32 inSz, word16* out, word32* outSz)
sPymbed 16:048e5e270a58 1879 {
sPymbed 16:048e5e270a58 1880 int x = 0, y = 0;
sPymbed 16:048e5e270a58 1881 word32 t = 0;
sPymbed 16:048e5e270a58 1882
sPymbed 16:048e5e270a58 1883 /* check args */
sPymbed 16:048e5e270a58 1884 if (in == NULL || outSz == NULL) {
sPymbed 16:048e5e270a58 1885 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 1886 }
sPymbed 16:048e5e270a58 1887
sPymbed 16:048e5e270a58 1888 /* decode bytes */
sPymbed 16:048e5e270a58 1889 while (inSz--) {
sPymbed 16:048e5e270a58 1890 t = (t << 7) | (in[x] & 0x7F);
sPymbed 16:048e5e270a58 1891 if (!(in[x] & 0x80)) {
sPymbed 16:048e5e270a58 1892 if (y >= (int)*outSz) {
sPymbed 16:048e5e270a58 1893 return BUFFER_E;
sPymbed 16:048e5e270a58 1894 }
sPymbed 16:048e5e270a58 1895 if (y == 0) {
sPymbed 16:048e5e270a58 1896 out[0] = (t / 40);
sPymbed 16:048e5e270a58 1897 out[1] = (t % 40);
sPymbed 16:048e5e270a58 1898 y = 2;
sPymbed 16:048e5e270a58 1899 }
sPymbed 16:048e5e270a58 1900 else {
sPymbed 16:048e5e270a58 1901 out[y++] = t;
sPymbed 16:048e5e270a58 1902 }
sPymbed 16:048e5e270a58 1903 t = 0; /* reset tmp */
sPymbed 16:048e5e270a58 1904 }
sPymbed 16:048e5e270a58 1905 x++;
sPymbed 16:048e5e270a58 1906 }
sPymbed 16:048e5e270a58 1907
sPymbed 16:048e5e270a58 1908 /* return length */
sPymbed 16:048e5e270a58 1909 *outSz = y;
sPymbed 16:048e5e270a58 1910
sPymbed 16:048e5e270a58 1911 return 0;
sPymbed 16:048e5e270a58 1912 }
sPymbed 16:048e5e270a58 1913 #endif /* HAVE_OID_DECODING */
sPymbed 16:048e5e270a58 1914
sPymbed 16:048e5e270a58 1915 /* Get the DER/BER encoding of an ASN.1 OBJECT_ID header.
sPymbed 16:048e5e270a58 1916 *
sPymbed 16:048e5e270a58 1917 * input Buffer holding DER/BER encoded data.
sPymbed 16:048e5e270a58 1918 * inOutIdx Current index into buffer to parse.
sPymbed 16:048e5e270a58 1919 * len The number of bytes in the ASN.1 data.
sPymbed 16:048e5e270a58 1920 * maxIdx Length of data in buffer.
sPymbed 16:048e5e270a58 1921 * returns BUFFER_E when there is not enough data to parse.
sPymbed 16:048e5e270a58 1922 * ASN_OBJECt_ID_E when the OBJECT_ID tag is not found.
sPymbed 16:048e5e270a58 1923 * ASN_PARSE_E when length is invalid.
sPymbed 16:048e5e270a58 1924 * Otherwise, 0 to indicate success.
sPymbed 16:048e5e270a58 1925 */
sPymbed 16:048e5e270a58 1926 static int GetASNObjectId(const byte* input, word32* inOutIdx, int* len,
sPymbed 16:048e5e270a58 1927 word32 maxIdx)
sPymbed 16:048e5e270a58 1928 {
sPymbed 16:048e5e270a58 1929 word32 idx = *inOutIdx;
sPymbed 16:048e5e270a58 1930 byte b;
sPymbed 16:048e5e270a58 1931 int length;
sPymbed 16:048e5e270a58 1932
sPymbed 16:048e5e270a58 1933 if ((idx + 1) > maxIdx)
sPymbed 16:048e5e270a58 1934 return BUFFER_E;
sPymbed 16:048e5e270a58 1935
sPymbed 16:048e5e270a58 1936 b = input[idx++];
sPymbed 16:048e5e270a58 1937 if (b != ASN_OBJECT_ID)
sPymbed 16:048e5e270a58 1938 return ASN_OBJECT_ID_E;
sPymbed 16:048e5e270a58 1939
sPymbed 16:048e5e270a58 1940 if (GetLength(input, &idx, &length, maxIdx) < 0)
sPymbed 16:048e5e270a58 1941 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 1942
sPymbed 16:048e5e270a58 1943 *len = length;
sPymbed 16:048e5e270a58 1944 *inOutIdx = idx;
sPymbed 16:048e5e270a58 1945 return 0;
sPymbed 16:048e5e270a58 1946 }
sPymbed 16:048e5e270a58 1947
sPymbed 16:048e5e270a58 1948 /* Set the DER/BER encoding of the ASN.1 OBJECT_ID header.
sPymbed 16:048e5e270a58 1949 *
sPymbed 16:048e5e270a58 1950 * len Length of the OBJECT_ID data.
sPymbed 16:048e5e270a58 1951 * output Buffer to write into.
sPymbed 16:048e5e270a58 1952 * returns the number of bytes added to the buffer.
sPymbed 16:048e5e270a58 1953 */
sPymbed 16:048e5e270a58 1954 static int SetObjectId(int len, byte* output)
sPymbed 16:048e5e270a58 1955 {
sPymbed 16:048e5e270a58 1956 int idx = 0;
sPymbed 16:048e5e270a58 1957
sPymbed 16:048e5e270a58 1958 output[idx++] = ASN_OBJECT_ID;
sPymbed 16:048e5e270a58 1959 idx += SetLength(len, output + idx);
sPymbed 16:048e5e270a58 1960
sPymbed 16:048e5e270a58 1961 return idx;
sPymbed 16:048e5e270a58 1962 }
sPymbed 16:048e5e270a58 1963
sPymbed 16:048e5e270a58 1964 int GetObjectId(const byte* input, word32* inOutIdx, word32* oid,
sPymbed 16:048e5e270a58 1965 word32 oidType, word32 maxIdx)
sPymbed 16:048e5e270a58 1966 {
sPymbed 16:048e5e270a58 1967 int ret = 0, length;
sPymbed 16:048e5e270a58 1968 word32 idx = *inOutIdx;
sPymbed 16:048e5e270a58 1969 #ifndef NO_VERIFY_OID
sPymbed 16:048e5e270a58 1970 word32 actualOidSz = 0;
sPymbed 16:048e5e270a58 1971 const byte* actualOid;
sPymbed 16:048e5e270a58 1972 #endif /* NO_VERIFY_OID */
sPymbed 16:048e5e270a58 1973
sPymbed 16:048e5e270a58 1974 (void)oidType;
sPymbed 16:048e5e270a58 1975 WOLFSSL_ENTER("GetObjectId()");
sPymbed 16:048e5e270a58 1976 *oid = 0;
sPymbed 16:048e5e270a58 1977
sPymbed 16:048e5e270a58 1978 ret = GetASNObjectId(input, &idx, &length, maxIdx);
sPymbed 16:048e5e270a58 1979 if (ret != 0)
sPymbed 16:048e5e270a58 1980 return ret;
sPymbed 16:048e5e270a58 1981
sPymbed 16:048e5e270a58 1982 #ifndef NO_VERIFY_OID
sPymbed 16:048e5e270a58 1983 actualOid = &input[idx];
sPymbed 16:048e5e270a58 1984 if (length > 0)
sPymbed 16:048e5e270a58 1985 actualOidSz = (word32)length;
sPymbed 16:048e5e270a58 1986 #endif /* NO_VERIFY_OID */
sPymbed 16:048e5e270a58 1987
sPymbed 16:048e5e270a58 1988 while (length--) {
sPymbed 16:048e5e270a58 1989 /* odd HC08 compiler behavior here when input[idx++] */
sPymbed 16:048e5e270a58 1990 *oid += (word32)input[idx];
sPymbed 16:048e5e270a58 1991 idx++;
sPymbed 16:048e5e270a58 1992 }
sPymbed 16:048e5e270a58 1993 /* just sum it up for now */
sPymbed 16:048e5e270a58 1994
sPymbed 16:048e5e270a58 1995 *inOutIdx = idx;
sPymbed 16:048e5e270a58 1996
sPymbed 16:048e5e270a58 1997 #ifndef NO_VERIFY_OID
sPymbed 16:048e5e270a58 1998 {
sPymbed 16:048e5e270a58 1999 const byte* checkOid = NULL;
sPymbed 16:048e5e270a58 2000 word32 checkOidSz;
sPymbed 16:048e5e270a58 2001 #ifdef ASN_DUMP_OID
sPymbed 16:048e5e270a58 2002 word32 i;
sPymbed 16:048e5e270a58 2003 #endif
sPymbed 16:048e5e270a58 2004
sPymbed 16:048e5e270a58 2005 if (oidType != oidIgnoreType) {
sPymbed 16:048e5e270a58 2006 checkOid = OidFromId(*oid, oidType, &checkOidSz);
sPymbed 16:048e5e270a58 2007
sPymbed 16:048e5e270a58 2008 #ifdef ASN_DUMP_OID
sPymbed 16:048e5e270a58 2009 /* support for dumping OID information */
sPymbed 16:048e5e270a58 2010 printf("OID (Type %d, Sz %d, Sum %d): ", oidType, actualOidSz, *oid);
sPymbed 16:048e5e270a58 2011 for (i=0; i<actualOidSz; i++) {
sPymbed 16:048e5e270a58 2012 printf("%d, ", actualOid[i]);
sPymbed 16:048e5e270a58 2013 }
sPymbed 16:048e5e270a58 2014 printf("\n");
sPymbed 16:048e5e270a58 2015 #ifdef HAVE_OID_DECODING
sPymbed 16:048e5e270a58 2016 {
sPymbed 16:048e5e270a58 2017 word16 decOid[16];
sPymbed 16:048e5e270a58 2018 word32 decOidSz = sizeof(decOid);
sPymbed 16:048e5e270a58 2019 ret = DecodeObjectId(actualOid, actualOidSz, decOid, &decOidSz);
sPymbed 16:048e5e270a58 2020 if (ret == 0) {
sPymbed 16:048e5e270a58 2021 printf(" Decoded (Sz %d): ", decOidSz);
sPymbed 16:048e5e270a58 2022 for (i=0; i<decOidSz; i++) {
sPymbed 16:048e5e270a58 2023 printf("%d.", decOid[i]);
sPymbed 16:048e5e270a58 2024 }
sPymbed 16:048e5e270a58 2025 printf("\n");
sPymbed 16:048e5e270a58 2026 }
sPymbed 16:048e5e270a58 2027 else {
sPymbed 16:048e5e270a58 2028 printf("DecodeObjectId failed: %d\n", ret);
sPymbed 16:048e5e270a58 2029 }
sPymbed 16:048e5e270a58 2030 }
sPymbed 16:048e5e270a58 2031 #endif /* HAVE_OID_DECODING */
sPymbed 16:048e5e270a58 2032 #endif /* ASN_DUMP_OID */
sPymbed 16:048e5e270a58 2033
sPymbed 16:048e5e270a58 2034 if (checkOid != NULL &&
sPymbed 16:048e5e270a58 2035 (checkOidSz != actualOidSz ||
sPymbed 16:048e5e270a58 2036 XMEMCMP(actualOid, checkOid, checkOidSz) != 0)) {
sPymbed 16:048e5e270a58 2037 WOLFSSL_MSG("OID Check Failed");
sPymbed 16:048e5e270a58 2038 return ASN_UNKNOWN_OID_E;
sPymbed 16:048e5e270a58 2039 }
sPymbed 16:048e5e270a58 2040 }
sPymbed 16:048e5e270a58 2041 }
sPymbed 16:048e5e270a58 2042 #endif /* NO_VERIFY_OID */
sPymbed 16:048e5e270a58 2043
sPymbed 16:048e5e270a58 2044 return ret;
sPymbed 16:048e5e270a58 2045 }
sPymbed 16:048e5e270a58 2046
sPymbed 16:048e5e270a58 2047 static int SkipObjectId(const byte* input, word32* inOutIdx, word32 maxIdx)
sPymbed 16:048e5e270a58 2048 {
sPymbed 16:048e5e270a58 2049 word32 idx = *inOutIdx;
sPymbed 16:048e5e270a58 2050 int length;
sPymbed 16:048e5e270a58 2051 int ret;
sPymbed 16:048e5e270a58 2052
sPymbed 16:048e5e270a58 2053 ret = GetASNObjectId(input, &idx, &length, maxIdx);
sPymbed 16:048e5e270a58 2054 if (ret != 0)
sPymbed 16:048e5e270a58 2055 return ret;
sPymbed 16:048e5e270a58 2056
sPymbed 16:048e5e270a58 2057 idx += length;
sPymbed 16:048e5e270a58 2058 *inOutIdx = idx;
sPymbed 16:048e5e270a58 2059
sPymbed 16:048e5e270a58 2060 return 0;
sPymbed 16:048e5e270a58 2061 }
sPymbed 16:048e5e270a58 2062
sPymbed 16:048e5e270a58 2063 WOLFSSL_LOCAL int GetAlgoId(const byte* input, word32* inOutIdx, word32* oid,
sPymbed 16:048e5e270a58 2064 word32 oidType, word32 maxIdx)
sPymbed 16:048e5e270a58 2065 {
sPymbed 16:048e5e270a58 2066 int length;
sPymbed 16:048e5e270a58 2067 word32 idx = *inOutIdx;
sPymbed 16:048e5e270a58 2068 int ret;
sPymbed 16:048e5e270a58 2069 *oid = 0;
sPymbed 16:048e5e270a58 2070
sPymbed 16:048e5e270a58 2071 WOLFSSL_ENTER("GetAlgoId");
sPymbed 16:048e5e270a58 2072
sPymbed 16:048e5e270a58 2073 if (GetSequence(input, &idx, &length, maxIdx) < 0)
sPymbed 16:048e5e270a58 2074 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 2075
sPymbed 16:048e5e270a58 2076 if (GetObjectId(input, &idx, oid, oidType, maxIdx) < 0)
sPymbed 16:048e5e270a58 2077 return ASN_OBJECT_ID_E;
sPymbed 16:048e5e270a58 2078
sPymbed 16:048e5e270a58 2079 /* could have NULL tag and 0 terminator, but may not */
sPymbed 16:048e5e270a58 2080 if (idx < maxIdx && input[idx] == ASN_TAG_NULL) {
sPymbed 16:048e5e270a58 2081 ret = GetASNNull(input, &idx, maxIdx);
sPymbed 16:048e5e270a58 2082 if (ret != 0)
sPymbed 16:048e5e270a58 2083 return ret;
sPymbed 16:048e5e270a58 2084 }
sPymbed 16:048e5e270a58 2085
sPymbed 16:048e5e270a58 2086 *inOutIdx = idx;
sPymbed 16:048e5e270a58 2087
sPymbed 16:048e5e270a58 2088 return 0;
sPymbed 16:048e5e270a58 2089 }
sPymbed 16:048e5e270a58 2090
sPymbed 16:048e5e270a58 2091 #ifndef NO_RSA
sPymbed 16:048e5e270a58 2092
sPymbed 16:048e5e270a58 2093 #ifndef HAVE_USER_RSA
sPymbed 16:048e5e270a58 2094 int wc_RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
sPymbed 16:048e5e270a58 2095 word32 inSz)
sPymbed 16:048e5e270a58 2096 {
sPymbed 16:048e5e270a58 2097 int version, length;
sPymbed 16:048e5e270a58 2098
sPymbed 16:048e5e270a58 2099 if (inOutIdx == NULL) {
sPymbed 16:048e5e270a58 2100 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 2101 }
sPymbed 16:048e5e270a58 2102 if (GetSequence(input, inOutIdx, &length, inSz) < 0)
sPymbed 16:048e5e270a58 2103 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 2104
sPymbed 16:048e5e270a58 2105 if (GetMyVersion(input, inOutIdx, &version, inSz) < 0)
sPymbed 16:048e5e270a58 2106 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 2107
sPymbed 16:048e5e270a58 2108 key->type = RSA_PRIVATE;
sPymbed 16:048e5e270a58 2109
sPymbed 16:048e5e270a58 2110 if (GetInt(&key->n, input, inOutIdx, inSz) < 0 ||
sPymbed 16:048e5e270a58 2111 GetInt(&key->e, input, inOutIdx, inSz) < 0 ||
sPymbed 16:048e5e270a58 2112 GetInt(&key->d, input, inOutIdx, inSz) < 0 ||
sPymbed 16:048e5e270a58 2113 GetInt(&key->p, input, inOutIdx, inSz) < 0 ||
sPymbed 16:048e5e270a58 2114 GetInt(&key->q, input, inOutIdx, inSz) < 0) return ASN_RSA_KEY_E;
sPymbed 16:048e5e270a58 2115 #if defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || !defined(RSA_LOW_MEM)
sPymbed 16:048e5e270a58 2116 if (GetInt(&key->dP, input, inOutIdx, inSz) < 0 ||
sPymbed 16:048e5e270a58 2117 GetInt(&key->dQ, input, inOutIdx, inSz) < 0 ||
sPymbed 16:048e5e270a58 2118 GetInt(&key->u, input, inOutIdx, inSz) < 0 ) return ASN_RSA_KEY_E;
sPymbed 16:048e5e270a58 2119 #else
sPymbed 16:048e5e270a58 2120 if (SkipInt(input, inOutIdx, inSz) < 0 ||
sPymbed 16:048e5e270a58 2121 SkipInt(input, inOutIdx, inSz) < 0 ||
sPymbed 16:048e5e270a58 2122 SkipInt(input, inOutIdx, inSz) < 0 ) return ASN_RSA_KEY_E;
sPymbed 16:048e5e270a58 2123 #endif
sPymbed 16:048e5e270a58 2124
sPymbed 16:048e5e270a58 2125 #ifdef WOLFSSL_XILINX_CRYPT
sPymbed 16:048e5e270a58 2126 if (wc_InitRsaHw(key) != 0) {
sPymbed 16:048e5e270a58 2127 return BAD_STATE_E;
sPymbed 16:048e5e270a58 2128 }
sPymbed 16:048e5e270a58 2129 #endif
sPymbed 16:048e5e270a58 2130
sPymbed 16:048e5e270a58 2131 return 0;
sPymbed 16:048e5e270a58 2132 }
sPymbed 16:048e5e270a58 2133 #endif /* HAVE_USER_RSA */
sPymbed 16:048e5e270a58 2134 #endif /* NO_RSA */
sPymbed 16:048e5e270a58 2135
sPymbed 16:048e5e270a58 2136 /* Remove PKCS8 header, place inOutIdx at beginning of traditional,
sPymbed 16:048e5e270a58 2137 * return traditional length on success, negative on error */
sPymbed 16:048e5e270a58 2138 int ToTraditionalInline(const byte* input, word32* inOutIdx, word32 sz)
sPymbed 16:048e5e270a58 2139 {
sPymbed 16:048e5e270a58 2140 word32 idx, oid;
sPymbed 16:048e5e270a58 2141 int version, length;
sPymbed 16:048e5e270a58 2142 int ret;
sPymbed 16:048e5e270a58 2143
sPymbed 16:048e5e270a58 2144 if (input == NULL || inOutIdx == NULL)
sPymbed 16:048e5e270a58 2145 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 2146
sPymbed 16:048e5e270a58 2147 idx = *inOutIdx;
sPymbed 16:048e5e270a58 2148
sPymbed 16:048e5e270a58 2149 if (GetSequence(input, &idx, &length, sz) < 0)
sPymbed 16:048e5e270a58 2150 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 2151
sPymbed 16:048e5e270a58 2152 if (GetMyVersion(input, &idx, &version, sz) < 0)
sPymbed 16:048e5e270a58 2153 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 2154
sPymbed 16:048e5e270a58 2155 if (GetAlgoId(input, &idx, &oid, oidKeyType, sz) < 0)
sPymbed 16:048e5e270a58 2156 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 2157
sPymbed 16:048e5e270a58 2158 if (input[idx] == ASN_OBJECT_ID) {
sPymbed 16:048e5e270a58 2159 if (SkipObjectId(input, &idx, sz) < 0)
sPymbed 16:048e5e270a58 2160 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 2161 }
sPymbed 16:048e5e270a58 2162
sPymbed 16:048e5e270a58 2163 ret = GetOctetString(input, &idx, &length, sz);
sPymbed 16:048e5e270a58 2164 if (ret < 0)
sPymbed 16:048e5e270a58 2165 return ret;
sPymbed 16:048e5e270a58 2166
sPymbed 16:048e5e270a58 2167 *inOutIdx = idx;
sPymbed 16:048e5e270a58 2168
sPymbed 16:048e5e270a58 2169 return length;
sPymbed 16:048e5e270a58 2170 }
sPymbed 16:048e5e270a58 2171
sPymbed 16:048e5e270a58 2172 /* Remove PKCS8 header, move beginning of traditional to beginning of input */
sPymbed 16:048e5e270a58 2173 int ToTraditional(byte* input, word32 sz)
sPymbed 16:048e5e270a58 2174 {
sPymbed 16:048e5e270a58 2175 word32 inOutIdx = 0;
sPymbed 16:048e5e270a58 2176 int length;
sPymbed 16:048e5e270a58 2177
sPymbed 16:048e5e270a58 2178 if (input == NULL)
sPymbed 16:048e5e270a58 2179 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 2180
sPymbed 16:048e5e270a58 2181 length = ToTraditionalInline(input, &inOutIdx, sz);
sPymbed 16:048e5e270a58 2182 if (length < 0)
sPymbed 16:048e5e270a58 2183 return length;
sPymbed 16:048e5e270a58 2184
sPymbed 16:048e5e270a58 2185 XMEMMOVE(input, input + inOutIdx, length);
sPymbed 16:048e5e270a58 2186
sPymbed 16:048e5e270a58 2187 return length;
sPymbed 16:048e5e270a58 2188 }
sPymbed 16:048e5e270a58 2189
sPymbed 16:048e5e270a58 2190
sPymbed 16:048e5e270a58 2191 /* find beginning of traditional key inside PKCS#8 unencrypted buffer
sPymbed 16:048e5e270a58 2192 * return traditional length on success, with inOutIdx at beginning of
sPymbed 16:048e5e270a58 2193 * traditional
sPymbed 16:048e5e270a58 2194 * return negative on failure/error */
sPymbed 16:048e5e270a58 2195 int wc_GetPkcs8TraditionalOffset(byte* input, word32* inOutIdx, word32 sz)
sPymbed 16:048e5e270a58 2196 {
sPymbed 16:048e5e270a58 2197 int length;
sPymbed 16:048e5e270a58 2198
sPymbed 16:048e5e270a58 2199 if (input == NULL || inOutIdx == NULL || (*inOutIdx > sz))
sPymbed 16:048e5e270a58 2200 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 2201
sPymbed 16:048e5e270a58 2202 length = ToTraditionalInline(input, inOutIdx, sz);
sPymbed 16:048e5e270a58 2203
sPymbed 16:048e5e270a58 2204 return length;
sPymbed 16:048e5e270a58 2205 }
sPymbed 16:048e5e270a58 2206
sPymbed 16:048e5e270a58 2207
sPymbed 16:048e5e270a58 2208 /* PKCS#8 from RFC 5208
sPymbed 16:048e5e270a58 2209 * This function takes in a DER key and converts it to PKCS#8 format. Used
sPymbed 16:048e5e270a58 2210 * in creating PKCS#12 shrouded key bags.
sPymbed 16:048e5e270a58 2211 * Reverse of ToTraditional
sPymbed 16:048e5e270a58 2212 *
sPymbed 16:048e5e270a58 2213 * PrivateKeyInfo ::= SEQUENCE {
sPymbed 16:048e5e270a58 2214 * version Version,
sPymbed 16:048e5e270a58 2215 * privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
sPymbed 16:048e5e270a58 2216 * privateKey PrivateKey,
sPymbed 16:048e5e270a58 2217 * attributes optional
sPymbed 16:048e5e270a58 2218 * }
sPymbed 16:048e5e270a58 2219 * Version ::= INTEGER
sPymbed 16:048e5e270a58 2220 * PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
sPymbed 16:048e5e270a58 2221 * PrivateKey ::= OCTET STRING
sPymbed 16:048e5e270a58 2222 *
sPymbed 16:048e5e270a58 2223 * out buffer to place result in
sPymbed 16:048e5e270a58 2224 * outSz size of out buffer
sPymbed 16:048e5e270a58 2225 * key buffer with DER key
sPymbed 16:048e5e270a58 2226 * keySz size of key buffer
sPymbed 16:048e5e270a58 2227 * algoID algorithm ID i.e. RSAk
sPymbed 16:048e5e270a58 2228 * curveOID ECC curve oid if used. Should be NULL for RSA keys.
sPymbed 16:048e5e270a58 2229 * oidSz size of curve oid. Is set to 0 if curveOID is NULL.
sPymbed 16:048e5e270a58 2230 *
sPymbed 16:048e5e270a58 2231 * Returns the size of PKCS#8 placed into out. In error cases returns negative
sPymbed 16:048e5e270a58 2232 * values.
sPymbed 16:048e5e270a58 2233 */
sPymbed 16:048e5e270a58 2234 int wc_CreatePKCS8Key(byte* out, word32* outSz, byte* key, word32 keySz,
sPymbed 16:048e5e270a58 2235 int algoID, const byte* curveOID, word32 oidSz)
sPymbed 16:048e5e270a58 2236 {
sPymbed 16:048e5e270a58 2237 word32 keyIdx = 0;
sPymbed 16:048e5e270a58 2238 word32 tmpSz = 0;
sPymbed 16:048e5e270a58 2239 word32 sz;
sPymbed 16:048e5e270a58 2240
sPymbed 16:048e5e270a58 2241
sPymbed 16:048e5e270a58 2242 /* If out is NULL then return the max size needed
sPymbed 16:048e5e270a58 2243 * + 2 for ASN_OBJECT_ID and ASN_OCTET_STRING tags */
sPymbed 16:048e5e270a58 2244 if (out == NULL && outSz != NULL) {
sPymbed 16:048e5e270a58 2245 *outSz = keySz + MAX_SEQ_SZ + MAX_VERSION_SZ + MAX_ALGO_SZ
sPymbed 16:048e5e270a58 2246 + MAX_LENGTH_SZ + MAX_LENGTH_SZ + 2;
sPymbed 16:048e5e270a58 2247
sPymbed 16:048e5e270a58 2248 if (curveOID != NULL)
sPymbed 16:048e5e270a58 2249 *outSz += oidSz + MAX_LENGTH_SZ + 1;
sPymbed 16:048e5e270a58 2250
sPymbed 16:048e5e270a58 2251 WOLFSSL_MSG("Checking size of PKCS8");
sPymbed 16:048e5e270a58 2252
sPymbed 16:048e5e270a58 2253 return LENGTH_ONLY_E;
sPymbed 16:048e5e270a58 2254 }
sPymbed 16:048e5e270a58 2255
sPymbed 16:048e5e270a58 2256 WOLFSSL_ENTER("wc_CreatePKCS8Key()");
sPymbed 16:048e5e270a58 2257
sPymbed 16:048e5e270a58 2258 if (key == NULL || out == NULL || outSz == NULL) {
sPymbed 16:048e5e270a58 2259 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 2260 }
sPymbed 16:048e5e270a58 2261
sPymbed 16:048e5e270a58 2262 /* check the buffer has enough room for largest possible size */
sPymbed 16:048e5e270a58 2263 if (curveOID != NULL) {
sPymbed 16:048e5e270a58 2264 if (*outSz < (keySz + MAX_SEQ_SZ + MAX_VERSION_SZ + MAX_ALGO_SZ
sPymbed 16:048e5e270a58 2265 + MAX_LENGTH_SZ + MAX_LENGTH_SZ + 3 + oidSz + MAX_LENGTH_SZ))
sPymbed 16:048e5e270a58 2266 return BUFFER_E;
sPymbed 16:048e5e270a58 2267 }
sPymbed 16:048e5e270a58 2268 else {
sPymbed 16:048e5e270a58 2269 oidSz = 0; /* with no curveOID oid size must be 0 */
sPymbed 16:048e5e270a58 2270 if (*outSz < (keySz + MAX_SEQ_SZ + MAX_VERSION_SZ + MAX_ALGO_SZ
sPymbed 16:048e5e270a58 2271 + MAX_LENGTH_SZ + MAX_LENGTH_SZ + 2))
sPymbed 16:048e5e270a58 2272 return BUFFER_E;
sPymbed 16:048e5e270a58 2273 }
sPymbed 16:048e5e270a58 2274
sPymbed 16:048e5e270a58 2275 /* PrivateKeyInfo ::= SEQUENCE */
sPymbed 16:048e5e270a58 2276 keyIdx += MAX_SEQ_SZ; /* save room for sequence */
sPymbed 16:048e5e270a58 2277
sPymbed 16:048e5e270a58 2278 /* version Version
sPymbed 16:048e5e270a58 2279 * no header information just INTEGER */
sPymbed 16:048e5e270a58 2280 sz = SetMyVersion(PKCS8v0, out + keyIdx, 0);
sPymbed 16:048e5e270a58 2281 tmpSz += sz; keyIdx += sz;
sPymbed 16:048e5e270a58 2282
sPymbed 16:048e5e270a58 2283 /* privateKeyAlgorithm PrivateKeyAlgorithmIdentifier */
sPymbed 16:048e5e270a58 2284 sz = 0; /* set sz to 0 and get privateKey oid buffer size needed */
sPymbed 16:048e5e270a58 2285 if (curveOID != NULL && oidSz > 0) {
sPymbed 16:048e5e270a58 2286 byte buf[MAX_LENGTH_SZ];
sPymbed 16:048e5e270a58 2287 sz = SetLength(oidSz, buf);
sPymbed 16:048e5e270a58 2288 sz += 1; /* plus one for ASN object id */
sPymbed 16:048e5e270a58 2289 }
sPymbed 16:048e5e270a58 2290 sz = SetAlgoID(algoID, out + keyIdx, oidKeyType, oidSz + sz);
sPymbed 16:048e5e270a58 2291 tmpSz += sz; keyIdx += sz;
sPymbed 16:048e5e270a58 2292
sPymbed 16:048e5e270a58 2293 /* privateKey PrivateKey *
sPymbed 16:048e5e270a58 2294 * pkcs8 ecc uses slightly different format. Places curve oid in
sPymbed 16:048e5e270a58 2295 * buffer */
sPymbed 16:048e5e270a58 2296 if (curveOID != NULL && oidSz > 0) {
sPymbed 16:048e5e270a58 2297 sz = SetObjectId(oidSz, out + keyIdx);
sPymbed 16:048e5e270a58 2298 keyIdx += sz; tmpSz += sz;
sPymbed 16:048e5e270a58 2299 XMEMCPY(out + keyIdx, curveOID, oidSz);
sPymbed 16:048e5e270a58 2300 keyIdx += oidSz; tmpSz += oidSz;
sPymbed 16:048e5e270a58 2301 }
sPymbed 16:048e5e270a58 2302
sPymbed 16:048e5e270a58 2303 sz = SetOctetString(keySz, out + keyIdx);
sPymbed 16:048e5e270a58 2304 keyIdx += sz; tmpSz += sz;
sPymbed 16:048e5e270a58 2305 XMEMCPY(out + keyIdx, key, keySz);
sPymbed 16:048e5e270a58 2306 tmpSz += keySz;
sPymbed 16:048e5e270a58 2307
sPymbed 16:048e5e270a58 2308 /* attributes optional
sPymbed 16:048e5e270a58 2309 * No attributes currently added */
sPymbed 16:048e5e270a58 2310
sPymbed 16:048e5e270a58 2311 /* rewind and add sequence */
sPymbed 16:048e5e270a58 2312 sz = SetSequence(tmpSz, out);
sPymbed 16:048e5e270a58 2313 XMEMMOVE(out + sz, out + MAX_SEQ_SZ, tmpSz);
sPymbed 16:048e5e270a58 2314
sPymbed 16:048e5e270a58 2315 return tmpSz + sz;
sPymbed 16:048e5e270a58 2316 }
sPymbed 16:048e5e270a58 2317
sPymbed 16:048e5e270a58 2318
sPymbed 16:048e5e270a58 2319 /* check that the private key is a pair for the public key in certificate
sPymbed 16:048e5e270a58 2320 * return 1 (true) on match
sPymbed 16:048e5e270a58 2321 * return 0 or negative value on failure/error
sPymbed 16:048e5e270a58 2322 *
sPymbed 16:048e5e270a58 2323 * key : buffer holding DER fromat key
sPymbed 16:048e5e270a58 2324 * keySz : size of key buffer
sPymbed 16:048e5e270a58 2325 * der : a initialized and parsed DecodedCert holding a certificate */
sPymbed 16:048e5e270a58 2326 int wc_CheckPrivateKey(byte* key, word32 keySz, DecodedCert* der)
sPymbed 16:048e5e270a58 2327 {
sPymbed 16:048e5e270a58 2328 int ret;
sPymbed 16:048e5e270a58 2329 (void)keySz;
sPymbed 16:048e5e270a58 2330
sPymbed 16:048e5e270a58 2331 if (key == NULL || der == NULL) {
sPymbed 16:048e5e270a58 2332 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 2333 }
sPymbed 16:048e5e270a58 2334
sPymbed 16:048e5e270a58 2335 #if !defined(NO_RSA)
sPymbed 16:048e5e270a58 2336 /* test if RSA key */
sPymbed 16:048e5e270a58 2337 if (der->keyOID == RSAk) {
sPymbed 16:048e5e270a58 2338 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 2339 RsaKey* a = NULL;
sPymbed 16:048e5e270a58 2340 RsaKey* b = NULL;
sPymbed 16:048e5e270a58 2341 #else
sPymbed 16:048e5e270a58 2342 RsaKey a[1], b[1];
sPymbed 16:048e5e270a58 2343 #endif
sPymbed 16:048e5e270a58 2344 word32 keyIdx = 0;
sPymbed 16:048e5e270a58 2345
sPymbed 16:048e5e270a58 2346 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 2347 a = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_RSA);
sPymbed 16:048e5e270a58 2348 if (a == NULL)
sPymbed 16:048e5e270a58 2349 return MEMORY_E;
sPymbed 16:048e5e270a58 2350 b = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_RSA);
sPymbed 16:048e5e270a58 2351 if (b == NULL) {
sPymbed 16:048e5e270a58 2352 XFREE(a, NULL, DYNAMIC_TYPE_RSA);
sPymbed 16:048e5e270a58 2353 return MEMORY_E;
sPymbed 16:048e5e270a58 2354 }
sPymbed 16:048e5e270a58 2355 #endif
sPymbed 16:048e5e270a58 2356
sPymbed 16:048e5e270a58 2357 if ((ret = wc_InitRsaKey(a, NULL)) < 0) {
sPymbed 16:048e5e270a58 2358 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 2359 XFREE(b, NULL, DYNAMIC_TYPE_RSA);
sPymbed 16:048e5e270a58 2360 XFREE(a, NULL, DYNAMIC_TYPE_RSA);
sPymbed 16:048e5e270a58 2361 #endif
sPymbed 16:048e5e270a58 2362 return ret;
sPymbed 16:048e5e270a58 2363 }
sPymbed 16:048e5e270a58 2364 if ((ret = wc_InitRsaKey(b, NULL)) < 0) {
sPymbed 16:048e5e270a58 2365 wc_FreeRsaKey(a);
sPymbed 16:048e5e270a58 2366 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 2367 XFREE(b, NULL, DYNAMIC_TYPE_RSA);
sPymbed 16:048e5e270a58 2368 XFREE(a, NULL, DYNAMIC_TYPE_RSA);
sPymbed 16:048e5e270a58 2369 #endif
sPymbed 16:048e5e270a58 2370 return ret;
sPymbed 16:048e5e270a58 2371 }
sPymbed 16:048e5e270a58 2372 if ((ret = wc_RsaPrivateKeyDecode(key, &keyIdx, a, keySz)) == 0) {
sPymbed 16:048e5e270a58 2373 WOLFSSL_MSG("Checking RSA key pair");
sPymbed 16:048e5e270a58 2374 keyIdx = 0; /* reset to 0 for parsing public key */
sPymbed 16:048e5e270a58 2375
sPymbed 16:048e5e270a58 2376 if ((ret = wc_RsaPublicKeyDecode(der->publicKey, &keyIdx, b,
sPymbed 16:048e5e270a58 2377 der->pubKeySize)) == 0) {
sPymbed 16:048e5e270a58 2378 /* limit for user RSA crypto because of RsaKey
sPymbed 16:048e5e270a58 2379 * dereference. */
sPymbed 16:048e5e270a58 2380 #if defined(HAVE_USER_RSA)
sPymbed 16:048e5e270a58 2381 WOLFSSL_MSG("Cannot verify RSA pair with user RSA");
sPymbed 16:048e5e270a58 2382 ret = 1; /* return first RSA cert as match */
sPymbed 16:048e5e270a58 2383 #else
sPymbed 16:048e5e270a58 2384 /* both keys extracted successfully now check n and e
sPymbed 16:048e5e270a58 2385 * values are the same. This is dereferencing RsaKey */
sPymbed 16:048e5e270a58 2386 if (mp_cmp(&(a->n), &(b->n)) != MP_EQ ||
sPymbed 16:048e5e270a58 2387 mp_cmp(&(a->e), &(b->e)) != MP_EQ) {
sPymbed 16:048e5e270a58 2388 ret = MP_CMP_E;
sPymbed 16:048e5e270a58 2389 }
sPymbed 16:048e5e270a58 2390 else
sPymbed 16:048e5e270a58 2391 ret = 1;
sPymbed 16:048e5e270a58 2392 #endif
sPymbed 16:048e5e270a58 2393 }
sPymbed 16:048e5e270a58 2394 }
sPymbed 16:048e5e270a58 2395 wc_FreeRsaKey(b);
sPymbed 16:048e5e270a58 2396 wc_FreeRsaKey(a);
sPymbed 16:048e5e270a58 2397 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 2398 XFREE(b, NULL, DYNAMIC_TYPE_RSA);
sPymbed 16:048e5e270a58 2399 XFREE(a, NULL, DYNAMIC_TYPE_RSA);
sPymbed 16:048e5e270a58 2400 #endif
sPymbed 16:048e5e270a58 2401 }
sPymbed 16:048e5e270a58 2402 else
sPymbed 16:048e5e270a58 2403 #endif /* NO_RSA */
sPymbed 16:048e5e270a58 2404
sPymbed 16:048e5e270a58 2405 #ifdef HAVE_ECC
sPymbed 16:048e5e270a58 2406 if (der->keyOID == ECDSAk) {
sPymbed 16:048e5e270a58 2407 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 2408 ecc_key* key_pair = NULL;
sPymbed 16:048e5e270a58 2409 byte* privDer;
sPymbed 16:048e5e270a58 2410 #else
sPymbed 16:048e5e270a58 2411 ecc_key key_pair[1];
sPymbed 16:048e5e270a58 2412 byte privDer[MAX_ECC_BYTES];
sPymbed 16:048e5e270a58 2413 #endif
sPymbed 16:048e5e270a58 2414 word32 privSz = MAX_ECC_BYTES;
sPymbed 16:048e5e270a58 2415 word32 keyIdx = 0;
sPymbed 16:048e5e270a58 2416
sPymbed 16:048e5e270a58 2417 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 2418 key_pair = (ecc_key*)XMALLOC(sizeof(ecc_key), NULL, DYNAMIC_TYPE_ECC);
sPymbed 16:048e5e270a58 2419 if (key_pair == NULL)
sPymbed 16:048e5e270a58 2420 return MEMORY_E;
sPymbed 16:048e5e270a58 2421 privDer = (byte*)XMALLOC(MAX_ECC_BYTES, NULL, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 2422 if (privDer == NULL) {
sPymbed 16:048e5e270a58 2423 XFREE(key_pair, NULL, DYNAMIC_TYPE_ECC);
sPymbed 16:048e5e270a58 2424 return MEMORY_E;
sPymbed 16:048e5e270a58 2425 }
sPymbed 16:048e5e270a58 2426 #endif
sPymbed 16:048e5e270a58 2427
sPymbed 16:048e5e270a58 2428 if ((ret = wc_ecc_init(key_pair)) < 0) {
sPymbed 16:048e5e270a58 2429 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 2430 XFREE(privDer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 2431 XFREE(key_pair, NULL, DYNAMIC_TYPE_ECC);
sPymbed 16:048e5e270a58 2432 #endif
sPymbed 16:048e5e270a58 2433 return ret;
sPymbed 16:048e5e270a58 2434 }
sPymbed 16:048e5e270a58 2435
sPymbed 16:048e5e270a58 2436 if ((ret = wc_EccPrivateKeyDecode(key, &keyIdx, key_pair,
sPymbed 16:048e5e270a58 2437 keySz)) == 0) {
sPymbed 16:048e5e270a58 2438 WOLFSSL_MSG("Checking ECC key pair");
sPymbed 16:048e5e270a58 2439
sPymbed 16:048e5e270a58 2440 if ((ret = wc_ecc_export_private_only(key_pair, privDer, &privSz))
sPymbed 16:048e5e270a58 2441 == 0) {
sPymbed 16:048e5e270a58 2442 wc_ecc_free(key_pair);
sPymbed 16:048e5e270a58 2443 ret = wc_ecc_init(key_pair);
sPymbed 16:048e5e270a58 2444 if (ret == 0) {
sPymbed 16:048e5e270a58 2445 ret = wc_ecc_import_private_key((const byte*)privDer,
sPymbed 16:048e5e270a58 2446 privSz, (const byte*)der->publicKey,
sPymbed 16:048e5e270a58 2447 der->pubKeySize, key_pair);
sPymbed 16:048e5e270a58 2448 }
sPymbed 16:048e5e270a58 2449
sPymbed 16:048e5e270a58 2450 /* public and private extracted successfuly now check if is
sPymbed 16:048e5e270a58 2451 * a pair and also do sanity checks on key. wc_ecc_check_key
sPymbed 16:048e5e270a58 2452 * checks that private * base generator equals pubkey */
sPymbed 16:048e5e270a58 2453 if (ret == 0) {
sPymbed 16:048e5e270a58 2454 if ((ret = wc_ecc_check_key(key_pair)) == 0) {
sPymbed 16:048e5e270a58 2455 ret = 1;
sPymbed 16:048e5e270a58 2456 }
sPymbed 16:048e5e270a58 2457 }
sPymbed 16:048e5e270a58 2458 ForceZero(privDer, privSz);
sPymbed 16:048e5e270a58 2459 }
sPymbed 16:048e5e270a58 2460 }
sPymbed 16:048e5e270a58 2461 wc_ecc_free(key_pair);
sPymbed 16:048e5e270a58 2462 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 2463 XFREE(privDer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 2464 XFREE(key_pair, NULL, DYNAMIC_TYPE_ECC);
sPymbed 16:048e5e270a58 2465 #endif
sPymbed 16:048e5e270a58 2466 }
sPymbed 16:048e5e270a58 2467 else
sPymbed 16:048e5e270a58 2468 #endif /* HAVE_ECC */
sPymbed 16:048e5e270a58 2469
sPymbed 16:048e5e270a58 2470 #ifdef HAVE_ED25519
sPymbed 16:048e5e270a58 2471 if (der->keyOID == ED25519k) {
sPymbed 16:048e5e270a58 2472 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 2473 ed25519_key* key_pair = NULL;
sPymbed 16:048e5e270a58 2474 #else
sPymbed 16:048e5e270a58 2475 ed25519_key key_pair[1];
sPymbed 16:048e5e270a58 2476 #endif
sPymbed 16:048e5e270a58 2477 word32 keyIdx = 0;
sPymbed 16:048e5e270a58 2478
sPymbed 16:048e5e270a58 2479 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 2480 key_pair = (ed25519_key*)XMALLOC(sizeof(ed25519_key), NULL,
sPymbed 16:048e5e270a58 2481 DYNAMIC_TYPE_ED25519);
sPymbed 16:048e5e270a58 2482 if (key_pair == NULL)
sPymbed 16:048e5e270a58 2483 return MEMORY_E;
sPymbed 16:048e5e270a58 2484 #endif
sPymbed 16:048e5e270a58 2485
sPymbed 16:048e5e270a58 2486 if ((ret = wc_ed25519_init(key_pair)) < 0) {
sPymbed 16:048e5e270a58 2487 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 2488 XFREE(key_pair, NULL, DYNAMIC_TYPE_ED25519);
sPymbed 16:048e5e270a58 2489 #endif
sPymbed 16:048e5e270a58 2490 return ret;
sPymbed 16:048e5e270a58 2491 }
sPymbed 16:048e5e270a58 2492 if ((ret = wc_Ed25519PrivateKeyDecode(key, &keyIdx, key_pair,
sPymbed 16:048e5e270a58 2493 keySz)) == 0) {
sPymbed 16:048e5e270a58 2494 WOLFSSL_MSG("Checking ED25519 key pair");
sPymbed 16:048e5e270a58 2495 keyIdx = 0;
sPymbed 16:048e5e270a58 2496 if ((ret = wc_ed25519_import_public(der->publicKey, der->pubKeySize,
sPymbed 16:048e5e270a58 2497 key_pair)) == 0) {
sPymbed 16:048e5e270a58 2498 /* public and private extracted successfuly no check if is
sPymbed 16:048e5e270a58 2499 * a pair and also do sanity checks on key. wc_ecc_check_key
sPymbed 16:048e5e270a58 2500 * checks that private * base generator equals pubkey */
sPymbed 16:048e5e270a58 2501 if ((ret = wc_ed25519_check_key(key_pair)) == 0)
sPymbed 16:048e5e270a58 2502 ret = 1;
sPymbed 16:048e5e270a58 2503 }
sPymbed 16:048e5e270a58 2504 }
sPymbed 16:048e5e270a58 2505 wc_ed25519_free(key_pair);
sPymbed 16:048e5e270a58 2506 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 2507 XFREE(key_pair, NULL, DYNAMIC_TYPE_ED25519);
sPymbed 16:048e5e270a58 2508 #endif
sPymbed 16:048e5e270a58 2509 }
sPymbed 16:048e5e270a58 2510 else
sPymbed 16:048e5e270a58 2511 #endif
sPymbed 16:048e5e270a58 2512 {
sPymbed 16:048e5e270a58 2513 ret = 0;
sPymbed 16:048e5e270a58 2514 }
sPymbed 16:048e5e270a58 2515
sPymbed 16:048e5e270a58 2516 (void)keySz;
sPymbed 16:048e5e270a58 2517
sPymbed 16:048e5e270a58 2518 return ret;
sPymbed 16:048e5e270a58 2519 }
sPymbed 16:048e5e270a58 2520
sPymbed 16:048e5e270a58 2521 #ifndef NO_PWDBASED
sPymbed 16:048e5e270a58 2522
sPymbed 16:048e5e270a58 2523 /* Check To see if PKCS version algo is supported, set id if it is return 0
sPymbed 16:048e5e270a58 2524 < 0 on error */
sPymbed 16:048e5e270a58 2525 static int CheckAlgo(int first, int second, int* id, int* version)
sPymbed 16:048e5e270a58 2526 {
sPymbed 16:048e5e270a58 2527 *id = ALGO_ID_E;
sPymbed 16:048e5e270a58 2528 *version = PKCS5; /* default */
sPymbed 16:048e5e270a58 2529
sPymbed 16:048e5e270a58 2530 if (first == 1) {
sPymbed 16:048e5e270a58 2531 switch (second) {
sPymbed 16:048e5e270a58 2532 #if !defined(NO_SHA)
sPymbed 16:048e5e270a58 2533 #ifndef NO_RC4
sPymbed 16:048e5e270a58 2534 case PBE_SHA1_RC4_128:
sPymbed 16:048e5e270a58 2535 *id = PBE_SHA1_RC4_128;
sPymbed 16:048e5e270a58 2536 *version = PKCS12v1;
sPymbed 16:048e5e270a58 2537 return 0;
sPymbed 16:048e5e270a58 2538 #endif
sPymbed 16:048e5e270a58 2539 #ifndef NO_DES3
sPymbed 16:048e5e270a58 2540 case PBE_SHA1_DES3:
sPymbed 16:048e5e270a58 2541 *id = PBE_SHA1_DES3;
sPymbed 16:048e5e270a58 2542 *version = PKCS12v1;
sPymbed 16:048e5e270a58 2543 return 0;
sPymbed 16:048e5e270a58 2544 #endif
sPymbed 16:048e5e270a58 2545 #endif /* !NO_SHA */
sPymbed 16:048e5e270a58 2546 default:
sPymbed 16:048e5e270a58 2547 return ALGO_ID_E;
sPymbed 16:048e5e270a58 2548 }
sPymbed 16:048e5e270a58 2549 }
sPymbed 16:048e5e270a58 2550
sPymbed 16:048e5e270a58 2551 if (first != PKCS5)
sPymbed 16:048e5e270a58 2552 return ASN_INPUT_E; /* VERSION ERROR */
sPymbed 16:048e5e270a58 2553
sPymbed 16:048e5e270a58 2554 if (second == PBES2) {
sPymbed 16:048e5e270a58 2555 *version = PKCS5v2;
sPymbed 16:048e5e270a58 2556 return 0;
sPymbed 16:048e5e270a58 2557 }
sPymbed 16:048e5e270a58 2558
sPymbed 16:048e5e270a58 2559 switch (second) {
sPymbed 16:048e5e270a58 2560 #ifndef NO_DES3
sPymbed 16:048e5e270a58 2561 #ifndef NO_MD5
sPymbed 16:048e5e270a58 2562 case 3: /* see RFC 2898 for ids */
sPymbed 16:048e5e270a58 2563 *id = PBE_MD5_DES;
sPymbed 16:048e5e270a58 2564 return 0;
sPymbed 16:048e5e270a58 2565 #endif
sPymbed 16:048e5e270a58 2566 #ifndef NO_SHA
sPymbed 16:048e5e270a58 2567 case 10:
sPymbed 16:048e5e270a58 2568 *id = PBE_SHA1_DES;
sPymbed 16:048e5e270a58 2569 return 0;
sPymbed 16:048e5e270a58 2570 #endif
sPymbed 16:048e5e270a58 2571 #endif /* !NO_DES3 */
sPymbed 16:048e5e270a58 2572 default:
sPymbed 16:048e5e270a58 2573 return ALGO_ID_E;
sPymbed 16:048e5e270a58 2574
sPymbed 16:048e5e270a58 2575 }
sPymbed 16:048e5e270a58 2576 }
sPymbed 16:048e5e270a58 2577
sPymbed 16:048e5e270a58 2578
sPymbed 16:048e5e270a58 2579 /* Check To see if PKCS v2 algo is supported, set id if it is return 0
sPymbed 16:048e5e270a58 2580 < 0 on error */
sPymbed 16:048e5e270a58 2581 static int CheckAlgoV2(int oid, int* id)
sPymbed 16:048e5e270a58 2582 {
sPymbed 16:048e5e270a58 2583 (void)id; /* not used if AES and DES3 disabled */
sPymbed 16:048e5e270a58 2584 switch (oid) {
sPymbed 16:048e5e270a58 2585 #if !defined(NO_DES3) && !defined(NO_SHA)
sPymbed 16:048e5e270a58 2586 case DESb:
sPymbed 16:048e5e270a58 2587 *id = PBE_SHA1_DES;
sPymbed 16:048e5e270a58 2588 return 0;
sPymbed 16:048e5e270a58 2589 case DES3b:
sPymbed 16:048e5e270a58 2590 *id = PBE_SHA1_DES3;
sPymbed 16:048e5e270a58 2591 return 0;
sPymbed 16:048e5e270a58 2592 #endif
sPymbed 16:048e5e270a58 2593 #ifdef WOLFSSL_AES_256
sPymbed 16:048e5e270a58 2594 case AES256CBCb:
sPymbed 16:048e5e270a58 2595 *id = PBE_AES256_CBC;
sPymbed 16:048e5e270a58 2596 return 0;
sPymbed 16:048e5e270a58 2597 #endif
sPymbed 16:048e5e270a58 2598 default:
sPymbed 16:048e5e270a58 2599 return ALGO_ID_E;
sPymbed 16:048e5e270a58 2600
sPymbed 16:048e5e270a58 2601 }
sPymbed 16:048e5e270a58 2602 }
sPymbed 16:048e5e270a58 2603
sPymbed 16:048e5e270a58 2604
sPymbed 16:048e5e270a58 2605 int wc_GetKeyOID(byte* key, word32 keySz, const byte** curveOID, word32* oidSz,
sPymbed 16:048e5e270a58 2606 int* algoID, void* heap)
sPymbed 16:048e5e270a58 2607 {
sPymbed 16:048e5e270a58 2608 word32 tmpIdx = 0;
sPymbed 16:048e5e270a58 2609
sPymbed 16:048e5e270a58 2610 if (key == NULL || algoID == NULL)
sPymbed 16:048e5e270a58 2611 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 2612
sPymbed 16:048e5e270a58 2613 *algoID = 0;
sPymbed 16:048e5e270a58 2614
sPymbed 16:048e5e270a58 2615 #ifndef NO_RSA
sPymbed 16:048e5e270a58 2616 {
sPymbed 16:048e5e270a58 2617 RsaKey rsa;
sPymbed 16:048e5e270a58 2618
sPymbed 16:048e5e270a58 2619 wc_InitRsaKey(&rsa, heap);
sPymbed 16:048e5e270a58 2620 if (wc_RsaPrivateKeyDecode(key, &tmpIdx, &rsa, keySz) == 0) {
sPymbed 16:048e5e270a58 2621 *algoID = RSAk;
sPymbed 16:048e5e270a58 2622 }
sPymbed 16:048e5e270a58 2623 else {
sPymbed 16:048e5e270a58 2624 WOLFSSL_MSG("Not RSA DER key");
sPymbed 16:048e5e270a58 2625 }
sPymbed 16:048e5e270a58 2626 wc_FreeRsaKey(&rsa);
sPymbed 16:048e5e270a58 2627 }
sPymbed 16:048e5e270a58 2628 #endif /* NO_RSA */
sPymbed 16:048e5e270a58 2629 #ifdef HAVE_ECC
sPymbed 16:048e5e270a58 2630 if (*algoID == 0) {
sPymbed 16:048e5e270a58 2631 ecc_key ecc;
sPymbed 16:048e5e270a58 2632
sPymbed 16:048e5e270a58 2633 tmpIdx = 0;
sPymbed 16:048e5e270a58 2634 wc_ecc_init_ex(&ecc, heap, INVALID_DEVID);
sPymbed 16:048e5e270a58 2635 if (wc_EccPrivateKeyDecode(key, &tmpIdx, &ecc, keySz) == 0) {
sPymbed 16:048e5e270a58 2636 *algoID = ECDSAk;
sPymbed 16:048e5e270a58 2637
sPymbed 16:048e5e270a58 2638 /* now find oid */
sPymbed 16:048e5e270a58 2639 if (wc_ecc_get_oid(ecc.dp->oidSum, curveOID, oidSz) < 0) {
sPymbed 16:048e5e270a58 2640 WOLFSSL_MSG("Error getting ECC curve OID");
sPymbed 16:048e5e270a58 2641 wc_ecc_free(&ecc);
sPymbed 16:048e5e270a58 2642 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 2643 }
sPymbed 16:048e5e270a58 2644 }
sPymbed 16:048e5e270a58 2645 else {
sPymbed 16:048e5e270a58 2646 WOLFSSL_MSG("Not ECC DER key either");
sPymbed 16:048e5e270a58 2647 }
sPymbed 16:048e5e270a58 2648 wc_ecc_free(&ecc);
sPymbed 16:048e5e270a58 2649 }
sPymbed 16:048e5e270a58 2650 #endif /* HAVE_ECC */
sPymbed 16:048e5e270a58 2651 #ifdef HAVE_ED25519
sPymbed 16:048e5e270a58 2652 if (*algoID != RSAk && *algoID != ECDSAk) {
sPymbed 16:048e5e270a58 2653 ed25519_key ed25519;
sPymbed 16:048e5e270a58 2654
sPymbed 16:048e5e270a58 2655 tmpIdx = 0;
sPymbed 16:048e5e270a58 2656 if (wc_ed25519_init(&ed25519) == 0) {
sPymbed 16:048e5e270a58 2657 if (wc_Ed25519PrivateKeyDecode(key, &tmpIdx, &ed25519, keySz)
sPymbed 16:048e5e270a58 2658 == 0) {
sPymbed 16:048e5e270a58 2659 *algoID = ED25519k;
sPymbed 16:048e5e270a58 2660 }
sPymbed 16:048e5e270a58 2661 else {
sPymbed 16:048e5e270a58 2662 WOLFSSL_MSG("Not ED25519 DER key");
sPymbed 16:048e5e270a58 2663 }
sPymbed 16:048e5e270a58 2664 wc_ed25519_free(&ed25519);
sPymbed 16:048e5e270a58 2665 }
sPymbed 16:048e5e270a58 2666 else {
sPymbed 16:048e5e270a58 2667 WOLFSSL_MSG("GetKeyOID wc_ed25519_init failed");
sPymbed 16:048e5e270a58 2668 }
sPymbed 16:048e5e270a58 2669 }
sPymbed 16:048e5e270a58 2670 #endif
sPymbed 16:048e5e270a58 2671
sPymbed 16:048e5e270a58 2672 /* if flag is not set then is neither RSA or ECC key that could be
sPymbed 16:048e5e270a58 2673 * found */
sPymbed 16:048e5e270a58 2674 if (*algoID == 0) {
sPymbed 16:048e5e270a58 2675 WOLFSSL_MSG("Bad key DER or compile options");
sPymbed 16:048e5e270a58 2676 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 2677 }
sPymbed 16:048e5e270a58 2678
sPymbed 16:048e5e270a58 2679 (void)curveOID;
sPymbed 16:048e5e270a58 2680 (void)oidSz;
sPymbed 16:048e5e270a58 2681
sPymbed 16:048e5e270a58 2682 return 1;
sPymbed 16:048e5e270a58 2683 }
sPymbed 16:048e5e270a58 2684
sPymbed 16:048e5e270a58 2685
sPymbed 16:048e5e270a58 2686 /*
sPymbed 16:048e5e270a58 2687 * Used when creating PKCS12 shrouded key bags
sPymbed 16:048e5e270a58 2688 * vPKCS is the version of PKCS to use
sPymbed 16:048e5e270a58 2689 * vAlgo is the algorithm version to use
sPymbed 16:048e5e270a58 2690 *
sPymbed 16:048e5e270a58 2691 * if salt is NULL a random number is generated
sPymbed 16:048e5e270a58 2692 *
sPymbed 16:048e5e270a58 2693 * returns the size of encrypted data on success
sPymbed 16:048e5e270a58 2694 */
sPymbed 16:048e5e270a58 2695 int UnTraditionalEnc(byte* key, word32 keySz, byte* out, word32* outSz,
sPymbed 16:048e5e270a58 2696 const char* password,int passwordSz, int vPKCS, int vAlgo,
sPymbed 16:048e5e270a58 2697 byte* salt, word32 saltSz, int itt, WC_RNG* rng, void* heap)
sPymbed 16:048e5e270a58 2698 {
sPymbed 16:048e5e270a58 2699 int algoID = 0;
sPymbed 16:048e5e270a58 2700 byte* tmp;
sPymbed 16:048e5e270a58 2701 word32 tmpSz = 0;
sPymbed 16:048e5e270a58 2702 word32 sz;
sPymbed 16:048e5e270a58 2703 word32 seqSz;
sPymbed 16:048e5e270a58 2704 word32 inOutIdx = 0;
sPymbed 16:048e5e270a58 2705 word32 totalSz = 0;
sPymbed 16:048e5e270a58 2706 int version, id;
sPymbed 16:048e5e270a58 2707 int ret;
sPymbed 16:048e5e270a58 2708
sPymbed 16:048e5e270a58 2709 const byte* curveOID = NULL;
sPymbed 16:048e5e270a58 2710 word32 oidSz = 0;
sPymbed 16:048e5e270a58 2711
sPymbed 16:048e5e270a58 2712 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 2713 byte* saltTmp = NULL;
sPymbed 16:048e5e270a58 2714 byte* cbcIv = NULL;
sPymbed 16:048e5e270a58 2715 #else
sPymbed 16:048e5e270a58 2716 byte saltTmp[MAX_IV_SIZE];
sPymbed 16:048e5e270a58 2717 byte cbcIv[MAX_IV_SIZE];
sPymbed 16:048e5e270a58 2718 #endif
sPymbed 16:048e5e270a58 2719
sPymbed 16:048e5e270a58 2720 WOLFSSL_ENTER("UnTraditionalEnc()");
sPymbed 16:048e5e270a58 2721
sPymbed 16:048e5e270a58 2722 if (saltSz > MAX_SALT_SIZE)
sPymbed 16:048e5e270a58 2723 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 2724
sPymbed 16:048e5e270a58 2725
sPymbed 16:048e5e270a58 2726 inOutIdx += MAX_SEQ_SZ; /* leave room for size of finished shroud */
sPymbed 16:048e5e270a58 2727 if (CheckAlgo(vPKCS, vAlgo, &id, &version) < 0) {
sPymbed 16:048e5e270a58 2728 WOLFSSL_MSG("Bad/Unsupported algorithm ID");
sPymbed 16:048e5e270a58 2729 return ASN_INPUT_E; /* Algo ID error */
sPymbed 16:048e5e270a58 2730 }
sPymbed 16:048e5e270a58 2731
sPymbed 16:048e5e270a58 2732 if (out != NULL) {
sPymbed 16:048e5e270a58 2733 if (*outSz < inOutIdx + MAX_ALGO_SZ + MAX_SALT_SIZE + MAX_SEQ_SZ + 1 +
sPymbed 16:048e5e270a58 2734 MAX_LENGTH_SZ + MAX_SHORT_SZ + 1)
sPymbed 16:048e5e270a58 2735 return BUFFER_E;
sPymbed 16:048e5e270a58 2736
sPymbed 16:048e5e270a58 2737 if (version == PKCS5v2) {
sPymbed 16:048e5e270a58 2738 WOLFSSL_MSG("PKCS5v2 Not supported yet\n");
sPymbed 16:048e5e270a58 2739 return ASN_VERSION_E;
sPymbed 16:048e5e270a58 2740 }
sPymbed 16:048e5e270a58 2741
sPymbed 16:048e5e270a58 2742 if (salt == NULL || saltSz <= 0) {
sPymbed 16:048e5e270a58 2743 saltSz = 8;
sPymbed 16:048e5e270a58 2744 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 2745 saltTmp = (byte*)XMALLOC(saltSz, heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 2746 if (saltTmp == NULL)
sPymbed 16:048e5e270a58 2747 return MEMORY_E;
sPymbed 16:048e5e270a58 2748 #endif
sPymbed 16:048e5e270a58 2749 salt = saltTmp;
sPymbed 16:048e5e270a58 2750
sPymbed 16:048e5e270a58 2751 if ((ret = wc_RNG_GenerateBlock(rng, saltTmp, saltSz)) != 0) {
sPymbed 16:048e5e270a58 2752 WOLFSSL_MSG("Error generating random salt");
sPymbed 16:048e5e270a58 2753 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 2754 if (saltTmp != NULL)
sPymbed 16:048e5e270a58 2755 XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 2756 #endif
sPymbed 16:048e5e270a58 2757 return ret;
sPymbed 16:048e5e270a58 2758 }
sPymbed 16:048e5e270a58 2759 }
sPymbed 16:048e5e270a58 2760
sPymbed 16:048e5e270a58 2761
sPymbed 16:048e5e270a58 2762 /* leave room for a sequence (contains salt and iterations int) */
sPymbed 16:048e5e270a58 2763 inOutIdx += MAX_SEQ_SZ; sz = 0;
sPymbed 16:048e5e270a58 2764 inOutIdx += MAX_ALGO_SZ;
sPymbed 16:048e5e270a58 2765
sPymbed 16:048e5e270a58 2766 /* place salt in buffer */
sPymbed 16:048e5e270a58 2767 out[inOutIdx++] = ASN_OCTET_STRING; sz++;
sPymbed 16:048e5e270a58 2768 tmpSz = SetLength(saltSz, out + inOutIdx);
sPymbed 16:048e5e270a58 2769 inOutIdx += tmpSz; sz += tmpSz;
sPymbed 16:048e5e270a58 2770 XMEMCPY(out + inOutIdx, salt, saltSz);
sPymbed 16:048e5e270a58 2771 inOutIdx += saltSz; sz += saltSz;
sPymbed 16:048e5e270a58 2772
sPymbed 16:048e5e270a58 2773 /* place iteration count in buffer */
sPymbed 16:048e5e270a58 2774 ret = SetShortInt(out, &inOutIdx, itt, *outSz);
sPymbed 16:048e5e270a58 2775 if (ret < 0) {
sPymbed 16:048e5e270a58 2776 return ret;
sPymbed 16:048e5e270a58 2777 }
sPymbed 16:048e5e270a58 2778 sz += (word32)ret;
sPymbed 16:048e5e270a58 2779
sPymbed 16:048e5e270a58 2780 /* wind back index and set sequence then clean up buffer */
sPymbed 16:048e5e270a58 2781 inOutIdx -= (sz + MAX_SEQ_SZ);
sPymbed 16:048e5e270a58 2782 tmpSz = SetSequence(sz, out + inOutIdx);
sPymbed 16:048e5e270a58 2783 XMEMMOVE(out + inOutIdx + tmpSz, out + inOutIdx + MAX_SEQ_SZ, sz);
sPymbed 16:048e5e270a58 2784 totalSz += tmpSz + sz; sz += tmpSz;
sPymbed 16:048e5e270a58 2785
sPymbed 16:048e5e270a58 2786 /* add in algo ID */
sPymbed 16:048e5e270a58 2787 inOutIdx -= MAX_ALGO_SZ;
sPymbed 16:048e5e270a58 2788 tmpSz = SetAlgoID(id, out + inOutIdx, oidPBEType, sz);
sPymbed 16:048e5e270a58 2789 XMEMMOVE(out + inOutIdx + tmpSz, out + inOutIdx + MAX_ALGO_SZ, sz);
sPymbed 16:048e5e270a58 2790 totalSz += tmpSz; inOutIdx += tmpSz + sz;
sPymbed 16:048e5e270a58 2791
sPymbed 16:048e5e270a58 2792 /* octet string containing encrypted key */
sPymbed 16:048e5e270a58 2793 out[inOutIdx++] = ASN_OCTET_STRING; totalSz++;
sPymbed 16:048e5e270a58 2794 }
sPymbed 16:048e5e270a58 2795
sPymbed 16:048e5e270a58 2796 /* check key type and get OID if ECC */
sPymbed 16:048e5e270a58 2797 if ((ret = wc_GetKeyOID(key, keySz, &curveOID, &oidSz, &algoID, heap))< 0) {
sPymbed 16:048e5e270a58 2798 return ret;
sPymbed 16:048e5e270a58 2799 }
sPymbed 16:048e5e270a58 2800
sPymbed 16:048e5e270a58 2801 /* PKCS#8 wrapping around key */
sPymbed 16:048e5e270a58 2802 if (wc_CreatePKCS8Key(NULL, &tmpSz, key, keySz, algoID, curveOID, oidSz)
sPymbed 16:048e5e270a58 2803 != LENGTH_ONLY_E) {
sPymbed 16:048e5e270a58 2804 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 2805 if (saltTmp != NULL)
sPymbed 16:048e5e270a58 2806 XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 2807 #endif
sPymbed 16:048e5e270a58 2808 return MEMORY_E;
sPymbed 16:048e5e270a58 2809 }
sPymbed 16:048e5e270a58 2810
sPymbed 16:048e5e270a58 2811 /* check if should return max size */
sPymbed 16:048e5e270a58 2812 if (out == NULL) {
sPymbed 16:048e5e270a58 2813 /* account for salt size */
sPymbed 16:048e5e270a58 2814 if (salt == NULL || saltSz <= 0) {
sPymbed 16:048e5e270a58 2815 tmpSz += MAX_SALT_SIZE;
sPymbed 16:048e5e270a58 2816 }
sPymbed 16:048e5e270a58 2817 else {
sPymbed 16:048e5e270a58 2818 tmpSz += saltSz;
sPymbed 16:048e5e270a58 2819 }
sPymbed 16:048e5e270a58 2820
sPymbed 16:048e5e270a58 2821 /* plus 3 for tags */
sPymbed 16:048e5e270a58 2822 *outSz = tmpSz + MAX_ALGO_SZ + MAX_LENGTH_SZ +MAX_LENGTH_SZ + MAX_SEQ_SZ
sPymbed 16:048e5e270a58 2823 + MAX_LENGTH_SZ + MAX_SEQ_SZ + 3;
sPymbed 16:048e5e270a58 2824 return LENGTH_ONLY_E;
sPymbed 16:048e5e270a58 2825 }
sPymbed 16:048e5e270a58 2826
sPymbed 16:048e5e270a58 2827 tmp = (byte*)XMALLOC(tmpSz, heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 2828 if (tmp == NULL) {
sPymbed 16:048e5e270a58 2829 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 2830 if (saltTmp != NULL)
sPymbed 16:048e5e270a58 2831 XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 2832 #endif
sPymbed 16:048e5e270a58 2833 return MEMORY_E;
sPymbed 16:048e5e270a58 2834 }
sPymbed 16:048e5e270a58 2835
sPymbed 16:048e5e270a58 2836 if ((ret = wc_CreatePKCS8Key(tmp, &tmpSz, key, keySz, algoID, curveOID,
sPymbed 16:048e5e270a58 2837 oidSz)) < 0) {
sPymbed 16:048e5e270a58 2838 XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 2839 WOLFSSL_MSG("Error wrapping key with PKCS#8");
sPymbed 16:048e5e270a58 2840 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 2841 if (saltTmp != NULL)
sPymbed 16:048e5e270a58 2842 XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 2843 #endif
sPymbed 16:048e5e270a58 2844 return ret;
sPymbed 16:048e5e270a58 2845 }
sPymbed 16:048e5e270a58 2846 tmpSz = ret;
sPymbed 16:048e5e270a58 2847
sPymbed 16:048e5e270a58 2848 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 2849 cbcIv = (byte*)XMALLOC(MAX_IV_SIZE, heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 2850 if (cbcIv == NULL) {
sPymbed 16:048e5e270a58 2851 if (saltTmp != NULL)
sPymbed 16:048e5e270a58 2852 XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 2853 XFREE(salt, heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 2854 return MEMORY_E;
sPymbed 16:048e5e270a58 2855 }
sPymbed 16:048e5e270a58 2856 #endif
sPymbed 16:048e5e270a58 2857
sPymbed 16:048e5e270a58 2858 /* encrypt PKCS#8 wrapped key */
sPymbed 16:048e5e270a58 2859 if ((ret = wc_CryptKey(password, passwordSz, salt, saltSz, itt, id,
sPymbed 16:048e5e270a58 2860 tmp, tmpSz, version, cbcIv, 1)) < 0) {
sPymbed 16:048e5e270a58 2861 XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 2862 WOLFSSL_MSG("Error encrypting key");
sPymbed 16:048e5e270a58 2863 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 2864 if (saltTmp != NULL)
sPymbed 16:048e5e270a58 2865 XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 2866 if (cbcIv != NULL)
sPymbed 16:048e5e270a58 2867 XFREE(cbcIv, heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 2868 #endif
sPymbed 16:048e5e270a58 2869 return ret; /* encryption failure */
sPymbed 16:048e5e270a58 2870 }
sPymbed 16:048e5e270a58 2871 totalSz += tmpSz;
sPymbed 16:048e5e270a58 2872
sPymbed 16:048e5e270a58 2873 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 2874 if (saltTmp != NULL)
sPymbed 16:048e5e270a58 2875 XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 2876 if (cbcIv != NULL)
sPymbed 16:048e5e270a58 2877 XFREE(cbcIv, heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 2878 #endif
sPymbed 16:048e5e270a58 2879
sPymbed 16:048e5e270a58 2880 if (*outSz < inOutIdx + tmpSz + MAX_LENGTH_SZ) {
sPymbed 16:048e5e270a58 2881 XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 2882 return BUFFER_E;
sPymbed 16:048e5e270a58 2883 }
sPymbed 16:048e5e270a58 2884
sPymbed 16:048e5e270a58 2885 /* set length of key and copy over encrypted key */
sPymbed 16:048e5e270a58 2886 seqSz = SetLength(tmpSz, out + inOutIdx);
sPymbed 16:048e5e270a58 2887 inOutIdx += seqSz; totalSz += seqSz;
sPymbed 16:048e5e270a58 2888 XMEMCPY(out + inOutIdx, tmp, tmpSz);
sPymbed 16:048e5e270a58 2889 XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 2890
sPymbed 16:048e5e270a58 2891 /* set total size at begining */
sPymbed 16:048e5e270a58 2892 sz = SetSequence(totalSz, out);
sPymbed 16:048e5e270a58 2893 XMEMMOVE(out + sz, out + MAX_SEQ_SZ, totalSz);
sPymbed 16:048e5e270a58 2894
sPymbed 16:048e5e270a58 2895 return totalSz + sz;
sPymbed 16:048e5e270a58 2896 }
sPymbed 16:048e5e270a58 2897
sPymbed 16:048e5e270a58 2898
sPymbed 16:048e5e270a58 2899 /* Remove Encrypted PKCS8 header, move beginning of traditional to beginning
sPymbed 16:048e5e270a58 2900 of input */
sPymbed 16:048e5e270a58 2901 int ToTraditionalEnc(byte* input, word32 sz,const char* password,int passwordSz)
sPymbed 16:048e5e270a58 2902 {
sPymbed 16:048e5e270a58 2903 word32 inOutIdx = 0, seqEnd, oid;
sPymbed 16:048e5e270a58 2904 int ret = 0, first, second, length = 0, version, saltSz, id;
sPymbed 16:048e5e270a58 2905 int iterations = 0, keySz = 0;
sPymbed 16:048e5e270a58 2906 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 2907 byte* salt = NULL;
sPymbed 16:048e5e270a58 2908 byte* cbcIv = NULL;
sPymbed 16:048e5e270a58 2909 #else
sPymbed 16:048e5e270a58 2910 byte salt[MAX_SALT_SIZE];
sPymbed 16:048e5e270a58 2911 byte cbcIv[MAX_IV_SIZE];
sPymbed 16:048e5e270a58 2912 #endif
sPymbed 16:048e5e270a58 2913
sPymbed 16:048e5e270a58 2914 if (passwordSz < 0) {
sPymbed 16:048e5e270a58 2915 WOLFSSL_MSG("Bad password size");
sPymbed 16:048e5e270a58 2916 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 2917 }
sPymbed 16:048e5e270a58 2918
sPymbed 16:048e5e270a58 2919 if (GetSequence(input, &inOutIdx, &length, sz) < 0) {
sPymbed 16:048e5e270a58 2920 ERROR_OUT(ASN_PARSE_E, exit_tte);
sPymbed 16:048e5e270a58 2921 }
sPymbed 16:048e5e270a58 2922
sPymbed 16:048e5e270a58 2923 if (GetAlgoId(input, &inOutIdx, &oid, oidIgnoreType, sz) < 0) {
sPymbed 16:048e5e270a58 2924 ERROR_OUT(ASN_PARSE_E, exit_tte);
sPymbed 16:048e5e270a58 2925 }
sPymbed 16:048e5e270a58 2926
sPymbed 16:048e5e270a58 2927 first = input[inOutIdx - 2]; /* PKCS version always 2nd to last byte */
sPymbed 16:048e5e270a58 2928 second = input[inOutIdx - 1]; /* version.algo, algo id last byte */
sPymbed 16:048e5e270a58 2929
sPymbed 16:048e5e270a58 2930 if (CheckAlgo(first, second, &id, &version) < 0) {
sPymbed 16:048e5e270a58 2931 ERROR_OUT(ASN_INPUT_E, exit_tte); /* Algo ID error */
sPymbed 16:048e5e270a58 2932 }
sPymbed 16:048e5e270a58 2933
sPymbed 16:048e5e270a58 2934 if (version == PKCS5v2) {
sPymbed 16:048e5e270a58 2935 if (GetSequence(input, &inOutIdx, &length, sz) < 0) {
sPymbed 16:048e5e270a58 2936 ERROR_OUT(ASN_PARSE_E, exit_tte);
sPymbed 16:048e5e270a58 2937 }
sPymbed 16:048e5e270a58 2938
sPymbed 16:048e5e270a58 2939 if (GetAlgoId(input, &inOutIdx, &oid, oidKdfType, sz) < 0) {
sPymbed 16:048e5e270a58 2940 ERROR_OUT(ASN_PARSE_E, exit_tte);
sPymbed 16:048e5e270a58 2941 }
sPymbed 16:048e5e270a58 2942
sPymbed 16:048e5e270a58 2943 if (oid != PBKDF2_OID) {
sPymbed 16:048e5e270a58 2944 ERROR_OUT(ASN_PARSE_E, exit_tte);
sPymbed 16:048e5e270a58 2945 }
sPymbed 16:048e5e270a58 2946 }
sPymbed 16:048e5e270a58 2947
sPymbed 16:048e5e270a58 2948 if (GetSequence(input, &inOutIdx, &length, sz) <= 0) {
sPymbed 16:048e5e270a58 2949 ERROR_OUT(ASN_PARSE_E, exit_tte);
sPymbed 16:048e5e270a58 2950 }
sPymbed 16:048e5e270a58 2951 /* Find the end of this SEQUENCE so we can check for the OPTIONAL and
sPymbed 16:048e5e270a58 2952 * DEFAULT items. */
sPymbed 16:048e5e270a58 2953 seqEnd = inOutIdx + length;
sPymbed 16:048e5e270a58 2954
sPymbed 16:048e5e270a58 2955 ret = GetOctetString(input, &inOutIdx, &saltSz, sz);
sPymbed 16:048e5e270a58 2956 if (ret < 0)
sPymbed 16:048e5e270a58 2957 goto exit_tte;
sPymbed 16:048e5e270a58 2958
sPymbed 16:048e5e270a58 2959 if (saltSz > MAX_SALT_SIZE) {
sPymbed 16:048e5e270a58 2960 ERROR_OUT(ASN_PARSE_E, exit_tte);
sPymbed 16:048e5e270a58 2961 }
sPymbed 16:048e5e270a58 2962
sPymbed 16:048e5e270a58 2963 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 2964 salt = (byte*)XMALLOC(MAX_SALT_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 2965 if (salt == NULL) {
sPymbed 16:048e5e270a58 2966 ERROR_OUT(MEMORY_E, exit_tte);
sPymbed 16:048e5e270a58 2967 }
sPymbed 16:048e5e270a58 2968 #endif
sPymbed 16:048e5e270a58 2969
sPymbed 16:048e5e270a58 2970 XMEMCPY(salt, &input[inOutIdx], saltSz);
sPymbed 16:048e5e270a58 2971 inOutIdx += saltSz;
sPymbed 16:048e5e270a58 2972
sPymbed 16:048e5e270a58 2973 if (GetShortInt(input, &inOutIdx, &iterations, sz) < 0) {
sPymbed 16:048e5e270a58 2974 ERROR_OUT(ASN_PARSE_E, exit_tte);
sPymbed 16:048e5e270a58 2975 }
sPymbed 16:048e5e270a58 2976
sPymbed 16:048e5e270a58 2977 /* OPTIONAL key length */
sPymbed 16:048e5e270a58 2978 if (seqEnd > inOutIdx && input[inOutIdx] == ASN_INTEGER) {
sPymbed 16:048e5e270a58 2979 if (GetShortInt(input, &inOutIdx, &keySz, sz) < 0) {
sPymbed 16:048e5e270a58 2980 ERROR_OUT(ASN_PARSE_E, exit_tte);
sPymbed 16:048e5e270a58 2981 }
sPymbed 16:048e5e270a58 2982 }
sPymbed 16:048e5e270a58 2983
sPymbed 16:048e5e270a58 2984 /* DEFAULT HMAC is SHA-1 */
sPymbed 16:048e5e270a58 2985 if (seqEnd > inOutIdx) {
sPymbed 16:048e5e270a58 2986 if (GetAlgoId(input, &inOutIdx, &oid, oidHmacType, sz) < 0) {
sPymbed 16:048e5e270a58 2987 ERROR_OUT(ASN_PARSE_E, exit_tte);
sPymbed 16:048e5e270a58 2988 }
sPymbed 16:048e5e270a58 2989 }
sPymbed 16:048e5e270a58 2990
sPymbed 16:048e5e270a58 2991 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 2992 cbcIv = (byte*)XMALLOC(MAX_IV_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 2993 if (cbcIv == NULL) {
sPymbed 16:048e5e270a58 2994 ERROR_OUT(MEMORY_E, exit_tte);
sPymbed 16:048e5e270a58 2995 }
sPymbed 16:048e5e270a58 2996 #endif
sPymbed 16:048e5e270a58 2997
sPymbed 16:048e5e270a58 2998 if (version == PKCS5v2) {
sPymbed 16:048e5e270a58 2999 /* get encryption algo */
sPymbed 16:048e5e270a58 3000 if (GetAlgoId(input, &inOutIdx, &oid, oidBlkType, sz) < 0) {
sPymbed 16:048e5e270a58 3001 ERROR_OUT(ASN_PARSE_E, exit_tte);
sPymbed 16:048e5e270a58 3002 }
sPymbed 16:048e5e270a58 3003
sPymbed 16:048e5e270a58 3004 if (CheckAlgoV2(oid, &id) < 0) {
sPymbed 16:048e5e270a58 3005 ERROR_OUT(ASN_PARSE_E, exit_tte); /* PKCS v2 algo id error */
sPymbed 16:048e5e270a58 3006 }
sPymbed 16:048e5e270a58 3007
sPymbed 16:048e5e270a58 3008 ret = GetOctetString(input, &inOutIdx, &length, sz);
sPymbed 16:048e5e270a58 3009 if (ret < 0)
sPymbed 16:048e5e270a58 3010 goto exit_tte;
sPymbed 16:048e5e270a58 3011
sPymbed 16:048e5e270a58 3012 if (length > MAX_IV_SIZE) {
sPymbed 16:048e5e270a58 3013 ERROR_OUT(ASN_PARSE_E, exit_tte);
sPymbed 16:048e5e270a58 3014 }
sPymbed 16:048e5e270a58 3015
sPymbed 16:048e5e270a58 3016 XMEMCPY(cbcIv, &input[inOutIdx], length);
sPymbed 16:048e5e270a58 3017 inOutIdx += length;
sPymbed 16:048e5e270a58 3018 }
sPymbed 16:048e5e270a58 3019
sPymbed 16:048e5e270a58 3020 ret = GetOctetString(input, &inOutIdx, &length, sz);
sPymbed 16:048e5e270a58 3021 if (ret < 0)
sPymbed 16:048e5e270a58 3022 goto exit_tte;
sPymbed 16:048e5e270a58 3023
sPymbed 16:048e5e270a58 3024 ret = wc_CryptKey(password, passwordSz, salt, saltSz, iterations, id,
sPymbed 16:048e5e270a58 3025 input + inOutIdx, length, version, cbcIv, 0);
sPymbed 16:048e5e270a58 3026
sPymbed 16:048e5e270a58 3027 exit_tte:
sPymbed 16:048e5e270a58 3028 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 3029 XFREE(salt, NULL, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 3030 XFREE(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 3031 #endif
sPymbed 16:048e5e270a58 3032
sPymbed 16:048e5e270a58 3033 if (ret == 0) {
sPymbed 16:048e5e270a58 3034 XMEMMOVE(input, input + inOutIdx, length);
sPymbed 16:048e5e270a58 3035 ret = ToTraditional(input, length);
sPymbed 16:048e5e270a58 3036 }
sPymbed 16:048e5e270a58 3037
sPymbed 16:048e5e270a58 3038 return ret;
sPymbed 16:048e5e270a58 3039 }
sPymbed 16:048e5e270a58 3040
sPymbed 16:048e5e270a58 3041
sPymbed 16:048e5e270a58 3042 /* encrypt PKCS 12 content
sPymbed 16:048e5e270a58 3043 *
sPymbed 16:048e5e270a58 3044 * NOTE: if out is NULL then outSz is set with the total buffer size needed and
sPymbed 16:048e5e270a58 3045 * the error value LENGTH_ONLY_E is returned.
sPymbed 16:048e5e270a58 3046 *
sPymbed 16:048e5e270a58 3047 * input data to encrypt
sPymbed 16:048e5e270a58 3048 * inputSz size of input buffer
sPymbed 16:048e5e270a58 3049 * out buffer to hold the result
sPymbed 16:048e5e270a58 3050 * outSz size of out buffer
sPymbed 16:048e5e270a58 3051 * password password if used. Can be NULL for no password
sPymbed 16:048e5e270a58 3052 * passwordSz size of password buffer
sPymbed 16:048e5e270a58 3053 * vPKCS version of PKCS i.e. PKCS5v2
sPymbed 16:048e5e270a58 3054 * vAlgo algorithm version
sPymbed 16:048e5e270a58 3055 * salt buffer holding salt if used. If NULL then a random salt is created
sPymbed 16:048e5e270a58 3056 * saltSz size of salt buffer if it is not NULL
sPymbed 16:048e5e270a58 3057 * itt number of iterations used
sPymbed 16:048e5e270a58 3058 * rng random number generator to use
sPymbed 16:048e5e270a58 3059 * heap possible heap hint for mallocs/frees
sPymbed 16:048e5e270a58 3060 *
sPymbed 16:048e5e270a58 3061 * returns the total size of encrypted content on success.
sPymbed 16:048e5e270a58 3062 */
sPymbed 16:048e5e270a58 3063 int EncryptContent(byte* input, word32 inputSz, byte* out, word32* outSz,
sPymbed 16:048e5e270a58 3064 const char* password, int passwordSz, int vPKCS, int vAlgo,
sPymbed 16:048e5e270a58 3065 byte* salt, word32 saltSz, int itt, WC_RNG* rng, void* heap)
sPymbed 16:048e5e270a58 3066 {
sPymbed 16:048e5e270a58 3067 word32 sz;
sPymbed 16:048e5e270a58 3068 word32 inOutIdx = 0;
sPymbed 16:048e5e270a58 3069 word32 tmpIdx = 0;
sPymbed 16:048e5e270a58 3070 word32 totalSz = 0;
sPymbed 16:048e5e270a58 3071 word32 seqSz;
sPymbed 16:048e5e270a58 3072 int ret;
sPymbed 16:048e5e270a58 3073 int version, id;
sPymbed 16:048e5e270a58 3074 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 3075 byte* saltTmp = NULL;
sPymbed 16:048e5e270a58 3076 byte* cbcIv = NULL;
sPymbed 16:048e5e270a58 3077 #else
sPymbed 16:048e5e270a58 3078 byte saltTmp[MAX_SALT_SIZE];
sPymbed 16:048e5e270a58 3079 byte cbcIv[MAX_IV_SIZE];
sPymbed 16:048e5e270a58 3080 #endif
sPymbed 16:048e5e270a58 3081
sPymbed 16:048e5e270a58 3082 (void)heap;
sPymbed 16:048e5e270a58 3083
sPymbed 16:048e5e270a58 3084 WOLFSSL_ENTER("EncryptContent()");
sPymbed 16:048e5e270a58 3085
sPymbed 16:048e5e270a58 3086 if (CheckAlgo(vPKCS, vAlgo, &id, &version) < 0)
sPymbed 16:048e5e270a58 3087 return ASN_INPUT_E; /* Algo ID error */
sPymbed 16:048e5e270a58 3088
sPymbed 16:048e5e270a58 3089 if (version == PKCS5v2) {
sPymbed 16:048e5e270a58 3090 WOLFSSL_MSG("PKCS#5 version 2 not supported yet");
sPymbed 16:048e5e270a58 3091 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 3092 }
sPymbed 16:048e5e270a58 3093
sPymbed 16:048e5e270a58 3094 if (saltSz > MAX_SALT_SIZE)
sPymbed 16:048e5e270a58 3095 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 3096
sPymbed 16:048e5e270a58 3097 if (outSz == NULL) {
sPymbed 16:048e5e270a58 3098 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 3099 }
sPymbed 16:048e5e270a58 3100
sPymbed 16:048e5e270a58 3101 if (out == NULL) {
sPymbed 16:048e5e270a58 3102 sz = inputSz;
sPymbed 16:048e5e270a58 3103 switch (id) {
sPymbed 16:048e5e270a58 3104 #if !defined(NO_DES3) && (!defined(NO_MD5) || !defined(NO_SHA))
sPymbed 16:048e5e270a58 3105 case PBE_MD5_DES:
sPymbed 16:048e5e270a58 3106 case PBE_SHA1_DES:
sPymbed 16:048e5e270a58 3107 case PBE_SHA1_DES3:
sPymbed 16:048e5e270a58 3108 /* set to block size of 8 for DES operations. This rounds up
sPymbed 16:048e5e270a58 3109 * to the nearset multiple of 8 */
sPymbed 16:048e5e270a58 3110 sz &= 0xfffffff8;
sPymbed 16:048e5e270a58 3111 sz += 8;
sPymbed 16:048e5e270a58 3112 break;
sPymbed 16:048e5e270a58 3113 #endif /* !NO_DES3 && (!NO_MD5 || !NO_SHA) */
sPymbed 16:048e5e270a58 3114 #if !defined(NO_RC4) && !defined(NO_SHA)
sPymbed 16:048e5e270a58 3115 case PBE_SHA1_RC4_128:
sPymbed 16:048e5e270a58 3116 break;
sPymbed 16:048e5e270a58 3117 #endif
sPymbed 16:048e5e270a58 3118 case -1:
sPymbed 16:048e5e270a58 3119 break;
sPymbed 16:048e5e270a58 3120
sPymbed 16:048e5e270a58 3121 default:
sPymbed 16:048e5e270a58 3122 return ALGO_ID_E;
sPymbed 16:048e5e270a58 3123 }
sPymbed 16:048e5e270a58 3124
sPymbed 16:048e5e270a58 3125 if (saltSz <= 0) {
sPymbed 16:048e5e270a58 3126 sz += MAX_SALT_SIZE;
sPymbed 16:048e5e270a58 3127 }
sPymbed 16:048e5e270a58 3128 else {
sPymbed 16:048e5e270a58 3129 sz += saltSz;
sPymbed 16:048e5e270a58 3130 }
sPymbed 16:048e5e270a58 3131
sPymbed 16:048e5e270a58 3132 /* add 2 for tags */
sPymbed 16:048e5e270a58 3133 *outSz = sz + MAX_ALGO_SZ + MAX_SEQ_SZ + MAX_LENGTH_SZ +
sPymbed 16:048e5e270a58 3134 MAX_LENGTH_SZ + MAX_LENGTH_SZ + MAX_SHORT_SZ + 2;
sPymbed 16:048e5e270a58 3135
sPymbed 16:048e5e270a58 3136 return LENGTH_ONLY_E;
sPymbed 16:048e5e270a58 3137 }
sPymbed 16:048e5e270a58 3138
sPymbed 16:048e5e270a58 3139 if (inOutIdx + MAX_ALGO_SZ + MAX_SEQ_SZ + 1 > *outSz)
sPymbed 16:048e5e270a58 3140 return BUFFER_E;
sPymbed 16:048e5e270a58 3141
sPymbed 16:048e5e270a58 3142 sz = SetAlgoID(id, out + inOutIdx, oidPBEType, 0);
sPymbed 16:048e5e270a58 3143 inOutIdx += sz; totalSz += sz;
sPymbed 16:048e5e270a58 3144 tmpIdx = inOutIdx;
sPymbed 16:048e5e270a58 3145 tmpIdx += MAX_SEQ_SZ; /* save room for salt and itter sequence */
sPymbed 16:048e5e270a58 3146 out[tmpIdx++] = ASN_OCTET_STRING;
sPymbed 16:048e5e270a58 3147
sPymbed 16:048e5e270a58 3148 /* create random salt if one not provided */
sPymbed 16:048e5e270a58 3149 if (salt == NULL || saltSz <= 0) {
sPymbed 16:048e5e270a58 3150 saltSz = 8;
sPymbed 16:048e5e270a58 3151 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 3152 saltTmp = (byte*)XMALLOC(saltSz, heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 3153 if (saltTmp == NULL)
sPymbed 16:048e5e270a58 3154 return MEMORY_E;
sPymbed 16:048e5e270a58 3155 #endif
sPymbed 16:048e5e270a58 3156 salt = saltTmp;
sPymbed 16:048e5e270a58 3157
sPymbed 16:048e5e270a58 3158 if ((ret = wc_RNG_GenerateBlock(rng, saltTmp, saltSz)) != 0) {
sPymbed 16:048e5e270a58 3159 WOLFSSL_MSG("Error generating random salt");
sPymbed 16:048e5e270a58 3160 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 3161 XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 3162 #endif
sPymbed 16:048e5e270a58 3163 return ret;
sPymbed 16:048e5e270a58 3164 }
sPymbed 16:048e5e270a58 3165 }
sPymbed 16:048e5e270a58 3166
sPymbed 16:048e5e270a58 3167 if (tmpIdx + MAX_LENGTH_SZ + saltSz + MAX_SHORT_SZ > *outSz) {
sPymbed 16:048e5e270a58 3168 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 3169 XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 3170 #endif
sPymbed 16:048e5e270a58 3171 return BUFFER_E;
sPymbed 16:048e5e270a58 3172 }
sPymbed 16:048e5e270a58 3173
sPymbed 16:048e5e270a58 3174 sz = SetLength(saltSz, out + tmpIdx);
sPymbed 16:048e5e270a58 3175 tmpIdx += sz;
sPymbed 16:048e5e270a58 3176
sPymbed 16:048e5e270a58 3177 XMEMCPY(out + tmpIdx, salt, saltSz);
sPymbed 16:048e5e270a58 3178 tmpIdx += saltSz;
sPymbed 16:048e5e270a58 3179
sPymbed 16:048e5e270a58 3180 /* place itteration setting in buffer */
sPymbed 16:048e5e270a58 3181 ret = SetShortInt(out, &tmpIdx, itt, *outSz);
sPymbed 16:048e5e270a58 3182 if (ret < 0) {
sPymbed 16:048e5e270a58 3183 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 3184 XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 3185 #endif
sPymbed 16:048e5e270a58 3186 return ret;
sPymbed 16:048e5e270a58 3187 }
sPymbed 16:048e5e270a58 3188
sPymbed 16:048e5e270a58 3189 /* rewind and place sequence */
sPymbed 16:048e5e270a58 3190 sz = tmpIdx - inOutIdx - MAX_SEQ_SZ;
sPymbed 16:048e5e270a58 3191 seqSz = SetSequence(sz, out + inOutIdx);
sPymbed 16:048e5e270a58 3192 XMEMMOVE(out + inOutIdx + seqSz, out + inOutIdx + MAX_SEQ_SZ, sz);
sPymbed 16:048e5e270a58 3193 inOutIdx += seqSz; totalSz += seqSz;
sPymbed 16:048e5e270a58 3194 inOutIdx += sz; totalSz += sz;
sPymbed 16:048e5e270a58 3195
sPymbed 16:048e5e270a58 3196 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 3197 cbcIv = (byte*)XMALLOC(MAX_IV_SIZE, heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 3198 if (cbcIv == NULL) {
sPymbed 16:048e5e270a58 3199 XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 3200 return MEMORY_E;
sPymbed 16:048e5e270a58 3201 }
sPymbed 16:048e5e270a58 3202 #endif
sPymbed 16:048e5e270a58 3203
sPymbed 16:048e5e270a58 3204 if ((ret = wc_CryptKey(password, passwordSz, salt, saltSz, itt, id,
sPymbed 16:048e5e270a58 3205 input, inputSz, version, cbcIv, 1)) < 0) {
sPymbed 16:048e5e270a58 3206
sPymbed 16:048e5e270a58 3207 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 3208 XFREE(cbcIv, heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 3209 XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 3210 #endif
sPymbed 16:048e5e270a58 3211 return ret; /* encrypt failure */
sPymbed 16:048e5e270a58 3212 }
sPymbed 16:048e5e270a58 3213
sPymbed 16:048e5e270a58 3214 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 3215 XFREE(cbcIv, heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 3216 XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 3217 #endif
sPymbed 16:048e5e270a58 3218
sPymbed 16:048e5e270a58 3219 if (inOutIdx + 1 + MAX_LENGTH_SZ + inputSz > *outSz)
sPymbed 16:048e5e270a58 3220 return BUFFER_E;
sPymbed 16:048e5e270a58 3221
sPymbed 16:048e5e270a58 3222 out[inOutIdx++] = ASN_LONG_LENGTH; totalSz++;
sPymbed 16:048e5e270a58 3223 sz = SetLength(inputSz, out + inOutIdx);
sPymbed 16:048e5e270a58 3224 inOutIdx += sz; totalSz += sz;
sPymbed 16:048e5e270a58 3225 XMEMCPY(out + inOutIdx, input, inputSz);
sPymbed 16:048e5e270a58 3226 totalSz += inputSz;
sPymbed 16:048e5e270a58 3227
sPymbed 16:048e5e270a58 3228 return totalSz;
sPymbed 16:048e5e270a58 3229 }
sPymbed 16:048e5e270a58 3230
sPymbed 16:048e5e270a58 3231
sPymbed 16:048e5e270a58 3232 /* decrypt PKCS
sPymbed 16:048e5e270a58 3233 *
sPymbed 16:048e5e270a58 3234 * NOTE: input buffer is overwritten with decrypted data!
sPymbed 16:048e5e270a58 3235 *
sPymbed 16:048e5e270a58 3236 * input[in/out] data to decrypt and results are written to
sPymbed 16:048e5e270a58 3237 * sz size of input buffer
sPymbed 16:048e5e270a58 3238 * password password if used. Can be NULL for no password
sPymbed 16:048e5e270a58 3239 * passwordSz size of password buffer
sPymbed 16:048e5e270a58 3240 *
sPymbed 16:048e5e270a58 3241 * returns the total size of decrypted content on success.
sPymbed 16:048e5e270a58 3242 */
sPymbed 16:048e5e270a58 3243 int DecryptContent(byte* input, word32 sz,const char* password,int passwordSz)
sPymbed 16:048e5e270a58 3244 {
sPymbed 16:048e5e270a58 3245 word32 inOutIdx = 0, seqEnd, oid;
sPymbed 16:048e5e270a58 3246 int ret = 0;
sPymbed 16:048e5e270a58 3247 int first, second, length = 0, version, saltSz, id;
sPymbed 16:048e5e270a58 3248 int iterations = 0, keySz = 0;
sPymbed 16:048e5e270a58 3249 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 3250 byte* salt = NULL;
sPymbed 16:048e5e270a58 3251 byte* cbcIv = NULL;
sPymbed 16:048e5e270a58 3252 #else
sPymbed 16:048e5e270a58 3253 byte salt[MAX_SALT_SIZE];
sPymbed 16:048e5e270a58 3254 byte cbcIv[MAX_IV_SIZE];
sPymbed 16:048e5e270a58 3255 #endif
sPymbed 16:048e5e270a58 3256
sPymbed 16:048e5e270a58 3257 if (GetAlgoId(input, &inOutIdx, &oid, oidIgnoreType, sz) < 0) {
sPymbed 16:048e5e270a58 3258 ERROR_OUT(ASN_PARSE_E, exit_dc);
sPymbed 16:048e5e270a58 3259 }
sPymbed 16:048e5e270a58 3260
sPymbed 16:048e5e270a58 3261 first = input[inOutIdx - 2]; /* PKCS version always 2nd to last byte */
sPymbed 16:048e5e270a58 3262 second = input[inOutIdx - 1]; /* version.algo, algo id last byte */
sPymbed 16:048e5e270a58 3263
sPymbed 16:048e5e270a58 3264 if (CheckAlgo(first, second, &id, &version) < 0) {
sPymbed 16:048e5e270a58 3265 ERROR_OUT(ASN_INPUT_E, exit_dc); /* Algo ID error */
sPymbed 16:048e5e270a58 3266 }
sPymbed 16:048e5e270a58 3267
sPymbed 16:048e5e270a58 3268 if (version == PKCS5v2) {
sPymbed 16:048e5e270a58 3269 if (GetSequence(input, &inOutIdx, &length, sz) < 0) {
sPymbed 16:048e5e270a58 3270 ERROR_OUT(ASN_PARSE_E, exit_dc);
sPymbed 16:048e5e270a58 3271 }
sPymbed 16:048e5e270a58 3272
sPymbed 16:048e5e270a58 3273 if (GetAlgoId(input, &inOutIdx, &oid, oidKdfType, sz) < 0) {
sPymbed 16:048e5e270a58 3274 ERROR_OUT(ASN_PARSE_E, exit_dc);
sPymbed 16:048e5e270a58 3275 }
sPymbed 16:048e5e270a58 3276
sPymbed 16:048e5e270a58 3277 if (oid != PBKDF2_OID) {
sPymbed 16:048e5e270a58 3278 ERROR_OUT(ASN_PARSE_E, exit_dc);
sPymbed 16:048e5e270a58 3279 }
sPymbed 16:048e5e270a58 3280 }
sPymbed 16:048e5e270a58 3281
sPymbed 16:048e5e270a58 3282 if (GetSequence(input, &inOutIdx, &length, sz) <= 0) {
sPymbed 16:048e5e270a58 3283 ERROR_OUT(ASN_PARSE_E, exit_dc);
sPymbed 16:048e5e270a58 3284 }
sPymbed 16:048e5e270a58 3285 /* Find the end of this SEQUENCE so we can check for the OPTIONAL and
sPymbed 16:048e5e270a58 3286 * DEFAULT items. */
sPymbed 16:048e5e270a58 3287 seqEnd = inOutIdx + length;
sPymbed 16:048e5e270a58 3288
sPymbed 16:048e5e270a58 3289 ret = GetOctetString(input, &inOutIdx, &saltSz, sz);
sPymbed 16:048e5e270a58 3290 if (ret < 0)
sPymbed 16:048e5e270a58 3291 goto exit_dc;
sPymbed 16:048e5e270a58 3292
sPymbed 16:048e5e270a58 3293 if (saltSz > MAX_SALT_SIZE) {
sPymbed 16:048e5e270a58 3294 ERROR_OUT(ASN_PARSE_E, exit_dc);
sPymbed 16:048e5e270a58 3295 }
sPymbed 16:048e5e270a58 3296
sPymbed 16:048e5e270a58 3297 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 3298 salt = (byte*)XMALLOC(MAX_SALT_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 3299 if (salt == NULL) {
sPymbed 16:048e5e270a58 3300 ERROR_OUT(MEMORY_E, exit_dc);
sPymbed 16:048e5e270a58 3301 }
sPymbed 16:048e5e270a58 3302 #endif
sPymbed 16:048e5e270a58 3303
sPymbed 16:048e5e270a58 3304 XMEMCPY(salt, &input[inOutIdx], saltSz);
sPymbed 16:048e5e270a58 3305 inOutIdx += saltSz;
sPymbed 16:048e5e270a58 3306
sPymbed 16:048e5e270a58 3307 if (GetShortInt(input, &inOutIdx, &iterations, sz) < 0) {
sPymbed 16:048e5e270a58 3308 ERROR_OUT(ASN_PARSE_E, exit_dc);
sPymbed 16:048e5e270a58 3309 }
sPymbed 16:048e5e270a58 3310
sPymbed 16:048e5e270a58 3311 /* OPTIONAL key length */
sPymbed 16:048e5e270a58 3312 if (seqEnd > inOutIdx && input[inOutIdx] == ASN_INTEGER) {
sPymbed 16:048e5e270a58 3313 if (GetShortInt(input, &inOutIdx, &keySz, sz) < 0) {
sPymbed 16:048e5e270a58 3314 ERROR_OUT(ASN_PARSE_E, exit_dc);
sPymbed 16:048e5e270a58 3315 }
sPymbed 16:048e5e270a58 3316 }
sPymbed 16:048e5e270a58 3317
sPymbed 16:048e5e270a58 3318 /* DEFAULT HMAC is SHA-1 */
sPymbed 16:048e5e270a58 3319 if (seqEnd > inOutIdx) {
sPymbed 16:048e5e270a58 3320 if (GetAlgoId(input, &inOutIdx, &oid, oidHmacType, sz) < 0) {
sPymbed 16:048e5e270a58 3321 ERROR_OUT(ASN_PARSE_E, exit_dc);
sPymbed 16:048e5e270a58 3322 }
sPymbed 16:048e5e270a58 3323 }
sPymbed 16:048e5e270a58 3324
sPymbed 16:048e5e270a58 3325 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 3326 cbcIv = (byte*)XMALLOC(MAX_IV_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 3327 if (cbcIv == NULL) {
sPymbed 16:048e5e270a58 3328 ERROR_OUT(MEMORY_E, exit_dc);
sPymbed 16:048e5e270a58 3329 }
sPymbed 16:048e5e270a58 3330 #endif
sPymbed 16:048e5e270a58 3331
sPymbed 16:048e5e270a58 3332 if (version == PKCS5v2) {
sPymbed 16:048e5e270a58 3333 /* get encryption algo */
sPymbed 16:048e5e270a58 3334 if (GetAlgoId(input, &inOutIdx, &oid, oidBlkType, sz) < 0) {
sPymbed 16:048e5e270a58 3335 ERROR_OUT(ASN_PARSE_E, exit_dc);
sPymbed 16:048e5e270a58 3336 }
sPymbed 16:048e5e270a58 3337
sPymbed 16:048e5e270a58 3338 if (CheckAlgoV2(oid, &id) < 0) {
sPymbed 16:048e5e270a58 3339 ERROR_OUT(ASN_PARSE_E, exit_dc); /* PKCS v2 algo id error */
sPymbed 16:048e5e270a58 3340 }
sPymbed 16:048e5e270a58 3341
sPymbed 16:048e5e270a58 3342 ret = GetOctetString(input, &inOutIdx, &length, sz);
sPymbed 16:048e5e270a58 3343 if (ret < 0)
sPymbed 16:048e5e270a58 3344 goto exit_dc;
sPymbed 16:048e5e270a58 3345
sPymbed 16:048e5e270a58 3346 if (length > MAX_IV_SIZE) {
sPymbed 16:048e5e270a58 3347 ERROR_OUT(ASN_PARSE_E, exit_dc);
sPymbed 16:048e5e270a58 3348 }
sPymbed 16:048e5e270a58 3349
sPymbed 16:048e5e270a58 3350 XMEMCPY(cbcIv, &input[inOutIdx], length);
sPymbed 16:048e5e270a58 3351 inOutIdx += length;
sPymbed 16:048e5e270a58 3352 }
sPymbed 16:048e5e270a58 3353
sPymbed 16:048e5e270a58 3354 if (input[inOutIdx++] != (ASN_CONTEXT_SPECIFIC | 0)) {
sPymbed 16:048e5e270a58 3355 ERROR_OUT(ASN_PARSE_E, exit_dc);
sPymbed 16:048e5e270a58 3356 }
sPymbed 16:048e5e270a58 3357
sPymbed 16:048e5e270a58 3358 if (GetLength(input, &inOutIdx, &length, sz) < 0) {
sPymbed 16:048e5e270a58 3359 ERROR_OUT(ASN_PARSE_E, exit_dc);
sPymbed 16:048e5e270a58 3360 }
sPymbed 16:048e5e270a58 3361
sPymbed 16:048e5e270a58 3362 ret = wc_CryptKey(password, passwordSz, salt, saltSz, iterations, id,
sPymbed 16:048e5e270a58 3363 input + inOutIdx, length, version, cbcIv, 0);
sPymbed 16:048e5e270a58 3364
sPymbed 16:048e5e270a58 3365 exit_dc:
sPymbed 16:048e5e270a58 3366
sPymbed 16:048e5e270a58 3367 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 3368 XFREE(salt, NULL, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 3369 XFREE(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 3370 #endif
sPymbed 16:048e5e270a58 3371
sPymbed 16:048e5e270a58 3372 if (ret == 0) {
sPymbed 16:048e5e270a58 3373 XMEMMOVE(input, input + inOutIdx, length);
sPymbed 16:048e5e270a58 3374 ret = length;
sPymbed 16:048e5e270a58 3375 }
sPymbed 16:048e5e270a58 3376
sPymbed 16:048e5e270a58 3377 return ret;
sPymbed 16:048e5e270a58 3378 }
sPymbed 16:048e5e270a58 3379 #endif /* NO_PWDBASED */
sPymbed 16:048e5e270a58 3380
sPymbed 16:048e5e270a58 3381 #ifndef NO_RSA
sPymbed 16:048e5e270a58 3382
sPymbed 16:048e5e270a58 3383 #ifndef HAVE_USER_RSA
sPymbed 16:048e5e270a58 3384 int wc_RsaPublicKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
sPymbed 16:048e5e270a58 3385 word32 inSz)
sPymbed 16:048e5e270a58 3386 {
sPymbed 16:048e5e270a58 3387 int length;
sPymbed 16:048e5e270a58 3388 #if defined(OPENSSL_EXTRA) || defined(RSA_DECODE_EXTRA)
sPymbed 16:048e5e270a58 3389 byte b;
sPymbed 16:048e5e270a58 3390 #endif
sPymbed 16:048e5e270a58 3391 int ret;
sPymbed 16:048e5e270a58 3392
sPymbed 16:048e5e270a58 3393 if (input == NULL || inOutIdx == NULL || key == NULL)
sPymbed 16:048e5e270a58 3394 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 3395
sPymbed 16:048e5e270a58 3396 if (GetSequence(input, inOutIdx, &length, inSz) < 0)
sPymbed 16:048e5e270a58 3397 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 3398
sPymbed 16:048e5e270a58 3399 key->type = RSA_PUBLIC;
sPymbed 16:048e5e270a58 3400
sPymbed 16:048e5e270a58 3401 #if defined(OPENSSL_EXTRA) || defined(RSA_DECODE_EXTRA)
sPymbed 16:048e5e270a58 3402 if ((*inOutIdx + 1) > inSz)
sPymbed 16:048e5e270a58 3403 return BUFFER_E;
sPymbed 16:048e5e270a58 3404
sPymbed 16:048e5e270a58 3405 b = input[*inOutIdx];
sPymbed 16:048e5e270a58 3406 if (b != ASN_INTEGER) {
sPymbed 16:048e5e270a58 3407 /* not from decoded cert, will have algo id, skip past */
sPymbed 16:048e5e270a58 3408 if (GetSequence(input, inOutIdx, &length, inSz) < 0)
sPymbed 16:048e5e270a58 3409 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 3410
sPymbed 16:048e5e270a58 3411 if (SkipObjectId(input, inOutIdx, inSz) < 0)
sPymbed 16:048e5e270a58 3412 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 3413
sPymbed 16:048e5e270a58 3414 /* Option NULL ASN.1 tag */
sPymbed 16:048e5e270a58 3415 if (*inOutIdx >= inSz) {
sPymbed 16:048e5e270a58 3416 return BUFFER_E;
sPymbed 16:048e5e270a58 3417 }
sPymbed 16:048e5e270a58 3418 if (input[*inOutIdx] == ASN_TAG_NULL) {
sPymbed 16:048e5e270a58 3419 ret = GetASNNull(input, inOutIdx, inSz);
sPymbed 16:048e5e270a58 3420 if (ret != 0)
sPymbed 16:048e5e270a58 3421 return ret;
sPymbed 16:048e5e270a58 3422 }
sPymbed 16:048e5e270a58 3423
sPymbed 16:048e5e270a58 3424 /* should have bit tag length and seq next */
sPymbed 16:048e5e270a58 3425 ret = CheckBitString(input, inOutIdx, NULL, inSz, 1, NULL);
sPymbed 16:048e5e270a58 3426 if (ret != 0)
sPymbed 16:048e5e270a58 3427 return ret;
sPymbed 16:048e5e270a58 3428
sPymbed 16:048e5e270a58 3429 if (GetSequence(input, inOutIdx, &length, inSz) < 0)
sPymbed 16:048e5e270a58 3430 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 3431 }
sPymbed 16:048e5e270a58 3432 #endif /* OPENSSL_EXTRA */
sPymbed 16:048e5e270a58 3433
sPymbed 16:048e5e270a58 3434 if (GetInt(&key->n, input, inOutIdx, inSz) < 0)
sPymbed 16:048e5e270a58 3435 return ASN_RSA_KEY_E;
sPymbed 16:048e5e270a58 3436 if (GetInt(&key->e, input, inOutIdx, inSz) < 0) {
sPymbed 16:048e5e270a58 3437 mp_clear(&key->n);
sPymbed 16:048e5e270a58 3438 return ASN_RSA_KEY_E;
sPymbed 16:048e5e270a58 3439 }
sPymbed 16:048e5e270a58 3440
sPymbed 16:048e5e270a58 3441 #ifdef WOLFSSL_XILINX_CRYPT
sPymbed 16:048e5e270a58 3442 if (wc_InitRsaHw(key) != 0) {
sPymbed 16:048e5e270a58 3443 return BAD_STATE_E;
sPymbed 16:048e5e270a58 3444 }
sPymbed 16:048e5e270a58 3445 #endif
sPymbed 16:048e5e270a58 3446
sPymbed 16:048e5e270a58 3447 return 0;
sPymbed 16:048e5e270a58 3448 }
sPymbed 16:048e5e270a58 3449
sPymbed 16:048e5e270a58 3450 /* import RSA public key elements (n, e) into RsaKey structure (key) */
sPymbed 16:048e5e270a58 3451 int wc_RsaPublicKeyDecodeRaw(const byte* n, word32 nSz, const byte* e,
sPymbed 16:048e5e270a58 3452 word32 eSz, RsaKey* key)
sPymbed 16:048e5e270a58 3453 {
sPymbed 16:048e5e270a58 3454 if (n == NULL || e == NULL || key == NULL)
sPymbed 16:048e5e270a58 3455 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 3456
sPymbed 16:048e5e270a58 3457 key->type = RSA_PUBLIC;
sPymbed 16:048e5e270a58 3458
sPymbed 16:048e5e270a58 3459 if (mp_init(&key->n) != MP_OKAY)
sPymbed 16:048e5e270a58 3460 return MP_INIT_E;
sPymbed 16:048e5e270a58 3461
sPymbed 16:048e5e270a58 3462 if (mp_read_unsigned_bin(&key->n, n, nSz) != 0) {
sPymbed 16:048e5e270a58 3463 mp_clear(&key->n);
sPymbed 16:048e5e270a58 3464 return ASN_GETINT_E;
sPymbed 16:048e5e270a58 3465 }
sPymbed 16:048e5e270a58 3466
sPymbed 16:048e5e270a58 3467 if (mp_init(&key->e) != MP_OKAY) {
sPymbed 16:048e5e270a58 3468 mp_clear(&key->n);
sPymbed 16:048e5e270a58 3469 return MP_INIT_E;
sPymbed 16:048e5e270a58 3470 }
sPymbed 16:048e5e270a58 3471
sPymbed 16:048e5e270a58 3472 if (mp_read_unsigned_bin(&key->e, e, eSz) != 0) {
sPymbed 16:048e5e270a58 3473 mp_clear(&key->n);
sPymbed 16:048e5e270a58 3474 mp_clear(&key->e);
sPymbed 16:048e5e270a58 3475 return ASN_GETINT_E;
sPymbed 16:048e5e270a58 3476 }
sPymbed 16:048e5e270a58 3477
sPymbed 16:048e5e270a58 3478 #ifdef WOLFSSL_XILINX_CRYPT
sPymbed 16:048e5e270a58 3479 if (wc_InitRsaHw(key) != 0) {
sPymbed 16:048e5e270a58 3480 return BAD_STATE_E;
sPymbed 16:048e5e270a58 3481 }
sPymbed 16:048e5e270a58 3482 #endif
sPymbed 16:048e5e270a58 3483
sPymbed 16:048e5e270a58 3484 return 0;
sPymbed 16:048e5e270a58 3485 }
sPymbed 16:048e5e270a58 3486 #endif /* HAVE_USER_RSA */
sPymbed 16:048e5e270a58 3487 #endif
sPymbed 16:048e5e270a58 3488
sPymbed 16:048e5e270a58 3489 #ifndef NO_DH
sPymbed 16:048e5e270a58 3490
sPymbed 16:048e5e270a58 3491 int wc_DhKeyDecode(const byte* input, word32* inOutIdx, DhKey* key, word32 inSz)
sPymbed 16:048e5e270a58 3492 {
sPymbed 16:048e5e270a58 3493 int length;
sPymbed 16:048e5e270a58 3494
sPymbed 16:048e5e270a58 3495 if (GetSequence(input, inOutIdx, &length, inSz) < 0)
sPymbed 16:048e5e270a58 3496 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 3497
sPymbed 16:048e5e270a58 3498 if (GetInt(&key->p, input, inOutIdx, inSz) < 0 ||
sPymbed 16:048e5e270a58 3499 GetInt(&key->g, input, inOutIdx, inSz) < 0) {
sPymbed 16:048e5e270a58 3500 return ASN_DH_KEY_E;
sPymbed 16:048e5e270a58 3501 }
sPymbed 16:048e5e270a58 3502
sPymbed 16:048e5e270a58 3503 return 0;
sPymbed 16:048e5e270a58 3504 }
sPymbed 16:048e5e270a58 3505
sPymbed 16:048e5e270a58 3506
sPymbed 16:048e5e270a58 3507 int wc_DhParamsLoad(const byte* input, word32 inSz, byte* p, word32* pInOutSz,
sPymbed 16:048e5e270a58 3508 byte* g, word32* gInOutSz)
sPymbed 16:048e5e270a58 3509 {
sPymbed 16:048e5e270a58 3510 word32 idx = 0;
sPymbed 16:048e5e270a58 3511 int ret;
sPymbed 16:048e5e270a58 3512 int length;
sPymbed 16:048e5e270a58 3513
sPymbed 16:048e5e270a58 3514 if (GetSequence(input, &idx, &length, inSz) <= 0)
sPymbed 16:048e5e270a58 3515 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 3516
sPymbed 16:048e5e270a58 3517 ret = GetASNInt(input, &idx, &length, inSz);
sPymbed 16:048e5e270a58 3518 if (ret != 0)
sPymbed 16:048e5e270a58 3519 return ret;
sPymbed 16:048e5e270a58 3520
sPymbed 16:048e5e270a58 3521 if (length <= (int)*pInOutSz) {
sPymbed 16:048e5e270a58 3522 XMEMCPY(p, &input[idx], length);
sPymbed 16:048e5e270a58 3523 *pInOutSz = length;
sPymbed 16:048e5e270a58 3524 }
sPymbed 16:048e5e270a58 3525 else {
sPymbed 16:048e5e270a58 3526 return BUFFER_E;
sPymbed 16:048e5e270a58 3527 }
sPymbed 16:048e5e270a58 3528 idx += length;
sPymbed 16:048e5e270a58 3529
sPymbed 16:048e5e270a58 3530 ret = GetASNInt(input, &idx, &length, inSz);
sPymbed 16:048e5e270a58 3531 if (ret != 0)
sPymbed 16:048e5e270a58 3532 return ret;
sPymbed 16:048e5e270a58 3533
sPymbed 16:048e5e270a58 3534 if (length <= (int)*gInOutSz) {
sPymbed 16:048e5e270a58 3535 XMEMCPY(g, &input[idx], length);
sPymbed 16:048e5e270a58 3536 *gInOutSz = length;
sPymbed 16:048e5e270a58 3537 }
sPymbed 16:048e5e270a58 3538 else {
sPymbed 16:048e5e270a58 3539 return BUFFER_E;
sPymbed 16:048e5e270a58 3540 }
sPymbed 16:048e5e270a58 3541
sPymbed 16:048e5e270a58 3542 return 0;
sPymbed 16:048e5e270a58 3543 }
sPymbed 16:048e5e270a58 3544
sPymbed 16:048e5e270a58 3545 #endif /* NO_DH */
sPymbed 16:048e5e270a58 3546
sPymbed 16:048e5e270a58 3547
sPymbed 16:048e5e270a58 3548 #ifndef NO_DSA
sPymbed 16:048e5e270a58 3549
sPymbed 16:048e5e270a58 3550 int DsaPublicKeyDecode(const byte* input, word32* inOutIdx, DsaKey* key,
sPymbed 16:048e5e270a58 3551 word32 inSz)
sPymbed 16:048e5e270a58 3552 {
sPymbed 16:048e5e270a58 3553 int length;
sPymbed 16:048e5e270a58 3554
sPymbed 16:048e5e270a58 3555 if (input == NULL || inOutIdx == NULL || key == NULL) {
sPymbed 16:048e5e270a58 3556 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 3557 }
sPymbed 16:048e5e270a58 3558
sPymbed 16:048e5e270a58 3559 if (GetSequence(input, inOutIdx, &length, inSz) < 0)
sPymbed 16:048e5e270a58 3560 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 3561
sPymbed 16:048e5e270a58 3562 if (GetInt(&key->p, input, inOutIdx, inSz) < 0 ||
sPymbed 16:048e5e270a58 3563 GetInt(&key->q, input, inOutIdx, inSz) < 0 ||
sPymbed 16:048e5e270a58 3564 GetInt(&key->g, input, inOutIdx, inSz) < 0 ||
sPymbed 16:048e5e270a58 3565 GetInt(&key->y, input, inOutIdx, inSz) < 0 )
sPymbed 16:048e5e270a58 3566 return ASN_DH_KEY_E;
sPymbed 16:048e5e270a58 3567
sPymbed 16:048e5e270a58 3568 key->type = DSA_PUBLIC;
sPymbed 16:048e5e270a58 3569 return 0;
sPymbed 16:048e5e270a58 3570 }
sPymbed 16:048e5e270a58 3571
sPymbed 16:048e5e270a58 3572
sPymbed 16:048e5e270a58 3573 int DsaPrivateKeyDecode(const byte* input, word32* inOutIdx, DsaKey* key,
sPymbed 16:048e5e270a58 3574 word32 inSz)
sPymbed 16:048e5e270a58 3575 {
sPymbed 16:048e5e270a58 3576 int length, version;
sPymbed 16:048e5e270a58 3577
sPymbed 16:048e5e270a58 3578 /* Sanity checks on input */
sPymbed 16:048e5e270a58 3579 if (input == NULL || inOutIdx == NULL || key == NULL) {
sPymbed 16:048e5e270a58 3580 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 3581 }
sPymbed 16:048e5e270a58 3582
sPymbed 16:048e5e270a58 3583 if (GetSequence(input, inOutIdx, &length, inSz) < 0)
sPymbed 16:048e5e270a58 3584 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 3585
sPymbed 16:048e5e270a58 3586 if (GetMyVersion(input, inOutIdx, &version, inSz) < 0)
sPymbed 16:048e5e270a58 3587 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 3588
sPymbed 16:048e5e270a58 3589 if (GetInt(&key->p, input, inOutIdx, inSz) < 0 ||
sPymbed 16:048e5e270a58 3590 GetInt(&key->q, input, inOutIdx, inSz) < 0 ||
sPymbed 16:048e5e270a58 3591 GetInt(&key->g, input, inOutIdx, inSz) < 0 ||
sPymbed 16:048e5e270a58 3592 GetInt(&key->y, input, inOutIdx, inSz) < 0 ||
sPymbed 16:048e5e270a58 3593 GetInt(&key->x, input, inOutIdx, inSz) < 0 )
sPymbed 16:048e5e270a58 3594 return ASN_DH_KEY_E;
sPymbed 16:048e5e270a58 3595
sPymbed 16:048e5e270a58 3596 key->type = DSA_PRIVATE;
sPymbed 16:048e5e270a58 3597 return 0;
sPymbed 16:048e5e270a58 3598 }
sPymbed 16:048e5e270a58 3599
sPymbed 16:048e5e270a58 3600 static mp_int* GetDsaInt(DsaKey* key, int idx)
sPymbed 16:048e5e270a58 3601 {
sPymbed 16:048e5e270a58 3602 if (idx == 0)
sPymbed 16:048e5e270a58 3603 return &key->p;
sPymbed 16:048e5e270a58 3604 if (idx == 1)
sPymbed 16:048e5e270a58 3605 return &key->q;
sPymbed 16:048e5e270a58 3606 if (idx == 2)
sPymbed 16:048e5e270a58 3607 return &key->g;
sPymbed 16:048e5e270a58 3608 if (idx == 3)
sPymbed 16:048e5e270a58 3609 return &key->y;
sPymbed 16:048e5e270a58 3610 if (idx == 4)
sPymbed 16:048e5e270a58 3611 return &key->x;
sPymbed 16:048e5e270a58 3612
sPymbed 16:048e5e270a58 3613 return NULL;
sPymbed 16:048e5e270a58 3614 }
sPymbed 16:048e5e270a58 3615
sPymbed 16:048e5e270a58 3616 /* Release Tmp DSA resources */
sPymbed 16:048e5e270a58 3617 static WC_INLINE void FreeTmpDsas(byte** tmps, void* heap)
sPymbed 16:048e5e270a58 3618 {
sPymbed 16:048e5e270a58 3619 int i;
sPymbed 16:048e5e270a58 3620
sPymbed 16:048e5e270a58 3621 for (i = 0; i < DSA_INTS; i++)
sPymbed 16:048e5e270a58 3622 XFREE(tmps[i], heap, DYNAMIC_TYPE_DSA);
sPymbed 16:048e5e270a58 3623
sPymbed 16:048e5e270a58 3624 (void)heap;
sPymbed 16:048e5e270a58 3625 }
sPymbed 16:048e5e270a58 3626
sPymbed 16:048e5e270a58 3627 /* Convert DsaKey key to DER format, write to output (inLen), return bytes
sPymbed 16:048e5e270a58 3628 written */
sPymbed 16:048e5e270a58 3629 int wc_DsaKeyToDer(DsaKey* key, byte* output, word32 inLen)
sPymbed 16:048e5e270a58 3630 {
sPymbed 16:048e5e270a58 3631 word32 seqSz, verSz, rawLen, intTotalLen = 0;
sPymbed 16:048e5e270a58 3632 word32 sizes[DSA_INTS];
sPymbed 16:048e5e270a58 3633 int i, j, outLen, ret = 0, mpSz;
sPymbed 16:048e5e270a58 3634
sPymbed 16:048e5e270a58 3635 byte seq[MAX_SEQ_SZ];
sPymbed 16:048e5e270a58 3636 byte ver[MAX_VERSION_SZ];
sPymbed 16:048e5e270a58 3637 byte* tmps[DSA_INTS];
sPymbed 16:048e5e270a58 3638
sPymbed 16:048e5e270a58 3639 if (!key || !output)
sPymbed 16:048e5e270a58 3640 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 3641
sPymbed 16:048e5e270a58 3642 if (key->type != DSA_PRIVATE)
sPymbed 16:048e5e270a58 3643 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 3644
sPymbed 16:048e5e270a58 3645 for (i = 0; i < DSA_INTS; i++)
sPymbed 16:048e5e270a58 3646 tmps[i] = NULL;
sPymbed 16:048e5e270a58 3647
sPymbed 16:048e5e270a58 3648 /* write all big ints from key to DER tmps */
sPymbed 16:048e5e270a58 3649 for (i = 0; i < DSA_INTS; i++) {
sPymbed 16:048e5e270a58 3650 mp_int* keyInt = GetDsaInt(key, i);
sPymbed 16:048e5e270a58 3651
sPymbed 16:048e5e270a58 3652 rawLen = mp_unsigned_bin_size(keyInt) + 1;
sPymbed 16:048e5e270a58 3653 tmps[i] = (byte*)XMALLOC(rawLen + MAX_SEQ_SZ, key->heap,
sPymbed 16:048e5e270a58 3654 DYNAMIC_TYPE_DSA);
sPymbed 16:048e5e270a58 3655 if (tmps[i] == NULL) {
sPymbed 16:048e5e270a58 3656 ret = MEMORY_E;
sPymbed 16:048e5e270a58 3657 break;
sPymbed 16:048e5e270a58 3658 }
sPymbed 16:048e5e270a58 3659
sPymbed 16:048e5e270a58 3660 mpSz = SetASNIntMP(keyInt, -1, tmps[i]);
sPymbed 16:048e5e270a58 3661 if (mpSz < 0) {
sPymbed 16:048e5e270a58 3662 ret = mpSz;
sPymbed 16:048e5e270a58 3663 break;
sPymbed 16:048e5e270a58 3664 }
sPymbed 16:048e5e270a58 3665 intTotalLen += (sizes[i] = mpSz);
sPymbed 16:048e5e270a58 3666 }
sPymbed 16:048e5e270a58 3667
sPymbed 16:048e5e270a58 3668 if (ret != 0) {
sPymbed 16:048e5e270a58 3669 FreeTmpDsas(tmps, key->heap);
sPymbed 16:048e5e270a58 3670 return ret;
sPymbed 16:048e5e270a58 3671 }
sPymbed 16:048e5e270a58 3672
sPymbed 16:048e5e270a58 3673 /* make headers */
sPymbed 16:048e5e270a58 3674 verSz = SetMyVersion(0, ver, FALSE);
sPymbed 16:048e5e270a58 3675 seqSz = SetSequence(verSz + intTotalLen, seq);
sPymbed 16:048e5e270a58 3676
sPymbed 16:048e5e270a58 3677 outLen = seqSz + verSz + intTotalLen;
sPymbed 16:048e5e270a58 3678 if (outLen > (int)inLen)
sPymbed 16:048e5e270a58 3679 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 3680
sPymbed 16:048e5e270a58 3681 /* write to output */
sPymbed 16:048e5e270a58 3682 XMEMCPY(output, seq, seqSz);
sPymbed 16:048e5e270a58 3683 j = seqSz;
sPymbed 16:048e5e270a58 3684 XMEMCPY(output + j, ver, verSz);
sPymbed 16:048e5e270a58 3685 j += verSz;
sPymbed 16:048e5e270a58 3686
sPymbed 16:048e5e270a58 3687 for (i = 0; i < DSA_INTS; i++) {
sPymbed 16:048e5e270a58 3688 XMEMCPY(output + j, tmps[i], sizes[i]);
sPymbed 16:048e5e270a58 3689 j += sizes[i];
sPymbed 16:048e5e270a58 3690 }
sPymbed 16:048e5e270a58 3691 FreeTmpDsas(tmps, key->heap);
sPymbed 16:048e5e270a58 3692
sPymbed 16:048e5e270a58 3693 return outLen;
sPymbed 16:048e5e270a58 3694 }
sPymbed 16:048e5e270a58 3695
sPymbed 16:048e5e270a58 3696 #endif /* NO_DSA */
sPymbed 16:048e5e270a58 3697
sPymbed 16:048e5e270a58 3698
sPymbed 16:048e5e270a58 3699 void InitDecodedCert(DecodedCert* cert, byte* source, word32 inSz, void* heap)
sPymbed 16:048e5e270a58 3700 {
sPymbed 16:048e5e270a58 3701 if (cert != NULL) {
sPymbed 16:048e5e270a58 3702 XMEMSET(cert, 0, sizeof(DecodedCert));
sPymbed 16:048e5e270a58 3703
sPymbed 16:048e5e270a58 3704 cert->subjectCNEnc = CTC_UTF8;
sPymbed 16:048e5e270a58 3705 cert->issuer[0] = '\0';
sPymbed 16:048e5e270a58 3706 cert->subject[0] = '\0';
sPymbed 16:048e5e270a58 3707 cert->source = source; /* don't own */
sPymbed 16:048e5e270a58 3708 cert->maxIdx = inSz; /* can't go over this index */
sPymbed 16:048e5e270a58 3709 cert->heap = heap;
sPymbed 16:048e5e270a58 3710 #ifdef WOLFSSL_CERT_GEN
sPymbed 16:048e5e270a58 3711 cert->subjectSNEnc = CTC_UTF8;
sPymbed 16:048e5e270a58 3712 cert->subjectCEnc = CTC_PRINTABLE;
sPymbed 16:048e5e270a58 3713 cert->subjectLEnc = CTC_UTF8;
sPymbed 16:048e5e270a58 3714 cert->subjectSTEnc = CTC_UTF8;
sPymbed 16:048e5e270a58 3715 cert->subjectOEnc = CTC_UTF8;
sPymbed 16:048e5e270a58 3716 cert->subjectOUEnc = CTC_UTF8;
sPymbed 16:048e5e270a58 3717 #endif /* WOLFSSL_CERT_GEN */
sPymbed 16:048e5e270a58 3718
sPymbed 16:048e5e270a58 3719 InitSignatureCtx(&cert->sigCtx, heap, INVALID_DEVID);
sPymbed 16:048e5e270a58 3720 }
sPymbed 16:048e5e270a58 3721 }
sPymbed 16:048e5e270a58 3722
sPymbed 16:048e5e270a58 3723
sPymbed 16:048e5e270a58 3724 void FreeAltNames(DNS_entry* altNames, void* heap)
sPymbed 16:048e5e270a58 3725 {
sPymbed 16:048e5e270a58 3726 (void)heap;
sPymbed 16:048e5e270a58 3727
sPymbed 16:048e5e270a58 3728 while (altNames) {
sPymbed 16:048e5e270a58 3729 DNS_entry* tmp = altNames->next;
sPymbed 16:048e5e270a58 3730
sPymbed 16:048e5e270a58 3731 XFREE(altNames->name, heap, DYNAMIC_TYPE_ALTNAME);
sPymbed 16:048e5e270a58 3732 XFREE(altNames, heap, DYNAMIC_TYPE_ALTNAME);
sPymbed 16:048e5e270a58 3733 altNames = tmp;
sPymbed 16:048e5e270a58 3734 }
sPymbed 16:048e5e270a58 3735 }
sPymbed 16:048e5e270a58 3736
sPymbed 16:048e5e270a58 3737 #ifndef IGNORE_NAME_CONSTRAINTS
sPymbed 16:048e5e270a58 3738
sPymbed 16:048e5e270a58 3739 void FreeNameSubtrees(Base_entry* names, void* heap)
sPymbed 16:048e5e270a58 3740 {
sPymbed 16:048e5e270a58 3741 (void)heap;
sPymbed 16:048e5e270a58 3742
sPymbed 16:048e5e270a58 3743 while (names) {
sPymbed 16:048e5e270a58 3744 Base_entry* tmp = names->next;
sPymbed 16:048e5e270a58 3745
sPymbed 16:048e5e270a58 3746 XFREE(names->name, heap, DYNAMIC_TYPE_ALTNAME);
sPymbed 16:048e5e270a58 3747 XFREE(names, heap, DYNAMIC_TYPE_ALTNAME);
sPymbed 16:048e5e270a58 3748 names = tmp;
sPymbed 16:048e5e270a58 3749 }
sPymbed 16:048e5e270a58 3750 }
sPymbed 16:048e5e270a58 3751
sPymbed 16:048e5e270a58 3752 #endif /* IGNORE_NAME_CONSTRAINTS */
sPymbed 16:048e5e270a58 3753
sPymbed 16:048e5e270a58 3754 void FreeDecodedCert(DecodedCert* cert)
sPymbed 16:048e5e270a58 3755 {
sPymbed 16:048e5e270a58 3756 if (cert->subjectCNStored == 1)
sPymbed 16:048e5e270a58 3757 XFREE(cert->subjectCN, cert->heap, DYNAMIC_TYPE_SUBJECT_CN);
sPymbed 16:048e5e270a58 3758 if (cert->pubKeyStored == 1)
sPymbed 16:048e5e270a58 3759 XFREE(cert->publicKey, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
sPymbed 16:048e5e270a58 3760 if (cert->weOwnAltNames && cert->altNames)
sPymbed 16:048e5e270a58 3761 FreeAltNames(cert->altNames, cert->heap);
sPymbed 16:048e5e270a58 3762 #ifndef IGNORE_NAME_CONSTRAINTS
sPymbed 16:048e5e270a58 3763 if (cert->altEmailNames)
sPymbed 16:048e5e270a58 3764 FreeAltNames(cert->altEmailNames, cert->heap);
sPymbed 16:048e5e270a58 3765 if (cert->permittedNames)
sPymbed 16:048e5e270a58 3766 FreeNameSubtrees(cert->permittedNames, cert->heap);
sPymbed 16:048e5e270a58 3767 if (cert->excludedNames)
sPymbed 16:048e5e270a58 3768 FreeNameSubtrees(cert->excludedNames, cert->heap);
sPymbed 16:048e5e270a58 3769 #endif /* IGNORE_NAME_CONSTRAINTS */
sPymbed 16:048e5e270a58 3770 #ifdef WOLFSSL_SEP
sPymbed 16:048e5e270a58 3771 XFREE(cert->deviceType, cert->heap, DYNAMIC_TYPE_X509_EXT);
sPymbed 16:048e5e270a58 3772 XFREE(cert->hwType, cert->heap, DYNAMIC_TYPE_X509_EXT);
sPymbed 16:048e5e270a58 3773 XFREE(cert->hwSerialNum, cert->heap, DYNAMIC_TYPE_X509_EXT);
sPymbed 16:048e5e270a58 3774 #endif /* WOLFSSL_SEP */
sPymbed 16:048e5e270a58 3775 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
sPymbed 16:048e5e270a58 3776 if (cert->issuerName.fullName != NULL)
sPymbed 16:048e5e270a58 3777 XFREE(cert->issuerName.fullName, cert->heap, DYNAMIC_TYPE_X509);
sPymbed 16:048e5e270a58 3778 if (cert->subjectName.fullName != NULL)
sPymbed 16:048e5e270a58 3779 XFREE(cert->subjectName.fullName, cert->heap, DYNAMIC_TYPE_X509);
sPymbed 16:048e5e270a58 3780 #endif /* OPENSSL_EXTRA */
sPymbed 16:048e5e270a58 3781 FreeSignatureCtx(&cert->sigCtx);
sPymbed 16:048e5e270a58 3782 }
sPymbed 16:048e5e270a58 3783
sPymbed 16:048e5e270a58 3784 static int GetCertHeader(DecodedCert* cert)
sPymbed 16:048e5e270a58 3785 {
sPymbed 16:048e5e270a58 3786 int ret = 0, len;
sPymbed 16:048e5e270a58 3787
sPymbed 16:048e5e270a58 3788 if (GetSequence(cert->source, &cert->srcIdx, &len, cert->maxIdx) < 0)
sPymbed 16:048e5e270a58 3789 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 3790
sPymbed 16:048e5e270a58 3791 cert->certBegin = cert->srcIdx;
sPymbed 16:048e5e270a58 3792
sPymbed 16:048e5e270a58 3793 if (GetSequence(cert->source, &cert->srcIdx, &len, cert->maxIdx) < 0)
sPymbed 16:048e5e270a58 3794 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 3795 cert->sigIndex = len + cert->srcIdx;
sPymbed 16:048e5e270a58 3796
sPymbed 16:048e5e270a58 3797 if (GetExplicitVersion(cert->source, &cert->srcIdx, &cert->version,
sPymbed 16:048e5e270a58 3798 cert->maxIdx) < 0)
sPymbed 16:048e5e270a58 3799 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 3800
sPymbed 16:048e5e270a58 3801 if (GetSerialNumber(cert->source, &cert->srcIdx, cert->serial,
sPymbed 16:048e5e270a58 3802 &cert->serialSz, cert->maxIdx) < 0)
sPymbed 16:048e5e270a58 3803 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 3804
sPymbed 16:048e5e270a58 3805 return ret;
sPymbed 16:048e5e270a58 3806 }
sPymbed 16:048e5e270a58 3807
sPymbed 16:048e5e270a58 3808 #if !defined(NO_RSA)
sPymbed 16:048e5e270a58 3809 /* Store Rsa Key, may save later, Dsa could use in future */
sPymbed 16:048e5e270a58 3810 static int StoreRsaKey(DecodedCert* cert)
sPymbed 16:048e5e270a58 3811 {
sPymbed 16:048e5e270a58 3812 int length;
sPymbed 16:048e5e270a58 3813 word32 recvd = cert->srcIdx;
sPymbed 16:048e5e270a58 3814
sPymbed 16:048e5e270a58 3815 if (GetSequence(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0)
sPymbed 16:048e5e270a58 3816 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 3817
sPymbed 16:048e5e270a58 3818 recvd = cert->srcIdx - recvd;
sPymbed 16:048e5e270a58 3819 length += recvd;
sPymbed 16:048e5e270a58 3820
sPymbed 16:048e5e270a58 3821 while (recvd--)
sPymbed 16:048e5e270a58 3822 cert->srcIdx--;
sPymbed 16:048e5e270a58 3823
sPymbed 16:048e5e270a58 3824 cert->pubKeySize = length;
sPymbed 16:048e5e270a58 3825 cert->publicKey = cert->source + cert->srcIdx;
sPymbed 16:048e5e270a58 3826 cert->srcIdx += length;
sPymbed 16:048e5e270a58 3827
sPymbed 16:048e5e270a58 3828 return 0;
sPymbed 16:048e5e270a58 3829 }
sPymbed 16:048e5e270a58 3830 #endif /* !NO_RSA */
sPymbed 16:048e5e270a58 3831
sPymbed 16:048e5e270a58 3832 #ifdef HAVE_ECC
sPymbed 16:048e5e270a58 3833
sPymbed 16:048e5e270a58 3834 /* return 0 on success if the ECC curve oid sum is supported */
sPymbed 16:048e5e270a58 3835 static int CheckCurve(word32 oid)
sPymbed 16:048e5e270a58 3836 {
sPymbed 16:048e5e270a58 3837 int ret = 0;
sPymbed 16:048e5e270a58 3838 word32 oidSz = 0;
sPymbed 16:048e5e270a58 3839
sPymbed 16:048e5e270a58 3840 ret = wc_ecc_get_oid(oid, NULL, &oidSz);
sPymbed 16:048e5e270a58 3841 if (ret < 0 || oidSz <= 0) {
sPymbed 16:048e5e270a58 3842 WOLFSSL_MSG("CheckCurve not found");
sPymbed 16:048e5e270a58 3843 ret = ALGO_ID_E;
sPymbed 16:048e5e270a58 3844 }
sPymbed 16:048e5e270a58 3845
sPymbed 16:048e5e270a58 3846 return ret;
sPymbed 16:048e5e270a58 3847 }
sPymbed 16:048e5e270a58 3848
sPymbed 16:048e5e270a58 3849 #endif /* HAVE_ECC */
sPymbed 16:048e5e270a58 3850
sPymbed 16:048e5e270a58 3851 static int GetKey(DecodedCert* cert)
sPymbed 16:048e5e270a58 3852 {
sPymbed 16:048e5e270a58 3853 int length;
sPymbed 16:048e5e270a58 3854 #if defined(HAVE_ECC) || defined(HAVE_NTRU)
sPymbed 16:048e5e270a58 3855 int tmpIdx = cert->srcIdx;
sPymbed 16:048e5e270a58 3856 #endif
sPymbed 16:048e5e270a58 3857
sPymbed 16:048e5e270a58 3858 if (GetSequence(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0)
sPymbed 16:048e5e270a58 3859 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 3860
sPymbed 16:048e5e270a58 3861 if (GetAlgoId(cert->source, &cert->srcIdx,
sPymbed 16:048e5e270a58 3862 &cert->keyOID, oidKeyType, cert->maxIdx) < 0)
sPymbed 16:048e5e270a58 3863 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 3864
sPymbed 16:048e5e270a58 3865 switch (cert->keyOID) {
sPymbed 16:048e5e270a58 3866 #ifndef NO_RSA
sPymbed 16:048e5e270a58 3867 case RSAk:
sPymbed 16:048e5e270a58 3868 {
sPymbed 16:048e5e270a58 3869 int ret;
sPymbed 16:048e5e270a58 3870 ret = CheckBitString(cert->source, &cert->srcIdx, NULL,
sPymbed 16:048e5e270a58 3871 cert->maxIdx, 1, NULL);
sPymbed 16:048e5e270a58 3872 if (ret != 0)
sPymbed 16:048e5e270a58 3873 return ret;
sPymbed 16:048e5e270a58 3874
sPymbed 16:048e5e270a58 3875 return StoreRsaKey(cert);
sPymbed 16:048e5e270a58 3876 }
sPymbed 16:048e5e270a58 3877
sPymbed 16:048e5e270a58 3878 #endif /* NO_RSA */
sPymbed 16:048e5e270a58 3879 #ifdef HAVE_NTRU
sPymbed 16:048e5e270a58 3880 case NTRUk:
sPymbed 16:048e5e270a58 3881 {
sPymbed 16:048e5e270a58 3882 const byte* key = &cert->source[tmpIdx];
sPymbed 16:048e5e270a58 3883 byte* next = (byte*)key;
sPymbed 16:048e5e270a58 3884 word16 keyLen;
sPymbed 16:048e5e270a58 3885 word32 rc;
sPymbed 16:048e5e270a58 3886 word32 remaining = cert->maxIdx - cert->srcIdx;
sPymbed 16:048e5e270a58 3887 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 3888 byte* keyBlob = NULL;
sPymbed 16:048e5e270a58 3889 #else
sPymbed 16:048e5e270a58 3890 byte keyBlob[MAX_NTRU_KEY_SZ];
sPymbed 16:048e5e270a58 3891 #endif
sPymbed 16:048e5e270a58 3892 rc = ntru_crypto_ntru_encrypt_subjectPublicKeyInfo2PublicKey(key,
sPymbed 16:048e5e270a58 3893 &keyLen, NULL, &next, &remaining);
sPymbed 16:048e5e270a58 3894 if (rc != NTRU_OK)
sPymbed 16:048e5e270a58 3895 return ASN_NTRU_KEY_E;
sPymbed 16:048e5e270a58 3896 if (keyLen > MAX_NTRU_KEY_SZ)
sPymbed 16:048e5e270a58 3897 return ASN_NTRU_KEY_E;
sPymbed 16:048e5e270a58 3898
sPymbed 16:048e5e270a58 3899 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 3900 keyBlob = (byte*)XMALLOC(MAX_NTRU_KEY_SZ, cert->heap,
sPymbed 16:048e5e270a58 3901 DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 3902 if (keyBlob == NULL)
sPymbed 16:048e5e270a58 3903 return MEMORY_E;
sPymbed 16:048e5e270a58 3904 #endif
sPymbed 16:048e5e270a58 3905
sPymbed 16:048e5e270a58 3906 rc = ntru_crypto_ntru_encrypt_subjectPublicKeyInfo2PublicKey(key,
sPymbed 16:048e5e270a58 3907 &keyLen, keyBlob, &next, &remaining);
sPymbed 16:048e5e270a58 3908 if (rc != NTRU_OK) {
sPymbed 16:048e5e270a58 3909 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 3910 XFREE(keyBlob, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 3911 #endif
sPymbed 16:048e5e270a58 3912 return ASN_NTRU_KEY_E;
sPymbed 16:048e5e270a58 3913 }
sPymbed 16:048e5e270a58 3914
sPymbed 16:048e5e270a58 3915 if ( (next - key) < 0) {
sPymbed 16:048e5e270a58 3916 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 3917 XFREE(keyBlob, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 3918 #endif
sPymbed 16:048e5e270a58 3919 return ASN_NTRU_KEY_E;
sPymbed 16:048e5e270a58 3920 }
sPymbed 16:048e5e270a58 3921
sPymbed 16:048e5e270a58 3922 cert->srcIdx = tmpIdx + (int)(next - key);
sPymbed 16:048e5e270a58 3923
sPymbed 16:048e5e270a58 3924 cert->publicKey = (byte*)XMALLOC(keyLen, cert->heap,
sPymbed 16:048e5e270a58 3925 DYNAMIC_TYPE_PUBLIC_KEY);
sPymbed 16:048e5e270a58 3926 if (cert->publicKey == NULL) {
sPymbed 16:048e5e270a58 3927 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 3928 XFREE(keyBlob, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 3929 #endif
sPymbed 16:048e5e270a58 3930 return MEMORY_E;
sPymbed 16:048e5e270a58 3931 }
sPymbed 16:048e5e270a58 3932 XMEMCPY(cert->publicKey, keyBlob, keyLen);
sPymbed 16:048e5e270a58 3933 cert->pubKeyStored = 1;
sPymbed 16:048e5e270a58 3934 cert->pubKeySize = keyLen;
sPymbed 16:048e5e270a58 3935
sPymbed 16:048e5e270a58 3936 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 3937 XFREE(keyBlob, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 3938 #endif
sPymbed 16:048e5e270a58 3939
sPymbed 16:048e5e270a58 3940 return 0;
sPymbed 16:048e5e270a58 3941 }
sPymbed 16:048e5e270a58 3942 #endif /* HAVE_NTRU */
sPymbed 16:048e5e270a58 3943 #ifdef HAVE_ECC
sPymbed 16:048e5e270a58 3944 case ECDSAk:
sPymbed 16:048e5e270a58 3945 {
sPymbed 16:048e5e270a58 3946 int ret;
sPymbed 16:048e5e270a58 3947 byte seq[5];
sPymbed 16:048e5e270a58 3948 int pubLen = length + 1 + SetLength(length, seq);
sPymbed 16:048e5e270a58 3949
sPymbed 16:048e5e270a58 3950 if (cert->source[cert->srcIdx] !=
sPymbed 16:048e5e270a58 3951 (ASN_SEQUENCE | ASN_CONSTRUCTED)) {
sPymbed 16:048e5e270a58 3952 if (GetObjectId(cert->source, &cert->srcIdx,
sPymbed 16:048e5e270a58 3953 &cert->pkCurveOID, oidCurveType, cert->maxIdx) < 0)
sPymbed 16:048e5e270a58 3954 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 3955
sPymbed 16:048e5e270a58 3956 if (CheckCurve(cert->pkCurveOID) < 0)
sPymbed 16:048e5e270a58 3957 return ECC_CURVE_OID_E;
sPymbed 16:048e5e270a58 3958
sPymbed 16:048e5e270a58 3959 /* key header */
sPymbed 16:048e5e270a58 3960 ret = CheckBitString(cert->source, &cert->srcIdx, &length,
sPymbed 16:048e5e270a58 3961 cert->maxIdx, 1, NULL);
sPymbed 16:048e5e270a58 3962 if (ret != 0)
sPymbed 16:048e5e270a58 3963 return ret;
sPymbed 16:048e5e270a58 3964 }
sPymbed 16:048e5e270a58 3965
sPymbed 16:048e5e270a58 3966 cert->publicKey = (byte*)XMALLOC(pubLen, cert->heap,
sPymbed 16:048e5e270a58 3967 DYNAMIC_TYPE_PUBLIC_KEY);
sPymbed 16:048e5e270a58 3968 if (cert->publicKey == NULL)
sPymbed 16:048e5e270a58 3969 return MEMORY_E;
sPymbed 16:048e5e270a58 3970 XMEMCPY(cert->publicKey, &cert->source[tmpIdx], pubLen);
sPymbed 16:048e5e270a58 3971 cert->pubKeyStored = 1;
sPymbed 16:048e5e270a58 3972 cert->pubKeySize = pubLen;
sPymbed 16:048e5e270a58 3973
sPymbed 16:048e5e270a58 3974 cert->srcIdx = tmpIdx + pubLen;
sPymbed 16:048e5e270a58 3975
sPymbed 16:048e5e270a58 3976 return 0;
sPymbed 16:048e5e270a58 3977 }
sPymbed 16:048e5e270a58 3978 #endif /* HAVE_ECC */
sPymbed 16:048e5e270a58 3979 #ifdef HAVE_ED25519
sPymbed 16:048e5e270a58 3980 case ED25519k:
sPymbed 16:048e5e270a58 3981 {
sPymbed 16:048e5e270a58 3982 int ret;
sPymbed 16:048e5e270a58 3983
sPymbed 16:048e5e270a58 3984 cert->pkCurveOID = ED25519k;
sPymbed 16:048e5e270a58 3985
sPymbed 16:048e5e270a58 3986 ret = CheckBitString(cert->source, &cert->srcIdx, &length,
sPymbed 16:048e5e270a58 3987 cert->maxIdx, 1, NULL);
sPymbed 16:048e5e270a58 3988 if (ret != 0)
sPymbed 16:048e5e270a58 3989 return ret;
sPymbed 16:048e5e270a58 3990
sPymbed 16:048e5e270a58 3991 cert->publicKey = (byte*) XMALLOC(length, cert->heap,
sPymbed 16:048e5e270a58 3992 DYNAMIC_TYPE_PUBLIC_KEY);
sPymbed 16:048e5e270a58 3993 if (cert->publicKey == NULL)
sPymbed 16:048e5e270a58 3994 return MEMORY_E;
sPymbed 16:048e5e270a58 3995 XMEMCPY(cert->publicKey, &cert->source[cert->srcIdx], length);
sPymbed 16:048e5e270a58 3996 cert->pubKeyStored = 1;
sPymbed 16:048e5e270a58 3997 cert->pubKeySize = length;
sPymbed 16:048e5e270a58 3998
sPymbed 16:048e5e270a58 3999 cert->srcIdx += length;
sPymbed 16:048e5e270a58 4000
sPymbed 16:048e5e270a58 4001 return 0;
sPymbed 16:048e5e270a58 4002 }
sPymbed 16:048e5e270a58 4003 #endif /* HAVE_ED25519 */
sPymbed 16:048e5e270a58 4004 default:
sPymbed 16:048e5e270a58 4005 return ASN_UNKNOWN_OID_E;
sPymbed 16:048e5e270a58 4006 }
sPymbed 16:048e5e270a58 4007 }
sPymbed 16:048e5e270a58 4008
sPymbed 16:048e5e270a58 4009 /* process NAME, either issuer or subject */
sPymbed 16:048e5e270a58 4010 static int GetName(DecodedCert* cert, int nameType)
sPymbed 16:048e5e270a58 4011 {
sPymbed 16:048e5e270a58 4012 int length; /* length of all distinguished names */
sPymbed 16:048e5e270a58 4013 int dummy;
sPymbed 16:048e5e270a58 4014 int ret;
sPymbed 16:048e5e270a58 4015 char* full;
sPymbed 16:048e5e270a58 4016 byte* hash;
sPymbed 16:048e5e270a58 4017 word32 idx;
sPymbed 16:048e5e270a58 4018 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
sPymbed 16:048e5e270a58 4019 DecodedName* dName =
sPymbed 16:048e5e270a58 4020 (nameType == ISSUER) ? &cert->issuerName : &cert->subjectName;
sPymbed 16:048e5e270a58 4021 int dcnum = 0;
sPymbed 16:048e5e270a58 4022 #endif /* OPENSSL_EXTRA */
sPymbed 16:048e5e270a58 4023
sPymbed 16:048e5e270a58 4024 WOLFSSL_MSG("Getting Cert Name");
sPymbed 16:048e5e270a58 4025
sPymbed 16:048e5e270a58 4026 if (nameType == ISSUER) {
sPymbed 16:048e5e270a58 4027 full = cert->issuer;
sPymbed 16:048e5e270a58 4028 hash = cert->issuerHash;
sPymbed 16:048e5e270a58 4029 }
sPymbed 16:048e5e270a58 4030 else {
sPymbed 16:048e5e270a58 4031 full = cert->subject;
sPymbed 16:048e5e270a58 4032 hash = cert->subjectHash;
sPymbed 16:048e5e270a58 4033 }
sPymbed 16:048e5e270a58 4034
sPymbed 16:048e5e270a58 4035 if (cert->srcIdx >= cert->maxIdx) {
sPymbed 16:048e5e270a58 4036 return BUFFER_E;
sPymbed 16:048e5e270a58 4037 }
sPymbed 16:048e5e270a58 4038
sPymbed 16:048e5e270a58 4039 if (cert->source[cert->srcIdx] == ASN_OBJECT_ID) {
sPymbed 16:048e5e270a58 4040 WOLFSSL_MSG("Trying optional prefix...");
sPymbed 16:048e5e270a58 4041
sPymbed 16:048e5e270a58 4042 if (SkipObjectId(cert->source, &cert->srcIdx, cert->maxIdx) < 0)
sPymbed 16:048e5e270a58 4043 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 4044 WOLFSSL_MSG("Got optional prefix");
sPymbed 16:048e5e270a58 4045 }
sPymbed 16:048e5e270a58 4046
sPymbed 16:048e5e270a58 4047 /* For OCSP, RFC2560 section 4.1.1 states the issuer hash should be
sPymbed 16:048e5e270a58 4048 * calculated over the entire DER encoding of the Name field, including
sPymbed 16:048e5e270a58 4049 * the tag and length. */
sPymbed 16:048e5e270a58 4050 idx = cert->srcIdx;
sPymbed 16:048e5e270a58 4051 if (GetSequence(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0)
sPymbed 16:048e5e270a58 4052 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 4053
sPymbed 16:048e5e270a58 4054 #ifdef NO_SHA
sPymbed 16:048e5e270a58 4055 ret = wc_Sha256Hash(&cert->source[idx], length + cert->srcIdx - idx, hash);
sPymbed 16:048e5e270a58 4056 #else
sPymbed 16:048e5e270a58 4057 ret = wc_ShaHash(&cert->source[idx], length + cert->srcIdx - idx, hash);
sPymbed 16:048e5e270a58 4058 #endif
sPymbed 16:048e5e270a58 4059 if (ret != 0)
sPymbed 16:048e5e270a58 4060 return ret;
sPymbed 16:048e5e270a58 4061
sPymbed 16:048e5e270a58 4062 length += cert->srcIdx;
sPymbed 16:048e5e270a58 4063 idx = 0;
sPymbed 16:048e5e270a58 4064
sPymbed 16:048e5e270a58 4065 #ifdef HAVE_PKCS7
sPymbed 16:048e5e270a58 4066 /* store pointer to raw issuer */
sPymbed 16:048e5e270a58 4067 if (nameType == ISSUER) {
sPymbed 16:048e5e270a58 4068 cert->issuerRaw = &cert->source[cert->srcIdx];
sPymbed 16:048e5e270a58 4069 cert->issuerRawLen = length - cert->srcIdx;
sPymbed 16:048e5e270a58 4070 }
sPymbed 16:048e5e270a58 4071 #endif
sPymbed 16:048e5e270a58 4072 #ifndef IGNORE_NAME_CONSTRAINTS
sPymbed 16:048e5e270a58 4073 if (nameType == SUBJECT) {
sPymbed 16:048e5e270a58 4074 cert->subjectRaw = &cert->source[cert->srcIdx];
sPymbed 16:048e5e270a58 4075 cert->subjectRawLen = length - cert->srcIdx;
sPymbed 16:048e5e270a58 4076 }
sPymbed 16:048e5e270a58 4077 #endif
sPymbed 16:048e5e270a58 4078
sPymbed 16:048e5e270a58 4079 while (cert->srcIdx < (word32)length) {
sPymbed 16:048e5e270a58 4080 byte b;
sPymbed 16:048e5e270a58 4081 byte joint[2];
sPymbed 16:048e5e270a58 4082 byte tooBig = FALSE;
sPymbed 16:048e5e270a58 4083 int oidSz;
sPymbed 16:048e5e270a58 4084
sPymbed 16:048e5e270a58 4085 if (GetSet(cert->source, &cert->srcIdx, &dummy, cert->maxIdx) < 0) {
sPymbed 16:048e5e270a58 4086 WOLFSSL_MSG("Cert name lacks set header, trying sequence");
sPymbed 16:048e5e270a58 4087 }
sPymbed 16:048e5e270a58 4088
sPymbed 16:048e5e270a58 4089 if (GetSequence(cert->source, &cert->srcIdx, &dummy, cert->maxIdx) <= 0)
sPymbed 16:048e5e270a58 4090 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 4091
sPymbed 16:048e5e270a58 4092 ret = GetASNObjectId(cert->source, &cert->srcIdx, &oidSz, cert->maxIdx);
sPymbed 16:048e5e270a58 4093 if (ret != 0)
sPymbed 16:048e5e270a58 4094 return ret;
sPymbed 16:048e5e270a58 4095
sPymbed 16:048e5e270a58 4096 /* make sure there is room for joint */
sPymbed 16:048e5e270a58 4097 if ((cert->srcIdx + sizeof(joint)) > cert->maxIdx)
sPymbed 16:048e5e270a58 4098 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 4099
sPymbed 16:048e5e270a58 4100 XMEMCPY(joint, &cert->source[cert->srcIdx], sizeof(joint));
sPymbed 16:048e5e270a58 4101
sPymbed 16:048e5e270a58 4102 /* v1 name types */
sPymbed 16:048e5e270a58 4103 if (joint[0] == 0x55 && joint[1] == 0x04) {
sPymbed 16:048e5e270a58 4104 const char* copy = NULL;
sPymbed 16:048e5e270a58 4105 int strLen;
sPymbed 16:048e5e270a58 4106 byte id;
sPymbed 16:048e5e270a58 4107
sPymbed 16:048e5e270a58 4108 cert->srcIdx += 2;
sPymbed 16:048e5e270a58 4109 id = cert->source[cert->srcIdx++];
sPymbed 16:048e5e270a58 4110 b = cert->source[cert->srcIdx++]; /* encoding */
sPymbed 16:048e5e270a58 4111
sPymbed 16:048e5e270a58 4112 if (GetLength(cert->source, &cert->srcIdx, &strLen,
sPymbed 16:048e5e270a58 4113 cert->maxIdx) < 0)
sPymbed 16:048e5e270a58 4114 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 4115
sPymbed 16:048e5e270a58 4116 if ( (strLen + 14) > (int)(ASN_NAME_MAX - idx)) {
sPymbed 16:048e5e270a58 4117 /* include biggest pre fix header too 4 = "/serialNumber=" */
sPymbed 16:048e5e270a58 4118 WOLFSSL_MSG("ASN Name too big, skipping");
sPymbed 16:048e5e270a58 4119 tooBig = TRUE;
sPymbed 16:048e5e270a58 4120 }
sPymbed 16:048e5e270a58 4121
sPymbed 16:048e5e270a58 4122 if (id == ASN_COMMON_NAME) {
sPymbed 16:048e5e270a58 4123 if (nameType == SUBJECT) {
sPymbed 16:048e5e270a58 4124 cert->subjectCN = (char *)&cert->source[cert->srcIdx];
sPymbed 16:048e5e270a58 4125 cert->subjectCNLen = strLen;
sPymbed 16:048e5e270a58 4126 cert->subjectCNEnc = b;
sPymbed 16:048e5e270a58 4127 }
sPymbed 16:048e5e270a58 4128
sPymbed 16:048e5e270a58 4129 copy = WOLFSSL_COMMON_NAME;
sPymbed 16:048e5e270a58 4130 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
sPymbed 16:048e5e270a58 4131 dName->cnIdx = cert->srcIdx;
sPymbed 16:048e5e270a58 4132 dName->cnLen = strLen;
sPymbed 16:048e5e270a58 4133 #endif /* OPENSSL_EXTRA */
sPymbed 16:048e5e270a58 4134 }
sPymbed 16:048e5e270a58 4135 else if (id == ASN_SUR_NAME) {
sPymbed 16:048e5e270a58 4136 copy = WOLFSSL_SUR_NAME;
sPymbed 16:048e5e270a58 4137 #ifdef WOLFSSL_CERT_GEN
sPymbed 16:048e5e270a58 4138 if (nameType == SUBJECT) {
sPymbed 16:048e5e270a58 4139 cert->subjectSN = (char*)&cert->source[cert->srcIdx];
sPymbed 16:048e5e270a58 4140 cert->subjectSNLen = strLen;
sPymbed 16:048e5e270a58 4141 cert->subjectSNEnc = b;
sPymbed 16:048e5e270a58 4142 }
sPymbed 16:048e5e270a58 4143 #endif /* WOLFSSL_CERT_GEN */
sPymbed 16:048e5e270a58 4144 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
sPymbed 16:048e5e270a58 4145 dName->snIdx = cert->srcIdx;
sPymbed 16:048e5e270a58 4146 dName->snLen = strLen;
sPymbed 16:048e5e270a58 4147 #endif /* OPENSSL_EXTRA */
sPymbed 16:048e5e270a58 4148 }
sPymbed 16:048e5e270a58 4149 else if (id == ASN_COUNTRY_NAME) {
sPymbed 16:048e5e270a58 4150 copy = WOLFSSL_COUNTRY_NAME;
sPymbed 16:048e5e270a58 4151 #ifdef WOLFSSL_CERT_GEN
sPymbed 16:048e5e270a58 4152 if (nameType == SUBJECT) {
sPymbed 16:048e5e270a58 4153 cert->subjectC = (char*)&cert->source[cert->srcIdx];
sPymbed 16:048e5e270a58 4154 cert->subjectCLen = strLen;
sPymbed 16:048e5e270a58 4155 cert->subjectCEnc = b;
sPymbed 16:048e5e270a58 4156 }
sPymbed 16:048e5e270a58 4157 #endif /* WOLFSSL_CERT_GEN */
sPymbed 16:048e5e270a58 4158 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
sPymbed 16:048e5e270a58 4159 dName->cIdx = cert->srcIdx;
sPymbed 16:048e5e270a58 4160 dName->cLen = strLen;
sPymbed 16:048e5e270a58 4161 #endif /* OPENSSL_EXTRA */
sPymbed 16:048e5e270a58 4162 }
sPymbed 16:048e5e270a58 4163 else if (id == ASN_LOCALITY_NAME) {
sPymbed 16:048e5e270a58 4164 copy = WOLFSSL_LOCALITY_NAME;
sPymbed 16:048e5e270a58 4165 #ifdef WOLFSSL_CERT_GEN
sPymbed 16:048e5e270a58 4166 if (nameType == SUBJECT) {
sPymbed 16:048e5e270a58 4167 cert->subjectL = (char*)&cert->source[cert->srcIdx];
sPymbed 16:048e5e270a58 4168 cert->subjectLLen = strLen;
sPymbed 16:048e5e270a58 4169 cert->subjectLEnc = b;
sPymbed 16:048e5e270a58 4170 }
sPymbed 16:048e5e270a58 4171 #endif /* WOLFSSL_CERT_GEN */
sPymbed 16:048e5e270a58 4172 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
sPymbed 16:048e5e270a58 4173 dName->lIdx = cert->srcIdx;
sPymbed 16:048e5e270a58 4174 dName->lLen = strLen;
sPymbed 16:048e5e270a58 4175 #endif /* OPENSSL_EXTRA */
sPymbed 16:048e5e270a58 4176 }
sPymbed 16:048e5e270a58 4177 else if (id == ASN_STATE_NAME) {
sPymbed 16:048e5e270a58 4178 copy = WOLFSSL_STATE_NAME;
sPymbed 16:048e5e270a58 4179 #ifdef WOLFSSL_CERT_GEN
sPymbed 16:048e5e270a58 4180 if (nameType == SUBJECT) {
sPymbed 16:048e5e270a58 4181 cert->subjectST = (char*)&cert->source[cert->srcIdx];
sPymbed 16:048e5e270a58 4182 cert->subjectSTLen = strLen;
sPymbed 16:048e5e270a58 4183 cert->subjectSTEnc = b;
sPymbed 16:048e5e270a58 4184 }
sPymbed 16:048e5e270a58 4185 #endif /* WOLFSSL_CERT_GEN */
sPymbed 16:048e5e270a58 4186 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
sPymbed 16:048e5e270a58 4187 dName->stIdx = cert->srcIdx;
sPymbed 16:048e5e270a58 4188 dName->stLen = strLen;
sPymbed 16:048e5e270a58 4189 #endif /* OPENSSL_EXTRA */
sPymbed 16:048e5e270a58 4190 }
sPymbed 16:048e5e270a58 4191 else if (id == ASN_ORG_NAME) {
sPymbed 16:048e5e270a58 4192 copy = WOLFSSL_ORG_NAME;
sPymbed 16:048e5e270a58 4193 #ifdef WOLFSSL_CERT_GEN
sPymbed 16:048e5e270a58 4194 if (nameType == SUBJECT) {
sPymbed 16:048e5e270a58 4195 cert->subjectO = (char*)&cert->source[cert->srcIdx];
sPymbed 16:048e5e270a58 4196 cert->subjectOLen = strLen;
sPymbed 16:048e5e270a58 4197 cert->subjectOEnc = b;
sPymbed 16:048e5e270a58 4198 }
sPymbed 16:048e5e270a58 4199 #endif /* WOLFSSL_CERT_GEN */
sPymbed 16:048e5e270a58 4200 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
sPymbed 16:048e5e270a58 4201 dName->oIdx = cert->srcIdx;
sPymbed 16:048e5e270a58 4202 dName->oLen = strLen;
sPymbed 16:048e5e270a58 4203 #endif /* OPENSSL_EXTRA */
sPymbed 16:048e5e270a58 4204 }
sPymbed 16:048e5e270a58 4205 else if (id == ASN_ORGUNIT_NAME) {
sPymbed 16:048e5e270a58 4206 copy = WOLFSSL_ORGUNIT_NAME;
sPymbed 16:048e5e270a58 4207 #ifdef WOLFSSL_CERT_GEN
sPymbed 16:048e5e270a58 4208 if (nameType == SUBJECT) {
sPymbed 16:048e5e270a58 4209 cert->subjectOU = (char*)&cert->source[cert->srcIdx];
sPymbed 16:048e5e270a58 4210 cert->subjectOULen = strLen;
sPymbed 16:048e5e270a58 4211 cert->subjectOUEnc = b;
sPymbed 16:048e5e270a58 4212 }
sPymbed 16:048e5e270a58 4213 #endif /* WOLFSSL_CERT_GEN */
sPymbed 16:048e5e270a58 4214 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
sPymbed 16:048e5e270a58 4215 dName->ouIdx = cert->srcIdx;
sPymbed 16:048e5e270a58 4216 dName->ouLen = strLen;
sPymbed 16:048e5e270a58 4217 #endif /* OPENSSL_EXTRA */
sPymbed 16:048e5e270a58 4218 }
sPymbed 16:048e5e270a58 4219 else if (id == ASN_SERIAL_NUMBER) {
sPymbed 16:048e5e270a58 4220 copy = WOLFSSL_SERIAL_NUMBER;
sPymbed 16:048e5e270a58 4221 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
sPymbed 16:048e5e270a58 4222 dName->snIdx = cert->srcIdx;
sPymbed 16:048e5e270a58 4223 dName->snLen = strLen;
sPymbed 16:048e5e270a58 4224 #endif /* OPENSSL_EXTRA */
sPymbed 16:048e5e270a58 4225 }
sPymbed 16:048e5e270a58 4226 if (copy && !tooBig) {
sPymbed 16:048e5e270a58 4227 XMEMCPY(&full[idx], copy, XSTRLEN(copy));
sPymbed 16:048e5e270a58 4228 idx += (word32)XSTRLEN(copy);
sPymbed 16:048e5e270a58 4229 #ifdef WOLFSSL_WPAS
sPymbed 16:048e5e270a58 4230 full[idx] = '=';
sPymbed 16:048e5e270a58 4231 idx++;
sPymbed 16:048e5e270a58 4232 #endif
sPymbed 16:048e5e270a58 4233 XMEMCPY(&full[idx], &cert->source[cert->srcIdx], strLen);
sPymbed 16:048e5e270a58 4234 idx += strLen;
sPymbed 16:048e5e270a58 4235 }
sPymbed 16:048e5e270a58 4236
sPymbed 16:048e5e270a58 4237 cert->srcIdx += strLen;
sPymbed 16:048e5e270a58 4238 }
sPymbed 16:048e5e270a58 4239 else {
sPymbed 16:048e5e270a58 4240 /* skip */
sPymbed 16:048e5e270a58 4241 byte email = FALSE;
sPymbed 16:048e5e270a58 4242 byte pilot = FALSE;
sPymbed 16:048e5e270a58 4243 byte id = 0;
sPymbed 16:048e5e270a58 4244 int adv;
sPymbed 16:048e5e270a58 4245
sPymbed 16:048e5e270a58 4246 if (joint[0] == 0x2a && joint[1] == 0x86) /* email id hdr */
sPymbed 16:048e5e270a58 4247 email = TRUE;
sPymbed 16:048e5e270a58 4248
sPymbed 16:048e5e270a58 4249 if (joint[0] == 0x9 && joint[1] == 0x92) { /* uid id hdr */
sPymbed 16:048e5e270a58 4250 /* last value of OID is the type of pilot attribute */
sPymbed 16:048e5e270a58 4251 id = cert->source[cert->srcIdx + oidSz - 1];
sPymbed 16:048e5e270a58 4252 pilot = TRUE;
sPymbed 16:048e5e270a58 4253 }
sPymbed 16:048e5e270a58 4254
sPymbed 16:048e5e270a58 4255 cert->srcIdx += oidSz + 1;
sPymbed 16:048e5e270a58 4256
sPymbed 16:048e5e270a58 4257 if (GetLength(cert->source, &cert->srcIdx, &adv, cert->maxIdx) < 0)
sPymbed 16:048e5e270a58 4258 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 4259
sPymbed 16:048e5e270a58 4260 if (adv > (int)(ASN_NAME_MAX - idx)) {
sPymbed 16:048e5e270a58 4261 WOLFSSL_MSG("ASN name too big, skipping");
sPymbed 16:048e5e270a58 4262 tooBig = TRUE;
sPymbed 16:048e5e270a58 4263 }
sPymbed 16:048e5e270a58 4264
sPymbed 16:048e5e270a58 4265 if (email) {
sPymbed 16:048e5e270a58 4266 if ( (14 + adv) > (int)(ASN_NAME_MAX - idx)) {
sPymbed 16:048e5e270a58 4267 WOLFSSL_MSG("ASN name too big, skipping");
sPymbed 16:048e5e270a58 4268 tooBig = TRUE;
sPymbed 16:048e5e270a58 4269 }
sPymbed 16:048e5e270a58 4270 if (!tooBig) {
sPymbed 16:048e5e270a58 4271 XMEMCPY(&full[idx], "/emailAddress=", 14);
sPymbed 16:048e5e270a58 4272 idx += 14;
sPymbed 16:048e5e270a58 4273 }
sPymbed 16:048e5e270a58 4274
sPymbed 16:048e5e270a58 4275 #ifdef WOLFSSL_CERT_GEN
sPymbed 16:048e5e270a58 4276 if (nameType == SUBJECT) {
sPymbed 16:048e5e270a58 4277 cert->subjectEmail = (char*)&cert->source[cert->srcIdx];
sPymbed 16:048e5e270a58 4278 cert->subjectEmailLen = adv;
sPymbed 16:048e5e270a58 4279 }
sPymbed 16:048e5e270a58 4280 #endif /* WOLFSSL_CERT_GEN */
sPymbed 16:048e5e270a58 4281 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
sPymbed 16:048e5e270a58 4282 dName->emailIdx = cert->srcIdx;
sPymbed 16:048e5e270a58 4283 dName->emailLen = adv;
sPymbed 16:048e5e270a58 4284 #endif /* OPENSSL_EXTRA */
sPymbed 16:048e5e270a58 4285 #ifndef IGNORE_NAME_CONSTRAINTS
sPymbed 16:048e5e270a58 4286 {
sPymbed 16:048e5e270a58 4287 DNS_entry* emailName = NULL;
sPymbed 16:048e5e270a58 4288
sPymbed 16:048e5e270a58 4289 emailName = (DNS_entry*)XMALLOC(sizeof(DNS_entry),
sPymbed 16:048e5e270a58 4290 cert->heap, DYNAMIC_TYPE_ALTNAME);
sPymbed 16:048e5e270a58 4291 if (emailName == NULL) {
sPymbed 16:048e5e270a58 4292 WOLFSSL_MSG("\tOut of Memory");
sPymbed 16:048e5e270a58 4293 return MEMORY_E;
sPymbed 16:048e5e270a58 4294 }
sPymbed 16:048e5e270a58 4295 emailName->type = 0;
sPymbed 16:048e5e270a58 4296 emailName->name = (char*)XMALLOC(adv + 1,
sPymbed 16:048e5e270a58 4297 cert->heap, DYNAMIC_TYPE_ALTNAME);
sPymbed 16:048e5e270a58 4298 if (emailName->name == NULL) {
sPymbed 16:048e5e270a58 4299 WOLFSSL_MSG("\tOut of Memory");
sPymbed 16:048e5e270a58 4300 XFREE(emailName, cert->heap, DYNAMIC_TYPE_ALTNAME);
sPymbed 16:048e5e270a58 4301 return MEMORY_E;
sPymbed 16:048e5e270a58 4302 }
sPymbed 16:048e5e270a58 4303 emailName->len = adv;
sPymbed 16:048e5e270a58 4304 XMEMCPY(emailName->name,
sPymbed 16:048e5e270a58 4305 &cert->source[cert->srcIdx], adv);
sPymbed 16:048e5e270a58 4306 emailName->name[adv] = '\0';
sPymbed 16:048e5e270a58 4307
sPymbed 16:048e5e270a58 4308 emailName->next = cert->altEmailNames;
sPymbed 16:048e5e270a58 4309 cert->altEmailNames = emailName;
sPymbed 16:048e5e270a58 4310 }
sPymbed 16:048e5e270a58 4311 #endif /* IGNORE_NAME_CONSTRAINTS */
sPymbed 16:048e5e270a58 4312 if (!tooBig) {
sPymbed 16:048e5e270a58 4313 XMEMCPY(&full[idx], &cert->source[cert->srcIdx], adv);
sPymbed 16:048e5e270a58 4314 idx += adv;
sPymbed 16:048e5e270a58 4315 }
sPymbed 16:048e5e270a58 4316 }
sPymbed 16:048e5e270a58 4317
sPymbed 16:048e5e270a58 4318 if (pilot) {
sPymbed 16:048e5e270a58 4319 if ( (5 + adv) > (int)(ASN_NAME_MAX - idx)) {
sPymbed 16:048e5e270a58 4320 WOLFSSL_MSG("ASN name too big, skipping");
sPymbed 16:048e5e270a58 4321 tooBig = TRUE;
sPymbed 16:048e5e270a58 4322 }
sPymbed 16:048e5e270a58 4323 if (!tooBig) {
sPymbed 16:048e5e270a58 4324 switch (id) {
sPymbed 16:048e5e270a58 4325 case ASN_USER_ID:
sPymbed 16:048e5e270a58 4326 XMEMCPY(&full[idx], "/UID=", 5);
sPymbed 16:048e5e270a58 4327 idx += 5;
sPymbed 16:048e5e270a58 4328 #if defined(OPENSSL_EXTRA) || \
sPymbed 16:048e5e270a58 4329 defined(OPENSSL_EXTRA_X509_SMALL)
sPymbed 16:048e5e270a58 4330 dName->uidIdx = cert->srcIdx;
sPymbed 16:048e5e270a58 4331 dName->uidLen = adv;
sPymbed 16:048e5e270a58 4332 #endif /* OPENSSL_EXTRA */
sPymbed 16:048e5e270a58 4333 break;
sPymbed 16:048e5e270a58 4334
sPymbed 16:048e5e270a58 4335 case ASN_DOMAIN_COMPONENT:
sPymbed 16:048e5e270a58 4336 XMEMCPY(&full[idx], "/DC=", 4);
sPymbed 16:048e5e270a58 4337 idx += 4;
sPymbed 16:048e5e270a58 4338 #if defined(OPENSSL_EXTRA) || \
sPymbed 16:048e5e270a58 4339 defined(OPENSSL_EXTRA_X509_SMALL)
sPymbed 16:048e5e270a58 4340 dName->dcIdx[dcnum] = cert->srcIdx;
sPymbed 16:048e5e270a58 4341 dName->dcLen[dcnum] = adv;
sPymbed 16:048e5e270a58 4342 dName->dcNum = dcnum + 1;
sPymbed 16:048e5e270a58 4343 dcnum++;
sPymbed 16:048e5e270a58 4344 #endif /* OPENSSL_EXTRA */
sPymbed 16:048e5e270a58 4345 break;
sPymbed 16:048e5e270a58 4346
sPymbed 16:048e5e270a58 4347 default:
sPymbed 16:048e5e270a58 4348 WOLFSSL_MSG("Unknown pilot attribute type");
sPymbed 16:048e5e270a58 4349 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 4350 }
sPymbed 16:048e5e270a58 4351 XMEMCPY(&full[idx], &cert->source[cert->srcIdx], adv);
sPymbed 16:048e5e270a58 4352 idx += adv;
sPymbed 16:048e5e270a58 4353 }
sPymbed 16:048e5e270a58 4354 }
sPymbed 16:048e5e270a58 4355
sPymbed 16:048e5e270a58 4356 cert->srcIdx += adv;
sPymbed 16:048e5e270a58 4357 }
sPymbed 16:048e5e270a58 4358 }
sPymbed 16:048e5e270a58 4359 full[idx++] = 0;
sPymbed 16:048e5e270a58 4360
sPymbed 16:048e5e270a58 4361 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
sPymbed 16:048e5e270a58 4362 {
sPymbed 16:048e5e270a58 4363 int totalLen = 0;
sPymbed 16:048e5e270a58 4364 int i = 0;
sPymbed 16:048e5e270a58 4365
sPymbed 16:048e5e270a58 4366 if (dName->cnLen != 0)
sPymbed 16:048e5e270a58 4367 totalLen += dName->cnLen + 4;
sPymbed 16:048e5e270a58 4368 if (dName->snLen != 0)
sPymbed 16:048e5e270a58 4369 totalLen += dName->snLen + 4;
sPymbed 16:048e5e270a58 4370 if (dName->cLen != 0)
sPymbed 16:048e5e270a58 4371 totalLen += dName->cLen + 3;
sPymbed 16:048e5e270a58 4372 if (dName->lLen != 0)
sPymbed 16:048e5e270a58 4373 totalLen += dName->lLen + 3;
sPymbed 16:048e5e270a58 4374 if (dName->stLen != 0)
sPymbed 16:048e5e270a58 4375 totalLen += dName->stLen + 4;
sPymbed 16:048e5e270a58 4376 if (dName->oLen != 0)
sPymbed 16:048e5e270a58 4377 totalLen += dName->oLen + 3;
sPymbed 16:048e5e270a58 4378 if (dName->ouLen != 0)
sPymbed 16:048e5e270a58 4379 totalLen += dName->ouLen + 4;
sPymbed 16:048e5e270a58 4380 if (dName->emailLen != 0)
sPymbed 16:048e5e270a58 4381 totalLen += dName->emailLen + 14;
sPymbed 16:048e5e270a58 4382 if (dName->uidLen != 0)
sPymbed 16:048e5e270a58 4383 totalLen += dName->uidLen + 5;
sPymbed 16:048e5e270a58 4384 if (dName->serialLen != 0)
sPymbed 16:048e5e270a58 4385 totalLen += dName->serialLen + 14;
sPymbed 16:048e5e270a58 4386 if (dName->dcNum != 0){
sPymbed 16:048e5e270a58 4387 for (i = 0;i < dName->dcNum;i++)
sPymbed 16:048e5e270a58 4388 totalLen += dName->dcLen[i] + 4;
sPymbed 16:048e5e270a58 4389 }
sPymbed 16:048e5e270a58 4390
sPymbed 16:048e5e270a58 4391 dName->fullName = (char*)XMALLOC(totalLen + 1, cert->heap,
sPymbed 16:048e5e270a58 4392 DYNAMIC_TYPE_X509);
sPymbed 16:048e5e270a58 4393 if (dName->fullName != NULL) {
sPymbed 16:048e5e270a58 4394 idx = 0;
sPymbed 16:048e5e270a58 4395
sPymbed 16:048e5e270a58 4396 if (dName->cnLen != 0) {
sPymbed 16:048e5e270a58 4397 dName->entryCount++;
sPymbed 16:048e5e270a58 4398 XMEMCPY(&dName->fullName[idx], WOLFSSL_COMMON_NAME, 4);
sPymbed 16:048e5e270a58 4399 idx += 4;
sPymbed 16:048e5e270a58 4400 XMEMCPY(&dName->fullName[idx],
sPymbed 16:048e5e270a58 4401 &cert->source[dName->cnIdx], dName->cnLen);
sPymbed 16:048e5e270a58 4402 dName->cnIdx = idx;
sPymbed 16:048e5e270a58 4403 idx += dName->cnLen;
sPymbed 16:048e5e270a58 4404 }
sPymbed 16:048e5e270a58 4405 if (dName->snLen != 0) {
sPymbed 16:048e5e270a58 4406 dName->entryCount++;
sPymbed 16:048e5e270a58 4407 XMEMCPY(&dName->fullName[idx], WOLFSSL_SUR_NAME, 4);
sPymbed 16:048e5e270a58 4408 idx += 4;
sPymbed 16:048e5e270a58 4409 XMEMCPY(&dName->fullName[idx],
sPymbed 16:048e5e270a58 4410 &cert->source[dName->snIdx], dName->snLen);
sPymbed 16:048e5e270a58 4411 dName->snIdx = idx;
sPymbed 16:048e5e270a58 4412 idx += dName->snLen;
sPymbed 16:048e5e270a58 4413 }
sPymbed 16:048e5e270a58 4414 if (dName->cLen != 0) {
sPymbed 16:048e5e270a58 4415 dName->entryCount++;
sPymbed 16:048e5e270a58 4416 XMEMCPY(&dName->fullName[idx], WOLFSSL_COUNTRY_NAME, 3);
sPymbed 16:048e5e270a58 4417 idx += 3;
sPymbed 16:048e5e270a58 4418 XMEMCPY(&dName->fullName[idx],
sPymbed 16:048e5e270a58 4419 &cert->source[dName->cIdx], dName->cLen);
sPymbed 16:048e5e270a58 4420 dName->cIdx = idx;
sPymbed 16:048e5e270a58 4421 idx += dName->cLen;
sPymbed 16:048e5e270a58 4422 }
sPymbed 16:048e5e270a58 4423 if (dName->lLen != 0) {
sPymbed 16:048e5e270a58 4424 dName->entryCount++;
sPymbed 16:048e5e270a58 4425 XMEMCPY(&dName->fullName[idx], WOLFSSL_LOCALITY_NAME, 3);
sPymbed 16:048e5e270a58 4426 idx += 3;
sPymbed 16:048e5e270a58 4427 XMEMCPY(&dName->fullName[idx],
sPymbed 16:048e5e270a58 4428 &cert->source[dName->lIdx], dName->lLen);
sPymbed 16:048e5e270a58 4429 dName->lIdx = idx;
sPymbed 16:048e5e270a58 4430 idx += dName->lLen;
sPymbed 16:048e5e270a58 4431 }
sPymbed 16:048e5e270a58 4432 if (dName->stLen != 0) {
sPymbed 16:048e5e270a58 4433 dName->entryCount++;
sPymbed 16:048e5e270a58 4434 XMEMCPY(&dName->fullName[idx], WOLFSSL_STATE_NAME, 4);
sPymbed 16:048e5e270a58 4435 idx += 4;
sPymbed 16:048e5e270a58 4436 XMEMCPY(&dName->fullName[idx],
sPymbed 16:048e5e270a58 4437 &cert->source[dName->stIdx], dName->stLen);
sPymbed 16:048e5e270a58 4438 dName->stIdx = idx;
sPymbed 16:048e5e270a58 4439 idx += dName->stLen;
sPymbed 16:048e5e270a58 4440 }
sPymbed 16:048e5e270a58 4441 if (dName->oLen != 0) {
sPymbed 16:048e5e270a58 4442 dName->entryCount++;
sPymbed 16:048e5e270a58 4443 XMEMCPY(&dName->fullName[idx], WOLFSSL_ORG_NAME, 3);
sPymbed 16:048e5e270a58 4444 idx += 3;
sPymbed 16:048e5e270a58 4445 XMEMCPY(&dName->fullName[idx],
sPymbed 16:048e5e270a58 4446 &cert->source[dName->oIdx], dName->oLen);
sPymbed 16:048e5e270a58 4447 dName->oIdx = idx;
sPymbed 16:048e5e270a58 4448 idx += dName->oLen;
sPymbed 16:048e5e270a58 4449 }
sPymbed 16:048e5e270a58 4450 if (dName->ouLen != 0) {
sPymbed 16:048e5e270a58 4451 dName->entryCount++;
sPymbed 16:048e5e270a58 4452 XMEMCPY(&dName->fullName[idx], WOLFSSL_ORGUNIT_NAME, 4);
sPymbed 16:048e5e270a58 4453 idx += 4;
sPymbed 16:048e5e270a58 4454 XMEMCPY(&dName->fullName[idx],
sPymbed 16:048e5e270a58 4455 &cert->source[dName->ouIdx], dName->ouLen);
sPymbed 16:048e5e270a58 4456 dName->ouIdx = idx;
sPymbed 16:048e5e270a58 4457 idx += dName->ouLen;
sPymbed 16:048e5e270a58 4458 }
sPymbed 16:048e5e270a58 4459 if (dName->emailLen != 0) {
sPymbed 16:048e5e270a58 4460 dName->entryCount++;
sPymbed 16:048e5e270a58 4461 XMEMCPY(&dName->fullName[idx], "/emailAddress=", 14);
sPymbed 16:048e5e270a58 4462 idx += 14;
sPymbed 16:048e5e270a58 4463 XMEMCPY(&dName->fullName[idx],
sPymbed 16:048e5e270a58 4464 &cert->source[dName->emailIdx], dName->emailLen);
sPymbed 16:048e5e270a58 4465 dName->emailIdx = idx;
sPymbed 16:048e5e270a58 4466 idx += dName->emailLen;
sPymbed 16:048e5e270a58 4467 }
sPymbed 16:048e5e270a58 4468 for (i = 0;i < dName->dcNum;i++){
sPymbed 16:048e5e270a58 4469 if (dName->dcLen[i] != 0) {
sPymbed 16:048e5e270a58 4470 dName->entryCount++;
sPymbed 16:048e5e270a58 4471 XMEMCPY(&dName->fullName[idx], WOLFSSL_DOMAIN_COMPONENT, 4);
sPymbed 16:048e5e270a58 4472 idx += 4;
sPymbed 16:048e5e270a58 4473 XMEMCPY(&dName->fullName[idx],
sPymbed 16:048e5e270a58 4474 &cert->source[dName->dcIdx[i]], dName->dcLen[i]);
sPymbed 16:048e5e270a58 4475 dName->dcIdx[i] = idx;
sPymbed 16:048e5e270a58 4476 idx += dName->dcLen[i];
sPymbed 16:048e5e270a58 4477 }
sPymbed 16:048e5e270a58 4478 }
sPymbed 16:048e5e270a58 4479 if (dName->uidLen != 0) {
sPymbed 16:048e5e270a58 4480 dName->entryCount++;
sPymbed 16:048e5e270a58 4481 XMEMCPY(&dName->fullName[idx], "/UID=", 5);
sPymbed 16:048e5e270a58 4482 idx += 5;
sPymbed 16:048e5e270a58 4483 XMEMCPY(&dName->fullName[idx],
sPymbed 16:048e5e270a58 4484 &cert->source[dName->uidIdx], dName->uidLen);
sPymbed 16:048e5e270a58 4485 dName->uidIdx = idx;
sPymbed 16:048e5e270a58 4486 idx += dName->uidLen;
sPymbed 16:048e5e270a58 4487 }
sPymbed 16:048e5e270a58 4488 if (dName->serialLen != 0) {
sPymbed 16:048e5e270a58 4489 dName->entryCount++;
sPymbed 16:048e5e270a58 4490 XMEMCPY(&dName->fullName[idx], WOLFSSL_SERIAL_NUMBER, 14);
sPymbed 16:048e5e270a58 4491 idx += 14;
sPymbed 16:048e5e270a58 4492 XMEMCPY(&dName->fullName[idx],
sPymbed 16:048e5e270a58 4493 &cert->source[dName->serialIdx], dName->serialLen);
sPymbed 16:048e5e270a58 4494 dName->serialIdx = idx;
sPymbed 16:048e5e270a58 4495 idx += dName->serialLen;
sPymbed 16:048e5e270a58 4496 }
sPymbed 16:048e5e270a58 4497 dName->fullName[idx] = '\0';
sPymbed 16:048e5e270a58 4498 dName->fullNameLen = totalLen;
sPymbed 16:048e5e270a58 4499 }
sPymbed 16:048e5e270a58 4500 }
sPymbed 16:048e5e270a58 4501 #endif /* OPENSSL_EXTRA */
sPymbed 16:048e5e270a58 4502
sPymbed 16:048e5e270a58 4503 return 0;
sPymbed 16:048e5e270a58 4504 }
sPymbed 16:048e5e270a58 4505
sPymbed 16:048e5e270a58 4506
sPymbed 16:048e5e270a58 4507 #ifndef NO_ASN_TIME
sPymbed 16:048e5e270a58 4508
sPymbed 16:048e5e270a58 4509 /* two byte date/time, add to value */
sPymbed 16:048e5e270a58 4510 static WC_INLINE void GetTime(int* value, const byte* date, int* idx)
sPymbed 16:048e5e270a58 4511 {
sPymbed 16:048e5e270a58 4512 int i = *idx;
sPymbed 16:048e5e270a58 4513
sPymbed 16:048e5e270a58 4514 *value += btoi(date[i++]) * 10;
sPymbed 16:048e5e270a58 4515 *value += btoi(date[i++]);
sPymbed 16:048e5e270a58 4516
sPymbed 16:048e5e270a58 4517 *idx = i;
sPymbed 16:048e5e270a58 4518 }
sPymbed 16:048e5e270a58 4519
sPymbed 16:048e5e270a58 4520 int ExtractDate(const unsigned char* date, unsigned char format,
sPymbed 16:048e5e270a58 4521 struct tm* certTime, int* idx)
sPymbed 16:048e5e270a58 4522 {
sPymbed 16:048e5e270a58 4523 XMEMSET(certTime, 0, sizeof(certTime));
sPymbed 16:048e5e270a58 4524
sPymbed 16:048e5e270a58 4525 if (format == ASN_UTC_TIME) {
sPymbed 16:048e5e270a58 4526 /*if (btoi(date[0]) >= 5)
sPymbed 16:048e5e270a58 4527 certTime->tm_year = 1900;
sPymbed 16:048e5e270a58 4528 else
sPymbed 16:048e5e270a58 4529 certTime->tm_year = 2000;*/
sPymbed 16:048e5e270a58 4530 }
sPymbed 16:048e5e270a58 4531 else { /* format == GENERALIZED_TIME */
sPymbed 16:048e5e270a58 4532 //certTime->tm_year += btoi(date[*idx]) * 1000; *idx = *idx + 1;
sPymbed 16:048e5e270a58 4533 //certTime->tm_year += btoi(date[*idx]) * 100; *idx = *idx + 1;
sPymbed 16:048e5e270a58 4534 }
sPymbed 16:048e5e270a58 4535
sPymbed 16:048e5e270a58 4536 /* adjust tm_year, tm_mon */
sPymbed 16:048e5e270a58 4537 /*GetTime((int*)&certTime->tm_year, date, idx); certTime->tm_year -= 1900;
sPymbed 16:048e5e270a58 4538 GetTime((int*)&certTime->tm_mon, date, idx); certTime->tm_mon -= 1;
sPymbed 16:048e5e270a58 4539 GetTime((int*)&certTime->tm_mday, date, idx);
sPymbed 16:048e5e270a58 4540 GetTime((int*)&certTime->tm_hour, date, idx);
sPymbed 16:048e5e270a58 4541 GetTime((int*)&certTime->tm_min, date, idx);
sPymbed 16:048e5e270a58 4542 GetTime((int*)&certTime->tm_sec, date, idx);*/
sPymbed 16:048e5e270a58 4543
sPymbed 16:048e5e270a58 4544 return 1;
sPymbed 16:048e5e270a58 4545 }
sPymbed 16:048e5e270a58 4546
sPymbed 16:048e5e270a58 4547
sPymbed 16:048e5e270a58 4548 #if defined(OPENSSL_ALL) || defined(WOLFSSL_MYSQL_COMPATIBLE) || \
sPymbed 16:048e5e270a58 4549 defined(OPENSSL_EXTRA) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
sPymbed 16:048e5e270a58 4550 int GetTimeString(byte* date, int format, char* buf, int len)
sPymbed 16:048e5e270a58 4551 {
sPymbed 16:048e5e270a58 4552 struct tm t;
sPymbed 16:048e5e270a58 4553 int idx = 0;
sPymbed 16:048e5e270a58 4554
sPymbed 16:048e5e270a58 4555 if (!ExtractDate(date, (unsigned char)format, &t, &idx)) {
sPymbed 16:048e5e270a58 4556 return 0;
sPymbed 16:048e5e270a58 4557 }
sPymbed 16:048e5e270a58 4558
sPymbed 16:048e5e270a58 4559 if (date[idx] != 'Z') {
sPymbed 16:048e5e270a58 4560 WOLFSSL_MSG("UTCtime, not Zulu") ;
sPymbed 16:048e5e270a58 4561 return 0;
sPymbed 16:048e5e270a58 4562 }
sPymbed 16:048e5e270a58 4563
sPymbed 16:048e5e270a58 4564 /* place month in buffer */
sPymbed 16:048e5e270a58 4565 buf[0] = '\0';
sPymbed 16:048e5e270a58 4566 switch(t.tm_mon) {
sPymbed 16:048e5e270a58 4567 case 0: XSTRNCAT(buf, "Jan ", 4); break;
sPymbed 16:048e5e270a58 4568 case 1: XSTRNCAT(buf, "Feb ", 4); break;
sPymbed 16:048e5e270a58 4569 case 2: XSTRNCAT(buf, "Mar ", 4); break;
sPymbed 16:048e5e270a58 4570 case 3: XSTRNCAT(buf, "Apr ", 4); break;
sPymbed 16:048e5e270a58 4571 case 4: XSTRNCAT(buf, "May ", 4); break;
sPymbed 16:048e5e270a58 4572 case 5: XSTRNCAT(buf, "Jun ", 4); break;
sPymbed 16:048e5e270a58 4573 case 6: XSTRNCAT(buf, "Jul ", 4); break;
sPymbed 16:048e5e270a58 4574 case 7: XSTRNCAT(buf, "Aug ", 4); break;
sPymbed 16:048e5e270a58 4575 case 8: XSTRNCAT(buf, "Sep ", 4); break;
sPymbed 16:048e5e270a58 4576 case 9: XSTRNCAT(buf, "Oct ", 4); break;
sPymbed 16:048e5e270a58 4577 case 10: XSTRNCAT(buf, "Nov ", 4); break;
sPymbed 16:048e5e270a58 4578 case 11: XSTRNCAT(buf, "Dec ", 4); break;
sPymbed 16:048e5e270a58 4579 default:
sPymbed 16:048e5e270a58 4580 return 0;
sPymbed 16:048e5e270a58 4581
sPymbed 16:048e5e270a58 4582 }
sPymbed 16:048e5e270a58 4583 idx = 4; /* use idx now for char buffer */
sPymbed 16:048e5e270a58 4584 buf[idx] = ' ';
sPymbed 16:048e5e270a58 4585
sPymbed 16:048e5e270a58 4586 XSNPRINTF(buf + idx, len - idx, "%2d %02d:%02d:%02d %d GMT",
sPymbed 16:048e5e270a58 4587 t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec, t.tm_year + 1900);
sPymbed 16:048e5e270a58 4588
sPymbed 16:048e5e270a58 4589 return 1;
sPymbed 16:048e5e270a58 4590 }
sPymbed 16:048e5e270a58 4591 #endif /* OPENSSL_ALL || WOLFSSL_MYSQL_COMPATIBLE || WOLFSSL_NGINX || WOLFSSL_HAPROXY */
sPymbed 16:048e5e270a58 4592
sPymbed 16:048e5e270a58 4593
sPymbed 16:048e5e270a58 4594 #if defined(USE_WOLF_VALIDDATE)
sPymbed 16:048e5e270a58 4595
sPymbed 16:048e5e270a58 4596 /* to the second */
sPymbed 16:048e5e270a58 4597 static int DateGreaterThan(const struct tm* a, const struct tm* b)
sPymbed 16:048e5e270a58 4598 {
sPymbed 16:048e5e270a58 4599 /*if (a->tm_year > b->tm_year)
sPymbed 16:048e5e270a58 4600 return 1;
sPymbed 16:048e5e270a58 4601
sPymbed 16:048e5e270a58 4602 if (a->tm_year == b->tm_year && a->tm_mon > b->tm_mon)
sPymbed 16:048e5e270a58 4603 return 1;
sPymbed 16:048e5e270a58 4604
sPymbed 16:048e5e270a58 4605 if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
sPymbed 16:048e5e270a58 4606 a->tm_mday > b->tm_mday)
sPymbed 16:048e5e270a58 4607 return 1;
sPymbed 16:048e5e270a58 4608
sPymbed 16:048e5e270a58 4609 if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
sPymbed 16:048e5e270a58 4610 a->tm_mday == b->tm_mday && a->tm_hour > b->tm_hour)
sPymbed 16:048e5e270a58 4611 return 1;
sPymbed 16:048e5e270a58 4612
sPymbed 16:048e5e270a58 4613 if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
sPymbed 16:048e5e270a58 4614 a->tm_mday == b->tm_mday && a->tm_hour == b->tm_hour &&
sPymbed 16:048e5e270a58 4615 a->tm_min > b->tm_min)
sPymbed 16:048e5e270a58 4616 return 1;
sPymbed 16:048e5e270a58 4617
sPymbed 16:048e5e270a58 4618 if (a->tm_year == b->tm_year && a->tm_mon == b->tm_mon &&
sPymbed 16:048e5e270a58 4619 a->tm_mday == b->tm_mday && a->tm_hour == b->tm_hour &&
sPymbed 16:048e5e270a58 4620 a->tm_min == b->tm_min && a->tm_sec > b->tm_sec)
sPymbed 16:048e5e270a58 4621 return 1;*/
sPymbed 16:048e5e270a58 4622
sPymbed 16:048e5e270a58 4623 return 0; /* false */
sPymbed 16:048e5e270a58 4624 }
sPymbed 16:048e5e270a58 4625
sPymbed 16:048e5e270a58 4626
sPymbed 16:048e5e270a58 4627 static WC_INLINE int DateLessThan(const struct tm* a, const struct tm* b)
sPymbed 16:048e5e270a58 4628 {
sPymbed 16:048e5e270a58 4629 return DateGreaterThan(b,a);
sPymbed 16:048e5e270a58 4630 }
sPymbed 16:048e5e270a58 4631
sPymbed 16:048e5e270a58 4632 /* like atoi but only use first byte */
sPymbed 16:048e5e270a58 4633 /* Make sure before and after dates are valid */
sPymbed 16:048e5e270a58 4634 int ValidateDate(const byte* date, byte format, int dateType)
sPymbed 16:048e5e270a58 4635 {
sPymbed 16:048e5e270a58 4636 time_t ltime;
sPymbed 16:048e5e270a58 4637 struct tm certTime;
sPymbed 16:048e5e270a58 4638 struct tm* localTime;
sPymbed 16:048e5e270a58 4639 struct tm* tmpTime = NULL;
sPymbed 16:048e5e270a58 4640 int i = 0;
sPymbed 16:048e5e270a58 4641 int timeDiff = 0 ;
sPymbed 16:048e5e270a58 4642 int diffHH = 0 ; int diffMM = 0 ;
sPymbed 16:048e5e270a58 4643 int diffSign = 0 ;
sPymbed 16:048e5e270a58 4644
sPymbed 16:048e5e270a58 4645 #if defined(NEED_TMP_TIME)
sPymbed 16:048e5e270a58 4646 struct tm tmpTimeStorage;
sPymbed 16:048e5e270a58 4647 tmpTime = &tmpTimeStorage;
sPymbed 16:048e5e270a58 4648 #else
sPymbed 16:048e5e270a58 4649 (void)tmpTime;
sPymbed 16:048e5e270a58 4650 #endif
sPymbed 16:048e5e270a58 4651
sPymbed 16:048e5e270a58 4652 ltime = XTIME(0);
sPymbed 16:048e5e270a58 4653
sPymbed 16:048e5e270a58 4654 #ifdef WOLFSSL_BEFORE_DATE_CLOCK_SKEW
sPymbed 16:048e5e270a58 4655 if (dateType == BEFORE) {
sPymbed 16:048e5e270a58 4656 WOLFSSL_MSG("Skewing local time for before date check");
sPymbed 16:048e5e270a58 4657 ltime += WOLFSSL_BEFORE_DATE_CLOCK_SKEW;
sPymbed 16:048e5e270a58 4658 }
sPymbed 16:048e5e270a58 4659 #endif
sPymbed 16:048e5e270a58 4660
sPymbed 16:048e5e270a58 4661 #ifdef WOLFSSL_AFTER_DATE_CLOCK_SKEW
sPymbed 16:048e5e270a58 4662 if (dateType == AFTER) {
sPymbed 16:048e5e270a58 4663 WOLFSSL_MSG("Skewing local time for after date check");
sPymbed 16:048e5e270a58 4664 ltime -= WOLFSSL_AFTER_DATE_CLOCK_SKEW;
sPymbed 16:048e5e270a58 4665 }
sPymbed 16:048e5e270a58 4666 #endif
sPymbed 16:048e5e270a58 4667
sPymbed 16:048e5e270a58 4668 if (!ExtractDate(date, format, &certTime, &i)) {
sPymbed 16:048e5e270a58 4669 WOLFSSL_MSG("Error extracting the date");
sPymbed 16:048e5e270a58 4670 return 0;
sPymbed 16:048e5e270a58 4671 }
sPymbed 16:048e5e270a58 4672
sPymbed 16:048e5e270a58 4673 if ((date[i] == '+') || (date[i] == '-')) {
sPymbed 16:048e5e270a58 4674 WOLFSSL_MSG("Using time differential, not Zulu") ;
sPymbed 16:048e5e270a58 4675 diffSign = date[i++] == '+' ? 1 : -1 ;
sPymbed 16:048e5e270a58 4676 GetTime(&diffHH, date, &i);
sPymbed 16:048e5e270a58 4677 GetTime(&diffMM, date, &i);
sPymbed 16:048e5e270a58 4678 timeDiff = diffSign * (diffHH*60 + diffMM) * 60 ;
sPymbed 16:048e5e270a58 4679 } else if (date[i] != 'Z') {
sPymbed 16:048e5e270a58 4680 WOLFSSL_MSG("UTCtime, niether Zulu or time differential") ;
sPymbed 16:048e5e270a58 4681 return 0;
sPymbed 16:048e5e270a58 4682 }
sPymbed 16:048e5e270a58 4683
sPymbed 16:048e5e270a58 4684 ltime -= (time_t)timeDiff ;
sPymbed 16:048e5e270a58 4685 localTime = XGMTIME(&ltime, tmpTime);
sPymbed 16:048e5e270a58 4686
sPymbed 16:048e5e270a58 4687 if (localTime == NULL) {
sPymbed 16:048e5e270a58 4688 WOLFSSL_MSG("XGMTIME failed");
sPymbed 16:048e5e270a58 4689 return 0;
sPymbed 16:048e5e270a58 4690 }
sPymbed 16:048e5e270a58 4691
sPymbed 16:048e5e270a58 4692 if (dateType == BEFORE) {
sPymbed 16:048e5e270a58 4693 if (DateLessThan(localTime, &certTime)) {
sPymbed 16:048e5e270a58 4694 WOLFSSL_MSG("Date BEFORE check failed");
sPymbed 16:048e5e270a58 4695 return 0;
sPymbed 16:048e5e270a58 4696 }
sPymbed 16:048e5e270a58 4697 }
sPymbed 16:048e5e270a58 4698 else { /* dateType == AFTER */
sPymbed 16:048e5e270a58 4699 if (DateGreaterThan(localTime, &certTime)) {
sPymbed 16:048e5e270a58 4700 WOLFSSL_MSG("Date AFTER check failed");
sPymbed 16:048e5e270a58 4701 return 0;
sPymbed 16:048e5e270a58 4702 }
sPymbed 16:048e5e270a58 4703 }
sPymbed 16:048e5e270a58 4704
sPymbed 16:048e5e270a58 4705 return 1;
sPymbed 16:048e5e270a58 4706 }
sPymbed 16:048e5e270a58 4707 #endif /* USE_WOLF_VALIDDATE */
sPymbed 16:048e5e270a58 4708
sPymbed 16:048e5e270a58 4709 int wc_GetTime(void* timePtr, word32 timeSize)
sPymbed 16:048e5e270a58 4710 {
sPymbed 16:048e5e270a58 4711 time_t* ltime = (time_t*)timePtr;
sPymbed 16:048e5e270a58 4712
sPymbed 16:048e5e270a58 4713 if (timePtr == NULL) {
sPymbed 16:048e5e270a58 4714 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 4715 }
sPymbed 16:048e5e270a58 4716
sPymbed 16:048e5e270a58 4717 if ((word32)sizeof(time_t) > timeSize) {
sPymbed 16:048e5e270a58 4718 return BUFFER_E;
sPymbed 16:048e5e270a58 4719 }
sPymbed 16:048e5e270a58 4720
sPymbed 16:048e5e270a58 4721 *ltime = XTIME(0);
sPymbed 16:048e5e270a58 4722
sPymbed 16:048e5e270a58 4723 return 0;
sPymbed 16:048e5e270a58 4724 }
sPymbed 16:048e5e270a58 4725
sPymbed 16:048e5e270a58 4726 #endif /* !NO_ASN_TIME */
sPymbed 16:048e5e270a58 4727
sPymbed 16:048e5e270a58 4728
sPymbed 16:048e5e270a58 4729 /* Get date buffer, format and length. Returns 0=success or error */
sPymbed 16:048e5e270a58 4730 static int GetDateInfo(const byte* source, word32* idx, const byte** pDate,
sPymbed 16:048e5e270a58 4731 byte* pFormat, int* pLength, word32 maxIdx)
sPymbed 16:048e5e270a58 4732 {
sPymbed 16:048e5e270a58 4733 int length;
sPymbed 16:048e5e270a58 4734 byte format;
sPymbed 16:048e5e270a58 4735
sPymbed 16:048e5e270a58 4736 if (source == NULL || idx == NULL)
sPymbed 16:048e5e270a58 4737 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 4738
sPymbed 16:048e5e270a58 4739 /* get ASN format header */
sPymbed 16:048e5e270a58 4740 if (*idx+1 > maxIdx)
sPymbed 16:048e5e270a58 4741 return BUFFER_E;
sPymbed 16:048e5e270a58 4742 format = source[*idx];
sPymbed 16:048e5e270a58 4743 *idx += 1;
sPymbed 16:048e5e270a58 4744 if (format != ASN_UTC_TIME && format != ASN_GENERALIZED_TIME)
sPymbed 16:048e5e270a58 4745 return ASN_TIME_E;
sPymbed 16:048e5e270a58 4746
sPymbed 16:048e5e270a58 4747 /* get length */
sPymbed 16:048e5e270a58 4748 if (GetLength(source, idx, &length, maxIdx) < 0)
sPymbed 16:048e5e270a58 4749 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 4750 if (length > MAX_DATE_SIZE || length < MIN_DATE_SIZE)
sPymbed 16:048e5e270a58 4751 return ASN_DATE_SZ_E;
sPymbed 16:048e5e270a58 4752
sPymbed 16:048e5e270a58 4753 /* return format, date and length */
sPymbed 16:048e5e270a58 4754 if (pFormat)
sPymbed 16:048e5e270a58 4755 *pFormat = format;
sPymbed 16:048e5e270a58 4756 if (pDate)
sPymbed 16:048e5e270a58 4757 *pDate = &source[*idx];
sPymbed 16:048e5e270a58 4758 if (pLength)
sPymbed 16:048e5e270a58 4759 *pLength = length;
sPymbed 16:048e5e270a58 4760
sPymbed 16:048e5e270a58 4761 *idx += length;
sPymbed 16:048e5e270a58 4762
sPymbed 16:048e5e270a58 4763 return 0;
sPymbed 16:048e5e270a58 4764 }
sPymbed 16:048e5e270a58 4765
sPymbed 16:048e5e270a58 4766 static int GetDate(DecodedCert* cert, int dateType, int verify)
sPymbed 16:048e5e270a58 4767 {
sPymbed 16:048e5e270a58 4768 int ret, length;
sPymbed 16:048e5e270a58 4769 const byte *datePtr = NULL;
sPymbed 16:048e5e270a58 4770 byte date[MAX_DATE_SIZE];
sPymbed 16:048e5e270a58 4771 byte format;
sPymbed 16:048e5e270a58 4772 word32 startIdx = 0;
sPymbed 16:048e5e270a58 4773
sPymbed 16:048e5e270a58 4774 if (dateType == BEFORE)
sPymbed 16:048e5e270a58 4775 cert->beforeDate = &cert->source[cert->srcIdx];
sPymbed 16:048e5e270a58 4776 else
sPymbed 16:048e5e270a58 4777 cert->afterDate = &cert->source[cert->srcIdx];
sPymbed 16:048e5e270a58 4778 startIdx = cert->srcIdx;
sPymbed 16:048e5e270a58 4779
sPymbed 16:048e5e270a58 4780 ret = GetDateInfo(cert->source, &cert->srcIdx, &datePtr, &format,
sPymbed 16:048e5e270a58 4781 &length, cert->maxIdx);
sPymbed 16:048e5e270a58 4782 if (ret < 0)
sPymbed 16:048e5e270a58 4783 return ret;
sPymbed 16:048e5e270a58 4784
sPymbed 16:048e5e270a58 4785 XMEMSET(date, 0, MAX_DATE_SIZE);
sPymbed 16:048e5e270a58 4786 XMEMCPY(date, datePtr, length);
sPymbed 16:048e5e270a58 4787
sPymbed 16:048e5e270a58 4788 if (dateType == BEFORE)
sPymbed 16:048e5e270a58 4789 cert->beforeDateLen = cert->srcIdx - startIdx;
sPymbed 16:048e5e270a58 4790 else
sPymbed 16:048e5e270a58 4791 cert->afterDateLen = cert->srcIdx - startIdx;
sPymbed 16:048e5e270a58 4792
sPymbed 16:048e5e270a58 4793 #ifndef NO_ASN_TIME
sPymbed 16:048e5e270a58 4794 if (verify != NO_VERIFY && !XVALIDATE_DATE(date, format, dateType)) {
sPymbed 16:048e5e270a58 4795 if (dateType == BEFORE)
sPymbed 16:048e5e270a58 4796 return ASN_BEFORE_DATE_E;
sPymbed 16:048e5e270a58 4797 else
sPymbed 16:048e5e270a58 4798 return ASN_AFTER_DATE_E;
sPymbed 16:048e5e270a58 4799 }
sPymbed 16:048e5e270a58 4800 #else
sPymbed 16:048e5e270a58 4801 (void)verify;
sPymbed 16:048e5e270a58 4802 #endif
sPymbed 16:048e5e270a58 4803
sPymbed 16:048e5e270a58 4804 return 0;
sPymbed 16:048e5e270a58 4805 }
sPymbed 16:048e5e270a58 4806
sPymbed 16:048e5e270a58 4807 static int GetValidity(DecodedCert* cert, int verify)
sPymbed 16:048e5e270a58 4808 {
sPymbed 16:048e5e270a58 4809 int length;
sPymbed 16:048e5e270a58 4810 int badDate = 0;
sPymbed 16:048e5e270a58 4811
sPymbed 16:048e5e270a58 4812 if (GetSequence(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0)
sPymbed 16:048e5e270a58 4813 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 4814
sPymbed 16:048e5e270a58 4815 if (GetDate(cert, BEFORE, verify) < 0)
sPymbed 16:048e5e270a58 4816 badDate = ASN_BEFORE_DATE_E; /* continue parsing */
sPymbed 16:048e5e270a58 4817
sPymbed 16:048e5e270a58 4818 if (GetDate(cert, AFTER, verify) < 0)
sPymbed 16:048e5e270a58 4819 return ASN_AFTER_DATE_E;
sPymbed 16:048e5e270a58 4820
sPymbed 16:048e5e270a58 4821 if (badDate != 0)
sPymbed 16:048e5e270a58 4822 return badDate;
sPymbed 16:048e5e270a58 4823
sPymbed 16:048e5e270a58 4824 return 0;
sPymbed 16:048e5e270a58 4825 }
sPymbed 16:048e5e270a58 4826
sPymbed 16:048e5e270a58 4827
sPymbed 16:048e5e270a58 4828 int wc_GetDateInfo(const byte* certDate, int certDateSz, const byte** date,
sPymbed 16:048e5e270a58 4829 byte* format, int* length)
sPymbed 16:048e5e270a58 4830 {
sPymbed 16:048e5e270a58 4831 int ret;
sPymbed 16:048e5e270a58 4832 word32 idx = 0;
sPymbed 16:048e5e270a58 4833
sPymbed 16:048e5e270a58 4834 ret = GetDateInfo(certDate, &idx, date, format, length, certDateSz);
sPymbed 16:048e5e270a58 4835 if (ret < 0)
sPymbed 16:048e5e270a58 4836 return ret;
sPymbed 16:048e5e270a58 4837
sPymbed 16:048e5e270a58 4838 return 0;
sPymbed 16:048e5e270a58 4839 }
sPymbed 16:048e5e270a58 4840
sPymbed 16:048e5e270a58 4841 #ifndef NO_ASN_TIME
sPymbed 16:048e5e270a58 4842 int wc_GetDateAsCalendarTime(const byte* date, int length, byte format,
sPymbed 16:048e5e270a58 4843 struct tm* timearg)
sPymbed 16:048e5e270a58 4844 {
sPymbed 16:048e5e270a58 4845 int idx = 0;
sPymbed 16:048e5e270a58 4846 (void)length;
sPymbed 16:048e5e270a58 4847 if (!ExtractDate(date, format, timearg, &idx))
sPymbed 16:048e5e270a58 4848 return ASN_TIME_E;
sPymbed 16:048e5e270a58 4849 return 0;
sPymbed 16:048e5e270a58 4850 }
sPymbed 16:048e5e270a58 4851
sPymbed 16:048e5e270a58 4852 #if defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_ALT_NAMES)
sPymbed 16:048e5e270a58 4853 int wc_GetCertDates(Cert* cert, struct tm* before, struct tm* after)
sPymbed 16:048e5e270a58 4854 {
sPymbed 16:048e5e270a58 4855 int ret = 0;
sPymbed 16:048e5e270a58 4856 const byte* date;
sPymbed 16:048e5e270a58 4857 byte format;
sPymbed 16:048e5e270a58 4858 int length;
sPymbed 16:048e5e270a58 4859
sPymbed 16:048e5e270a58 4860 if (cert == NULL)
sPymbed 16:048e5e270a58 4861 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 4862
sPymbed 16:048e5e270a58 4863 if (before && cert->beforeDateSz > 0) {
sPymbed 16:048e5e270a58 4864 ret = wc_GetDateInfo(cert->beforeDate, cert->beforeDateSz, &date,
sPymbed 16:048e5e270a58 4865 &format, &length);
sPymbed 16:048e5e270a58 4866 if (ret == 0)
sPymbed 16:048e5e270a58 4867 ret = wc_GetDateAsCalendarTime(date, length, format, before);
sPymbed 16:048e5e270a58 4868 }
sPymbed 16:048e5e270a58 4869 if (after && cert->afterDateSz > 0) {
sPymbed 16:048e5e270a58 4870 ret = wc_GetDateInfo(cert->afterDate, cert->afterDateSz, &date,
sPymbed 16:048e5e270a58 4871 &format, &length);
sPymbed 16:048e5e270a58 4872 if (ret == 0)
sPymbed 16:048e5e270a58 4873 ret = wc_GetDateAsCalendarTime(date, length, format, after);
sPymbed 16:048e5e270a58 4874 }
sPymbed 16:048e5e270a58 4875
sPymbed 16:048e5e270a58 4876 return ret;
sPymbed 16:048e5e270a58 4877 }
sPymbed 16:048e5e270a58 4878 #endif /* WOLFSSL_CERT_GEN && WOLFSSL_ALT_NAMES */
sPymbed 16:048e5e270a58 4879 #endif /* !NO_ASN_TIME */
sPymbed 16:048e5e270a58 4880
sPymbed 16:048e5e270a58 4881
sPymbed 16:048e5e270a58 4882 int DecodeToKey(DecodedCert* cert, int verify)
sPymbed 16:048e5e270a58 4883 {
sPymbed 16:048e5e270a58 4884 int badDate = 0;
sPymbed 16:048e5e270a58 4885 int ret;
sPymbed 16:048e5e270a58 4886
sPymbed 16:048e5e270a58 4887 if ( (ret = GetCertHeader(cert)) < 0)
sPymbed 16:048e5e270a58 4888 return ret;
sPymbed 16:048e5e270a58 4889
sPymbed 16:048e5e270a58 4890 WOLFSSL_MSG("Got Cert Header");
sPymbed 16:048e5e270a58 4891
sPymbed 16:048e5e270a58 4892 if ( (ret = GetAlgoId(cert->source, &cert->srcIdx, &cert->signatureOID,
sPymbed 16:048e5e270a58 4893 oidSigType, cert->maxIdx)) < 0)
sPymbed 16:048e5e270a58 4894 return ret;
sPymbed 16:048e5e270a58 4895
sPymbed 16:048e5e270a58 4896 WOLFSSL_MSG("Got Algo ID");
sPymbed 16:048e5e270a58 4897
sPymbed 16:048e5e270a58 4898 if ( (ret = GetName(cert, ISSUER)) < 0)
sPymbed 16:048e5e270a58 4899 return ret;
sPymbed 16:048e5e270a58 4900
sPymbed 16:048e5e270a58 4901 if ( (ret = GetValidity(cert, verify)) < 0)
sPymbed 16:048e5e270a58 4902 badDate = ret;
sPymbed 16:048e5e270a58 4903
sPymbed 16:048e5e270a58 4904 if ( (ret = GetName(cert, SUBJECT)) < 0)
sPymbed 16:048e5e270a58 4905 return ret;
sPymbed 16:048e5e270a58 4906
sPymbed 16:048e5e270a58 4907 WOLFSSL_MSG("Got Subject Name");
sPymbed 16:048e5e270a58 4908
sPymbed 16:048e5e270a58 4909 if ( (ret = GetKey(cert)) < 0)
sPymbed 16:048e5e270a58 4910 return ret;
sPymbed 16:048e5e270a58 4911
sPymbed 16:048e5e270a58 4912 WOLFSSL_MSG("Got Key");
sPymbed 16:048e5e270a58 4913
sPymbed 16:048e5e270a58 4914 if (badDate != 0)
sPymbed 16:048e5e270a58 4915 return badDate;
sPymbed 16:048e5e270a58 4916
sPymbed 16:048e5e270a58 4917 return ret;
sPymbed 16:048e5e270a58 4918 }
sPymbed 16:048e5e270a58 4919
sPymbed 16:048e5e270a58 4920 static int GetSignature(DecodedCert* cert)
sPymbed 16:048e5e270a58 4921 {
sPymbed 16:048e5e270a58 4922 int length;
sPymbed 16:048e5e270a58 4923 int ret;
sPymbed 16:048e5e270a58 4924 ret = CheckBitString(cert->source, &cert->srcIdx, &length, cert->maxIdx, 1,
sPymbed 16:048e5e270a58 4925 NULL);
sPymbed 16:048e5e270a58 4926 if (ret != 0)
sPymbed 16:048e5e270a58 4927 return ret;
sPymbed 16:048e5e270a58 4928
sPymbed 16:048e5e270a58 4929 cert->sigLength = length;
sPymbed 16:048e5e270a58 4930 cert->signature = &cert->source[cert->srcIdx];
sPymbed 16:048e5e270a58 4931 cert->srcIdx += cert->sigLength;
sPymbed 16:048e5e270a58 4932
sPymbed 16:048e5e270a58 4933 return 0;
sPymbed 16:048e5e270a58 4934 }
sPymbed 16:048e5e270a58 4935
sPymbed 16:048e5e270a58 4936 static word32 SetOctetString8Bit(word32 len, byte* output)
sPymbed 16:048e5e270a58 4937 {
sPymbed 16:048e5e270a58 4938 output[0] = ASN_OCTET_STRING;
sPymbed 16:048e5e270a58 4939 output[1] = (byte)len;
sPymbed 16:048e5e270a58 4940 return 2;
sPymbed 16:048e5e270a58 4941 }
sPymbed 16:048e5e270a58 4942
sPymbed 16:048e5e270a58 4943 static word32 SetDigest(const byte* digest, word32 digSz, byte* output)
sPymbed 16:048e5e270a58 4944 {
sPymbed 16:048e5e270a58 4945 word32 idx = SetOctetString8Bit(digSz, output);
sPymbed 16:048e5e270a58 4946 XMEMCPY(&output[idx], digest, digSz);
sPymbed 16:048e5e270a58 4947
sPymbed 16:048e5e270a58 4948 return idx + digSz;
sPymbed 16:048e5e270a58 4949 }
sPymbed 16:048e5e270a58 4950
sPymbed 16:048e5e270a58 4951
sPymbed 16:048e5e270a58 4952 static word32 BytePrecision(word32 value)
sPymbed 16:048e5e270a58 4953 {
sPymbed 16:048e5e270a58 4954 word32 i;
sPymbed 16:048e5e270a58 4955 for (i = sizeof(value); i; --i)
sPymbed 16:048e5e270a58 4956 if (value >> ((i - 1) * WOLFSSL_BIT_SIZE))
sPymbed 16:048e5e270a58 4957 break;
sPymbed 16:048e5e270a58 4958
sPymbed 16:048e5e270a58 4959 return i;
sPymbed 16:048e5e270a58 4960 }
sPymbed 16:048e5e270a58 4961
sPymbed 16:048e5e270a58 4962
sPymbed 16:048e5e270a58 4963 WOLFSSL_LOCAL word32 SetLength(word32 length, byte* output)
sPymbed 16:048e5e270a58 4964 {
sPymbed 16:048e5e270a58 4965 word32 i = 0, j;
sPymbed 16:048e5e270a58 4966
sPymbed 16:048e5e270a58 4967 if (length < ASN_LONG_LENGTH)
sPymbed 16:048e5e270a58 4968 output[i++] = (byte)length;
sPymbed 16:048e5e270a58 4969 else {
sPymbed 16:048e5e270a58 4970 output[i++] = (byte)(BytePrecision(length) | ASN_LONG_LENGTH);
sPymbed 16:048e5e270a58 4971
sPymbed 16:048e5e270a58 4972 for (j = BytePrecision(length); j; --j) {
sPymbed 16:048e5e270a58 4973 output[i] = (byte)(length >> ((j - 1) * WOLFSSL_BIT_SIZE));
sPymbed 16:048e5e270a58 4974 i++;
sPymbed 16:048e5e270a58 4975 }
sPymbed 16:048e5e270a58 4976 }
sPymbed 16:048e5e270a58 4977
sPymbed 16:048e5e270a58 4978 return i;
sPymbed 16:048e5e270a58 4979 }
sPymbed 16:048e5e270a58 4980
sPymbed 16:048e5e270a58 4981
sPymbed 16:048e5e270a58 4982 WOLFSSL_LOCAL word32 SetSequence(word32 len, byte* output)
sPymbed 16:048e5e270a58 4983 {
sPymbed 16:048e5e270a58 4984 output[0] = ASN_SEQUENCE | ASN_CONSTRUCTED;
sPymbed 16:048e5e270a58 4985 return SetLength(len, output + 1) + 1;
sPymbed 16:048e5e270a58 4986 }
sPymbed 16:048e5e270a58 4987
sPymbed 16:048e5e270a58 4988 WOLFSSL_LOCAL word32 SetOctetString(word32 len, byte* output)
sPymbed 16:048e5e270a58 4989 {
sPymbed 16:048e5e270a58 4990 output[0] = ASN_OCTET_STRING;
sPymbed 16:048e5e270a58 4991 return SetLength(len, output + 1) + 1;
sPymbed 16:048e5e270a58 4992 }
sPymbed 16:048e5e270a58 4993
sPymbed 16:048e5e270a58 4994 /* Write a set header to output */
sPymbed 16:048e5e270a58 4995 WOLFSSL_LOCAL word32 SetSet(word32 len, byte* output)
sPymbed 16:048e5e270a58 4996 {
sPymbed 16:048e5e270a58 4997 output[0] = ASN_SET | ASN_CONSTRUCTED;
sPymbed 16:048e5e270a58 4998 return SetLength(len, output + 1) + 1;
sPymbed 16:048e5e270a58 4999 }
sPymbed 16:048e5e270a58 5000
sPymbed 16:048e5e270a58 5001 WOLFSSL_LOCAL word32 SetImplicit(byte tag, byte number, word32 len, byte* output)
sPymbed 16:048e5e270a58 5002 {
sPymbed 16:048e5e270a58 5003
sPymbed 16:048e5e270a58 5004 output[0] = ((tag == ASN_SEQUENCE || tag == ASN_SET) ? ASN_CONSTRUCTED : 0)
sPymbed 16:048e5e270a58 5005 | ASN_CONTEXT_SPECIFIC | number;
sPymbed 16:048e5e270a58 5006 return SetLength(len, output + 1) + 1;
sPymbed 16:048e5e270a58 5007 }
sPymbed 16:048e5e270a58 5008
sPymbed 16:048e5e270a58 5009 WOLFSSL_LOCAL word32 SetExplicit(byte number, word32 len, byte* output)
sPymbed 16:048e5e270a58 5010 {
sPymbed 16:048e5e270a58 5011 output[0] = ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | number;
sPymbed 16:048e5e270a58 5012 return SetLength(len, output + 1) + 1;
sPymbed 16:048e5e270a58 5013 }
sPymbed 16:048e5e270a58 5014
sPymbed 16:048e5e270a58 5015
sPymbed 16:048e5e270a58 5016 #if defined(HAVE_ECC)
sPymbed 16:048e5e270a58 5017
sPymbed 16:048e5e270a58 5018 static int SetCurve(ecc_key* key, byte* output)
sPymbed 16:048e5e270a58 5019 {
sPymbed 16:048e5e270a58 5020 #ifdef HAVE_OID_ENCODING
sPymbed 16:048e5e270a58 5021 int ret;
sPymbed 16:048e5e270a58 5022 #endif
sPymbed 16:048e5e270a58 5023 int idx = 0;
sPymbed 16:048e5e270a58 5024 word32 oidSz = 0;
sPymbed 16:048e5e270a58 5025
sPymbed 16:048e5e270a58 5026 /* validate key */
sPymbed 16:048e5e270a58 5027 if (key == NULL || key->dp == NULL) {
sPymbed 16:048e5e270a58 5028 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 5029 }
sPymbed 16:048e5e270a58 5030
sPymbed 16:048e5e270a58 5031 #ifdef HAVE_OID_ENCODING
sPymbed 16:048e5e270a58 5032 ret = EncodeObjectId(key->dp->oid, key->dp->oidSz, NULL, &oidSz);
sPymbed 16:048e5e270a58 5033 if (ret != 0) {
sPymbed 16:048e5e270a58 5034 return ret;
sPymbed 16:048e5e270a58 5035 }
sPymbed 16:048e5e270a58 5036 #else
sPymbed 16:048e5e270a58 5037 oidSz = key->dp->oidSz;
sPymbed 16:048e5e270a58 5038 #endif
sPymbed 16:048e5e270a58 5039
sPymbed 16:048e5e270a58 5040 idx += SetObjectId(oidSz, output);
sPymbed 16:048e5e270a58 5041
sPymbed 16:048e5e270a58 5042 #ifdef HAVE_OID_ENCODING
sPymbed 16:048e5e270a58 5043 ret = EncodeObjectId(key->dp->oid, key->dp->oidSz, output+idx, &oidSz);
sPymbed 16:048e5e270a58 5044 if (ret != 0) {
sPymbed 16:048e5e270a58 5045 return ret;
sPymbed 16:048e5e270a58 5046 }
sPymbed 16:048e5e270a58 5047 #else
sPymbed 16:048e5e270a58 5048 XMEMCPY(output+idx, key->dp->oid, oidSz);
sPymbed 16:048e5e270a58 5049 #endif
sPymbed 16:048e5e270a58 5050 idx += oidSz;
sPymbed 16:048e5e270a58 5051
sPymbed 16:048e5e270a58 5052 return idx;
sPymbed 16:048e5e270a58 5053 }
sPymbed 16:048e5e270a58 5054
sPymbed 16:048e5e270a58 5055 #endif /* HAVE_ECC */
sPymbed 16:048e5e270a58 5056
sPymbed 16:048e5e270a58 5057
sPymbed 16:048e5e270a58 5058 #ifdef HAVE_ECC
sPymbed 16:048e5e270a58 5059 static WC_INLINE int IsSigAlgoECDSA(int algoOID)
sPymbed 16:048e5e270a58 5060 {
sPymbed 16:048e5e270a58 5061 /* ECDSA sigAlgo must not have ASN1 NULL parameters */
sPymbed 16:048e5e270a58 5062 if (algoOID == CTC_SHAwECDSA || algoOID == CTC_SHA256wECDSA ||
sPymbed 16:048e5e270a58 5063 algoOID == CTC_SHA384wECDSA || algoOID == CTC_SHA512wECDSA) {
sPymbed 16:048e5e270a58 5064 return 1;
sPymbed 16:048e5e270a58 5065 }
sPymbed 16:048e5e270a58 5066
sPymbed 16:048e5e270a58 5067 return 0;
sPymbed 16:048e5e270a58 5068 }
sPymbed 16:048e5e270a58 5069 #endif
sPymbed 16:048e5e270a58 5070
sPymbed 16:048e5e270a58 5071 WOLFSSL_LOCAL word32 SetAlgoID(int algoOID, byte* output, int type, int curveSz)
sPymbed 16:048e5e270a58 5072 {
sPymbed 16:048e5e270a58 5073 word32 tagSz, idSz, seqSz, algoSz = 0;
sPymbed 16:048e5e270a58 5074 const byte* algoName = 0;
sPymbed 16:048e5e270a58 5075 byte ID_Length[1 + MAX_LENGTH_SZ];
sPymbed 16:048e5e270a58 5076 byte seqArray[MAX_SEQ_SZ + 1]; /* add object_id to end */
sPymbed 16:048e5e270a58 5077
sPymbed 16:048e5e270a58 5078 tagSz = (type == oidHashType ||
sPymbed 16:048e5e270a58 5079 (type == oidSigType
sPymbed 16:048e5e270a58 5080 #ifdef HAVE_ECC
sPymbed 16:048e5e270a58 5081 && !IsSigAlgoECDSA(algoOID)
sPymbed 16:048e5e270a58 5082 #endif
sPymbed 16:048e5e270a58 5083 #ifdef HAVE_ED25519
sPymbed 16:048e5e270a58 5084 && algoOID != ED25519k
sPymbed 16:048e5e270a58 5085 #endif
sPymbed 16:048e5e270a58 5086 ) ||
sPymbed 16:048e5e270a58 5087 (type == oidKeyType && algoOID == RSAk)) ? 2 : 0;
sPymbed 16:048e5e270a58 5088
sPymbed 16:048e5e270a58 5089 algoName = OidFromId(algoOID, type, &algoSz);
sPymbed 16:048e5e270a58 5090
sPymbed 16:048e5e270a58 5091 if (algoName == NULL) {
sPymbed 16:048e5e270a58 5092 WOLFSSL_MSG("Unknown Algorithm");
sPymbed 16:048e5e270a58 5093 return 0;
sPymbed 16:048e5e270a58 5094 }
sPymbed 16:048e5e270a58 5095
sPymbed 16:048e5e270a58 5096 idSz = SetObjectId(algoSz, ID_Length);
sPymbed 16:048e5e270a58 5097 seqSz = SetSequence(idSz + algoSz + tagSz + curveSz, seqArray);
sPymbed 16:048e5e270a58 5098
sPymbed 16:048e5e270a58 5099 XMEMCPY(output, seqArray, seqSz);
sPymbed 16:048e5e270a58 5100 XMEMCPY(output + seqSz, ID_Length, idSz);
sPymbed 16:048e5e270a58 5101 XMEMCPY(output + seqSz + idSz, algoName, algoSz);
sPymbed 16:048e5e270a58 5102 if (tagSz == 2)
sPymbed 16:048e5e270a58 5103 SetASNNull(&output[seqSz + idSz + algoSz]);
sPymbed 16:048e5e270a58 5104
sPymbed 16:048e5e270a58 5105 return seqSz + idSz + algoSz + tagSz;
sPymbed 16:048e5e270a58 5106
sPymbed 16:048e5e270a58 5107 }
sPymbed 16:048e5e270a58 5108
sPymbed 16:048e5e270a58 5109
sPymbed 16:048e5e270a58 5110 word32 wc_EncodeSignature(byte* out, const byte* digest, word32 digSz,
sPymbed 16:048e5e270a58 5111 int hashOID)
sPymbed 16:048e5e270a58 5112 {
sPymbed 16:048e5e270a58 5113 byte digArray[MAX_ENCODED_DIG_SZ];
sPymbed 16:048e5e270a58 5114 byte algoArray[MAX_ALGO_SZ];
sPymbed 16:048e5e270a58 5115 byte seqArray[MAX_SEQ_SZ];
sPymbed 16:048e5e270a58 5116 word32 encDigSz, algoSz, seqSz;
sPymbed 16:048e5e270a58 5117
sPymbed 16:048e5e270a58 5118 encDigSz = SetDigest(digest, digSz, digArray);
sPymbed 16:048e5e270a58 5119 algoSz = SetAlgoID(hashOID, algoArray, oidHashType, 0);
sPymbed 16:048e5e270a58 5120 seqSz = SetSequence(encDigSz + algoSz, seqArray);
sPymbed 16:048e5e270a58 5121
sPymbed 16:048e5e270a58 5122 XMEMCPY(out, seqArray, seqSz);
sPymbed 16:048e5e270a58 5123 XMEMCPY(out + seqSz, algoArray, algoSz);
sPymbed 16:048e5e270a58 5124 XMEMCPY(out + seqSz + algoSz, digArray, encDigSz);
sPymbed 16:048e5e270a58 5125
sPymbed 16:048e5e270a58 5126 return encDigSz + algoSz + seqSz;
sPymbed 16:048e5e270a58 5127 }
sPymbed 16:048e5e270a58 5128
sPymbed 16:048e5e270a58 5129
sPymbed 16:048e5e270a58 5130 int wc_GetCTC_HashOID(int type)
sPymbed 16:048e5e270a58 5131 {
sPymbed 16:048e5e270a58 5132 int ret;
sPymbed 16:048e5e270a58 5133 enum wc_HashType hType;
sPymbed 16:048e5e270a58 5134
sPymbed 16:048e5e270a58 5135 hType = wc_HashTypeConvert(type);
sPymbed 16:048e5e270a58 5136 ret = wc_HashGetOID(hType);
sPymbed 16:048e5e270a58 5137 if (ret < 0)
sPymbed 16:048e5e270a58 5138 ret = 0; /* backwards compatibility */
sPymbed 16:048e5e270a58 5139
sPymbed 16:048e5e270a58 5140 return ret;
sPymbed 16:048e5e270a58 5141 }
sPymbed 16:048e5e270a58 5142
sPymbed 16:048e5e270a58 5143 void InitSignatureCtx(SignatureCtx* sigCtx, void* heap, int devId)
sPymbed 16:048e5e270a58 5144 {
sPymbed 16:048e5e270a58 5145 if (sigCtx) {
sPymbed 16:048e5e270a58 5146 XMEMSET(sigCtx, 0, sizeof(SignatureCtx));
sPymbed 16:048e5e270a58 5147 sigCtx->devId = devId;
sPymbed 16:048e5e270a58 5148 sigCtx->heap = heap;
sPymbed 16:048e5e270a58 5149 }
sPymbed 16:048e5e270a58 5150 }
sPymbed 16:048e5e270a58 5151
sPymbed 16:048e5e270a58 5152 void FreeSignatureCtx(SignatureCtx* sigCtx)
sPymbed 16:048e5e270a58 5153 {
sPymbed 16:048e5e270a58 5154 if (sigCtx == NULL)
sPymbed 16:048e5e270a58 5155 return;
sPymbed 16:048e5e270a58 5156
sPymbed 16:048e5e270a58 5157 if (sigCtx->digest) {
sPymbed 16:048e5e270a58 5158 XFREE(sigCtx->digest, sigCtx->heap, DYNAMIC_TYPE_DIGEST);
sPymbed 16:048e5e270a58 5159 sigCtx->digest = NULL;
sPymbed 16:048e5e270a58 5160 }
sPymbed 16:048e5e270a58 5161 #ifndef NO_RSA
sPymbed 16:048e5e270a58 5162 if (sigCtx->plain) {
sPymbed 16:048e5e270a58 5163 XFREE(sigCtx->plain, sigCtx->heap, DYNAMIC_TYPE_SIGNATURE);
sPymbed 16:048e5e270a58 5164 sigCtx->plain = NULL;
sPymbed 16:048e5e270a58 5165 }
sPymbed 16:048e5e270a58 5166 #endif
sPymbed 16:048e5e270a58 5167 if (sigCtx->key.ptr) {
sPymbed 16:048e5e270a58 5168 switch (sigCtx->keyOID) {
sPymbed 16:048e5e270a58 5169 #ifndef NO_RSA
sPymbed 16:048e5e270a58 5170 case RSAk:
sPymbed 16:048e5e270a58 5171 wc_FreeRsaKey(sigCtx->key.rsa);
sPymbed 16:048e5e270a58 5172 XFREE(sigCtx->key.ptr, sigCtx->heap, DYNAMIC_TYPE_RSA);
sPymbed 16:048e5e270a58 5173 break;
sPymbed 16:048e5e270a58 5174 #endif /* !NO_RSA */
sPymbed 16:048e5e270a58 5175 #ifdef HAVE_ECC
sPymbed 16:048e5e270a58 5176 case ECDSAk:
sPymbed 16:048e5e270a58 5177 wc_ecc_free(sigCtx->key.ecc);
sPymbed 16:048e5e270a58 5178 XFREE(sigCtx->key.ecc, sigCtx->heap, DYNAMIC_TYPE_ECC);
sPymbed 16:048e5e270a58 5179 break;
sPymbed 16:048e5e270a58 5180 #endif /* HAVE_ECC */
sPymbed 16:048e5e270a58 5181 #ifdef HAVE_ED25519
sPymbed 16:048e5e270a58 5182 case ED25519k:
sPymbed 16:048e5e270a58 5183 wc_ed25519_free(sigCtx->key.ed25519);
sPymbed 16:048e5e270a58 5184 XFREE(sigCtx->key.ed25519, sigCtx->heap, DYNAMIC_TYPE_ED25519);
sPymbed 16:048e5e270a58 5185 break;
sPymbed 16:048e5e270a58 5186 #endif /* HAVE_ED25519 */
sPymbed 16:048e5e270a58 5187 default:
sPymbed 16:048e5e270a58 5188 break;
sPymbed 16:048e5e270a58 5189 } /* switch (keyOID) */
sPymbed 16:048e5e270a58 5190 sigCtx->key.ptr = NULL;
sPymbed 16:048e5e270a58 5191 }
sPymbed 16:048e5e270a58 5192
sPymbed 16:048e5e270a58 5193 /* reset state, we are done */
sPymbed 16:048e5e270a58 5194 sigCtx->state = SIG_STATE_BEGIN;
sPymbed 16:048e5e270a58 5195 }
sPymbed 16:048e5e270a58 5196
sPymbed 16:048e5e270a58 5197 static int HashForSignature(const byte* buf, word32 bufSz, word32 sigOID,
sPymbed 16:048e5e270a58 5198 byte* digest, int* typeH, int* digestSz, int verify)
sPymbed 16:048e5e270a58 5199 {
sPymbed 16:048e5e270a58 5200 int ret = 0;
sPymbed 16:048e5e270a58 5201
sPymbed 16:048e5e270a58 5202 (void)verify;
sPymbed 16:048e5e270a58 5203
sPymbed 16:048e5e270a58 5204 switch (sigOID) {
sPymbed 16:048e5e270a58 5205 #if defined(WOLFSSL_MD2)
sPymbed 16:048e5e270a58 5206 case CTC_MD2wRSA:
sPymbed 16:048e5e270a58 5207 if (!verify) {
sPymbed 16:048e5e270a58 5208 ret = HASH_TYPE_E;
sPymbed 16:048e5e270a58 5209 WOLFSSL_MSG("MD2 not supported for signing");
sPymbed 16:048e5e270a58 5210 }
sPymbed 16:048e5e270a58 5211 else if ((ret = wc_Md2Hash(buf, bufSz, digest)) == 0) {
sPymbed 16:048e5e270a58 5212 *typeH = MD2h;
sPymbed 16:048e5e270a58 5213 *digestSz = MD2_DIGEST_SIZE;
sPymbed 16:048e5e270a58 5214 }
sPymbed 16:048e5e270a58 5215 break;
sPymbed 16:048e5e270a58 5216 #endif
sPymbed 16:048e5e270a58 5217 #ifndef NO_MD5
sPymbed 16:048e5e270a58 5218 case CTC_MD5wRSA:
sPymbed 16:048e5e270a58 5219 if ((ret = wc_Md5Hash(buf, bufSz, digest)) == 0) {
sPymbed 16:048e5e270a58 5220 *typeH = MD5h;
sPymbed 16:048e5e270a58 5221 *digestSz = WC_MD5_DIGEST_SIZE;
sPymbed 16:048e5e270a58 5222 }
sPymbed 16:048e5e270a58 5223 break;
sPymbed 16:048e5e270a58 5224 #endif
sPymbed 16:048e5e270a58 5225 #ifndef NO_SHA
sPymbed 16:048e5e270a58 5226 case CTC_SHAwRSA:
sPymbed 16:048e5e270a58 5227 case CTC_SHAwDSA:
sPymbed 16:048e5e270a58 5228 case CTC_SHAwECDSA:
sPymbed 16:048e5e270a58 5229 if ((ret = wc_ShaHash(buf, bufSz, digest)) == 0) {
sPymbed 16:048e5e270a58 5230 *typeH = SHAh;
sPymbed 16:048e5e270a58 5231 *digestSz = WC_SHA_DIGEST_SIZE;
sPymbed 16:048e5e270a58 5232 }
sPymbed 16:048e5e270a58 5233 break;
sPymbed 16:048e5e270a58 5234 #endif
sPymbed 16:048e5e270a58 5235 #ifdef WOLFSSL_SHA224
sPymbed 16:048e5e270a58 5236 case CTC_SHA224wRSA:
sPymbed 16:048e5e270a58 5237 case CTC_SHA224wECDSA:
sPymbed 16:048e5e270a58 5238 if ((ret = wc_Sha224Hash(buf, bufSz, digest)) == 0) {
sPymbed 16:048e5e270a58 5239 *typeH = SHA224h;
sPymbed 16:048e5e270a58 5240 *digestSz = WC_SHA224_DIGEST_SIZE;
sPymbed 16:048e5e270a58 5241 }
sPymbed 16:048e5e270a58 5242 break;
sPymbed 16:048e5e270a58 5243 #endif
sPymbed 16:048e5e270a58 5244 #ifndef NO_SHA256
sPymbed 16:048e5e270a58 5245 case CTC_SHA256wRSA:
sPymbed 16:048e5e270a58 5246 case CTC_SHA256wECDSA:
sPymbed 16:048e5e270a58 5247 if ((ret = wc_Sha256Hash(buf, bufSz, digest)) == 0) {
sPymbed 16:048e5e270a58 5248 *typeH = SHA256h;
sPymbed 16:048e5e270a58 5249 *digestSz = WC_SHA256_DIGEST_SIZE;
sPymbed 16:048e5e270a58 5250 }
sPymbed 16:048e5e270a58 5251 break;
sPymbed 16:048e5e270a58 5252 #endif
sPymbed 16:048e5e270a58 5253 #ifdef WOLFSSL_SHA384
sPymbed 16:048e5e270a58 5254 case CTC_SHA384wRSA:
sPymbed 16:048e5e270a58 5255 case CTC_SHA384wECDSA:
sPymbed 16:048e5e270a58 5256 if ((ret = wc_Sha384Hash(buf, bufSz, digest)) == 0) {
sPymbed 16:048e5e270a58 5257 *typeH = SHA384h;
sPymbed 16:048e5e270a58 5258 *digestSz = WC_SHA384_DIGEST_SIZE;
sPymbed 16:048e5e270a58 5259 }
sPymbed 16:048e5e270a58 5260 break;
sPymbed 16:048e5e270a58 5261 #endif
sPymbed 16:048e5e270a58 5262 #ifdef WOLFSSL_SHA512
sPymbed 16:048e5e270a58 5263 case CTC_SHA512wRSA:
sPymbed 16:048e5e270a58 5264 case CTC_SHA512wECDSA:
sPymbed 16:048e5e270a58 5265 if ((ret = wc_Sha512Hash(buf, bufSz, digest)) == 0) {
sPymbed 16:048e5e270a58 5266 *typeH = SHA512h;
sPymbed 16:048e5e270a58 5267 *digestSz = WC_SHA512_DIGEST_SIZE;
sPymbed 16:048e5e270a58 5268 }
sPymbed 16:048e5e270a58 5269 break;
sPymbed 16:048e5e270a58 5270 #endif
sPymbed 16:048e5e270a58 5271 case CTC_ED25519:
sPymbed 16:048e5e270a58 5272 /* Hashes done in signing operation.
sPymbed 16:048e5e270a58 5273 * Two dependent hashes with prefixes performed.
sPymbed 16:048e5e270a58 5274 */
sPymbed 16:048e5e270a58 5275 break;
sPymbed 16:048e5e270a58 5276 default:
sPymbed 16:048e5e270a58 5277 ret = HASH_TYPE_E;
sPymbed 16:048e5e270a58 5278 WOLFSSL_MSG("Hash for Signature has unsupported type");
sPymbed 16:048e5e270a58 5279 }
sPymbed 16:048e5e270a58 5280
sPymbed 16:048e5e270a58 5281 return ret;
sPymbed 16:048e5e270a58 5282 }
sPymbed 16:048e5e270a58 5283
sPymbed 16:048e5e270a58 5284 /* Return codes: 0=Success, Negative (see error-crypt.h), ASN_SIG_CONFIRM_E */
sPymbed 16:048e5e270a58 5285 static int ConfirmSignature(SignatureCtx* sigCtx,
sPymbed 16:048e5e270a58 5286 const byte* buf, word32 bufSz,
sPymbed 16:048e5e270a58 5287 const byte* key, word32 keySz, word32 keyOID,
sPymbed 16:048e5e270a58 5288 const byte* sig, word32 sigSz, word32 sigOID)
sPymbed 16:048e5e270a58 5289 {
sPymbed 16:048e5e270a58 5290 int ret = 0;
sPymbed 16:048e5e270a58 5291
sPymbed 16:048e5e270a58 5292 if (sigCtx == NULL || buf == NULL || bufSz == 0 || key == NULL ||
sPymbed 16:048e5e270a58 5293 keySz == 0 || sig == NULL || sigSz == 0) {
sPymbed 16:048e5e270a58 5294 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 5295 }
sPymbed 16:048e5e270a58 5296
sPymbed 16:048e5e270a58 5297 (void)key;
sPymbed 16:048e5e270a58 5298 (void)keySz;
sPymbed 16:048e5e270a58 5299 (void)sig;
sPymbed 16:048e5e270a58 5300 (void)sigSz;
sPymbed 16:048e5e270a58 5301
sPymbed 16:048e5e270a58 5302 WOLFSSL_ENTER("ConfirmSignature");
sPymbed 16:048e5e270a58 5303
sPymbed 16:048e5e270a58 5304 switch (sigCtx->state) {
sPymbed 16:048e5e270a58 5305 case SIG_STATE_BEGIN:
sPymbed 16:048e5e270a58 5306 {
sPymbed 16:048e5e270a58 5307 sigCtx->digest = (byte*)XMALLOC(WC_MAX_DIGEST_SIZE, sigCtx->heap,
sPymbed 16:048e5e270a58 5308 DYNAMIC_TYPE_DIGEST);
sPymbed 16:048e5e270a58 5309 if (sigCtx->digest == NULL) {
sPymbed 16:048e5e270a58 5310 ERROR_OUT(MEMORY_E, exit_cs);
sPymbed 16:048e5e270a58 5311 }
sPymbed 16:048e5e270a58 5312
sPymbed 16:048e5e270a58 5313 sigCtx->state = SIG_STATE_HASH;
sPymbed 16:048e5e270a58 5314 } /* SIG_STATE_BEGIN */
sPymbed 16:048e5e270a58 5315 FALL_THROUGH;
sPymbed 16:048e5e270a58 5316
sPymbed 16:048e5e270a58 5317 case SIG_STATE_HASH:
sPymbed 16:048e5e270a58 5318 {
sPymbed 16:048e5e270a58 5319 ret = HashForSignature(buf, bufSz, sigOID, sigCtx->digest,
sPymbed 16:048e5e270a58 5320 &sigCtx->typeH, &sigCtx->digestSz, 1);
sPymbed 16:048e5e270a58 5321 if (ret != 0) {
sPymbed 16:048e5e270a58 5322 goto exit_cs;
sPymbed 16:048e5e270a58 5323 }
sPymbed 16:048e5e270a58 5324
sPymbed 16:048e5e270a58 5325 sigCtx->state = SIG_STATE_KEY;
sPymbed 16:048e5e270a58 5326 } /* SIG_STATE_HASH */
sPymbed 16:048e5e270a58 5327 FALL_THROUGH;
sPymbed 16:048e5e270a58 5328
sPymbed 16:048e5e270a58 5329 case SIG_STATE_KEY:
sPymbed 16:048e5e270a58 5330 {
sPymbed 16:048e5e270a58 5331 sigCtx->keyOID = keyOID;
sPymbed 16:048e5e270a58 5332
sPymbed 16:048e5e270a58 5333 switch (keyOID) {
sPymbed 16:048e5e270a58 5334 #ifndef NO_RSA
sPymbed 16:048e5e270a58 5335 case RSAk:
sPymbed 16:048e5e270a58 5336 {
sPymbed 16:048e5e270a58 5337 word32 idx = 0;
sPymbed 16:048e5e270a58 5338
sPymbed 16:048e5e270a58 5339 sigCtx->key.rsa = (RsaKey*)XMALLOC(sizeof(RsaKey),
sPymbed 16:048e5e270a58 5340 sigCtx->heap, DYNAMIC_TYPE_RSA);
sPymbed 16:048e5e270a58 5341 sigCtx->plain = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ,
sPymbed 16:048e5e270a58 5342 sigCtx->heap, DYNAMIC_TYPE_SIGNATURE);
sPymbed 16:048e5e270a58 5343 if (sigCtx->key.rsa == NULL || sigCtx->plain == NULL) {
sPymbed 16:048e5e270a58 5344 ERROR_OUT(MEMORY_E, exit_cs);
sPymbed 16:048e5e270a58 5345 }
sPymbed 16:048e5e270a58 5346 if ((ret = wc_InitRsaKey_ex(sigCtx->key.rsa, sigCtx->heap,
sPymbed 16:048e5e270a58 5347 sigCtx->devId)) != 0) {
sPymbed 16:048e5e270a58 5348 goto exit_cs;
sPymbed 16:048e5e270a58 5349 }
sPymbed 16:048e5e270a58 5350 if (sigSz > MAX_ENCODED_SIG_SZ) {
sPymbed 16:048e5e270a58 5351 WOLFSSL_MSG("Verify Signature is too big");
sPymbed 16:048e5e270a58 5352 ERROR_OUT(BUFFER_E, exit_cs);
sPymbed 16:048e5e270a58 5353 }
sPymbed 16:048e5e270a58 5354 if ((ret = wc_RsaPublicKeyDecode(key, &idx, sigCtx->key.rsa,
sPymbed 16:048e5e270a58 5355 keySz)) != 0) {
sPymbed 16:048e5e270a58 5356 WOLFSSL_MSG("ASN Key decode error RSA");
sPymbed 16:048e5e270a58 5357 goto exit_cs;
sPymbed 16:048e5e270a58 5358 }
sPymbed 16:048e5e270a58 5359 XMEMCPY(sigCtx->plain, sig, sigSz);
sPymbed 16:048e5e270a58 5360 sigCtx->out = NULL;
sPymbed 16:048e5e270a58 5361
sPymbed 16:048e5e270a58 5362 #ifdef WOLFSSL_ASYNC_CRYPT
sPymbed 16:048e5e270a58 5363 sigCtx->asyncDev = &sigCtx->key.rsa->asyncDev;
sPymbed 16:048e5e270a58 5364 #endif
sPymbed 16:048e5e270a58 5365 break;
sPymbed 16:048e5e270a58 5366 }
sPymbed 16:048e5e270a58 5367 #endif /* !NO_RSA */
sPymbed 16:048e5e270a58 5368 #ifdef HAVE_ECC
sPymbed 16:048e5e270a58 5369 case ECDSAk:
sPymbed 16:048e5e270a58 5370 {
sPymbed 16:048e5e270a58 5371 word32 idx = 0;
sPymbed 16:048e5e270a58 5372
sPymbed 16:048e5e270a58 5373 sigCtx->verify = 0;
sPymbed 16:048e5e270a58 5374 sigCtx->key.ecc = (ecc_key*)XMALLOC(sizeof(ecc_key),
sPymbed 16:048e5e270a58 5375 sigCtx->heap, DYNAMIC_TYPE_ECC);
sPymbed 16:048e5e270a58 5376 if (sigCtx->key.ecc == NULL) {
sPymbed 16:048e5e270a58 5377 ERROR_OUT(MEMORY_E, exit_cs);
sPymbed 16:048e5e270a58 5378 }
sPymbed 16:048e5e270a58 5379 if ((ret = wc_ecc_init_ex(sigCtx->key.ecc, sigCtx->heap,
sPymbed 16:048e5e270a58 5380 sigCtx->devId)) < 0) {
sPymbed 16:048e5e270a58 5381 goto exit_cs;
sPymbed 16:048e5e270a58 5382 }
sPymbed 16:048e5e270a58 5383 ret = wc_EccPublicKeyDecode(key, &idx, sigCtx->key.ecc,
sPymbed 16:048e5e270a58 5384 keySz);
sPymbed 16:048e5e270a58 5385 if (ret < 0) {
sPymbed 16:048e5e270a58 5386 WOLFSSL_MSG("ASN Key import error ECC");
sPymbed 16:048e5e270a58 5387 goto exit_cs;
sPymbed 16:048e5e270a58 5388 }
sPymbed 16:048e5e270a58 5389 #ifdef WOLFSSL_ASYNC_CRYPT
sPymbed 16:048e5e270a58 5390 sigCtx->asyncDev = &sigCtx->key.ecc->asyncDev;
sPymbed 16:048e5e270a58 5391 #endif
sPymbed 16:048e5e270a58 5392 break;
sPymbed 16:048e5e270a58 5393 }
sPymbed 16:048e5e270a58 5394 #endif /* HAVE_ECC */
sPymbed 16:048e5e270a58 5395 #ifdef HAVE_ED25519
sPymbed 16:048e5e270a58 5396 case ED25519k:
sPymbed 16:048e5e270a58 5397 {
sPymbed 16:048e5e270a58 5398 sigCtx->verify = 0;
sPymbed 16:048e5e270a58 5399 sigCtx->key.ed25519 = (ed25519_key*)XMALLOC(
sPymbed 16:048e5e270a58 5400 sizeof(ed25519_key), sigCtx->heap,
sPymbed 16:048e5e270a58 5401 DYNAMIC_TYPE_ED25519);
sPymbed 16:048e5e270a58 5402 if (sigCtx->key.ed25519 == NULL) {
sPymbed 16:048e5e270a58 5403 ERROR_OUT(MEMORY_E, exit_cs);
sPymbed 16:048e5e270a58 5404 }
sPymbed 16:048e5e270a58 5405 if ((ret = wc_ed25519_init(sigCtx->key.ed25519)) < 0) {
sPymbed 16:048e5e270a58 5406 goto exit_cs;
sPymbed 16:048e5e270a58 5407 }
sPymbed 16:048e5e270a58 5408 if ((ret = wc_ed25519_import_public(key, keySz,
sPymbed 16:048e5e270a58 5409 sigCtx->key.ed25519)) < 0) {
sPymbed 16:048e5e270a58 5410 WOLFSSL_MSG("ASN Key import error ED25519");
sPymbed 16:048e5e270a58 5411 goto exit_cs;
sPymbed 16:048e5e270a58 5412 }
sPymbed 16:048e5e270a58 5413 #ifdef WOLFSSL_ASYNC_CRYPT
sPymbed 16:048e5e270a58 5414 sigCtx->asyncDev = &sigCtx->key.ed25519->asyncDev;
sPymbed 16:048e5e270a58 5415 #endif
sPymbed 16:048e5e270a58 5416 break;
sPymbed 16:048e5e270a58 5417 }
sPymbed 16:048e5e270a58 5418 #endif
sPymbed 16:048e5e270a58 5419 default:
sPymbed 16:048e5e270a58 5420 WOLFSSL_MSG("Verify Key type unknown");
sPymbed 16:048e5e270a58 5421 ret = ASN_UNKNOWN_OID_E;
sPymbed 16:048e5e270a58 5422 break;
sPymbed 16:048e5e270a58 5423 } /* switch (keyOID) */
sPymbed 16:048e5e270a58 5424
sPymbed 16:048e5e270a58 5425 if (ret != 0) {
sPymbed 16:048e5e270a58 5426 goto exit_cs;
sPymbed 16:048e5e270a58 5427 }
sPymbed 16:048e5e270a58 5428
sPymbed 16:048e5e270a58 5429 sigCtx->state = SIG_STATE_DO;
sPymbed 16:048e5e270a58 5430
sPymbed 16:048e5e270a58 5431 #ifdef WOLFSSL_ASYNC_CRYPT
sPymbed 16:048e5e270a58 5432 if (sigCtx->devId != INVALID_DEVID && sigCtx->asyncDev && sigCtx->asyncCtx) {
sPymbed 16:048e5e270a58 5433 /* make sure event is intialized */
sPymbed 16:048e5e270a58 5434 WOLF_EVENT* event = &sigCtx->asyncDev->event;
sPymbed 16:048e5e270a58 5435 ret = wolfAsync_EventInit(event, WOLF_EVENT_TYPE_ASYNC_WOLFSSL,
sPymbed 16:048e5e270a58 5436 sigCtx->asyncCtx, WC_ASYNC_FLAG_CALL_AGAIN);
sPymbed 16:048e5e270a58 5437 }
sPymbed 16:048e5e270a58 5438 #endif
sPymbed 16:048e5e270a58 5439 } /* SIG_STATE_KEY */
sPymbed 16:048e5e270a58 5440 FALL_THROUGH;
sPymbed 16:048e5e270a58 5441
sPymbed 16:048e5e270a58 5442 case SIG_STATE_DO:
sPymbed 16:048e5e270a58 5443 {
sPymbed 16:048e5e270a58 5444 switch (keyOID) {
sPymbed 16:048e5e270a58 5445 #ifndef NO_RSA
sPymbed 16:048e5e270a58 5446 case RSAk:
sPymbed 16:048e5e270a58 5447 {
sPymbed 16:048e5e270a58 5448 #ifdef HAVE_PK_CALLBACKS
sPymbed 16:048e5e270a58 5449 if (sigCtx->pkCbRsa) {
sPymbed 16:048e5e270a58 5450 ret = sigCtx->pkCbRsa(
sPymbed 16:048e5e270a58 5451 sigCtx->plain, sigSz, &sigCtx->out,
sPymbed 16:048e5e270a58 5452 key, keySz,
sPymbed 16:048e5e270a58 5453 sigCtx->pkCtxRsa);
sPymbed 16:048e5e270a58 5454 }
sPymbed 16:048e5e270a58 5455 else
sPymbed 16:048e5e270a58 5456 #endif /* HAVE_PK_CALLBACKS */
sPymbed 16:048e5e270a58 5457 {
sPymbed 16:048e5e270a58 5458 ret = wc_RsaSSL_VerifyInline(sigCtx->plain, sigSz,
sPymbed 16:048e5e270a58 5459 &sigCtx->out, sigCtx->key.rsa);
sPymbed 16:048e5e270a58 5460 }
sPymbed 16:048e5e270a58 5461 break;
sPymbed 16:048e5e270a58 5462 }
sPymbed 16:048e5e270a58 5463 #endif /* !NO_RSA */
sPymbed 16:048e5e270a58 5464 #ifdef HAVE_ECC
sPymbed 16:048e5e270a58 5465 case ECDSAk:
sPymbed 16:048e5e270a58 5466 {
sPymbed 16:048e5e270a58 5467 #ifdef HAVE_PK_CALLBACKS
sPymbed 16:048e5e270a58 5468 if (sigCtx->pkCbEcc) {
sPymbed 16:048e5e270a58 5469 ret = sigCtx->pkCbEcc(
sPymbed 16:048e5e270a58 5470 sig, sigSz,
sPymbed 16:048e5e270a58 5471 sigCtx->digest, sigCtx->digestSz,
sPymbed 16:048e5e270a58 5472 key, keySz, &sigCtx->verify,
sPymbed 16:048e5e270a58 5473 sigCtx->pkCtxEcc);
sPymbed 16:048e5e270a58 5474 }
sPymbed 16:048e5e270a58 5475 else
sPymbed 16:048e5e270a58 5476 #endif /* HAVE_PK_CALLBACKS */
sPymbed 16:048e5e270a58 5477 {
sPymbed 16:048e5e270a58 5478 ret = wc_ecc_verify_hash(sig, sigSz, sigCtx->digest,
sPymbed 16:048e5e270a58 5479 sigCtx->digestSz, &sigCtx->verify,
sPymbed 16:048e5e270a58 5480 sigCtx->key.ecc);
sPymbed 16:048e5e270a58 5481 }
sPymbed 16:048e5e270a58 5482 break;
sPymbed 16:048e5e270a58 5483 }
sPymbed 16:048e5e270a58 5484 #endif /* HAVE_ECC */
sPymbed 16:048e5e270a58 5485 #ifdef HAVE_ED25519
sPymbed 16:048e5e270a58 5486 case ED25519k:
sPymbed 16:048e5e270a58 5487 {
sPymbed 16:048e5e270a58 5488 ret = wc_ed25519_verify_msg(sig, sigSz, buf, bufSz,
sPymbed 16:048e5e270a58 5489 &sigCtx->verify, sigCtx->key.ed25519);
sPymbed 16:048e5e270a58 5490 break;
sPymbed 16:048e5e270a58 5491 }
sPymbed 16:048e5e270a58 5492 #endif
sPymbed 16:048e5e270a58 5493 default:
sPymbed 16:048e5e270a58 5494 break;
sPymbed 16:048e5e270a58 5495 } /* switch (keyOID) */
sPymbed 16:048e5e270a58 5496
sPymbed 16:048e5e270a58 5497 if (ret < 0) {
sPymbed 16:048e5e270a58 5498 /* treat all non async RSA errors as ASN_SIG_CONFIRM_E */
sPymbed 16:048e5e270a58 5499 if (ret != WC_PENDING_E)
sPymbed 16:048e5e270a58 5500 ret = ASN_SIG_CONFIRM_E;
sPymbed 16:048e5e270a58 5501 goto exit_cs;
sPymbed 16:048e5e270a58 5502 }
sPymbed 16:048e5e270a58 5503
sPymbed 16:048e5e270a58 5504 sigCtx->state = SIG_STATE_CHECK;
sPymbed 16:048e5e270a58 5505 } /* SIG_STATE_DO */
sPymbed 16:048e5e270a58 5506 FALL_THROUGH;
sPymbed 16:048e5e270a58 5507
sPymbed 16:048e5e270a58 5508 case SIG_STATE_CHECK:
sPymbed 16:048e5e270a58 5509 {
sPymbed 16:048e5e270a58 5510 switch (keyOID) {
sPymbed 16:048e5e270a58 5511 #ifndef NO_RSA
sPymbed 16:048e5e270a58 5512 case RSAk:
sPymbed 16:048e5e270a58 5513 {
sPymbed 16:048e5e270a58 5514 int encodedSigSz, verifySz;
sPymbed 16:048e5e270a58 5515 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 5516 byte* encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ,
sPymbed 16:048e5e270a58 5517 sigCtx->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 5518 if (encodedSig == NULL) {
sPymbed 16:048e5e270a58 5519 ERROR_OUT(MEMORY_E, exit_cs);
sPymbed 16:048e5e270a58 5520 }
sPymbed 16:048e5e270a58 5521 #else
sPymbed 16:048e5e270a58 5522 byte encodedSig[MAX_ENCODED_SIG_SZ];
sPymbed 16:048e5e270a58 5523 #endif
sPymbed 16:048e5e270a58 5524
sPymbed 16:048e5e270a58 5525 verifySz = ret;
sPymbed 16:048e5e270a58 5526
sPymbed 16:048e5e270a58 5527 /* make sure we're right justified */
sPymbed 16:048e5e270a58 5528 encodedSigSz = wc_EncodeSignature(encodedSig,
sPymbed 16:048e5e270a58 5529 sigCtx->digest, sigCtx->digestSz, sigCtx->typeH);
sPymbed 16:048e5e270a58 5530 if (encodedSigSz == verifySz && sigCtx->out != NULL &&
sPymbed 16:048e5e270a58 5531 XMEMCMP(sigCtx->out, encodedSig, encodedSigSz) == 0) {
sPymbed 16:048e5e270a58 5532 ret = 0;
sPymbed 16:048e5e270a58 5533 }
sPymbed 16:048e5e270a58 5534 else {
sPymbed 16:048e5e270a58 5535 WOLFSSL_MSG("RSA SSL verify match encode error");
sPymbed 16:048e5e270a58 5536 ret = ASN_SIG_CONFIRM_E;
sPymbed 16:048e5e270a58 5537 }
sPymbed 16:048e5e270a58 5538
sPymbed 16:048e5e270a58 5539 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 5540 XFREE(encodedSig, sigCtx->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 5541 #endif
sPymbed 16:048e5e270a58 5542 break;
sPymbed 16:048e5e270a58 5543 }
sPymbed 16:048e5e270a58 5544 #endif /* NO_RSA */
sPymbed 16:048e5e270a58 5545 #ifdef HAVE_ECC
sPymbed 16:048e5e270a58 5546 case ECDSAk:
sPymbed 16:048e5e270a58 5547 {
sPymbed 16:048e5e270a58 5548 if (sigCtx->verify == 1) {
sPymbed 16:048e5e270a58 5549 ret = 0;
sPymbed 16:048e5e270a58 5550 }
sPymbed 16:048e5e270a58 5551 else {
sPymbed 16:048e5e270a58 5552 WOLFSSL_MSG("ECC Verify didn't match");
sPymbed 16:048e5e270a58 5553 ret = ASN_SIG_CONFIRM_E;
sPymbed 16:048e5e270a58 5554 }
sPymbed 16:048e5e270a58 5555 break;
sPymbed 16:048e5e270a58 5556 }
sPymbed 16:048e5e270a58 5557 #endif /* HAVE_ECC */
sPymbed 16:048e5e270a58 5558 #ifdef HAVE_ED25519
sPymbed 16:048e5e270a58 5559 case ED25519k:
sPymbed 16:048e5e270a58 5560 {
sPymbed 16:048e5e270a58 5561 if (sigCtx->verify == 1) {
sPymbed 16:048e5e270a58 5562 ret = 0;
sPymbed 16:048e5e270a58 5563 }
sPymbed 16:048e5e270a58 5564 else {
sPymbed 16:048e5e270a58 5565 WOLFSSL_MSG("ED25519 Verify didn't match");
sPymbed 16:048e5e270a58 5566 ret = ASN_SIG_CONFIRM_E;
sPymbed 16:048e5e270a58 5567 }
sPymbed 16:048e5e270a58 5568 break;
sPymbed 16:048e5e270a58 5569 }
sPymbed 16:048e5e270a58 5570 #endif /* HAVE_ED25519 */
sPymbed 16:048e5e270a58 5571 default:
sPymbed 16:048e5e270a58 5572 break;
sPymbed 16:048e5e270a58 5573 } /* switch (keyOID) */
sPymbed 16:048e5e270a58 5574
sPymbed 16:048e5e270a58 5575 break;
sPymbed 16:048e5e270a58 5576 } /* SIG_STATE_CHECK */
sPymbed 16:048e5e270a58 5577 } /* switch (sigCtx->state) */
sPymbed 16:048e5e270a58 5578
sPymbed 16:048e5e270a58 5579 exit_cs:
sPymbed 16:048e5e270a58 5580
sPymbed 16:048e5e270a58 5581 WOLFSSL_LEAVE("ConfirmSignature", ret);
sPymbed 16:048e5e270a58 5582
sPymbed 16:048e5e270a58 5583 if (ret != WC_PENDING_E) {
sPymbed 16:048e5e270a58 5584 FreeSignatureCtx(sigCtx);
sPymbed 16:048e5e270a58 5585 }
sPymbed 16:048e5e270a58 5586
sPymbed 16:048e5e270a58 5587 return ret;
sPymbed 16:048e5e270a58 5588 }
sPymbed 16:048e5e270a58 5589
sPymbed 16:048e5e270a58 5590
sPymbed 16:048e5e270a58 5591 #ifndef IGNORE_NAME_CONSTRAINTS
sPymbed 16:048e5e270a58 5592
sPymbed 16:048e5e270a58 5593 static int MatchBaseName(int type, const char* name, int nameSz,
sPymbed 16:048e5e270a58 5594 const char* base, int baseSz)
sPymbed 16:048e5e270a58 5595 {
sPymbed 16:048e5e270a58 5596 if (base == NULL || baseSz <= 0 || name == NULL || nameSz <= 0 ||
sPymbed 16:048e5e270a58 5597 name[0] == '.' || nameSz < baseSz ||
sPymbed 16:048e5e270a58 5598 (type != ASN_RFC822_TYPE && type != ASN_DNS_TYPE))
sPymbed 16:048e5e270a58 5599 return 0;
sPymbed 16:048e5e270a58 5600
sPymbed 16:048e5e270a58 5601 /* If an email type, handle special cases where the base is only
sPymbed 16:048e5e270a58 5602 * a domain, or is an email address itself. */
sPymbed 16:048e5e270a58 5603 if (type == ASN_RFC822_TYPE) {
sPymbed 16:048e5e270a58 5604 const char* p = NULL;
sPymbed 16:048e5e270a58 5605 int count = 0;
sPymbed 16:048e5e270a58 5606
sPymbed 16:048e5e270a58 5607 if (base[0] != '.') {
sPymbed 16:048e5e270a58 5608 p = base;
sPymbed 16:048e5e270a58 5609 count = 0;
sPymbed 16:048e5e270a58 5610
sPymbed 16:048e5e270a58 5611 /* find the '@' in the base */
sPymbed 16:048e5e270a58 5612 while (*p != '@' && count < baseSz) {
sPymbed 16:048e5e270a58 5613 count++;
sPymbed 16:048e5e270a58 5614 p++;
sPymbed 16:048e5e270a58 5615 }
sPymbed 16:048e5e270a58 5616
sPymbed 16:048e5e270a58 5617 /* No '@' in base, reset p to NULL */
sPymbed 16:048e5e270a58 5618 if (count >= baseSz)
sPymbed 16:048e5e270a58 5619 p = NULL;
sPymbed 16:048e5e270a58 5620 }
sPymbed 16:048e5e270a58 5621
sPymbed 16:048e5e270a58 5622 if (p == NULL) {
sPymbed 16:048e5e270a58 5623 /* Base isn't an email address, it is a domain name,
sPymbed 16:048e5e270a58 5624 * wind the name forward one character past its '@'. */
sPymbed 16:048e5e270a58 5625 p = name;
sPymbed 16:048e5e270a58 5626 count = 0;
sPymbed 16:048e5e270a58 5627 while (*p != '@' && count < baseSz) {
sPymbed 16:048e5e270a58 5628 count++;
sPymbed 16:048e5e270a58 5629 p++;
sPymbed 16:048e5e270a58 5630 }
sPymbed 16:048e5e270a58 5631
sPymbed 16:048e5e270a58 5632 if (count < baseSz && *p == '@') {
sPymbed 16:048e5e270a58 5633 name = p + 1;
sPymbed 16:048e5e270a58 5634 nameSz -= count + 1;
sPymbed 16:048e5e270a58 5635 }
sPymbed 16:048e5e270a58 5636 }
sPymbed 16:048e5e270a58 5637 }
sPymbed 16:048e5e270a58 5638
sPymbed 16:048e5e270a58 5639 if ((type == ASN_DNS_TYPE || type == ASN_RFC822_TYPE) && base[0] == '.') {
sPymbed 16:048e5e270a58 5640 int szAdjust = nameSz - baseSz;
sPymbed 16:048e5e270a58 5641 name += szAdjust;
sPymbed 16:048e5e270a58 5642 nameSz -= szAdjust;
sPymbed 16:048e5e270a58 5643 }
sPymbed 16:048e5e270a58 5644
sPymbed 16:048e5e270a58 5645 while (nameSz > 0) {
sPymbed 16:048e5e270a58 5646 if (XTOLOWER((unsigned char)*name++) !=
sPymbed 16:048e5e270a58 5647 XTOLOWER((unsigned char)*base++))
sPymbed 16:048e5e270a58 5648 return 0;
sPymbed 16:048e5e270a58 5649 nameSz--;
sPymbed 16:048e5e270a58 5650 }
sPymbed 16:048e5e270a58 5651
sPymbed 16:048e5e270a58 5652 return 1;
sPymbed 16:048e5e270a58 5653 }
sPymbed 16:048e5e270a58 5654
sPymbed 16:048e5e270a58 5655
sPymbed 16:048e5e270a58 5656 static int ConfirmNameConstraints(Signer* signer, DecodedCert* cert)
sPymbed 16:048e5e270a58 5657 {
sPymbed 16:048e5e270a58 5658 if (signer == NULL || cert == NULL)
sPymbed 16:048e5e270a58 5659 return 0;
sPymbed 16:048e5e270a58 5660
sPymbed 16:048e5e270a58 5661 /* Check against the excluded list */
sPymbed 16:048e5e270a58 5662 if (signer->excludedNames) {
sPymbed 16:048e5e270a58 5663 Base_entry* base = signer->excludedNames;
sPymbed 16:048e5e270a58 5664
sPymbed 16:048e5e270a58 5665 while (base != NULL) {
sPymbed 16:048e5e270a58 5666 switch (base->type) {
sPymbed 16:048e5e270a58 5667 case ASN_DNS_TYPE:
sPymbed 16:048e5e270a58 5668 {
sPymbed 16:048e5e270a58 5669 DNS_entry* name = cert->altNames;
sPymbed 16:048e5e270a58 5670 while (name != NULL) {
sPymbed 16:048e5e270a58 5671 if (MatchBaseName(ASN_DNS_TYPE,
sPymbed 16:048e5e270a58 5672 name->name, name->len,
sPymbed 16:048e5e270a58 5673 base->name, base->nameSz)) {
sPymbed 16:048e5e270a58 5674 return 0;
sPymbed 16:048e5e270a58 5675 }
sPymbed 16:048e5e270a58 5676 name = name->next;
sPymbed 16:048e5e270a58 5677 }
sPymbed 16:048e5e270a58 5678 break;
sPymbed 16:048e5e270a58 5679 }
sPymbed 16:048e5e270a58 5680 case ASN_RFC822_TYPE:
sPymbed 16:048e5e270a58 5681 {
sPymbed 16:048e5e270a58 5682 DNS_entry* name = cert->altEmailNames;
sPymbed 16:048e5e270a58 5683 while (name != NULL) {
sPymbed 16:048e5e270a58 5684 if (MatchBaseName(ASN_RFC822_TYPE,
sPymbed 16:048e5e270a58 5685 name->name, name->len,
sPymbed 16:048e5e270a58 5686 base->name, base->nameSz)) {
sPymbed 16:048e5e270a58 5687 return 0;
sPymbed 16:048e5e270a58 5688 }
sPymbed 16:048e5e270a58 5689 name = name->next;
sPymbed 16:048e5e270a58 5690 }
sPymbed 16:048e5e270a58 5691 break;
sPymbed 16:048e5e270a58 5692 }
sPymbed 16:048e5e270a58 5693 case ASN_DIR_TYPE:
sPymbed 16:048e5e270a58 5694 {
sPymbed 16:048e5e270a58 5695 /* allow permitted dirName smaller than actual subject */
sPymbed 16:048e5e270a58 5696 if (cert->subjectRawLen >= base->nameSz &&
sPymbed 16:048e5e270a58 5697 XMEMCMP(cert->subjectRaw, base->name,
sPymbed 16:048e5e270a58 5698 base->nameSz) == 0) {
sPymbed 16:048e5e270a58 5699 return 0;
sPymbed 16:048e5e270a58 5700 }
sPymbed 16:048e5e270a58 5701 break;
sPymbed 16:048e5e270a58 5702 }
sPymbed 16:048e5e270a58 5703 }; /* switch */
sPymbed 16:048e5e270a58 5704 base = base->next;
sPymbed 16:048e5e270a58 5705 }
sPymbed 16:048e5e270a58 5706 }
sPymbed 16:048e5e270a58 5707
sPymbed 16:048e5e270a58 5708 /* Check against the permitted list */
sPymbed 16:048e5e270a58 5709 if (signer->permittedNames != NULL) {
sPymbed 16:048e5e270a58 5710 int needDns = 0;
sPymbed 16:048e5e270a58 5711 int matchDns = 0;
sPymbed 16:048e5e270a58 5712 int needEmail = 0;
sPymbed 16:048e5e270a58 5713 int matchEmail = 0;
sPymbed 16:048e5e270a58 5714 int needDir = 0;
sPymbed 16:048e5e270a58 5715 int matchDir = 0;
sPymbed 16:048e5e270a58 5716 Base_entry* base = signer->permittedNames;
sPymbed 16:048e5e270a58 5717
sPymbed 16:048e5e270a58 5718 while (base != NULL) {
sPymbed 16:048e5e270a58 5719 switch (base->type) {
sPymbed 16:048e5e270a58 5720 case ASN_DNS_TYPE:
sPymbed 16:048e5e270a58 5721 {
sPymbed 16:048e5e270a58 5722 DNS_entry* name = cert->altNames;
sPymbed 16:048e5e270a58 5723
sPymbed 16:048e5e270a58 5724 if (name != NULL)
sPymbed 16:048e5e270a58 5725 needDns = 1;
sPymbed 16:048e5e270a58 5726
sPymbed 16:048e5e270a58 5727 while (name != NULL) {
sPymbed 16:048e5e270a58 5728 matchDns = MatchBaseName(ASN_DNS_TYPE,
sPymbed 16:048e5e270a58 5729 name->name, name->len,
sPymbed 16:048e5e270a58 5730 base->name, base->nameSz);
sPymbed 16:048e5e270a58 5731 name = name->next;
sPymbed 16:048e5e270a58 5732 }
sPymbed 16:048e5e270a58 5733 break;
sPymbed 16:048e5e270a58 5734 }
sPymbed 16:048e5e270a58 5735 case ASN_RFC822_TYPE:
sPymbed 16:048e5e270a58 5736 {
sPymbed 16:048e5e270a58 5737 DNS_entry* name = cert->altEmailNames;
sPymbed 16:048e5e270a58 5738
sPymbed 16:048e5e270a58 5739 if (name != NULL)
sPymbed 16:048e5e270a58 5740 needEmail = 1;
sPymbed 16:048e5e270a58 5741
sPymbed 16:048e5e270a58 5742 while (name != NULL) {
sPymbed 16:048e5e270a58 5743 matchEmail = MatchBaseName(ASN_DNS_TYPE,
sPymbed 16:048e5e270a58 5744 name->name, name->len,
sPymbed 16:048e5e270a58 5745 base->name, base->nameSz);
sPymbed 16:048e5e270a58 5746 name = name->next;
sPymbed 16:048e5e270a58 5747 }
sPymbed 16:048e5e270a58 5748 break;
sPymbed 16:048e5e270a58 5749 }
sPymbed 16:048e5e270a58 5750 case ASN_DIR_TYPE:
sPymbed 16:048e5e270a58 5751 {
sPymbed 16:048e5e270a58 5752 /* allow permitted dirName smaller than actual subject */
sPymbed 16:048e5e270a58 5753 needDir = 1;
sPymbed 16:048e5e270a58 5754 if (cert->subjectRaw != NULL &&
sPymbed 16:048e5e270a58 5755 cert->subjectRawLen >= base->nameSz &&
sPymbed 16:048e5e270a58 5756 XMEMCMP(cert->subjectRaw, base->name,
sPymbed 16:048e5e270a58 5757 base->nameSz) == 0) {
sPymbed 16:048e5e270a58 5758 matchDir = 1;
sPymbed 16:048e5e270a58 5759 }
sPymbed 16:048e5e270a58 5760 break;
sPymbed 16:048e5e270a58 5761 }
sPymbed 16:048e5e270a58 5762 } /* switch */
sPymbed 16:048e5e270a58 5763 base = base->next;
sPymbed 16:048e5e270a58 5764 }
sPymbed 16:048e5e270a58 5765
sPymbed 16:048e5e270a58 5766 if ((needDns && !matchDns) ||
sPymbed 16:048e5e270a58 5767 (needEmail && !matchEmail) ||
sPymbed 16:048e5e270a58 5768 (needDir && !matchDir)) {
sPymbed 16:048e5e270a58 5769 return 0;
sPymbed 16:048e5e270a58 5770 }
sPymbed 16:048e5e270a58 5771 }
sPymbed 16:048e5e270a58 5772
sPymbed 16:048e5e270a58 5773 return 1;
sPymbed 16:048e5e270a58 5774 }
sPymbed 16:048e5e270a58 5775
sPymbed 16:048e5e270a58 5776 #endif /* IGNORE_NAME_CONSTRAINTS */
sPymbed 16:048e5e270a58 5777
sPymbed 16:048e5e270a58 5778 static int DecodeAltNames(byte* input, int sz, DecodedCert* cert)
sPymbed 16:048e5e270a58 5779 {
sPymbed 16:048e5e270a58 5780 word32 idx = 0;
sPymbed 16:048e5e270a58 5781 int length = 0;
sPymbed 16:048e5e270a58 5782
sPymbed 16:048e5e270a58 5783 WOLFSSL_ENTER("DecodeAltNames");
sPymbed 16:048e5e270a58 5784
sPymbed 16:048e5e270a58 5785 if (GetSequence(input, &idx, &length, sz) < 0) {
sPymbed 16:048e5e270a58 5786 WOLFSSL_MSG("\tBad Sequence");
sPymbed 16:048e5e270a58 5787 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 5788 }
sPymbed 16:048e5e270a58 5789
sPymbed 16:048e5e270a58 5790 cert->weOwnAltNames = 1;
sPymbed 16:048e5e270a58 5791
sPymbed 16:048e5e270a58 5792 while (length > 0) {
sPymbed 16:048e5e270a58 5793 byte b = input[idx++];
sPymbed 16:048e5e270a58 5794
sPymbed 16:048e5e270a58 5795 length--;
sPymbed 16:048e5e270a58 5796
sPymbed 16:048e5e270a58 5797 /* Save DNS Type names in the altNames list. */
sPymbed 16:048e5e270a58 5798 /* Save Other Type names in the cert's OidMap */
sPymbed 16:048e5e270a58 5799 if (b == (ASN_CONTEXT_SPECIFIC | ASN_DNS_TYPE)) {
sPymbed 16:048e5e270a58 5800 DNS_entry* dnsEntry;
sPymbed 16:048e5e270a58 5801 int strLen;
sPymbed 16:048e5e270a58 5802 word32 lenStartIdx = idx;
sPymbed 16:048e5e270a58 5803
sPymbed 16:048e5e270a58 5804 if (GetLength(input, &idx, &strLen, sz) < 0) {
sPymbed 16:048e5e270a58 5805 WOLFSSL_MSG("\tfail: str length");
sPymbed 16:048e5e270a58 5806 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 5807 }
sPymbed 16:048e5e270a58 5808 length -= (idx - lenStartIdx);
sPymbed 16:048e5e270a58 5809
sPymbed 16:048e5e270a58 5810 dnsEntry = (DNS_entry*)XMALLOC(sizeof(DNS_entry), cert->heap,
sPymbed 16:048e5e270a58 5811 DYNAMIC_TYPE_ALTNAME);
sPymbed 16:048e5e270a58 5812 if (dnsEntry == NULL) {
sPymbed 16:048e5e270a58 5813 WOLFSSL_MSG("\tOut of Memory");
sPymbed 16:048e5e270a58 5814 return MEMORY_E;
sPymbed 16:048e5e270a58 5815 }
sPymbed 16:048e5e270a58 5816
sPymbed 16:048e5e270a58 5817 dnsEntry->type = ASN_DNS_TYPE;
sPymbed 16:048e5e270a58 5818 dnsEntry->name = (char*)XMALLOC(strLen + 1, cert->heap,
sPymbed 16:048e5e270a58 5819 DYNAMIC_TYPE_ALTNAME);
sPymbed 16:048e5e270a58 5820 if (dnsEntry->name == NULL) {
sPymbed 16:048e5e270a58 5821 WOLFSSL_MSG("\tOut of Memory");
sPymbed 16:048e5e270a58 5822 XFREE(dnsEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);
sPymbed 16:048e5e270a58 5823 return MEMORY_E;
sPymbed 16:048e5e270a58 5824 }
sPymbed 16:048e5e270a58 5825 dnsEntry->len = strLen;
sPymbed 16:048e5e270a58 5826 XMEMCPY(dnsEntry->name, &input[idx], strLen);
sPymbed 16:048e5e270a58 5827 dnsEntry->name[strLen] = '\0';
sPymbed 16:048e5e270a58 5828
sPymbed 16:048e5e270a58 5829 dnsEntry->next = cert->altNames;
sPymbed 16:048e5e270a58 5830 cert->altNames = dnsEntry;
sPymbed 16:048e5e270a58 5831
sPymbed 16:048e5e270a58 5832 length -= strLen;
sPymbed 16:048e5e270a58 5833 idx += strLen;
sPymbed 16:048e5e270a58 5834 }
sPymbed 16:048e5e270a58 5835 #ifndef IGNORE_NAME_CONSTRAINTS
sPymbed 16:048e5e270a58 5836 else if (b == (ASN_CONTEXT_SPECIFIC | ASN_RFC822_TYPE)) {
sPymbed 16:048e5e270a58 5837 DNS_entry* emailEntry;
sPymbed 16:048e5e270a58 5838 int strLen;
sPymbed 16:048e5e270a58 5839 word32 lenStartIdx = idx;
sPymbed 16:048e5e270a58 5840
sPymbed 16:048e5e270a58 5841 if (GetLength(input, &idx, &strLen, sz) < 0) {
sPymbed 16:048e5e270a58 5842 WOLFSSL_MSG("\tfail: str length");
sPymbed 16:048e5e270a58 5843 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 5844 }
sPymbed 16:048e5e270a58 5845 length -= (idx - lenStartIdx);
sPymbed 16:048e5e270a58 5846
sPymbed 16:048e5e270a58 5847 emailEntry = (DNS_entry*)XMALLOC(sizeof(DNS_entry), cert->heap,
sPymbed 16:048e5e270a58 5848 DYNAMIC_TYPE_ALTNAME);
sPymbed 16:048e5e270a58 5849 if (emailEntry == NULL) {
sPymbed 16:048e5e270a58 5850 WOLFSSL_MSG("\tOut of Memory");
sPymbed 16:048e5e270a58 5851 return MEMORY_E;
sPymbed 16:048e5e270a58 5852 }
sPymbed 16:048e5e270a58 5853
sPymbed 16:048e5e270a58 5854 emailEntry->type = ASN_RFC822_TYPE;
sPymbed 16:048e5e270a58 5855 emailEntry->name = (char*)XMALLOC(strLen + 1, cert->heap,
sPymbed 16:048e5e270a58 5856 DYNAMIC_TYPE_ALTNAME);
sPymbed 16:048e5e270a58 5857 if (emailEntry->name == NULL) {
sPymbed 16:048e5e270a58 5858 WOLFSSL_MSG("\tOut of Memory");
sPymbed 16:048e5e270a58 5859 XFREE(emailEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);
sPymbed 16:048e5e270a58 5860 return MEMORY_E;
sPymbed 16:048e5e270a58 5861 }
sPymbed 16:048e5e270a58 5862 emailEntry->len = strLen;
sPymbed 16:048e5e270a58 5863 XMEMCPY(emailEntry->name, &input[idx], strLen);
sPymbed 16:048e5e270a58 5864 emailEntry->name[strLen] = '\0';
sPymbed 16:048e5e270a58 5865
sPymbed 16:048e5e270a58 5866 emailEntry->next = cert->altEmailNames;
sPymbed 16:048e5e270a58 5867 cert->altEmailNames = emailEntry;
sPymbed 16:048e5e270a58 5868
sPymbed 16:048e5e270a58 5869 length -= strLen;
sPymbed 16:048e5e270a58 5870 idx += strLen;
sPymbed 16:048e5e270a58 5871 }
sPymbed 16:048e5e270a58 5872 else if (b == (ASN_CONTEXT_SPECIFIC | ASN_URI_TYPE)) {
sPymbed 16:048e5e270a58 5873 DNS_entry* uriEntry;
sPymbed 16:048e5e270a58 5874 int strLen;
sPymbed 16:048e5e270a58 5875 word32 lenStartIdx = idx;
sPymbed 16:048e5e270a58 5876
sPymbed 16:048e5e270a58 5877 WOLFSSL_MSG("\tPutting URI into list but not using");
sPymbed 16:048e5e270a58 5878 if (GetLength(input, &idx, &strLen, sz) < 0) {
sPymbed 16:048e5e270a58 5879 WOLFSSL_MSG("\tfail: str length");
sPymbed 16:048e5e270a58 5880 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 5881 }
sPymbed 16:048e5e270a58 5882 length -= (idx - lenStartIdx);
sPymbed 16:048e5e270a58 5883
sPymbed 16:048e5e270a58 5884 /* check that strLen at index is not past input buffer */
sPymbed 16:048e5e270a58 5885 if (strLen + (int)idx > sz) {
sPymbed 16:048e5e270a58 5886 return BUFFER_E;
sPymbed 16:048e5e270a58 5887 }
sPymbed 16:048e5e270a58 5888
sPymbed 16:048e5e270a58 5889 #ifndef WOLFSSL_NO_ASN_STRICT
sPymbed 16:048e5e270a58 5890 /* Verify RFC 5280 Sec 4.2.1.6 rule:
sPymbed 16:048e5e270a58 5891 "The name MUST NOT be a relative URI" */
sPymbed 16:048e5e270a58 5892
sPymbed 16:048e5e270a58 5893 {
sPymbed 16:048e5e270a58 5894 int i;
sPymbed 16:048e5e270a58 5895
sPymbed 16:048e5e270a58 5896 /* skip past scheme (i.e http,ftp,...) finding first ':' char */
sPymbed 16:048e5e270a58 5897 for (i = 0; i < strLen; i++) {
sPymbed 16:048e5e270a58 5898 if (input[idx + i] == ':') {
sPymbed 16:048e5e270a58 5899 break;
sPymbed 16:048e5e270a58 5900 }
sPymbed 16:048e5e270a58 5901 if (input[idx + i] == '/') {
sPymbed 16:048e5e270a58 5902 i = strLen; /* error, found relative path since '/' was
sPymbed 16:048e5e270a58 5903 * encountered before ':'. Returning error
sPymbed 16:048e5e270a58 5904 * value in next if statement. */
sPymbed 16:048e5e270a58 5905 }
sPymbed 16:048e5e270a58 5906 }
sPymbed 16:048e5e270a58 5907
sPymbed 16:048e5e270a58 5908 /* test if no ':' char was found and test that the next two
sPymbed 16:048e5e270a58 5909 * chars are // to match the pattern "://" */
sPymbed 16:048e5e270a58 5910 if (i >= strLen - 2 || (input[idx + i + 1] != '/' ||
sPymbed 16:048e5e270a58 5911 input[idx + i + 2] != '/')) {
sPymbed 16:048e5e270a58 5912 WOLFSSL_MSG("\tAlt Name must be absolute URI");
sPymbed 16:048e5e270a58 5913 return ASN_ALT_NAME_E;
sPymbed 16:048e5e270a58 5914 }
sPymbed 16:048e5e270a58 5915 }
sPymbed 16:048e5e270a58 5916 #endif
sPymbed 16:048e5e270a58 5917
sPymbed 16:048e5e270a58 5918 uriEntry = (DNS_entry*)XMALLOC(sizeof(DNS_entry), cert->heap,
sPymbed 16:048e5e270a58 5919 DYNAMIC_TYPE_ALTNAME);
sPymbed 16:048e5e270a58 5920 if (uriEntry == NULL) {
sPymbed 16:048e5e270a58 5921 WOLFSSL_MSG("\tOut of Memory");
sPymbed 16:048e5e270a58 5922 return MEMORY_E;
sPymbed 16:048e5e270a58 5923 }
sPymbed 16:048e5e270a58 5924
sPymbed 16:048e5e270a58 5925 uriEntry->type = ASN_URI_TYPE;
sPymbed 16:048e5e270a58 5926 uriEntry->name = (char*)XMALLOC(strLen + 1, cert->heap,
sPymbed 16:048e5e270a58 5927 DYNAMIC_TYPE_ALTNAME);
sPymbed 16:048e5e270a58 5928 if (uriEntry->name == NULL) {
sPymbed 16:048e5e270a58 5929 WOLFSSL_MSG("\tOut of Memory");
sPymbed 16:048e5e270a58 5930 XFREE(uriEntry, cert->heap, DYNAMIC_TYPE_ALTNAME);
sPymbed 16:048e5e270a58 5931 return MEMORY_E;
sPymbed 16:048e5e270a58 5932 }
sPymbed 16:048e5e270a58 5933 uriEntry->len = strLen;
sPymbed 16:048e5e270a58 5934 XMEMCPY(uriEntry->name, &input[idx], strLen);
sPymbed 16:048e5e270a58 5935 uriEntry->name[strLen] = '\0';
sPymbed 16:048e5e270a58 5936
sPymbed 16:048e5e270a58 5937 uriEntry->next = cert->altNames;
sPymbed 16:048e5e270a58 5938 cert->altNames = uriEntry;
sPymbed 16:048e5e270a58 5939
sPymbed 16:048e5e270a58 5940 length -= strLen;
sPymbed 16:048e5e270a58 5941 idx += strLen;
sPymbed 16:048e5e270a58 5942 }
sPymbed 16:048e5e270a58 5943 #endif /* IGNORE_NAME_CONSTRAINTS */
sPymbed 16:048e5e270a58 5944 #ifdef WOLFSSL_SEP
sPymbed 16:048e5e270a58 5945 else if (b == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | ASN_OTHER_TYPE))
sPymbed 16:048e5e270a58 5946 {
sPymbed 16:048e5e270a58 5947 int strLen;
sPymbed 16:048e5e270a58 5948 word32 lenStartIdx = idx;
sPymbed 16:048e5e270a58 5949 word32 oid = 0;
sPymbed 16:048e5e270a58 5950 int ret;
sPymbed 16:048e5e270a58 5951
sPymbed 16:048e5e270a58 5952 if (GetLength(input, &idx, &strLen, sz) < 0) {
sPymbed 16:048e5e270a58 5953 WOLFSSL_MSG("\tfail: other name length");
sPymbed 16:048e5e270a58 5954 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 5955 }
sPymbed 16:048e5e270a58 5956 /* Consume the rest of this sequence. */
sPymbed 16:048e5e270a58 5957 length -= (strLen + idx - lenStartIdx);
sPymbed 16:048e5e270a58 5958
sPymbed 16:048e5e270a58 5959 if (GetObjectId(input, &idx, &oid, oidCertAltNameType, sz) < 0) {
sPymbed 16:048e5e270a58 5960 WOLFSSL_MSG("\tbad OID");
sPymbed 16:048e5e270a58 5961 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 5962 }
sPymbed 16:048e5e270a58 5963
sPymbed 16:048e5e270a58 5964 if (oid != HW_NAME_OID) {
sPymbed 16:048e5e270a58 5965 WOLFSSL_MSG("\tincorrect OID");
sPymbed 16:048e5e270a58 5966 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 5967 }
sPymbed 16:048e5e270a58 5968
sPymbed 16:048e5e270a58 5969 if (input[idx++] != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) {
sPymbed 16:048e5e270a58 5970 WOLFSSL_MSG("\twrong type");
sPymbed 16:048e5e270a58 5971 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 5972 }
sPymbed 16:048e5e270a58 5973
sPymbed 16:048e5e270a58 5974 if (GetLength(input, &idx, &strLen, sz) < 0) {
sPymbed 16:048e5e270a58 5975 WOLFSSL_MSG("\tfail: str len");
sPymbed 16:048e5e270a58 5976 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 5977 }
sPymbed 16:048e5e270a58 5978
sPymbed 16:048e5e270a58 5979 if (GetSequence(input, &idx, &strLen, sz) < 0) {
sPymbed 16:048e5e270a58 5980 WOLFSSL_MSG("\tBad Sequence");
sPymbed 16:048e5e270a58 5981 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 5982 }
sPymbed 16:048e5e270a58 5983
sPymbed 16:048e5e270a58 5984 ret = GetASNObjectId(input, &idx, &strLen, sz);
sPymbed 16:048e5e270a58 5985 if (ret != 0) {
sPymbed 16:048e5e270a58 5986 WOLFSSL_MSG("\tbad OID");
sPymbed 16:048e5e270a58 5987 return ret;
sPymbed 16:048e5e270a58 5988 }
sPymbed 16:048e5e270a58 5989
sPymbed 16:048e5e270a58 5990 cert->hwType = (byte*)XMALLOC(strLen, cert->heap,
sPymbed 16:048e5e270a58 5991 DYNAMIC_TYPE_X509_EXT);
sPymbed 16:048e5e270a58 5992 if (cert->hwType == NULL) {
sPymbed 16:048e5e270a58 5993 WOLFSSL_MSG("\tOut of Memory");
sPymbed 16:048e5e270a58 5994 return MEMORY_E;
sPymbed 16:048e5e270a58 5995 }
sPymbed 16:048e5e270a58 5996
sPymbed 16:048e5e270a58 5997 XMEMCPY(cert->hwType, &input[idx], strLen);
sPymbed 16:048e5e270a58 5998 cert->hwTypeSz = strLen;
sPymbed 16:048e5e270a58 5999 idx += strLen;
sPymbed 16:048e5e270a58 6000
sPymbed 16:048e5e270a58 6001 ret = GetOctetString(input, &idx, &strLen, sz);
sPymbed 16:048e5e270a58 6002 if (ret < 0)
sPymbed 16:048e5e270a58 6003 return ret;
sPymbed 16:048e5e270a58 6004
sPymbed 16:048e5e270a58 6005 cert->hwSerialNum = (byte*)XMALLOC(strLen + 1, cert->heap,
sPymbed 16:048e5e270a58 6006 DYNAMIC_TYPE_X509_EXT);
sPymbed 16:048e5e270a58 6007 if (cert->hwSerialNum == NULL) {
sPymbed 16:048e5e270a58 6008 WOLFSSL_MSG("\tOut of Memory");
sPymbed 16:048e5e270a58 6009 return MEMORY_E;
sPymbed 16:048e5e270a58 6010 }
sPymbed 16:048e5e270a58 6011
sPymbed 16:048e5e270a58 6012 XMEMCPY(cert->hwSerialNum, &input[idx], strLen);
sPymbed 16:048e5e270a58 6013 cert->hwSerialNum[strLen] = '\0';
sPymbed 16:048e5e270a58 6014 cert->hwSerialNumSz = strLen;
sPymbed 16:048e5e270a58 6015 idx += strLen;
sPymbed 16:048e5e270a58 6016 }
sPymbed 16:048e5e270a58 6017 #endif /* WOLFSSL_SEP */
sPymbed 16:048e5e270a58 6018 else {
sPymbed 16:048e5e270a58 6019 int strLen;
sPymbed 16:048e5e270a58 6020 word32 lenStartIdx = idx;
sPymbed 16:048e5e270a58 6021
sPymbed 16:048e5e270a58 6022 WOLFSSL_MSG("\tUnsupported name type, skipping");
sPymbed 16:048e5e270a58 6023
sPymbed 16:048e5e270a58 6024 if (GetLength(input, &idx, &strLen, sz) < 0) {
sPymbed 16:048e5e270a58 6025 WOLFSSL_MSG("\tfail: unsupported name length");
sPymbed 16:048e5e270a58 6026 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 6027 }
sPymbed 16:048e5e270a58 6028 length -= (strLen + idx - lenStartIdx);
sPymbed 16:048e5e270a58 6029 idx += strLen;
sPymbed 16:048e5e270a58 6030 }
sPymbed 16:048e5e270a58 6031 }
sPymbed 16:048e5e270a58 6032 return 0;
sPymbed 16:048e5e270a58 6033 }
sPymbed 16:048e5e270a58 6034
sPymbed 16:048e5e270a58 6035 static int DecodeBasicCaConstraint(byte* input, int sz, DecodedCert* cert)
sPymbed 16:048e5e270a58 6036 {
sPymbed 16:048e5e270a58 6037 word32 idx = 0;
sPymbed 16:048e5e270a58 6038 int length = 0;
sPymbed 16:048e5e270a58 6039 int ret;
sPymbed 16:048e5e270a58 6040
sPymbed 16:048e5e270a58 6041 WOLFSSL_ENTER("DecodeBasicCaConstraint");
sPymbed 16:048e5e270a58 6042
sPymbed 16:048e5e270a58 6043 if (GetSequence(input, &idx, &length, sz) < 0) {
sPymbed 16:048e5e270a58 6044 WOLFSSL_MSG("\tfail: bad SEQUENCE");
sPymbed 16:048e5e270a58 6045 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 6046 }
sPymbed 16:048e5e270a58 6047
sPymbed 16:048e5e270a58 6048 if (length == 0)
sPymbed 16:048e5e270a58 6049 return 0;
sPymbed 16:048e5e270a58 6050
sPymbed 16:048e5e270a58 6051 /* If the basic ca constraint is false, this extension may be named, but
sPymbed 16:048e5e270a58 6052 * left empty. So, if the length is 0, just return. */
sPymbed 16:048e5e270a58 6053
sPymbed 16:048e5e270a58 6054 ret = GetBoolean(input, &idx, sz);
sPymbed 16:048e5e270a58 6055 if (ret < 0) {
sPymbed 16:048e5e270a58 6056 WOLFSSL_MSG("\tfail: constraint not valid BOOLEAN");
sPymbed 16:048e5e270a58 6057 return ret;
sPymbed 16:048e5e270a58 6058 }
sPymbed 16:048e5e270a58 6059
sPymbed 16:048e5e270a58 6060 cert->isCA = (byte)ret;
sPymbed 16:048e5e270a58 6061
sPymbed 16:048e5e270a58 6062 /* If there isn't any more data, return. */
sPymbed 16:048e5e270a58 6063 if (idx >= (word32)sz)
sPymbed 16:048e5e270a58 6064 return 0;
sPymbed 16:048e5e270a58 6065
sPymbed 16:048e5e270a58 6066 ret = GetInteger7Bit(input, &idx, sz);
sPymbed 16:048e5e270a58 6067 if (ret < 0)
sPymbed 16:048e5e270a58 6068 return ret;
sPymbed 16:048e5e270a58 6069
sPymbed 16:048e5e270a58 6070 cert->pathLength = (byte)ret;
sPymbed 16:048e5e270a58 6071 cert->pathLengthSet = 1;
sPymbed 16:048e5e270a58 6072
sPymbed 16:048e5e270a58 6073 return 0;
sPymbed 16:048e5e270a58 6074 }
sPymbed 16:048e5e270a58 6075
sPymbed 16:048e5e270a58 6076
sPymbed 16:048e5e270a58 6077 #define CRLDP_FULL_NAME 0
sPymbed 16:048e5e270a58 6078 /* From RFC3280 SS4.2.1.14, Distribution Point Name*/
sPymbed 16:048e5e270a58 6079 #define GENERALNAME_URI 6
sPymbed 16:048e5e270a58 6080 /* From RFC3280 SS4.2.1.7, GeneralName */
sPymbed 16:048e5e270a58 6081
sPymbed 16:048e5e270a58 6082 static int DecodeCrlDist(byte* input, int sz, DecodedCert* cert)
sPymbed 16:048e5e270a58 6083 {
sPymbed 16:048e5e270a58 6084 word32 idx = 0;
sPymbed 16:048e5e270a58 6085 int length = 0;
sPymbed 16:048e5e270a58 6086
sPymbed 16:048e5e270a58 6087 WOLFSSL_ENTER("DecodeCrlDist");
sPymbed 16:048e5e270a58 6088
sPymbed 16:048e5e270a58 6089 /* Unwrap the list of Distribution Points*/
sPymbed 16:048e5e270a58 6090 if (GetSequence(input, &idx, &length, sz) < 0)
sPymbed 16:048e5e270a58 6091 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 6092
sPymbed 16:048e5e270a58 6093 /* Unwrap a single Distribution Point */
sPymbed 16:048e5e270a58 6094 if (GetSequence(input, &idx, &length, sz) < 0)
sPymbed 16:048e5e270a58 6095 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 6096
sPymbed 16:048e5e270a58 6097 /* The Distribution Point has three explicit optional members
sPymbed 16:048e5e270a58 6098 * First check for a DistributionPointName
sPymbed 16:048e5e270a58 6099 */
sPymbed 16:048e5e270a58 6100 if (input[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
sPymbed 16:048e5e270a58 6101 {
sPymbed 16:048e5e270a58 6102 idx++;
sPymbed 16:048e5e270a58 6103 if (GetLength(input, &idx, &length, sz) < 0)
sPymbed 16:048e5e270a58 6104 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 6105
sPymbed 16:048e5e270a58 6106 if (input[idx] ==
sPymbed 16:048e5e270a58 6107 (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | CRLDP_FULL_NAME))
sPymbed 16:048e5e270a58 6108 {
sPymbed 16:048e5e270a58 6109 idx++;
sPymbed 16:048e5e270a58 6110 if (GetLength(input, &idx, &length, sz) < 0)
sPymbed 16:048e5e270a58 6111 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 6112
sPymbed 16:048e5e270a58 6113 if (input[idx] == (ASN_CONTEXT_SPECIFIC | GENERALNAME_URI))
sPymbed 16:048e5e270a58 6114 {
sPymbed 16:048e5e270a58 6115 idx++;
sPymbed 16:048e5e270a58 6116 if (GetLength(input, &idx, &length, sz) < 0)
sPymbed 16:048e5e270a58 6117 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 6118
sPymbed 16:048e5e270a58 6119 cert->extCrlInfoSz = length;
sPymbed 16:048e5e270a58 6120 cert->extCrlInfo = input + idx;
sPymbed 16:048e5e270a58 6121 idx += length;
sPymbed 16:048e5e270a58 6122 }
sPymbed 16:048e5e270a58 6123 else
sPymbed 16:048e5e270a58 6124 /* This isn't a URI, skip it. */
sPymbed 16:048e5e270a58 6125 idx += length;
sPymbed 16:048e5e270a58 6126 }
sPymbed 16:048e5e270a58 6127 else {
sPymbed 16:048e5e270a58 6128 /* This isn't a FULLNAME, skip it. */
sPymbed 16:048e5e270a58 6129 idx += length;
sPymbed 16:048e5e270a58 6130 }
sPymbed 16:048e5e270a58 6131 }
sPymbed 16:048e5e270a58 6132
sPymbed 16:048e5e270a58 6133 /* Check for reasonFlags */
sPymbed 16:048e5e270a58 6134 if (idx < (word32)sz &&
sPymbed 16:048e5e270a58 6135 input[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1))
sPymbed 16:048e5e270a58 6136 {
sPymbed 16:048e5e270a58 6137 idx++;
sPymbed 16:048e5e270a58 6138 if (GetLength(input, &idx, &length, sz) < 0)
sPymbed 16:048e5e270a58 6139 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 6140 idx += length;
sPymbed 16:048e5e270a58 6141 }
sPymbed 16:048e5e270a58 6142
sPymbed 16:048e5e270a58 6143 /* Check for cRLIssuer */
sPymbed 16:048e5e270a58 6144 if (idx < (word32)sz &&
sPymbed 16:048e5e270a58 6145 input[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 2))
sPymbed 16:048e5e270a58 6146 {
sPymbed 16:048e5e270a58 6147 idx++;
sPymbed 16:048e5e270a58 6148 if (GetLength(input, &idx, &length, sz) < 0)
sPymbed 16:048e5e270a58 6149 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 6150 idx += length;
sPymbed 16:048e5e270a58 6151 }
sPymbed 16:048e5e270a58 6152
sPymbed 16:048e5e270a58 6153 if (idx < (word32)sz)
sPymbed 16:048e5e270a58 6154 {
sPymbed 16:048e5e270a58 6155 WOLFSSL_MSG("\tThere are more CRL Distribution Point records, "
sPymbed 16:048e5e270a58 6156 "but we only use the first one.");
sPymbed 16:048e5e270a58 6157 }
sPymbed 16:048e5e270a58 6158
sPymbed 16:048e5e270a58 6159 return 0;
sPymbed 16:048e5e270a58 6160 }
sPymbed 16:048e5e270a58 6161
sPymbed 16:048e5e270a58 6162
sPymbed 16:048e5e270a58 6163 static int DecodeAuthInfo(byte* input, int sz, DecodedCert* cert)
sPymbed 16:048e5e270a58 6164 /*
sPymbed 16:048e5e270a58 6165 * Read the first of the Authority Information Access records. If there are
sPymbed 16:048e5e270a58 6166 * any issues, return without saving the record.
sPymbed 16:048e5e270a58 6167 */
sPymbed 16:048e5e270a58 6168 {
sPymbed 16:048e5e270a58 6169 word32 idx = 0;
sPymbed 16:048e5e270a58 6170 int length = 0;
sPymbed 16:048e5e270a58 6171 byte b;
sPymbed 16:048e5e270a58 6172 word32 oid;
sPymbed 16:048e5e270a58 6173
sPymbed 16:048e5e270a58 6174 WOLFSSL_ENTER("DecodeAuthInfo");
sPymbed 16:048e5e270a58 6175
sPymbed 16:048e5e270a58 6176 /* Unwrap the list of AIAs */
sPymbed 16:048e5e270a58 6177 if (GetSequence(input, &idx, &length, sz) < 0)
sPymbed 16:048e5e270a58 6178 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 6179
sPymbed 16:048e5e270a58 6180 while (idx < (word32)sz) {
sPymbed 16:048e5e270a58 6181 /* Unwrap a single AIA */
sPymbed 16:048e5e270a58 6182 if (GetSequence(input, &idx, &length, sz) < 0)
sPymbed 16:048e5e270a58 6183 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 6184
sPymbed 16:048e5e270a58 6185 oid = 0;
sPymbed 16:048e5e270a58 6186 if (GetObjectId(input, &idx, &oid, oidCertAuthInfoType, sz) < 0)
sPymbed 16:048e5e270a58 6187 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 6188
sPymbed 16:048e5e270a58 6189
sPymbed 16:048e5e270a58 6190 /* Only supporting URIs right now. */
sPymbed 16:048e5e270a58 6191 b = input[idx++];
sPymbed 16:048e5e270a58 6192 if (GetLength(input, &idx, &length, sz) < 0)
sPymbed 16:048e5e270a58 6193 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 6194
sPymbed 16:048e5e270a58 6195 if (b == (ASN_CONTEXT_SPECIFIC | GENERALNAME_URI) &&
sPymbed 16:048e5e270a58 6196 oid == AIA_OCSP_OID)
sPymbed 16:048e5e270a58 6197 {
sPymbed 16:048e5e270a58 6198 cert->extAuthInfoSz = length;
sPymbed 16:048e5e270a58 6199 cert->extAuthInfo = input + idx;
sPymbed 16:048e5e270a58 6200 break;
sPymbed 16:048e5e270a58 6201 }
sPymbed 16:048e5e270a58 6202 idx += length;
sPymbed 16:048e5e270a58 6203 }
sPymbed 16:048e5e270a58 6204
sPymbed 16:048e5e270a58 6205 return 0;
sPymbed 16:048e5e270a58 6206 }
sPymbed 16:048e5e270a58 6207
sPymbed 16:048e5e270a58 6208
sPymbed 16:048e5e270a58 6209 static int DecodeAuthKeyId(byte* input, int sz, DecodedCert* cert)
sPymbed 16:048e5e270a58 6210 {
sPymbed 16:048e5e270a58 6211 word32 idx = 0;
sPymbed 16:048e5e270a58 6212 int length = 0, ret = 0;
sPymbed 16:048e5e270a58 6213
sPymbed 16:048e5e270a58 6214 WOLFSSL_ENTER("DecodeAuthKeyId");
sPymbed 16:048e5e270a58 6215
sPymbed 16:048e5e270a58 6216 if (GetSequence(input, &idx, &length, sz) < 0) {
sPymbed 16:048e5e270a58 6217 WOLFSSL_MSG("\tfail: should be a SEQUENCE\n");
sPymbed 16:048e5e270a58 6218 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 6219 }
sPymbed 16:048e5e270a58 6220
sPymbed 16:048e5e270a58 6221 if (input[idx++] != (ASN_CONTEXT_SPECIFIC | 0)) {
sPymbed 16:048e5e270a58 6222 WOLFSSL_MSG("\tinfo: OPTIONAL item 0, not available\n");
sPymbed 16:048e5e270a58 6223 return 0;
sPymbed 16:048e5e270a58 6224 }
sPymbed 16:048e5e270a58 6225
sPymbed 16:048e5e270a58 6226 if (GetLength(input, &idx, &length, sz) <= 0) {
sPymbed 16:048e5e270a58 6227 WOLFSSL_MSG("\tfail: extension data length");
sPymbed 16:048e5e270a58 6228 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 6229 }
sPymbed 16:048e5e270a58 6230
sPymbed 16:048e5e270a58 6231 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
sPymbed 16:048e5e270a58 6232 cert->extAuthKeyIdSrc = &input[idx];
sPymbed 16:048e5e270a58 6233 cert->extAuthKeyIdSz = length;
sPymbed 16:048e5e270a58 6234 #endif /* OPENSSL_EXTRA */
sPymbed 16:048e5e270a58 6235
sPymbed 16:048e5e270a58 6236 if (length == KEYID_SIZE) {
sPymbed 16:048e5e270a58 6237 XMEMCPY(cert->extAuthKeyId, input + idx, length);
sPymbed 16:048e5e270a58 6238 }
sPymbed 16:048e5e270a58 6239 else {
sPymbed 16:048e5e270a58 6240 #ifdef NO_SHA
sPymbed 16:048e5e270a58 6241 ret = wc_Sha256Hash(input + idx, length, cert->extAuthKeyId);
sPymbed 16:048e5e270a58 6242 #else
sPymbed 16:048e5e270a58 6243 ret = wc_ShaHash(input + idx, length, cert->extAuthKeyId);
sPymbed 16:048e5e270a58 6244 #endif
sPymbed 16:048e5e270a58 6245 }
sPymbed 16:048e5e270a58 6246
sPymbed 16:048e5e270a58 6247 return ret;
sPymbed 16:048e5e270a58 6248 }
sPymbed 16:048e5e270a58 6249
sPymbed 16:048e5e270a58 6250
sPymbed 16:048e5e270a58 6251 static int DecodeSubjKeyId(byte* input, int sz, DecodedCert* cert)
sPymbed 16:048e5e270a58 6252 {
sPymbed 16:048e5e270a58 6253 word32 idx = 0;
sPymbed 16:048e5e270a58 6254 int length = 0, ret = 0;
sPymbed 16:048e5e270a58 6255
sPymbed 16:048e5e270a58 6256 WOLFSSL_ENTER("DecodeSubjKeyId");
sPymbed 16:048e5e270a58 6257
sPymbed 16:048e5e270a58 6258 if (sz <= 0)
sPymbed 16:048e5e270a58 6259 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 6260
sPymbed 16:048e5e270a58 6261 ret = GetOctetString(input, &idx, &length, sz);
sPymbed 16:048e5e270a58 6262 if (ret < 0)
sPymbed 16:048e5e270a58 6263 return ret;
sPymbed 16:048e5e270a58 6264
sPymbed 16:048e5e270a58 6265 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
sPymbed 16:048e5e270a58 6266 cert->extSubjKeyIdSrc = &input[idx];
sPymbed 16:048e5e270a58 6267 cert->extSubjKeyIdSz = length;
sPymbed 16:048e5e270a58 6268 #endif /* OPENSSL_EXTRA */
sPymbed 16:048e5e270a58 6269
sPymbed 16:048e5e270a58 6270 if (length == SIGNER_DIGEST_SIZE) {
sPymbed 16:048e5e270a58 6271 XMEMCPY(cert->extSubjKeyId, input + idx, length);
sPymbed 16:048e5e270a58 6272 }
sPymbed 16:048e5e270a58 6273 else {
sPymbed 16:048e5e270a58 6274 #ifdef NO_SHA
sPymbed 16:048e5e270a58 6275 ret = wc_Sha256Hash(input + idx, length, cert->extSubjKeyId);
sPymbed 16:048e5e270a58 6276 #else
sPymbed 16:048e5e270a58 6277 ret = wc_ShaHash(input + idx, length, cert->extSubjKeyId);
sPymbed 16:048e5e270a58 6278 #endif
sPymbed 16:048e5e270a58 6279 }
sPymbed 16:048e5e270a58 6280
sPymbed 16:048e5e270a58 6281 return ret;
sPymbed 16:048e5e270a58 6282 }
sPymbed 16:048e5e270a58 6283
sPymbed 16:048e5e270a58 6284
sPymbed 16:048e5e270a58 6285 static int DecodeKeyUsage(byte* input, int sz, DecodedCert* cert)
sPymbed 16:048e5e270a58 6286 {
sPymbed 16:048e5e270a58 6287 word32 idx = 0;
sPymbed 16:048e5e270a58 6288 int length;
sPymbed 16:048e5e270a58 6289 int ret;
sPymbed 16:048e5e270a58 6290 WOLFSSL_ENTER("DecodeKeyUsage");
sPymbed 16:048e5e270a58 6291
sPymbed 16:048e5e270a58 6292 ret = CheckBitString(input, &idx, &length, sz, 0, NULL);
sPymbed 16:048e5e270a58 6293 if (ret != 0)
sPymbed 16:048e5e270a58 6294 return ret;
sPymbed 16:048e5e270a58 6295
sPymbed 16:048e5e270a58 6296 cert->extKeyUsage = (word16)(input[idx]);
sPymbed 16:048e5e270a58 6297 if (length == 2)
sPymbed 16:048e5e270a58 6298 cert->extKeyUsage |= (word16)(input[idx+1] << 8);
sPymbed 16:048e5e270a58 6299
sPymbed 16:048e5e270a58 6300 return 0;
sPymbed 16:048e5e270a58 6301 }
sPymbed 16:048e5e270a58 6302
sPymbed 16:048e5e270a58 6303
sPymbed 16:048e5e270a58 6304 static int DecodeExtKeyUsage(byte* input, int sz, DecodedCert* cert)
sPymbed 16:048e5e270a58 6305 {
sPymbed 16:048e5e270a58 6306 word32 idx = 0, oid;
sPymbed 16:048e5e270a58 6307 int length;
sPymbed 16:048e5e270a58 6308
sPymbed 16:048e5e270a58 6309 WOLFSSL_ENTER("DecodeExtKeyUsage");
sPymbed 16:048e5e270a58 6310
sPymbed 16:048e5e270a58 6311 if (GetSequence(input, &idx, &length, sz) < 0) {
sPymbed 16:048e5e270a58 6312 WOLFSSL_MSG("\tfail: should be a SEQUENCE");
sPymbed 16:048e5e270a58 6313 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 6314 }
sPymbed 16:048e5e270a58 6315
sPymbed 16:048e5e270a58 6316 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
sPymbed 16:048e5e270a58 6317 cert->extExtKeyUsageSrc = input + idx;
sPymbed 16:048e5e270a58 6318 cert->extExtKeyUsageSz = length;
sPymbed 16:048e5e270a58 6319 #endif
sPymbed 16:048e5e270a58 6320
sPymbed 16:048e5e270a58 6321 while (idx < (word32)sz) {
sPymbed 16:048e5e270a58 6322 if (GetObjectId(input, &idx, &oid, oidCertKeyUseType, sz) < 0)
sPymbed 16:048e5e270a58 6323 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 6324
sPymbed 16:048e5e270a58 6325 switch (oid) {
sPymbed 16:048e5e270a58 6326 case EKU_ANY_OID:
sPymbed 16:048e5e270a58 6327 cert->extExtKeyUsage |= EXTKEYUSE_ANY;
sPymbed 16:048e5e270a58 6328 break;
sPymbed 16:048e5e270a58 6329 case EKU_SERVER_AUTH_OID:
sPymbed 16:048e5e270a58 6330 cert->extExtKeyUsage |= EXTKEYUSE_SERVER_AUTH;
sPymbed 16:048e5e270a58 6331 break;
sPymbed 16:048e5e270a58 6332 case EKU_CLIENT_AUTH_OID:
sPymbed 16:048e5e270a58 6333 cert->extExtKeyUsage |= EXTKEYUSE_CLIENT_AUTH;
sPymbed 16:048e5e270a58 6334 break;
sPymbed 16:048e5e270a58 6335 case EKU_CODESIGNING_OID:
sPymbed 16:048e5e270a58 6336 cert->extExtKeyUsage |= EXTKEYUSE_CODESIGN;
sPymbed 16:048e5e270a58 6337 break;
sPymbed 16:048e5e270a58 6338 case EKU_EMAILPROTECT_OID:
sPymbed 16:048e5e270a58 6339 cert->extExtKeyUsage |= EXTKEYUSE_EMAILPROT;
sPymbed 16:048e5e270a58 6340 break;
sPymbed 16:048e5e270a58 6341 case EKU_TIMESTAMP_OID:
sPymbed 16:048e5e270a58 6342 cert->extExtKeyUsage |= EXTKEYUSE_TIMESTAMP;
sPymbed 16:048e5e270a58 6343 break;
sPymbed 16:048e5e270a58 6344 case EKU_OCSP_SIGN_OID:
sPymbed 16:048e5e270a58 6345 cert->extExtKeyUsage |= EXTKEYUSE_OCSP_SIGN;
sPymbed 16:048e5e270a58 6346 break;
sPymbed 16:048e5e270a58 6347 }
sPymbed 16:048e5e270a58 6348
sPymbed 16:048e5e270a58 6349 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
sPymbed 16:048e5e270a58 6350 cert->extExtKeyUsageCount++;
sPymbed 16:048e5e270a58 6351 #endif
sPymbed 16:048e5e270a58 6352 }
sPymbed 16:048e5e270a58 6353
sPymbed 16:048e5e270a58 6354 return 0;
sPymbed 16:048e5e270a58 6355 }
sPymbed 16:048e5e270a58 6356
sPymbed 16:048e5e270a58 6357
sPymbed 16:048e5e270a58 6358 #ifndef IGNORE_NAME_CONSTRAINTS
sPymbed 16:048e5e270a58 6359 #define ASN_TYPE_MASK 0xF
sPymbed 16:048e5e270a58 6360 static int DecodeSubtree(byte* input, int sz, Base_entry** head, void* heap)
sPymbed 16:048e5e270a58 6361 {
sPymbed 16:048e5e270a58 6362 word32 idx = 0;
sPymbed 16:048e5e270a58 6363
sPymbed 16:048e5e270a58 6364 (void)heap;
sPymbed 16:048e5e270a58 6365
sPymbed 16:048e5e270a58 6366 while (idx < (word32)sz) {
sPymbed 16:048e5e270a58 6367 int seqLength, strLength;
sPymbed 16:048e5e270a58 6368 word32 nameIdx;
sPymbed 16:048e5e270a58 6369 byte b, bType;
sPymbed 16:048e5e270a58 6370
sPymbed 16:048e5e270a58 6371 if (GetSequence(input, &idx, &seqLength, sz) < 0) {
sPymbed 16:048e5e270a58 6372 WOLFSSL_MSG("\tfail: should be a SEQUENCE");
sPymbed 16:048e5e270a58 6373 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 6374 }
sPymbed 16:048e5e270a58 6375 nameIdx = idx;
sPymbed 16:048e5e270a58 6376 b = input[nameIdx++];
sPymbed 16:048e5e270a58 6377
sPymbed 16:048e5e270a58 6378 if (GetLength(input, &nameIdx, &strLength, sz) <= 0) {
sPymbed 16:048e5e270a58 6379 WOLFSSL_MSG("\tinvalid length");
sPymbed 16:048e5e270a58 6380 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 6381 }
sPymbed 16:048e5e270a58 6382
sPymbed 16:048e5e270a58 6383 /* Get type, LSB 4-bits */
sPymbed 16:048e5e270a58 6384 bType = (b & ASN_TYPE_MASK);
sPymbed 16:048e5e270a58 6385
sPymbed 16:048e5e270a58 6386 if (bType == ASN_DNS_TYPE || bType == ASN_RFC822_TYPE ||
sPymbed 16:048e5e270a58 6387 bType == ASN_DIR_TYPE) {
sPymbed 16:048e5e270a58 6388 Base_entry* entry;
sPymbed 16:048e5e270a58 6389
sPymbed 16:048e5e270a58 6390 /* if constructed has leading sequence */
sPymbed 16:048e5e270a58 6391 if (b & ASN_CONSTRUCTED) {
sPymbed 16:048e5e270a58 6392 if (GetSequence(input, &nameIdx, &strLength, sz) < 0) {
sPymbed 16:048e5e270a58 6393 WOLFSSL_MSG("\tfail: constructed be a SEQUENCE");
sPymbed 16:048e5e270a58 6394 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 6395 }
sPymbed 16:048e5e270a58 6396 }
sPymbed 16:048e5e270a58 6397
sPymbed 16:048e5e270a58 6398 entry = (Base_entry*)XMALLOC(sizeof(Base_entry), heap,
sPymbed 16:048e5e270a58 6399 DYNAMIC_TYPE_ALTNAME);
sPymbed 16:048e5e270a58 6400 if (entry == NULL) {
sPymbed 16:048e5e270a58 6401 WOLFSSL_MSG("allocate error");
sPymbed 16:048e5e270a58 6402 return MEMORY_E;
sPymbed 16:048e5e270a58 6403 }
sPymbed 16:048e5e270a58 6404
sPymbed 16:048e5e270a58 6405 entry->name = (char*)XMALLOC(strLength, heap, DYNAMIC_TYPE_ALTNAME);
sPymbed 16:048e5e270a58 6406 if (entry->name == NULL) {
sPymbed 16:048e5e270a58 6407 WOLFSSL_MSG("allocate error");
sPymbed 16:048e5e270a58 6408 XFREE(entry, heap, DYNAMIC_TYPE_ALTNAME);
sPymbed 16:048e5e270a58 6409 return MEMORY_E;
sPymbed 16:048e5e270a58 6410 }
sPymbed 16:048e5e270a58 6411
sPymbed 16:048e5e270a58 6412 XMEMCPY(entry->name, &input[nameIdx], strLength);
sPymbed 16:048e5e270a58 6413 entry->nameSz = strLength;
sPymbed 16:048e5e270a58 6414 entry->type = bType;
sPymbed 16:048e5e270a58 6415
sPymbed 16:048e5e270a58 6416 entry->next = *head;
sPymbed 16:048e5e270a58 6417 *head = entry;
sPymbed 16:048e5e270a58 6418 }
sPymbed 16:048e5e270a58 6419
sPymbed 16:048e5e270a58 6420 idx += seqLength;
sPymbed 16:048e5e270a58 6421 }
sPymbed 16:048e5e270a58 6422
sPymbed 16:048e5e270a58 6423 return 0;
sPymbed 16:048e5e270a58 6424 }
sPymbed 16:048e5e270a58 6425
sPymbed 16:048e5e270a58 6426
sPymbed 16:048e5e270a58 6427 static int DecodeNameConstraints(byte* input, int sz, DecodedCert* cert)
sPymbed 16:048e5e270a58 6428 {
sPymbed 16:048e5e270a58 6429 word32 idx = 0;
sPymbed 16:048e5e270a58 6430 int length = 0;
sPymbed 16:048e5e270a58 6431
sPymbed 16:048e5e270a58 6432 WOLFSSL_ENTER("DecodeNameConstraints");
sPymbed 16:048e5e270a58 6433
sPymbed 16:048e5e270a58 6434 if (GetSequence(input, &idx, &length, sz) < 0) {
sPymbed 16:048e5e270a58 6435 WOLFSSL_MSG("\tfail: should be a SEQUENCE");
sPymbed 16:048e5e270a58 6436 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 6437 }
sPymbed 16:048e5e270a58 6438
sPymbed 16:048e5e270a58 6439 while (idx < (word32)sz) {
sPymbed 16:048e5e270a58 6440 byte b = input[idx++];
sPymbed 16:048e5e270a58 6441 Base_entry** subtree = NULL;
sPymbed 16:048e5e270a58 6442
sPymbed 16:048e5e270a58 6443 if (GetLength(input, &idx, &length, sz) <= 0) {
sPymbed 16:048e5e270a58 6444 WOLFSSL_MSG("\tinvalid length");
sPymbed 16:048e5e270a58 6445 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 6446 }
sPymbed 16:048e5e270a58 6447
sPymbed 16:048e5e270a58 6448 if (b == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0))
sPymbed 16:048e5e270a58 6449 subtree = &cert->permittedNames;
sPymbed 16:048e5e270a58 6450 else if (b == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1))
sPymbed 16:048e5e270a58 6451 subtree = &cert->excludedNames;
sPymbed 16:048e5e270a58 6452 else {
sPymbed 16:048e5e270a58 6453 WOLFSSL_MSG("\tinvalid subtree");
sPymbed 16:048e5e270a58 6454 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 6455 }
sPymbed 16:048e5e270a58 6456
sPymbed 16:048e5e270a58 6457 DecodeSubtree(input + idx, length, subtree, cert->heap);
sPymbed 16:048e5e270a58 6458
sPymbed 16:048e5e270a58 6459 idx += length;
sPymbed 16:048e5e270a58 6460 }
sPymbed 16:048e5e270a58 6461
sPymbed 16:048e5e270a58 6462 return 0;
sPymbed 16:048e5e270a58 6463 }
sPymbed 16:048e5e270a58 6464 #endif /* IGNORE_NAME_CONSTRAINTS */
sPymbed 16:048e5e270a58 6465
sPymbed 16:048e5e270a58 6466 #if (defined(WOLFSSL_CERT_EXT) && !defined(WOLFSSL_SEP)) || defined(OPENSSL_EXTRA)
sPymbed 16:048e5e270a58 6467
sPymbed 16:048e5e270a58 6468 static int Word32ToString(char* d, word32 number)
sPymbed 16:048e5e270a58 6469 {
sPymbed 16:048e5e270a58 6470 int i = 0;
sPymbed 16:048e5e270a58 6471
sPymbed 16:048e5e270a58 6472 if (d != NULL) {
sPymbed 16:048e5e270a58 6473 word32 order = 1000000000;
sPymbed 16:048e5e270a58 6474 word32 digit;
sPymbed 16:048e5e270a58 6475
sPymbed 16:048e5e270a58 6476 if (number == 0) {
sPymbed 16:048e5e270a58 6477 d[i++] = '0';
sPymbed 16:048e5e270a58 6478 }
sPymbed 16:048e5e270a58 6479 else {
sPymbed 16:048e5e270a58 6480 while (order) {
sPymbed 16:048e5e270a58 6481 digit = number / order;
sPymbed 16:048e5e270a58 6482 if (i > 0 || digit != 0) {
sPymbed 16:048e5e270a58 6483 d[i++] = (char)digit + '0';
sPymbed 16:048e5e270a58 6484 }
sPymbed 16:048e5e270a58 6485 if (digit != 0)
sPymbed 16:048e5e270a58 6486 number %= digit * order;
sPymbed 16:048e5e270a58 6487 if (order > 1)
sPymbed 16:048e5e270a58 6488 order /= 10;
sPymbed 16:048e5e270a58 6489 else
sPymbed 16:048e5e270a58 6490 order = 0;
sPymbed 16:048e5e270a58 6491 }
sPymbed 16:048e5e270a58 6492 }
sPymbed 16:048e5e270a58 6493 d[i] = 0;
sPymbed 16:048e5e270a58 6494 }
sPymbed 16:048e5e270a58 6495
sPymbed 16:048e5e270a58 6496 return i;
sPymbed 16:048e5e270a58 6497 }
sPymbed 16:048e5e270a58 6498
sPymbed 16:048e5e270a58 6499
sPymbed 16:048e5e270a58 6500 /* Decode ITU-T X.690 OID format to a string representation
sPymbed 16:048e5e270a58 6501 * return string length */
sPymbed 16:048e5e270a58 6502 int DecodePolicyOID(char *out, word32 outSz, byte *in, word32 inSz)
sPymbed 16:048e5e270a58 6503 {
sPymbed 16:048e5e270a58 6504 word32 val, idx = 0, nb_bytes;
sPymbed 16:048e5e270a58 6505 size_t w_bytes = 0;
sPymbed 16:048e5e270a58 6506
sPymbed 16:048e5e270a58 6507 if (out == NULL || in == NULL || outSz < 4 || inSz < 2)
sPymbed 16:048e5e270a58 6508 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 6509
sPymbed 16:048e5e270a58 6510 /* first two byte must be interpreted as : 40 * int1 + int2 */
sPymbed 16:048e5e270a58 6511 val = (word16)in[idx++];
sPymbed 16:048e5e270a58 6512
sPymbed 16:048e5e270a58 6513 w_bytes = Word32ToString(out, val / 40);
sPymbed 16:048e5e270a58 6514 out[w_bytes++] = '.';
sPymbed 16:048e5e270a58 6515 w_bytes += Word32ToString(out+w_bytes, val % 40);
sPymbed 16:048e5e270a58 6516
sPymbed 16:048e5e270a58 6517 while (idx < inSz) {
sPymbed 16:048e5e270a58 6518 /* init value */
sPymbed 16:048e5e270a58 6519 val = 0;
sPymbed 16:048e5e270a58 6520 nb_bytes = 0;
sPymbed 16:048e5e270a58 6521
sPymbed 16:048e5e270a58 6522 /* check that output size is ok */
sPymbed 16:048e5e270a58 6523 if (w_bytes > (outSz - 3))
sPymbed 16:048e5e270a58 6524 return BUFFER_E;
sPymbed 16:048e5e270a58 6525
sPymbed 16:048e5e270a58 6526 /* first bit is used to set if value is coded on 1 or multiple bytes */
sPymbed 16:048e5e270a58 6527 while ((in[idx+nb_bytes] & 0x80))
sPymbed 16:048e5e270a58 6528 nb_bytes++;
sPymbed 16:048e5e270a58 6529
sPymbed 16:048e5e270a58 6530 if (!nb_bytes)
sPymbed 16:048e5e270a58 6531 val = (word32)(in[idx++] & 0x7f);
sPymbed 16:048e5e270a58 6532 else {
sPymbed 16:048e5e270a58 6533 word32 base = 1, tmp = nb_bytes;
sPymbed 16:048e5e270a58 6534
sPymbed 16:048e5e270a58 6535 while (tmp != 0) {
sPymbed 16:048e5e270a58 6536 val += (word32)(in[idx+tmp] & 0x7f) * base;
sPymbed 16:048e5e270a58 6537 base *= 128;
sPymbed 16:048e5e270a58 6538 tmp--;
sPymbed 16:048e5e270a58 6539 }
sPymbed 16:048e5e270a58 6540 val += (word32)(in[idx++] & 0x7f) * base;
sPymbed 16:048e5e270a58 6541
sPymbed 16:048e5e270a58 6542 idx += nb_bytes;
sPymbed 16:048e5e270a58 6543 }
sPymbed 16:048e5e270a58 6544
sPymbed 16:048e5e270a58 6545 out[w_bytes++] = '.';
sPymbed 16:048e5e270a58 6546 w_bytes += Word32ToString(out+w_bytes, val);
sPymbed 16:048e5e270a58 6547 }
sPymbed 16:048e5e270a58 6548
sPymbed 16:048e5e270a58 6549 return (int)w_bytes;
sPymbed 16:048e5e270a58 6550 }
sPymbed 16:048e5e270a58 6551 #endif /* WOLFSSL_CERT_EXT && !WOLFSSL_SEP */
sPymbed 16:048e5e270a58 6552
sPymbed 16:048e5e270a58 6553 #if defined(WOLFSSL_SEP) || defined(WOLFSSL_CERT_EXT)
sPymbed 16:048e5e270a58 6554 /* Reference: https://tools.ietf.org/html/rfc5280#section-4.2.1.4 */
sPymbed 16:048e5e270a58 6555 static int DecodeCertPolicy(byte* input, int sz, DecodedCert* cert)
sPymbed 16:048e5e270a58 6556 {
sPymbed 16:048e5e270a58 6557 word32 idx = 0;
sPymbed 16:048e5e270a58 6558 word32 oldIdx;
sPymbed 16:048e5e270a58 6559 int ret;
sPymbed 16:048e5e270a58 6560 int total_length = 0, policy_length = 0, length = 0;
sPymbed 16:048e5e270a58 6561 #if !defined(WOLFSSL_SEP) && defined(WOLFSSL_CERT_EXT) && \
sPymbed 16:048e5e270a58 6562 !defined(WOLFSSL_DUP_CERTPOL)
sPymbed 16:048e5e270a58 6563 int i;
sPymbed 16:048e5e270a58 6564 #endif
sPymbed 16:048e5e270a58 6565
sPymbed 16:048e5e270a58 6566 WOLFSSL_ENTER("DecodeCertPolicy");
sPymbed 16:048e5e270a58 6567
sPymbed 16:048e5e270a58 6568 if (GetSequence(input, &idx, &total_length, sz) < 0) {
sPymbed 16:048e5e270a58 6569 WOLFSSL_MSG("\tGet CertPolicy total seq failed");
sPymbed 16:048e5e270a58 6570 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 6571 }
sPymbed 16:048e5e270a58 6572
sPymbed 16:048e5e270a58 6573 /* Validate total length */
sPymbed 16:048e5e270a58 6574 if (total_length > (sz - (int)idx)) {
sPymbed 16:048e5e270a58 6575 WOLFSSL_MSG("\tCertPolicy length mismatch");
sPymbed 16:048e5e270a58 6576 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 6577 }
sPymbed 16:048e5e270a58 6578
sPymbed 16:048e5e270a58 6579 /* Unwrap certificatePolicies */
sPymbed 16:048e5e270a58 6580 do {
sPymbed 16:048e5e270a58 6581 if (GetSequence(input, &idx, &policy_length, sz) < 0) {
sPymbed 16:048e5e270a58 6582 WOLFSSL_MSG("\tGet CertPolicy seq failed");
sPymbed 16:048e5e270a58 6583 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 6584 }
sPymbed 16:048e5e270a58 6585
sPymbed 16:048e5e270a58 6586 oldIdx = idx;
sPymbed 16:048e5e270a58 6587 ret = GetASNObjectId(input, &idx, &length, sz);
sPymbed 16:048e5e270a58 6588 if (ret != 0)
sPymbed 16:048e5e270a58 6589 return ret;
sPymbed 16:048e5e270a58 6590 policy_length -= idx - oldIdx;
sPymbed 16:048e5e270a58 6591
sPymbed 16:048e5e270a58 6592 if (length > 0) {
sPymbed 16:048e5e270a58 6593 /* Verify length won't overrun buffer */
sPymbed 16:048e5e270a58 6594 if (length > (sz - (int)idx)) {
sPymbed 16:048e5e270a58 6595 WOLFSSL_MSG("\tCertPolicy length exceeds input buffer");
sPymbed 16:048e5e270a58 6596 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 6597 }
sPymbed 16:048e5e270a58 6598
sPymbed 16:048e5e270a58 6599 #if defined(WOLFSSL_SEP)
sPymbed 16:048e5e270a58 6600 cert->deviceType = (byte*)XMALLOC(length, cert->heap,
sPymbed 16:048e5e270a58 6601 DYNAMIC_TYPE_X509_EXT);
sPymbed 16:048e5e270a58 6602 if (cert->deviceType == NULL) {
sPymbed 16:048e5e270a58 6603 WOLFSSL_MSG("\tCouldn't alloc memory for deviceType");
sPymbed 16:048e5e270a58 6604 return MEMORY_E;
sPymbed 16:048e5e270a58 6605 }
sPymbed 16:048e5e270a58 6606 cert->deviceTypeSz = length;
sPymbed 16:048e5e270a58 6607 XMEMCPY(cert->deviceType, input + idx, length);
sPymbed 16:048e5e270a58 6608 break;
sPymbed 16:048e5e270a58 6609 #elif defined(WOLFSSL_CERT_EXT)
sPymbed 16:048e5e270a58 6610 /* decode cert policy */
sPymbed 16:048e5e270a58 6611 if (DecodePolicyOID(cert->extCertPolicies[cert->extCertPoliciesNb], MAX_CERTPOL_SZ,
sPymbed 16:048e5e270a58 6612 input + idx, length) <= 0) {
sPymbed 16:048e5e270a58 6613 WOLFSSL_MSG("\tCouldn't decode CertPolicy");
sPymbed 16:048e5e270a58 6614 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 6615 }
sPymbed 16:048e5e270a58 6616 #ifndef WOLFSSL_DUP_CERTPOL
sPymbed 16:048e5e270a58 6617 /* From RFC 5280 section 4.2.1.3 "A certificate policy OID MUST
sPymbed 16:048e5e270a58 6618 * NOT appear more than once in a certificate policies
sPymbed 16:048e5e270a58 6619 * extension". This is a sanity check for duplicates.
sPymbed 16:048e5e270a58 6620 * extCertPolicies should only have OID values, additional
sPymbed 16:048e5e270a58 6621 * qualifiers need to be stored in a seperate array. */
sPymbed 16:048e5e270a58 6622 for (i = 0; i < cert->extCertPoliciesNb; i++) {
sPymbed 16:048e5e270a58 6623 if (XMEMCMP(cert->extCertPolicies[i],
sPymbed 16:048e5e270a58 6624 cert->extCertPolicies[cert->extCertPoliciesNb],
sPymbed 16:048e5e270a58 6625 MAX_CERTPOL_SZ) == 0) {
sPymbed 16:048e5e270a58 6626 WOLFSSL_MSG("Duplicate policy OIDs not allowed");
sPymbed 16:048e5e270a58 6627 WOLFSSL_MSG("Use WOLFSSL_DUP_CERTPOL if wanted");
sPymbed 16:048e5e270a58 6628 return CERTPOLICIES_E;
sPymbed 16:048e5e270a58 6629 }
sPymbed 16:048e5e270a58 6630 }
sPymbed 16:048e5e270a58 6631 #endif /* !WOLFSSL_DUP_CERTPOL */
sPymbed 16:048e5e270a58 6632 cert->extCertPoliciesNb++;
sPymbed 16:048e5e270a58 6633 #else
sPymbed 16:048e5e270a58 6634 WOLFSSL_LEAVE("DecodeCertPolicy : unsupported mode", 0);
sPymbed 16:048e5e270a58 6635 return 0;
sPymbed 16:048e5e270a58 6636 #endif
sPymbed 16:048e5e270a58 6637 }
sPymbed 16:048e5e270a58 6638 idx += policy_length;
sPymbed 16:048e5e270a58 6639 } while((int)idx < total_length
sPymbed 16:048e5e270a58 6640 #if defined(WOLFSSL_CERT_EXT)
sPymbed 16:048e5e270a58 6641 && cert->extCertPoliciesNb < MAX_CERTPOL_NB
sPymbed 16:048e5e270a58 6642 #endif
sPymbed 16:048e5e270a58 6643 );
sPymbed 16:048e5e270a58 6644
sPymbed 16:048e5e270a58 6645 WOLFSSL_LEAVE("DecodeCertPolicy", 0);
sPymbed 16:048e5e270a58 6646 return 0;
sPymbed 16:048e5e270a58 6647 }
sPymbed 16:048e5e270a58 6648 #endif /* WOLFSSL_SEP */
sPymbed 16:048e5e270a58 6649
sPymbed 16:048e5e270a58 6650 /* Macro to check if bit is set, if not sets and return success.
sPymbed 16:048e5e270a58 6651 Otherwise returns failure */
sPymbed 16:048e5e270a58 6652 /* Macro required here because bit-field operation */
sPymbed 16:048e5e270a58 6653 #ifndef WOLFSSL_NO_ASN_STRICT
sPymbed 16:048e5e270a58 6654 #define VERIFY_AND_SET_OID(bit) \
sPymbed 16:048e5e270a58 6655 if (bit == 0) \
sPymbed 16:048e5e270a58 6656 bit = 1; \
sPymbed 16:048e5e270a58 6657 else \
sPymbed 16:048e5e270a58 6658 return ASN_OBJECT_ID_E;
sPymbed 16:048e5e270a58 6659 #else
sPymbed 16:048e5e270a58 6660 /* With no strict defined, the verify is skipped */
sPymbed 16:048e5e270a58 6661 #define VERIFY_AND_SET_OID(bit) bit = 1;
sPymbed 16:048e5e270a58 6662 #endif
sPymbed 16:048e5e270a58 6663
sPymbed 16:048e5e270a58 6664 static int DecodeCertExtensions(DecodedCert* cert)
sPymbed 16:048e5e270a58 6665 /*
sPymbed 16:048e5e270a58 6666 * Processing the Certificate Extensions. This does not modify the current
sPymbed 16:048e5e270a58 6667 * index. It is works starting with the recorded extensions pointer.
sPymbed 16:048e5e270a58 6668 */
sPymbed 16:048e5e270a58 6669 {
sPymbed 16:048e5e270a58 6670 int ret = 0;
sPymbed 16:048e5e270a58 6671 word32 idx = 0;
sPymbed 16:048e5e270a58 6672 int sz = cert->extensionsSz;
sPymbed 16:048e5e270a58 6673 byte* input = cert->extensions;
sPymbed 16:048e5e270a58 6674 int length;
sPymbed 16:048e5e270a58 6675 word32 oid;
sPymbed 16:048e5e270a58 6676 byte critical = 0;
sPymbed 16:048e5e270a58 6677 byte criticalFail = 0;
sPymbed 16:048e5e270a58 6678
sPymbed 16:048e5e270a58 6679 WOLFSSL_ENTER("DecodeCertExtensions");
sPymbed 16:048e5e270a58 6680
sPymbed 16:048e5e270a58 6681 if (input == NULL || sz == 0)
sPymbed 16:048e5e270a58 6682 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 6683
sPymbed 16:048e5e270a58 6684 if (input[idx++] != ASN_EXTENSIONS) {
sPymbed 16:048e5e270a58 6685 WOLFSSL_MSG("\tfail: should be an EXTENSIONS");
sPymbed 16:048e5e270a58 6686 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 6687 }
sPymbed 16:048e5e270a58 6688
sPymbed 16:048e5e270a58 6689 if (GetLength(input, &idx, &length, sz) < 0) {
sPymbed 16:048e5e270a58 6690 WOLFSSL_MSG("\tfail: invalid length");
sPymbed 16:048e5e270a58 6691 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 6692 }
sPymbed 16:048e5e270a58 6693
sPymbed 16:048e5e270a58 6694 if (GetSequence(input, &idx, &length, sz) < 0) {
sPymbed 16:048e5e270a58 6695 WOLFSSL_MSG("\tfail: should be a SEQUENCE (1)");
sPymbed 16:048e5e270a58 6696 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 6697 }
sPymbed 16:048e5e270a58 6698
sPymbed 16:048e5e270a58 6699 while (idx < (word32)sz) {
sPymbed 16:048e5e270a58 6700 if (GetSequence(input, &idx, &length, sz) < 0) {
sPymbed 16:048e5e270a58 6701 WOLFSSL_MSG("\tfail: should be a SEQUENCE");
sPymbed 16:048e5e270a58 6702 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 6703 }
sPymbed 16:048e5e270a58 6704
sPymbed 16:048e5e270a58 6705 oid = 0;
sPymbed 16:048e5e270a58 6706 if ((ret = GetObjectId(input, &idx, &oid, oidCertExtType, sz)) < 0) {
sPymbed 16:048e5e270a58 6707 WOLFSSL_MSG("\tfail: OBJECT ID");
sPymbed 16:048e5e270a58 6708 return ret;
sPymbed 16:048e5e270a58 6709 }
sPymbed 16:048e5e270a58 6710
sPymbed 16:048e5e270a58 6711 /* check for critical flag */
sPymbed 16:048e5e270a58 6712 critical = 0;
sPymbed 16:048e5e270a58 6713 if (input[idx] == ASN_BOOLEAN) {
sPymbed 16:048e5e270a58 6714 ret = GetBoolean(input, &idx, sz);
sPymbed 16:048e5e270a58 6715 if (ret < 0) {
sPymbed 16:048e5e270a58 6716 WOLFSSL_MSG("\tfail: critical boolean");
sPymbed 16:048e5e270a58 6717 return ret;
sPymbed 16:048e5e270a58 6718 }
sPymbed 16:048e5e270a58 6719
sPymbed 16:048e5e270a58 6720 critical = (byte)ret;
sPymbed 16:048e5e270a58 6721 }
sPymbed 16:048e5e270a58 6722
sPymbed 16:048e5e270a58 6723 /* process the extension based on the OID */
sPymbed 16:048e5e270a58 6724 ret = GetOctetString(input, &idx, &length, sz);
sPymbed 16:048e5e270a58 6725 if (ret < 0) {
sPymbed 16:048e5e270a58 6726 WOLFSSL_MSG("\tfail: bad OCTET STRING");
sPymbed 16:048e5e270a58 6727 return ret;
sPymbed 16:048e5e270a58 6728 }
sPymbed 16:048e5e270a58 6729
sPymbed 16:048e5e270a58 6730 switch (oid) {
sPymbed 16:048e5e270a58 6731 case BASIC_CA_OID:
sPymbed 16:048e5e270a58 6732 VERIFY_AND_SET_OID(cert->extBasicConstSet);
sPymbed 16:048e5e270a58 6733 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
sPymbed 16:048e5e270a58 6734 cert->extBasicConstCrit = critical;
sPymbed 16:048e5e270a58 6735 #endif
sPymbed 16:048e5e270a58 6736 if (DecodeBasicCaConstraint(&input[idx], length, cert) < 0)
sPymbed 16:048e5e270a58 6737 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 6738 break;
sPymbed 16:048e5e270a58 6739
sPymbed 16:048e5e270a58 6740 case CRL_DIST_OID:
sPymbed 16:048e5e270a58 6741 VERIFY_AND_SET_OID(cert->extCRLdistSet);
sPymbed 16:048e5e270a58 6742 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
sPymbed 16:048e5e270a58 6743 cert->extCRLdistCrit = critical;
sPymbed 16:048e5e270a58 6744 #endif
sPymbed 16:048e5e270a58 6745 if (DecodeCrlDist(&input[idx], length, cert) < 0)
sPymbed 16:048e5e270a58 6746 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 6747 break;
sPymbed 16:048e5e270a58 6748
sPymbed 16:048e5e270a58 6749 case AUTH_INFO_OID:
sPymbed 16:048e5e270a58 6750 VERIFY_AND_SET_OID(cert->extAuthInfoSet);
sPymbed 16:048e5e270a58 6751 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
sPymbed 16:048e5e270a58 6752 cert->extAuthInfoCrit = critical;
sPymbed 16:048e5e270a58 6753 #endif
sPymbed 16:048e5e270a58 6754 if (DecodeAuthInfo(&input[idx], length, cert) < 0)
sPymbed 16:048e5e270a58 6755 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 6756 break;
sPymbed 16:048e5e270a58 6757
sPymbed 16:048e5e270a58 6758 case ALT_NAMES_OID:
sPymbed 16:048e5e270a58 6759 VERIFY_AND_SET_OID(cert->extSubjAltNameSet);
sPymbed 16:048e5e270a58 6760 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
sPymbed 16:048e5e270a58 6761 cert->extSubjAltNameCrit = critical;
sPymbed 16:048e5e270a58 6762 #endif
sPymbed 16:048e5e270a58 6763 ret = DecodeAltNames(&input[idx], length, cert);
sPymbed 16:048e5e270a58 6764 if (ret < 0)
sPymbed 16:048e5e270a58 6765 return ret;
sPymbed 16:048e5e270a58 6766 break;
sPymbed 16:048e5e270a58 6767
sPymbed 16:048e5e270a58 6768 case AUTH_KEY_OID:
sPymbed 16:048e5e270a58 6769 VERIFY_AND_SET_OID(cert->extAuthKeyIdSet);
sPymbed 16:048e5e270a58 6770 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
sPymbed 16:048e5e270a58 6771 cert->extAuthKeyIdCrit = critical;
sPymbed 16:048e5e270a58 6772 #endif
sPymbed 16:048e5e270a58 6773 #ifndef WOLFSSL_ALLOW_CRIT_SKID
sPymbed 16:048e5e270a58 6774 /* This check is added due to RFC 5280 section 4.2.1.1
sPymbed 16:048e5e270a58 6775 * stating that conforming CA's must mark this extension
sPymbed 16:048e5e270a58 6776 * as non-critical. When parsing extensions check that
sPymbed 16:048e5e270a58 6777 * certificate was made in compliance with this. */
sPymbed 16:048e5e270a58 6778 if (critical) {
sPymbed 16:048e5e270a58 6779 WOLFSSL_MSG("Critical Auth Key ID is not allowed");
sPymbed 16:048e5e270a58 6780 WOLFSSL_MSG("Use macro WOLFSSL_ALLOW_CRIT_SKID if wanted");
sPymbed 16:048e5e270a58 6781 return ASN_CRIT_EXT_E;
sPymbed 16:048e5e270a58 6782 }
sPymbed 16:048e5e270a58 6783 #endif
sPymbed 16:048e5e270a58 6784 if (DecodeAuthKeyId(&input[idx], length, cert) < 0)
sPymbed 16:048e5e270a58 6785 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 6786 break;
sPymbed 16:048e5e270a58 6787
sPymbed 16:048e5e270a58 6788 case SUBJ_KEY_OID:
sPymbed 16:048e5e270a58 6789 VERIFY_AND_SET_OID(cert->extSubjKeyIdSet);
sPymbed 16:048e5e270a58 6790 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
sPymbed 16:048e5e270a58 6791 cert->extSubjKeyIdCrit = critical;
sPymbed 16:048e5e270a58 6792 #endif
sPymbed 16:048e5e270a58 6793 #ifndef WOLFSSL_ALLOW_CRIT_SKID
sPymbed 16:048e5e270a58 6794 /* This check is added due to RFC 5280 section 4.2.1.2
sPymbed 16:048e5e270a58 6795 * stating that conforming CA's must mark this extension
sPymbed 16:048e5e270a58 6796 * as non-critical. When parsing extensions check that
sPymbed 16:048e5e270a58 6797 * certificate was made in compliance with this. */
sPymbed 16:048e5e270a58 6798 if (critical) {
sPymbed 16:048e5e270a58 6799 WOLFSSL_MSG("Critical Subject Key ID is not allowed");
sPymbed 16:048e5e270a58 6800 WOLFSSL_MSG("Use macro WOLFSSL_ALLOW_CRIT_SKID if wanted");
sPymbed 16:048e5e270a58 6801 return ASN_CRIT_EXT_E;
sPymbed 16:048e5e270a58 6802 }
sPymbed 16:048e5e270a58 6803 #endif
sPymbed 16:048e5e270a58 6804
sPymbed 16:048e5e270a58 6805 if (DecodeSubjKeyId(&input[idx], length, cert) < 0)
sPymbed 16:048e5e270a58 6806 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 6807 break;
sPymbed 16:048e5e270a58 6808
sPymbed 16:048e5e270a58 6809 case CERT_POLICY_OID:
sPymbed 16:048e5e270a58 6810 #ifdef WOLFSSL_SEP
sPymbed 16:048e5e270a58 6811 VERIFY_AND_SET_OID(cert->extCertPolicySet);
sPymbed 16:048e5e270a58 6812 #if defined(OPENSSL_EXTRA) || \
sPymbed 16:048e5e270a58 6813 defined(OPENSSL_EXTRA_X509_SMALL)
sPymbed 16:048e5e270a58 6814 cert->extCertPolicyCrit = critical;
sPymbed 16:048e5e270a58 6815 #endif
sPymbed 16:048e5e270a58 6816 #endif
sPymbed 16:048e5e270a58 6817 #if defined(WOLFSSL_SEP) || defined(WOLFSSL_CERT_EXT)
sPymbed 16:048e5e270a58 6818 if (DecodeCertPolicy(&input[idx], length, cert) < 0) {
sPymbed 16:048e5e270a58 6819 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 6820 }
sPymbed 16:048e5e270a58 6821 #else
sPymbed 16:048e5e270a58 6822 WOLFSSL_MSG("Certificate Policy extension not supported yet.");
sPymbed 16:048e5e270a58 6823 #endif
sPymbed 16:048e5e270a58 6824 break;
sPymbed 16:048e5e270a58 6825
sPymbed 16:048e5e270a58 6826 case KEY_USAGE_OID:
sPymbed 16:048e5e270a58 6827 VERIFY_AND_SET_OID(cert->extKeyUsageSet);
sPymbed 16:048e5e270a58 6828 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
sPymbed 16:048e5e270a58 6829 cert->extKeyUsageCrit = critical;
sPymbed 16:048e5e270a58 6830 #endif
sPymbed 16:048e5e270a58 6831 if (DecodeKeyUsage(&input[idx], length, cert) < 0)
sPymbed 16:048e5e270a58 6832 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 6833 break;
sPymbed 16:048e5e270a58 6834
sPymbed 16:048e5e270a58 6835 case EXT_KEY_USAGE_OID:
sPymbed 16:048e5e270a58 6836 VERIFY_AND_SET_OID(cert->extExtKeyUsageSet);
sPymbed 16:048e5e270a58 6837 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
sPymbed 16:048e5e270a58 6838 cert->extExtKeyUsageCrit = critical;
sPymbed 16:048e5e270a58 6839 #endif
sPymbed 16:048e5e270a58 6840 if (DecodeExtKeyUsage(&input[idx], length, cert) < 0)
sPymbed 16:048e5e270a58 6841 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 6842 break;
sPymbed 16:048e5e270a58 6843
sPymbed 16:048e5e270a58 6844 #ifndef IGNORE_NAME_CONSTRAINTS
sPymbed 16:048e5e270a58 6845 case NAME_CONS_OID:
sPymbed 16:048e5e270a58 6846 #ifndef WOLFSSL_NO_ASN_STRICT
sPymbed 16:048e5e270a58 6847 /* Verify RFC 5280 Sec 4.2.1.10 rule:
sPymbed 16:048e5e270a58 6848 "The name constraints extension,
sPymbed 16:048e5e270a58 6849 which MUST be used only in a CA certificate" */
sPymbed 16:048e5e270a58 6850 if (!cert->isCA) {
sPymbed 16:048e5e270a58 6851 WOLFSSL_MSG("Name constraints allowed only for CA certs");
sPymbed 16:048e5e270a58 6852 return ASN_NAME_INVALID_E;
sPymbed 16:048e5e270a58 6853 }
sPymbed 16:048e5e270a58 6854 #endif
sPymbed 16:048e5e270a58 6855 VERIFY_AND_SET_OID(cert->extNameConstraintSet);
sPymbed 16:048e5e270a58 6856 #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
sPymbed 16:048e5e270a58 6857 cert->extNameConstraintCrit = critical;
sPymbed 16:048e5e270a58 6858 #endif
sPymbed 16:048e5e270a58 6859 if (DecodeNameConstraints(&input[idx], length, cert) < 0)
sPymbed 16:048e5e270a58 6860 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 6861 break;
sPymbed 16:048e5e270a58 6862 #endif /* IGNORE_NAME_CONSTRAINTS */
sPymbed 16:048e5e270a58 6863
sPymbed 16:048e5e270a58 6864 case INHIBIT_ANY_OID:
sPymbed 16:048e5e270a58 6865 VERIFY_AND_SET_OID(cert->inhibitAnyOidSet);
sPymbed 16:048e5e270a58 6866 WOLFSSL_MSG("Inhibit anyPolicy extension not supported yet.");
sPymbed 16:048e5e270a58 6867 break;
sPymbed 16:048e5e270a58 6868
sPymbed 16:048e5e270a58 6869 default:
sPymbed 16:048e5e270a58 6870 /* While it is a failure to not support critical extensions,
sPymbed 16:048e5e270a58 6871 * still parse the certificate ignoring the unsupported
sPymbed 16:048e5e270a58 6872 * extension to allow caller to accept it with the verify
sPymbed 16:048e5e270a58 6873 * callback. */
sPymbed 16:048e5e270a58 6874 if (critical)
sPymbed 16:048e5e270a58 6875 criticalFail = 1;
sPymbed 16:048e5e270a58 6876 break;
sPymbed 16:048e5e270a58 6877 }
sPymbed 16:048e5e270a58 6878 idx += length;
sPymbed 16:048e5e270a58 6879 }
sPymbed 16:048e5e270a58 6880
sPymbed 16:048e5e270a58 6881 return criticalFail ? ASN_CRIT_EXT_E : 0;
sPymbed 16:048e5e270a58 6882 }
sPymbed 16:048e5e270a58 6883
sPymbed 16:048e5e270a58 6884 int ParseCert(DecodedCert* cert, int type, int verify, void* cm)
sPymbed 16:048e5e270a58 6885 {
sPymbed 16:048e5e270a58 6886 int ret;
sPymbed 16:048e5e270a58 6887 char* ptr;
sPymbed 16:048e5e270a58 6888
sPymbed 16:048e5e270a58 6889 ret = ParseCertRelative(cert, type, verify, cm);
sPymbed 16:048e5e270a58 6890 if (ret < 0)
sPymbed 16:048e5e270a58 6891 return ret;
sPymbed 16:048e5e270a58 6892
sPymbed 16:048e5e270a58 6893 if (cert->subjectCNLen > 0) {
sPymbed 16:048e5e270a58 6894 ptr = (char*) XMALLOC(cert->subjectCNLen + 1, cert->heap,
sPymbed 16:048e5e270a58 6895 DYNAMIC_TYPE_SUBJECT_CN);
sPymbed 16:048e5e270a58 6896 if (ptr == NULL)
sPymbed 16:048e5e270a58 6897 return MEMORY_E;
sPymbed 16:048e5e270a58 6898 XMEMCPY(ptr, cert->subjectCN, cert->subjectCNLen);
sPymbed 16:048e5e270a58 6899 ptr[cert->subjectCNLen] = '\0';
sPymbed 16:048e5e270a58 6900 cert->subjectCN = ptr;
sPymbed 16:048e5e270a58 6901 cert->subjectCNStored = 1;
sPymbed 16:048e5e270a58 6902 }
sPymbed 16:048e5e270a58 6903
sPymbed 16:048e5e270a58 6904 if (cert->keyOID == RSAk &&
sPymbed 16:048e5e270a58 6905 cert->publicKey != NULL && cert->pubKeySize > 0) {
sPymbed 16:048e5e270a58 6906 ptr = (char*) XMALLOC(cert->pubKeySize, cert->heap,
sPymbed 16:048e5e270a58 6907 DYNAMIC_TYPE_PUBLIC_KEY);
sPymbed 16:048e5e270a58 6908 if (ptr == NULL)
sPymbed 16:048e5e270a58 6909 return MEMORY_E;
sPymbed 16:048e5e270a58 6910 XMEMCPY(ptr, cert->publicKey, cert->pubKeySize);
sPymbed 16:048e5e270a58 6911 cert->publicKey = (byte *)ptr;
sPymbed 16:048e5e270a58 6912 cert->pubKeyStored = 1;
sPymbed 16:048e5e270a58 6913 }
sPymbed 16:048e5e270a58 6914
sPymbed 16:048e5e270a58 6915 return ret;
sPymbed 16:048e5e270a58 6916 }
sPymbed 16:048e5e270a58 6917
sPymbed 16:048e5e270a58 6918 /* from SSL proper, for locking can't do find here anymore */
sPymbed 16:048e5e270a58 6919 #ifdef __cplusplus
sPymbed 16:048e5e270a58 6920 extern "C" {
sPymbed 16:048e5e270a58 6921 #endif
sPymbed 16:048e5e270a58 6922 WOLFSSL_LOCAL Signer* GetCA(void* signers, byte* hash);
sPymbed 16:048e5e270a58 6923 #ifndef NO_SKID
sPymbed 16:048e5e270a58 6924 WOLFSSL_LOCAL Signer* GetCAByName(void* signers, byte* hash);
sPymbed 16:048e5e270a58 6925 #endif
sPymbed 16:048e5e270a58 6926 #ifdef __cplusplus
sPymbed 16:048e5e270a58 6927 }
sPymbed 16:048e5e270a58 6928 #endif
sPymbed 16:048e5e270a58 6929
sPymbed 16:048e5e270a58 6930
sPymbed 16:048e5e270a58 6931 #if defined(WOLFCRYPT_ONLY) || defined(NO_CERTS)
sPymbed 16:048e5e270a58 6932
sPymbed 16:048e5e270a58 6933 /* dummy functions, not using wolfSSL so don't need actual ones */
sPymbed 16:048e5e270a58 6934 Signer* GetCA(void* signers, byte* hash)
sPymbed 16:048e5e270a58 6935 {
sPymbed 16:048e5e270a58 6936 (void)hash;
sPymbed 16:048e5e270a58 6937
sPymbed 16:048e5e270a58 6938 return (Signer*)signers;
sPymbed 16:048e5e270a58 6939 }
sPymbed 16:048e5e270a58 6940
sPymbed 16:048e5e270a58 6941 #ifndef NO_SKID
sPymbed 16:048e5e270a58 6942 Signer* GetCAByName(void* signers, byte* hash)
sPymbed 16:048e5e270a58 6943 {
sPymbed 16:048e5e270a58 6944 (void)hash;
sPymbed 16:048e5e270a58 6945
sPymbed 16:048e5e270a58 6946 return (Signer*)signers;
sPymbed 16:048e5e270a58 6947 }
sPymbed 16:048e5e270a58 6948 #endif /* NO_SKID */
sPymbed 16:048e5e270a58 6949
sPymbed 16:048e5e270a58 6950 #endif /* WOLFCRYPT_ONLY || NO_CERTS */
sPymbed 16:048e5e270a58 6951
sPymbed 16:048e5e270a58 6952 #if (defined(WOLFSSL_ALT_CERT_CHAINS) || \
sPymbed 16:048e5e270a58 6953 defined(WOLFSSL_NO_TRUSTED_CERTS_VERIFY)) && !defined(NO_SKID)
sPymbed 16:048e5e270a58 6954 static Signer* GetCABySubjectAndPubKey(DecodedCert* cert, void* cm)
sPymbed 16:048e5e270a58 6955 {
sPymbed 16:048e5e270a58 6956 Signer* ca = NULL;
sPymbed 16:048e5e270a58 6957 if (cert->extSubjKeyIdSet)
sPymbed 16:048e5e270a58 6958 ca = GetCA(cm, cert->extSubjKeyId);
sPymbed 16:048e5e270a58 6959 if (ca == NULL)
sPymbed 16:048e5e270a58 6960 ca = GetCAByName(cm, cert->subjectHash);
sPymbed 16:048e5e270a58 6961 if (ca) {
sPymbed 16:048e5e270a58 6962 if ((ca->pubKeySize == cert->pubKeySize) &&
sPymbed 16:048e5e270a58 6963 (XMEMCMP(ca->publicKey, cert->publicKey, ca->pubKeySize) == 0)) {
sPymbed 16:048e5e270a58 6964 return ca;
sPymbed 16:048e5e270a58 6965 }
sPymbed 16:048e5e270a58 6966 }
sPymbed 16:048e5e270a58 6967 return NULL;
sPymbed 16:048e5e270a58 6968 }
sPymbed 16:048e5e270a58 6969 #endif
sPymbed 16:048e5e270a58 6970
sPymbed 16:048e5e270a58 6971 int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm)
sPymbed 16:048e5e270a58 6972 {
sPymbed 16:048e5e270a58 6973 int ret = 0;
sPymbed 16:048e5e270a58 6974 int badDate = 0;
sPymbed 16:048e5e270a58 6975 int criticalExt = 0;
sPymbed 16:048e5e270a58 6976 word32 confirmOID;
sPymbed 16:048e5e270a58 6977 int selfSigned = 0;
sPymbed 16:048e5e270a58 6978
sPymbed 16:048e5e270a58 6979 if (cert == NULL) {
sPymbed 16:048e5e270a58 6980 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 6981 }
sPymbed 16:048e5e270a58 6982
sPymbed 16:048e5e270a58 6983 if (cert->sigCtx.state == SIG_STATE_BEGIN) {
sPymbed 16:048e5e270a58 6984 if ((ret = DecodeToKey(cert, verify)) < 0) {
sPymbed 16:048e5e270a58 6985 if (ret == ASN_BEFORE_DATE_E || ret == ASN_AFTER_DATE_E)
sPymbed 16:048e5e270a58 6986 badDate = ret;
sPymbed 16:048e5e270a58 6987 else
sPymbed 16:048e5e270a58 6988 return ret;
sPymbed 16:048e5e270a58 6989 }
sPymbed 16:048e5e270a58 6990
sPymbed 16:048e5e270a58 6991 WOLFSSL_MSG("Parsed Past Key");
sPymbed 16:048e5e270a58 6992
sPymbed 16:048e5e270a58 6993 if (cert->srcIdx < cert->sigIndex) {
sPymbed 16:048e5e270a58 6994 #ifndef ALLOW_V1_EXTENSIONS
sPymbed 16:048e5e270a58 6995 if (cert->version < 2) {
sPymbed 16:048e5e270a58 6996 WOLFSSL_MSG("\tv1 and v2 certs not allowed extensions");
sPymbed 16:048e5e270a58 6997 return ASN_VERSION_E;
sPymbed 16:048e5e270a58 6998 }
sPymbed 16:048e5e270a58 6999 #endif
sPymbed 16:048e5e270a58 7000
sPymbed 16:048e5e270a58 7001 /* save extensions */
sPymbed 16:048e5e270a58 7002 cert->extensions = &cert->source[cert->srcIdx];
sPymbed 16:048e5e270a58 7003 cert->extensionsSz = cert->sigIndex - cert->srcIdx;
sPymbed 16:048e5e270a58 7004 cert->extensionsIdx = cert->srcIdx; /* for potential later use */
sPymbed 16:048e5e270a58 7005
sPymbed 16:048e5e270a58 7006 if ((ret = DecodeCertExtensions(cert)) < 0) {
sPymbed 16:048e5e270a58 7007 if (ret == ASN_CRIT_EXT_E)
sPymbed 16:048e5e270a58 7008 criticalExt = ret;
sPymbed 16:048e5e270a58 7009 else
sPymbed 16:048e5e270a58 7010 return ret;
sPymbed 16:048e5e270a58 7011 }
sPymbed 16:048e5e270a58 7012
sPymbed 16:048e5e270a58 7013 /* advance past extensions */
sPymbed 16:048e5e270a58 7014 cert->srcIdx = cert->sigIndex;
sPymbed 16:048e5e270a58 7015 }
sPymbed 16:048e5e270a58 7016
sPymbed 16:048e5e270a58 7017 if ((ret = GetAlgoId(cert->source, &cert->srcIdx, &confirmOID,
sPymbed 16:048e5e270a58 7018 oidSigType, cert->maxIdx)) < 0)
sPymbed 16:048e5e270a58 7019 return ret;
sPymbed 16:048e5e270a58 7020
sPymbed 16:048e5e270a58 7021 if ((ret = GetSignature(cert)) < 0)
sPymbed 16:048e5e270a58 7022 return ret;
sPymbed 16:048e5e270a58 7023
sPymbed 16:048e5e270a58 7024 if (confirmOID != cert->signatureOID)
sPymbed 16:048e5e270a58 7025 return ASN_SIG_OID_E;
sPymbed 16:048e5e270a58 7026
sPymbed 16:048e5e270a58 7027 #ifndef NO_SKID
sPymbed 16:048e5e270a58 7028 if (cert->extSubjKeyIdSet == 0 && cert->publicKey != NULL &&
sPymbed 16:048e5e270a58 7029 cert->pubKeySize > 0) {
sPymbed 16:048e5e270a58 7030 #ifdef NO_SHA
sPymbed 16:048e5e270a58 7031 ret = wc_Sha256Hash(cert->publicKey, cert->pubKeySize,
sPymbed 16:048e5e270a58 7032 cert->extSubjKeyId);
sPymbed 16:048e5e270a58 7033 #else
sPymbed 16:048e5e270a58 7034 ret = wc_ShaHash(cert->publicKey, cert->pubKeySize,
sPymbed 16:048e5e270a58 7035 cert->extSubjKeyId);
sPymbed 16:048e5e270a58 7036 #endif /* NO_SHA */
sPymbed 16:048e5e270a58 7037 if (ret != 0)
sPymbed 16:048e5e270a58 7038 return ret;
sPymbed 16:048e5e270a58 7039 }
sPymbed 16:048e5e270a58 7040 #endif /* !NO_SKID */
sPymbed 16:048e5e270a58 7041
sPymbed 16:048e5e270a58 7042 if (verify != NO_VERIFY && type != CA_TYPE && type != TRUSTED_PEER_TYPE) {
sPymbed 16:048e5e270a58 7043 cert->ca = NULL;
sPymbed 16:048e5e270a58 7044 #ifndef NO_SKID
sPymbed 16:048e5e270a58 7045 if (cert->extAuthKeyIdSet)
sPymbed 16:048e5e270a58 7046 cert->ca = GetCA(cm, cert->extAuthKeyId);
sPymbed 16:048e5e270a58 7047 if (cert->ca == NULL)
sPymbed 16:048e5e270a58 7048 cert->ca = GetCAByName(cm, cert->issuerHash);
sPymbed 16:048e5e270a58 7049
sPymbed 16:048e5e270a58 7050 /* OCSP Only: alt lookup using subject and pub key w/o sig check */
sPymbed 16:048e5e270a58 7051 #ifdef WOLFSSL_NO_TRUSTED_CERTS_VERIFY
sPymbed 16:048e5e270a58 7052 if (cert->ca == NULL && verify == VERIFY_OCSP) {
sPymbed 16:048e5e270a58 7053 cert->ca = GetCABySubjectAndPubKey(cert, cm);
sPymbed 16:048e5e270a58 7054 if (cert->ca) {
sPymbed 16:048e5e270a58 7055 ret = 0; /* success */
sPymbed 16:048e5e270a58 7056 goto exit_pcr;
sPymbed 16:048e5e270a58 7057 }
sPymbed 16:048e5e270a58 7058 }
sPymbed 16:048e5e270a58 7059 #endif /* WOLFSSL_NO_TRUSTED_CERTS_VERIFY */
sPymbed 16:048e5e270a58 7060
sPymbed 16:048e5e270a58 7061 /* alt lookup using subject and public key */
sPymbed 16:048e5e270a58 7062 #ifdef WOLFSSL_ALT_CERT_CHAINS
sPymbed 16:048e5e270a58 7063 if (cert->ca == NULL)
sPymbed 16:048e5e270a58 7064 cert->ca = GetCABySubjectAndPubKey(cert, cm);
sPymbed 16:048e5e270a58 7065 #endif
sPymbed 16:048e5e270a58 7066 #else
sPymbed 16:048e5e270a58 7067 cert->ca = GetCA(cm, cert->issuerHash);
sPymbed 16:048e5e270a58 7068 if (XMEMCMP(cert->issuerHash, cert->subjectHash, KEYID_SIZE) == 0)
sPymbed 16:048e5e270a58 7069 selfSigned = 1;
sPymbed 16:048e5e270a58 7070 #endif /* !NO_SKID */
sPymbed 16:048e5e270a58 7071
sPymbed 16:048e5e270a58 7072 WOLFSSL_MSG("About to verify certificate signature");
sPymbed 16:048e5e270a58 7073 if (cert->ca) {
sPymbed 16:048e5e270a58 7074 if (cert->isCA && cert->ca->pathLengthSet) {
sPymbed 16:048e5e270a58 7075 if (selfSigned) {
sPymbed 16:048e5e270a58 7076 if (cert->ca->pathLength != 0) {
sPymbed 16:048e5e270a58 7077 WOLFSSL_MSG("Root CA with path length > 0");
sPymbed 16:048e5e270a58 7078 return ASN_PATHLEN_INV_E;
sPymbed 16:048e5e270a58 7079 }
sPymbed 16:048e5e270a58 7080 }
sPymbed 16:048e5e270a58 7081 else {
sPymbed 16:048e5e270a58 7082 if (cert->ca->pathLength == 0) {
sPymbed 16:048e5e270a58 7083 WOLFSSL_MSG("CA with path length 0 signing a CA");
sPymbed 16:048e5e270a58 7084 return ASN_PATHLEN_INV_E;
sPymbed 16:048e5e270a58 7085 }
sPymbed 16:048e5e270a58 7086 else if (cert->pathLength >= cert->ca->pathLength) {
sPymbed 16:048e5e270a58 7087
sPymbed 16:048e5e270a58 7088 WOLFSSL_MSG("CA signing CA with longer path length");
sPymbed 16:048e5e270a58 7089 return ASN_PATHLEN_INV_E;
sPymbed 16:048e5e270a58 7090 }
sPymbed 16:048e5e270a58 7091 }
sPymbed 16:048e5e270a58 7092 }
sPymbed 16:048e5e270a58 7093
sPymbed 16:048e5e270a58 7094 #ifdef HAVE_OCSP
sPymbed 16:048e5e270a58 7095 /* Need the CA's public key hash for OCSP */
sPymbed 16:048e5e270a58 7096 #ifdef NO_SHA
sPymbed 16:048e5e270a58 7097 ret = wc_Sha256Hash(cert->ca->publicKey, cert->ca->pubKeySize,
sPymbed 16:048e5e270a58 7098 cert->issuerKeyHash);
sPymbed 16:048e5e270a58 7099 #else
sPymbed 16:048e5e270a58 7100 ret = wc_ShaHash(cert->ca->publicKey, cert->ca->pubKeySize,
sPymbed 16:048e5e270a58 7101 cert->issuerKeyHash);
sPymbed 16:048e5e270a58 7102 #endif /* NO_SHA */
sPymbed 16:048e5e270a58 7103 if (ret != 0)
sPymbed 16:048e5e270a58 7104 return ret;
sPymbed 16:048e5e270a58 7105 #endif /* HAVE_OCSP */
sPymbed 16:048e5e270a58 7106 }
sPymbed 16:048e5e270a58 7107 }
sPymbed 16:048e5e270a58 7108 }
sPymbed 16:048e5e270a58 7109
sPymbed 16:048e5e270a58 7110 if (verify != NO_VERIFY && type != CA_TYPE && type != TRUSTED_PEER_TYPE) {
sPymbed 16:048e5e270a58 7111 if (cert->ca) {
sPymbed 16:048e5e270a58 7112 if (verify == VERIFY || verify == VERIFY_OCSP) {
sPymbed 16:048e5e270a58 7113 /* try to confirm/verify signature */
sPymbed 16:048e5e270a58 7114 if ((ret = ConfirmSignature(&cert->sigCtx,
sPymbed 16:048e5e270a58 7115 cert->source + cert->certBegin,
sPymbed 16:048e5e270a58 7116 cert->sigIndex - cert->certBegin,
sPymbed 16:048e5e270a58 7117 cert->ca->publicKey, cert->ca->pubKeySize,
sPymbed 16:048e5e270a58 7118 cert->ca->keyOID, cert->signature,
sPymbed 16:048e5e270a58 7119 cert->sigLength, cert->signatureOID)) != 0) {
sPymbed 16:048e5e270a58 7120 if (ret != WC_PENDING_E) {
sPymbed 16:048e5e270a58 7121 WOLFSSL_MSG("Confirm signature failed");
sPymbed 16:048e5e270a58 7122 }
sPymbed 16:048e5e270a58 7123 return ret;
sPymbed 16:048e5e270a58 7124 }
sPymbed 16:048e5e270a58 7125 #ifndef IGNORE_NAME_CONSTRAINTS
sPymbed 16:048e5e270a58 7126 /* check that this cert's name is permitted by the signer's
sPymbed 16:048e5e270a58 7127 * name constraints */
sPymbed 16:048e5e270a58 7128 if (!ConfirmNameConstraints(cert->ca, cert)) {
sPymbed 16:048e5e270a58 7129 WOLFSSL_MSG("Confirm name constraint failed");
sPymbed 16:048e5e270a58 7130 return ASN_NAME_INVALID_E;
sPymbed 16:048e5e270a58 7131 }
sPymbed 16:048e5e270a58 7132 #endif /* IGNORE_NAME_CONSTRAINTS */
sPymbed 16:048e5e270a58 7133 }
sPymbed 16:048e5e270a58 7134 }
sPymbed 16:048e5e270a58 7135 else {
sPymbed 16:048e5e270a58 7136 /* no signer */
sPymbed 16:048e5e270a58 7137 WOLFSSL_MSG("No CA signer to verify with");
sPymbed 16:048e5e270a58 7138 return ASN_NO_SIGNER_E;
sPymbed 16:048e5e270a58 7139 }
sPymbed 16:048e5e270a58 7140 }
sPymbed 16:048e5e270a58 7141
sPymbed 16:048e5e270a58 7142 #if defined(WOLFSSL_NO_TRUSTED_CERTS_VERIFY) && !defined(NO_SKID)
sPymbed 16:048e5e270a58 7143 exit_pcr:
sPymbed 16:048e5e270a58 7144 #endif
sPymbed 16:048e5e270a58 7145
sPymbed 16:048e5e270a58 7146 if (badDate != 0)
sPymbed 16:048e5e270a58 7147 return badDate;
sPymbed 16:048e5e270a58 7148
sPymbed 16:048e5e270a58 7149 if (criticalExt != 0)
sPymbed 16:048e5e270a58 7150 return criticalExt;
sPymbed 16:048e5e270a58 7151
sPymbed 16:048e5e270a58 7152 return ret;
sPymbed 16:048e5e270a58 7153 }
sPymbed 16:048e5e270a58 7154
sPymbed 16:048e5e270a58 7155 /* Create and init an new signer */
sPymbed 16:048e5e270a58 7156 Signer* MakeSigner(void* heap)
sPymbed 16:048e5e270a58 7157 {
sPymbed 16:048e5e270a58 7158 Signer* signer = (Signer*) XMALLOC(sizeof(Signer), heap,
sPymbed 16:048e5e270a58 7159 DYNAMIC_TYPE_SIGNER);
sPymbed 16:048e5e270a58 7160 if (signer) {
sPymbed 16:048e5e270a58 7161 signer->pubKeySize = 0;
sPymbed 16:048e5e270a58 7162 signer->keyOID = 0;
sPymbed 16:048e5e270a58 7163 signer->publicKey = NULL;
sPymbed 16:048e5e270a58 7164 signer->nameLen = 0;
sPymbed 16:048e5e270a58 7165 signer->name = NULL;
sPymbed 16:048e5e270a58 7166 #ifndef IGNORE_NAME_CONSTRAINTS
sPymbed 16:048e5e270a58 7167 signer->permittedNames = NULL;
sPymbed 16:048e5e270a58 7168 signer->excludedNames = NULL;
sPymbed 16:048e5e270a58 7169 #endif /* IGNORE_NAME_CONSTRAINTS */
sPymbed 16:048e5e270a58 7170 signer->pathLengthSet = 0;
sPymbed 16:048e5e270a58 7171 signer->pathLength = 0;
sPymbed 16:048e5e270a58 7172 #ifdef WOLFSSL_SIGNER_DER_CERT
sPymbed 16:048e5e270a58 7173 signer->derCert = NULL;
sPymbed 16:048e5e270a58 7174 #endif
sPymbed 16:048e5e270a58 7175 signer->next = NULL;
sPymbed 16:048e5e270a58 7176 }
sPymbed 16:048e5e270a58 7177 (void)heap;
sPymbed 16:048e5e270a58 7178
sPymbed 16:048e5e270a58 7179 return signer;
sPymbed 16:048e5e270a58 7180 }
sPymbed 16:048e5e270a58 7181
sPymbed 16:048e5e270a58 7182
sPymbed 16:048e5e270a58 7183 /* Free an individual signer */
sPymbed 16:048e5e270a58 7184 void FreeSigner(Signer* signer, void* heap)
sPymbed 16:048e5e270a58 7185 {
sPymbed 16:048e5e270a58 7186 XFREE(signer->name, heap, DYNAMIC_TYPE_SUBJECT_CN);
sPymbed 16:048e5e270a58 7187 XFREE(signer->publicKey, heap, DYNAMIC_TYPE_PUBLIC_KEY);
sPymbed 16:048e5e270a58 7188 #ifndef IGNORE_NAME_CONSTRAINTS
sPymbed 16:048e5e270a58 7189 if (signer->permittedNames)
sPymbed 16:048e5e270a58 7190 FreeNameSubtrees(signer->permittedNames, heap);
sPymbed 16:048e5e270a58 7191 if (signer->excludedNames)
sPymbed 16:048e5e270a58 7192 FreeNameSubtrees(signer->excludedNames, heap);
sPymbed 16:048e5e270a58 7193 #endif
sPymbed 16:048e5e270a58 7194 #ifdef WOLFSSL_SIGNER_DER_CERT
sPymbed 16:048e5e270a58 7195 FreeDer(&signer->derCert);
sPymbed 16:048e5e270a58 7196 #endif
sPymbed 16:048e5e270a58 7197 XFREE(signer, heap, DYNAMIC_TYPE_SIGNER);
sPymbed 16:048e5e270a58 7198
sPymbed 16:048e5e270a58 7199 (void)heap;
sPymbed 16:048e5e270a58 7200 }
sPymbed 16:048e5e270a58 7201
sPymbed 16:048e5e270a58 7202
sPymbed 16:048e5e270a58 7203 /* Free the whole singer table with number of rows */
sPymbed 16:048e5e270a58 7204 void FreeSignerTable(Signer** table, int rows, void* heap)
sPymbed 16:048e5e270a58 7205 {
sPymbed 16:048e5e270a58 7206 int i;
sPymbed 16:048e5e270a58 7207
sPymbed 16:048e5e270a58 7208 for (i = 0; i < rows; i++) {
sPymbed 16:048e5e270a58 7209 Signer* signer = table[i];
sPymbed 16:048e5e270a58 7210 while (signer) {
sPymbed 16:048e5e270a58 7211 Signer* next = signer->next;
sPymbed 16:048e5e270a58 7212 FreeSigner(signer, heap);
sPymbed 16:048e5e270a58 7213 signer = next;
sPymbed 16:048e5e270a58 7214 }
sPymbed 16:048e5e270a58 7215 table[i] = NULL;
sPymbed 16:048e5e270a58 7216 }
sPymbed 16:048e5e270a58 7217 }
sPymbed 16:048e5e270a58 7218
sPymbed 16:048e5e270a58 7219 #ifdef WOLFSSL_TRUST_PEER_CERT
sPymbed 16:048e5e270a58 7220 /* Free an individual trusted peer cert */
sPymbed 16:048e5e270a58 7221 void FreeTrustedPeer(TrustedPeerCert* tp, void* heap)
sPymbed 16:048e5e270a58 7222 {
sPymbed 16:048e5e270a58 7223 if (tp == NULL) {
sPymbed 16:048e5e270a58 7224 return;
sPymbed 16:048e5e270a58 7225 }
sPymbed 16:048e5e270a58 7226
sPymbed 16:048e5e270a58 7227 if (tp->name) {
sPymbed 16:048e5e270a58 7228 XFREE(tp->name, heap, DYNAMIC_TYPE_SUBJECT_CN);
sPymbed 16:048e5e270a58 7229 }
sPymbed 16:048e5e270a58 7230
sPymbed 16:048e5e270a58 7231 if (tp->sig) {
sPymbed 16:048e5e270a58 7232 XFREE(tp->sig, heap, DYNAMIC_TYPE_SIGNATURE);
sPymbed 16:048e5e270a58 7233 }
sPymbed 16:048e5e270a58 7234 #ifndef IGNORE_NAME_CONSTRAINTS
sPymbed 16:048e5e270a58 7235 if (tp->permittedNames)
sPymbed 16:048e5e270a58 7236 FreeNameSubtrees(tp->permittedNames, heap);
sPymbed 16:048e5e270a58 7237 if (tp->excludedNames)
sPymbed 16:048e5e270a58 7238 FreeNameSubtrees(tp->excludedNames, heap);
sPymbed 16:048e5e270a58 7239 #endif
sPymbed 16:048e5e270a58 7240 XFREE(tp, heap, DYNAMIC_TYPE_CERT);
sPymbed 16:048e5e270a58 7241
sPymbed 16:048e5e270a58 7242 (void)heap;
sPymbed 16:048e5e270a58 7243 }
sPymbed 16:048e5e270a58 7244
sPymbed 16:048e5e270a58 7245 /* Free the whole Trusted Peer linked list */
sPymbed 16:048e5e270a58 7246 void FreeTrustedPeerTable(TrustedPeerCert** table, int rows, void* heap)
sPymbed 16:048e5e270a58 7247 {
sPymbed 16:048e5e270a58 7248 int i;
sPymbed 16:048e5e270a58 7249
sPymbed 16:048e5e270a58 7250 for (i = 0; i < rows; i++) {
sPymbed 16:048e5e270a58 7251 TrustedPeerCert* tp = table[i];
sPymbed 16:048e5e270a58 7252 while (tp) {
sPymbed 16:048e5e270a58 7253 TrustedPeerCert* next = tp->next;
sPymbed 16:048e5e270a58 7254 FreeTrustedPeer(tp, heap);
sPymbed 16:048e5e270a58 7255 tp = next;
sPymbed 16:048e5e270a58 7256 }
sPymbed 16:048e5e270a58 7257 table[i] = NULL;
sPymbed 16:048e5e270a58 7258 }
sPymbed 16:048e5e270a58 7259 }
sPymbed 16:048e5e270a58 7260 #endif /* WOLFSSL_TRUST_PEER_CERT */
sPymbed 16:048e5e270a58 7261
sPymbed 16:048e5e270a58 7262 WOLFSSL_LOCAL int SetMyVersion(word32 version, byte* output, int header)
sPymbed 16:048e5e270a58 7263 {
sPymbed 16:048e5e270a58 7264 int i = 0;
sPymbed 16:048e5e270a58 7265
sPymbed 16:048e5e270a58 7266 if (output == NULL)
sPymbed 16:048e5e270a58 7267 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 7268
sPymbed 16:048e5e270a58 7269 if (header) {
sPymbed 16:048e5e270a58 7270 output[i++] = ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED;
sPymbed 16:048e5e270a58 7271 output[i++] = 3;
sPymbed 16:048e5e270a58 7272 }
sPymbed 16:048e5e270a58 7273 output[i++] = ASN_INTEGER;
sPymbed 16:048e5e270a58 7274 output[i++] = 0x01;
sPymbed 16:048e5e270a58 7275 output[i++] = (byte)version;
sPymbed 16:048e5e270a58 7276
sPymbed 16:048e5e270a58 7277 return i;
sPymbed 16:048e5e270a58 7278 }
sPymbed 16:048e5e270a58 7279
sPymbed 16:048e5e270a58 7280
sPymbed 16:048e5e270a58 7281 WOLFSSL_LOCAL int SetSerialNumber(const byte* sn, word32 snSz, byte* output,
sPymbed 16:048e5e270a58 7282 int maxSnSz)
sPymbed 16:048e5e270a58 7283 {
sPymbed 16:048e5e270a58 7284 int i = 0;
sPymbed 16:048e5e270a58 7285 int snSzInt = (int)snSz;
sPymbed 16:048e5e270a58 7286
sPymbed 16:048e5e270a58 7287 if (sn == NULL || output == NULL || snSzInt < 0)
sPymbed 16:048e5e270a58 7288 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 7289
sPymbed 16:048e5e270a58 7290 /* remove leading zeros */
sPymbed 16:048e5e270a58 7291 while (snSzInt > 0 && sn[0] == 0) {
sPymbed 16:048e5e270a58 7292 snSzInt--;
sPymbed 16:048e5e270a58 7293 sn++;
sPymbed 16:048e5e270a58 7294 }
sPymbed 16:048e5e270a58 7295
sPymbed 16:048e5e270a58 7296 /* truncate if input is too long */
sPymbed 16:048e5e270a58 7297 if (snSzInt > maxSnSz)
sPymbed 16:048e5e270a58 7298 snSzInt = maxSnSz;
sPymbed 16:048e5e270a58 7299
sPymbed 16:048e5e270a58 7300 /* encode ASN Integer, with length and value */
sPymbed 16:048e5e270a58 7301 output[i++] = ASN_INTEGER;
sPymbed 16:048e5e270a58 7302
sPymbed 16:048e5e270a58 7303 /* handle MSB, to make sure value is positive */
sPymbed 16:048e5e270a58 7304 if (sn[0] & 0x80) {
sPymbed 16:048e5e270a58 7305 /* make room for zero pad */
sPymbed 16:048e5e270a58 7306 if (snSzInt > maxSnSz-1)
sPymbed 16:048e5e270a58 7307 snSzInt = maxSnSz-1;
sPymbed 16:048e5e270a58 7308
sPymbed 16:048e5e270a58 7309 /* add zero pad */
sPymbed 16:048e5e270a58 7310 i += SetLength(snSzInt+1, &output[i]);
sPymbed 16:048e5e270a58 7311 output[i++] = 0x00;
sPymbed 16:048e5e270a58 7312 XMEMCPY(&output[i], sn, snSzInt);
sPymbed 16:048e5e270a58 7313 }
sPymbed 16:048e5e270a58 7314 else {
sPymbed 16:048e5e270a58 7315 i += SetLength(snSzInt, &output[i]);
sPymbed 16:048e5e270a58 7316 XMEMCPY(&output[i], sn, snSzInt);
sPymbed 16:048e5e270a58 7317 }
sPymbed 16:048e5e270a58 7318
sPymbed 16:048e5e270a58 7319 /* compute final length */
sPymbed 16:048e5e270a58 7320 i += snSzInt;
sPymbed 16:048e5e270a58 7321
sPymbed 16:048e5e270a58 7322 return i;
sPymbed 16:048e5e270a58 7323 }
sPymbed 16:048e5e270a58 7324
sPymbed 16:048e5e270a58 7325 WOLFSSL_LOCAL int GetSerialNumber(const byte* input, word32* inOutIdx,
sPymbed 16:048e5e270a58 7326 byte* serial, int* serialSz, word32 maxIdx)
sPymbed 16:048e5e270a58 7327 {
sPymbed 16:048e5e270a58 7328 int result = 0;
sPymbed 16:048e5e270a58 7329 int ret;
sPymbed 16:048e5e270a58 7330
sPymbed 16:048e5e270a58 7331 WOLFSSL_ENTER("GetSerialNumber");
sPymbed 16:048e5e270a58 7332
sPymbed 16:048e5e270a58 7333 if (serial == NULL || input == NULL || serialSz == NULL) {
sPymbed 16:048e5e270a58 7334 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 7335 }
sPymbed 16:048e5e270a58 7336
sPymbed 16:048e5e270a58 7337 /* First byte is ASN type */
sPymbed 16:048e5e270a58 7338 if ((*inOutIdx+1) > maxIdx) {
sPymbed 16:048e5e270a58 7339 WOLFSSL_MSG("Bad idx first");
sPymbed 16:048e5e270a58 7340 return BUFFER_E;
sPymbed 16:048e5e270a58 7341 }
sPymbed 16:048e5e270a58 7342
sPymbed 16:048e5e270a58 7343 ret = GetASNInt(input, inOutIdx, serialSz, maxIdx);
sPymbed 16:048e5e270a58 7344 if (ret != 0)
sPymbed 16:048e5e270a58 7345 return ret;
sPymbed 16:048e5e270a58 7346
sPymbed 16:048e5e270a58 7347 if (*serialSz > EXTERNAL_SERIAL_SIZE) {
sPymbed 16:048e5e270a58 7348 WOLFSSL_MSG("Serial size bad");
sPymbed 16:048e5e270a58 7349 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 7350 }
sPymbed 16:048e5e270a58 7351
sPymbed 16:048e5e270a58 7352 /* return serial */
sPymbed 16:048e5e270a58 7353 XMEMCPY(serial, &input[*inOutIdx], *serialSz);
sPymbed 16:048e5e270a58 7354 *inOutIdx += *serialSz;
sPymbed 16:048e5e270a58 7355
sPymbed 16:048e5e270a58 7356 return result;
sPymbed 16:048e5e270a58 7357 }
sPymbed 16:048e5e270a58 7358
sPymbed 16:048e5e270a58 7359
sPymbed 16:048e5e270a58 7360 int AllocDer(DerBuffer** pDer, word32 length, int type, void* heap)
sPymbed 16:048e5e270a58 7361 {
sPymbed 16:048e5e270a58 7362 int ret = BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 7363 if (pDer) {
sPymbed 16:048e5e270a58 7364 int dynType = 0;
sPymbed 16:048e5e270a58 7365 DerBuffer* der;
sPymbed 16:048e5e270a58 7366
sPymbed 16:048e5e270a58 7367 /* Determine dynamic type */
sPymbed 16:048e5e270a58 7368 switch (type) {
sPymbed 16:048e5e270a58 7369 case CA_TYPE: dynType = DYNAMIC_TYPE_CA; break;
sPymbed 16:048e5e270a58 7370 case CERT_TYPE: dynType = DYNAMIC_TYPE_CERT; break;
sPymbed 16:048e5e270a58 7371 case CRL_TYPE: dynType = DYNAMIC_TYPE_CRL; break;
sPymbed 16:048e5e270a58 7372 case DSA_TYPE: dynType = DYNAMIC_TYPE_DSA; break;
sPymbed 16:048e5e270a58 7373 case ECC_TYPE: dynType = DYNAMIC_TYPE_ECC; break;
sPymbed 16:048e5e270a58 7374 case RSA_TYPE: dynType = DYNAMIC_TYPE_RSA; break;
sPymbed 16:048e5e270a58 7375 default: dynType = DYNAMIC_TYPE_KEY; break;
sPymbed 16:048e5e270a58 7376 }
sPymbed 16:048e5e270a58 7377
sPymbed 16:048e5e270a58 7378 /* Setup new buffer */
sPymbed 16:048e5e270a58 7379 *pDer = (DerBuffer*)XMALLOC(sizeof(DerBuffer) + length, heap, dynType);
sPymbed 16:048e5e270a58 7380 if (*pDer == NULL) {
sPymbed 16:048e5e270a58 7381 return MEMORY_E;
sPymbed 16:048e5e270a58 7382 }
sPymbed 16:048e5e270a58 7383 XMEMSET(*pDer, 0, sizeof(DerBuffer) + length);
sPymbed 16:048e5e270a58 7384
sPymbed 16:048e5e270a58 7385 der = *pDer;
sPymbed 16:048e5e270a58 7386 der->type = type;
sPymbed 16:048e5e270a58 7387 der->dynType = dynType; /* Cache this for FreeDer */
sPymbed 16:048e5e270a58 7388 der->heap = heap;
sPymbed 16:048e5e270a58 7389 der->buffer = (byte*)der + sizeof(DerBuffer);
sPymbed 16:048e5e270a58 7390 der->length = length;
sPymbed 16:048e5e270a58 7391 ret = 0; /* Success */
sPymbed 16:048e5e270a58 7392 }
sPymbed 16:048e5e270a58 7393 return ret;
sPymbed 16:048e5e270a58 7394 }
sPymbed 16:048e5e270a58 7395
sPymbed 16:048e5e270a58 7396 void FreeDer(DerBuffer** pDer)
sPymbed 16:048e5e270a58 7397 {
sPymbed 16:048e5e270a58 7398 if (pDer && *pDer)
sPymbed 16:048e5e270a58 7399 {
sPymbed 16:048e5e270a58 7400 DerBuffer* der = (DerBuffer*)*pDer;
sPymbed 16:048e5e270a58 7401
sPymbed 16:048e5e270a58 7402 /* ForceZero private keys */
sPymbed 16:048e5e270a58 7403 if (der->type == PRIVATEKEY_TYPE) {
sPymbed 16:048e5e270a58 7404 ForceZero(der->buffer, der->length);
sPymbed 16:048e5e270a58 7405 }
sPymbed 16:048e5e270a58 7406 der->buffer = NULL;
sPymbed 16:048e5e270a58 7407 der->length = 0;
sPymbed 16:048e5e270a58 7408 XFREE(der, der->heap, der->dynType);
sPymbed 16:048e5e270a58 7409
sPymbed 16:048e5e270a58 7410 *pDer = NULL;
sPymbed 16:048e5e270a58 7411 }
sPymbed 16:048e5e270a58 7412 }
sPymbed 16:048e5e270a58 7413
sPymbed 16:048e5e270a58 7414
sPymbed 16:048e5e270a58 7415 #if defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM)
sPymbed 16:048e5e270a58 7416
sPymbed 16:048e5e270a58 7417 /* Max X509 header length indicates the max length + 2 ('\n', '\0') */
sPymbed 16:048e5e270a58 7418 #define MAX_X509_HEADER_SZ (37 + 2)
sPymbed 16:048e5e270a58 7419
sPymbed 16:048e5e270a58 7420 const char* const BEGIN_CERT = "-----BEGIN CERTIFICATE-----";
sPymbed 16:048e5e270a58 7421 const char* const END_CERT = "-----END CERTIFICATE-----";
sPymbed 16:048e5e270a58 7422 #ifdef WOLFSSL_CERT_REQ
sPymbed 16:048e5e270a58 7423 const char* const BEGIN_CERT_REQ = "-----BEGIN CERTIFICATE REQUEST-----";
sPymbed 16:048e5e270a58 7424 const char* const END_CERT_REQ = "-----END CERTIFICATE REQUEST-----";
sPymbed 16:048e5e270a58 7425 #endif
sPymbed 16:048e5e270a58 7426 #ifndef NO_DH
sPymbed 16:048e5e270a58 7427 const char* const BEGIN_DH_PARAM = "-----BEGIN DH PARAMETERS-----";
sPymbed 16:048e5e270a58 7428 const char* const END_DH_PARAM = "-----END DH PARAMETERS-----";
sPymbed 16:048e5e270a58 7429 #endif
sPymbed 16:048e5e270a58 7430 #ifndef NO_DSA
sPymbed 16:048e5e270a58 7431 const char* const BEGIN_DSA_PARAM = "-----BEGIN DSA PARAMETERS-----";
sPymbed 16:048e5e270a58 7432 const char* const END_DSA_PARAM = "-----END DSA PARAMETERS-----";
sPymbed 16:048e5e270a58 7433 #endif
sPymbed 16:048e5e270a58 7434 const char* const BEGIN_X509_CRL = "-----BEGIN X509 CRL-----";
sPymbed 16:048e5e270a58 7435 const char* const END_X509_CRL = "-----END X509 CRL-----";
sPymbed 16:048e5e270a58 7436 const char* const BEGIN_RSA_PRIV = "-----BEGIN RSA PRIVATE KEY-----";
sPymbed 16:048e5e270a58 7437 const char* const END_RSA_PRIV = "-----END RSA PRIVATE KEY-----";
sPymbed 16:048e5e270a58 7438 const char* const BEGIN_PRIV_KEY = "-----BEGIN PRIVATE KEY-----";
sPymbed 16:048e5e270a58 7439 const char* const END_PRIV_KEY = "-----END PRIVATE KEY-----";
sPymbed 16:048e5e270a58 7440 const char* const BEGIN_ENC_PRIV_KEY = "-----BEGIN ENCRYPTED PRIVATE KEY-----";
sPymbed 16:048e5e270a58 7441 const char* const END_ENC_PRIV_KEY = "-----END ENCRYPTED PRIVATE KEY-----";
sPymbed 16:048e5e270a58 7442 #ifdef HAVE_ECC
sPymbed 16:048e5e270a58 7443 const char* const BEGIN_EC_PRIV = "-----BEGIN EC PRIVATE KEY-----";
sPymbed 16:048e5e270a58 7444 const char* const END_EC_PRIV = "-----END EC PRIVATE KEY-----";
sPymbed 16:048e5e270a58 7445 #endif
sPymbed 16:048e5e270a58 7446 #if defined(HAVE_ECC) || defined(HAVE_ED25519) || !defined(NO_DSA)
sPymbed 16:048e5e270a58 7447 const char* const BEGIN_DSA_PRIV = "-----BEGIN DSA PRIVATE KEY-----";
sPymbed 16:048e5e270a58 7448 const char* const END_DSA_PRIV = "-----END DSA PRIVATE KEY-----";
sPymbed 16:048e5e270a58 7449 #endif
sPymbed 16:048e5e270a58 7450 const char* const BEGIN_PUB_KEY = "-----BEGIN PUBLIC KEY-----";
sPymbed 16:048e5e270a58 7451 const char* const END_PUB_KEY = "-----END PUBLIC KEY-----";
sPymbed 16:048e5e270a58 7452 #ifdef HAVE_ED25519
sPymbed 16:048e5e270a58 7453 const char* const BEGIN_EDDSA_PRIV = "-----BEGIN EDDSA PRIVATE KEY-----";
sPymbed 16:048e5e270a58 7454 const char* const END_EDDSA_PRIV = "-----END EDDSA PRIVATE KEY-----";
sPymbed 16:048e5e270a58 7455 #endif
sPymbed 16:048e5e270a58 7456 #ifdef HAVE_CRL
sPymbed 16:048e5e270a58 7457 const char *const BEGIN_CRL = "-----BEGIN X509 CRL-----";
sPymbed 16:048e5e270a58 7458 const char* const END_CRL = "-----END X509 CRL-----";
sPymbed 16:048e5e270a58 7459 #endif
sPymbed 16:048e5e270a58 7460
sPymbed 16:048e5e270a58 7461
sPymbed 16:048e5e270a58 7462
sPymbed 16:048e5e270a58 7463 int wc_PemGetHeaderFooter(int type, const char** header, const char** footer)
sPymbed 16:048e5e270a58 7464 {
sPymbed 16:048e5e270a58 7465 int ret = BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 7466
sPymbed 16:048e5e270a58 7467 switch (type) {
sPymbed 16:048e5e270a58 7468 case CA_TYPE: /* same as below */
sPymbed 16:048e5e270a58 7469 case TRUSTED_PEER_TYPE:
sPymbed 16:048e5e270a58 7470 case CERT_TYPE:
sPymbed 16:048e5e270a58 7471 if (header) *header = BEGIN_CERT;
sPymbed 16:048e5e270a58 7472 if (footer) *footer = END_CERT;
sPymbed 16:048e5e270a58 7473 ret = 0;
sPymbed 16:048e5e270a58 7474 break;
sPymbed 16:048e5e270a58 7475
sPymbed 16:048e5e270a58 7476 case CRL_TYPE:
sPymbed 16:048e5e270a58 7477 if (header) *header = BEGIN_X509_CRL;
sPymbed 16:048e5e270a58 7478 if (footer) *footer = END_X509_CRL;
sPymbed 16:048e5e270a58 7479 ret = 0;
sPymbed 16:048e5e270a58 7480 break;
sPymbed 16:048e5e270a58 7481 #ifndef NO_DH
sPymbed 16:048e5e270a58 7482 case DH_PARAM_TYPE:
sPymbed 16:048e5e270a58 7483 if (header) *header = BEGIN_DH_PARAM;
sPymbed 16:048e5e270a58 7484 if (footer) *footer = END_DH_PARAM;
sPymbed 16:048e5e270a58 7485 ret = 0;
sPymbed 16:048e5e270a58 7486 break;
sPymbed 16:048e5e270a58 7487 #endif
sPymbed 16:048e5e270a58 7488 #ifndef NO_DSA
sPymbed 16:048e5e270a58 7489 case DSA_PARAM_TYPE:
sPymbed 16:048e5e270a58 7490 if (header) *header = BEGIN_DSA_PARAM;
sPymbed 16:048e5e270a58 7491 if (footer) *footer = END_DSA_PARAM;
sPymbed 16:048e5e270a58 7492 ret = 0;
sPymbed 16:048e5e270a58 7493 break;
sPymbed 16:048e5e270a58 7494 #endif
sPymbed 16:048e5e270a58 7495 #ifdef WOLFSSL_CERT_REQ
sPymbed 16:048e5e270a58 7496 case CERTREQ_TYPE:
sPymbed 16:048e5e270a58 7497 if (header) *header = BEGIN_CERT_REQ;
sPymbed 16:048e5e270a58 7498 if (footer) *footer = END_CERT_REQ;
sPymbed 16:048e5e270a58 7499 ret = 0;
sPymbed 16:048e5e270a58 7500 break;
sPymbed 16:048e5e270a58 7501 #endif
sPymbed 16:048e5e270a58 7502 #ifndef NO_DSA
sPymbed 16:048e5e270a58 7503 case DSA_TYPE:
sPymbed 16:048e5e270a58 7504 case DSA_PRIVATEKEY_TYPE:
sPymbed 16:048e5e270a58 7505 if (header) *header = BEGIN_DSA_PRIV;
sPymbed 16:048e5e270a58 7506 if (footer) *footer = END_DSA_PRIV;
sPymbed 16:048e5e270a58 7507 ret = 0;
sPymbed 16:048e5e270a58 7508 break;
sPymbed 16:048e5e270a58 7509 #endif
sPymbed 16:048e5e270a58 7510 #ifdef HAVE_ECC
sPymbed 16:048e5e270a58 7511 case ECC_TYPE:
sPymbed 16:048e5e270a58 7512 case ECC_PRIVATEKEY_TYPE:
sPymbed 16:048e5e270a58 7513 if (header) *header = BEGIN_EC_PRIV;
sPymbed 16:048e5e270a58 7514 if (footer) *footer = END_EC_PRIV;
sPymbed 16:048e5e270a58 7515 ret = 0;
sPymbed 16:048e5e270a58 7516 break;
sPymbed 16:048e5e270a58 7517 #endif
sPymbed 16:048e5e270a58 7518 case RSA_TYPE:
sPymbed 16:048e5e270a58 7519 case PRIVATEKEY_TYPE:
sPymbed 16:048e5e270a58 7520 if (header) *header = BEGIN_RSA_PRIV;
sPymbed 16:048e5e270a58 7521 if (footer) *footer = END_RSA_PRIV;
sPymbed 16:048e5e270a58 7522 ret = 0;
sPymbed 16:048e5e270a58 7523 break;
sPymbed 16:048e5e270a58 7524 #ifdef HAVE_ED25519
sPymbed 16:048e5e270a58 7525 case ED25519_TYPE:
sPymbed 16:048e5e270a58 7526 case EDDSA_PRIVATEKEY_TYPE:
sPymbed 16:048e5e270a58 7527 if (header) *header = BEGIN_EDDSA_PRIV;
sPymbed 16:048e5e270a58 7528 if (footer) *footer = END_EDDSA_PRIV;
sPymbed 16:048e5e270a58 7529 ret = 0;
sPymbed 16:048e5e270a58 7530 break;
sPymbed 16:048e5e270a58 7531 #endif
sPymbed 16:048e5e270a58 7532 case PUBLICKEY_TYPE:
sPymbed 16:048e5e270a58 7533 if (header) *header = BEGIN_PUB_KEY;
sPymbed 16:048e5e270a58 7534 if (footer) *footer = END_PUB_KEY;
sPymbed 16:048e5e270a58 7535 ret = 0;
sPymbed 16:048e5e270a58 7536 break;
sPymbed 16:048e5e270a58 7537 default:
sPymbed 16:048e5e270a58 7538 break;
sPymbed 16:048e5e270a58 7539 }
sPymbed 16:048e5e270a58 7540 return ret;
sPymbed 16:048e5e270a58 7541 }
sPymbed 16:048e5e270a58 7542
sPymbed 16:048e5e270a58 7543 #ifdef WOLFSSL_ENCRYPTED_KEYS
sPymbed 16:048e5e270a58 7544
sPymbed 16:048e5e270a58 7545 static const char* const kProcTypeHeader = "Proc-Type";
sPymbed 16:048e5e270a58 7546 static const char* const kDecInfoHeader = "DEK-Info";
sPymbed 16:048e5e270a58 7547
sPymbed 16:048e5e270a58 7548 #ifdef WOLFSSL_PEM_TO_DER
sPymbed 16:048e5e270a58 7549 #ifndef NO_DES3
sPymbed 16:048e5e270a58 7550 static const char* const kEncTypeDes = "DES-CBC";
sPymbed 16:048e5e270a58 7551 static const char* const kEncTypeDes3 = "DES-EDE3-CBC";
sPymbed 16:048e5e270a58 7552 #endif
sPymbed 16:048e5e270a58 7553 #if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_128)
sPymbed 16:048e5e270a58 7554 static const char* const kEncTypeAesCbc128 = "AES-128-CBC";
sPymbed 16:048e5e270a58 7555 #endif
sPymbed 16:048e5e270a58 7556 #if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_192)
sPymbed 16:048e5e270a58 7557 static const char* const kEncTypeAesCbc192 = "AES-192-CBC";
sPymbed 16:048e5e270a58 7558 #endif
sPymbed 16:048e5e270a58 7559 #if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_256)
sPymbed 16:048e5e270a58 7560 static const char* const kEncTypeAesCbc256 = "AES-256-CBC";
sPymbed 16:048e5e270a58 7561 #endif
sPymbed 16:048e5e270a58 7562
sPymbed 16:048e5e270a58 7563 int wc_EncryptedInfoGet(EncryptedInfo* info, const char* cipherInfo)
sPymbed 16:048e5e270a58 7564 {
sPymbed 16:048e5e270a58 7565 int ret = 0;
sPymbed 16:048e5e270a58 7566
sPymbed 16:048e5e270a58 7567 if (info == NULL || cipherInfo == NULL)
sPymbed 16:048e5e270a58 7568 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 7569
sPymbed 16:048e5e270a58 7570 /* determine cipher information */
sPymbed 16:048e5e270a58 7571 #ifndef NO_DES3
sPymbed 16:048e5e270a58 7572 if (XSTRNCMP(cipherInfo, kEncTypeDes, XSTRLEN(kEncTypeDes)) == 0) {
sPymbed 16:048e5e270a58 7573 info->cipherType = WC_CIPHER_DES;
sPymbed 16:048e5e270a58 7574 info->keySz = DES_KEY_SIZE;
sPymbed 16:048e5e270a58 7575 if (info->ivSz == 0) info->ivSz = DES_IV_SIZE;
sPymbed 16:048e5e270a58 7576 }
sPymbed 16:048e5e270a58 7577 else if (XSTRNCMP(cipherInfo, kEncTypeDes3, XSTRLEN(kEncTypeDes3)) == 0) {
sPymbed 16:048e5e270a58 7578 info->cipherType = WC_CIPHER_DES3;
sPymbed 16:048e5e270a58 7579 info->keySz = DES3_KEY_SIZE;
sPymbed 16:048e5e270a58 7580 if (info->ivSz == 0) info->ivSz = DES_IV_SIZE;
sPymbed 16:048e5e270a58 7581 }
sPymbed 16:048e5e270a58 7582 else
sPymbed 16:048e5e270a58 7583 #endif /* !NO_DES3 */
sPymbed 16:048e5e270a58 7584 #if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_128)
sPymbed 16:048e5e270a58 7585 if (XSTRNCMP(cipherInfo, kEncTypeAesCbc128, XSTRLEN(kEncTypeAesCbc128)) == 0) {
sPymbed 16:048e5e270a58 7586 info->cipherType = WC_CIPHER_AES_CBC;
sPymbed 16:048e5e270a58 7587 info->keySz = AES_128_KEY_SIZE;
sPymbed 16:048e5e270a58 7588 if (info->ivSz == 0) info->ivSz = AES_IV_SIZE;
sPymbed 16:048e5e270a58 7589 }
sPymbed 16:048e5e270a58 7590 else
sPymbed 16:048e5e270a58 7591 #endif
sPymbed 16:048e5e270a58 7592 #if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_192)
sPymbed 16:048e5e270a58 7593 if (XSTRNCMP(cipherInfo, kEncTypeAesCbc192, XSTRLEN(kEncTypeAesCbc192)) == 0) {
sPymbed 16:048e5e270a58 7594 info->cipherType = WC_CIPHER_AES_CBC;
sPymbed 16:048e5e270a58 7595 info->keySz = AES_192_KEY_SIZE;
sPymbed 16:048e5e270a58 7596 if (info->ivSz == 0) info->ivSz = AES_IV_SIZE;
sPymbed 16:048e5e270a58 7597 }
sPymbed 16:048e5e270a58 7598 else
sPymbed 16:048e5e270a58 7599 #endif
sPymbed 16:048e5e270a58 7600 #if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_256)
sPymbed 16:048e5e270a58 7601 if (XSTRNCMP(cipherInfo, kEncTypeAesCbc256, XSTRLEN(kEncTypeAesCbc256)) == 0) {
sPymbed 16:048e5e270a58 7602 info->cipherType = WC_CIPHER_AES_CBC;
sPymbed 16:048e5e270a58 7603 info->keySz = AES_256_KEY_SIZE;
sPymbed 16:048e5e270a58 7604 if (info->ivSz == 0) info->ivSz = AES_IV_SIZE;
sPymbed 16:048e5e270a58 7605 }
sPymbed 16:048e5e270a58 7606 else
sPymbed 16:048e5e270a58 7607 #endif
sPymbed 16:048e5e270a58 7608 {
sPymbed 16:048e5e270a58 7609 ret = NOT_COMPILED_IN;
sPymbed 16:048e5e270a58 7610 }
sPymbed 16:048e5e270a58 7611 return ret;
sPymbed 16:048e5e270a58 7612 }
sPymbed 16:048e5e270a58 7613
sPymbed 16:048e5e270a58 7614 static int wc_EncryptedInfoParse(EncryptedInfo* info,
sPymbed 16:048e5e270a58 7615 char** pBuffer, size_t bufSz)
sPymbed 16:048e5e270a58 7616 {
sPymbed 16:048e5e270a58 7617 int err = 0;
sPymbed 16:048e5e270a58 7618 char* bufferStart;
sPymbed 16:048e5e270a58 7619 char* bufferEnd;
sPymbed 16:048e5e270a58 7620 char* line;
sPymbed 16:048e5e270a58 7621 word32 lineSz;
sPymbed 16:048e5e270a58 7622 char* finish;
sPymbed 16:048e5e270a58 7623 word32 finishSz;
sPymbed 16:048e5e270a58 7624 char* start = NULL;
sPymbed 16:048e5e270a58 7625 word32 startSz;
sPymbed 16:048e5e270a58 7626 char* newline = NULL;
sPymbed 16:048e5e270a58 7627
sPymbed 16:048e5e270a58 7628 if (info == NULL || pBuffer == NULL || bufSz == 0)
sPymbed 16:048e5e270a58 7629 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 7630
sPymbed 16:048e5e270a58 7631 bufferStart = *pBuffer;
sPymbed 16:048e5e270a58 7632 bufferEnd = bufferStart + bufSz;
sPymbed 16:048e5e270a58 7633
sPymbed 16:048e5e270a58 7634 /* find encrypted info marker */
sPymbed 16:048e5e270a58 7635 line = XSTRNSTR(bufferStart, kProcTypeHeader,
sPymbed 16:048e5e270a58 7636 min((word32)bufSz, PEM_LINE_LEN));
sPymbed 16:048e5e270a58 7637 if (line != NULL) {
sPymbed 16:048e5e270a58 7638 if (line >= bufferEnd) {
sPymbed 16:048e5e270a58 7639 return BUFFER_E;
sPymbed 16:048e5e270a58 7640 }
sPymbed 16:048e5e270a58 7641
sPymbed 16:048e5e270a58 7642 lineSz = (word32)(bufferEnd - line);
sPymbed 16:048e5e270a58 7643
sPymbed 16:048e5e270a58 7644 /* find DEC-Info marker */
sPymbed 16:048e5e270a58 7645 start = XSTRNSTR(line, kDecInfoHeader, min(lineSz, PEM_LINE_LEN));
sPymbed 16:048e5e270a58 7646
sPymbed 16:048e5e270a58 7647 if (start == NULL)
sPymbed 16:048e5e270a58 7648 return BUFFER_E;
sPymbed 16:048e5e270a58 7649
sPymbed 16:048e5e270a58 7650 /* skip dec-info and ": " */
sPymbed 16:048e5e270a58 7651 start += XSTRLEN(kDecInfoHeader);
sPymbed 16:048e5e270a58 7652 if (start >= bufferEnd)
sPymbed 16:048e5e270a58 7653 return BUFFER_E;
sPymbed 16:048e5e270a58 7654
sPymbed 16:048e5e270a58 7655 if (start[0] == ':') {
sPymbed 16:048e5e270a58 7656 start++;
sPymbed 16:048e5e270a58 7657 if (start >= bufferEnd)
sPymbed 16:048e5e270a58 7658 return BUFFER_E;
sPymbed 16:048e5e270a58 7659 }
sPymbed 16:048e5e270a58 7660 if (start[0] == ' ')
sPymbed 16:048e5e270a58 7661 start++;
sPymbed 16:048e5e270a58 7662
sPymbed 16:048e5e270a58 7663 startSz = (word32)(bufferEnd - start);
sPymbed 16:048e5e270a58 7664 finish = XSTRNSTR(start, ",", min(startSz, PEM_LINE_LEN));
sPymbed 16:048e5e270a58 7665
sPymbed 16:048e5e270a58 7666 if ((start != NULL) && (finish != NULL) && (start < finish)) {
sPymbed 16:048e5e270a58 7667 if (finish >= bufferEnd) {
sPymbed 16:048e5e270a58 7668 return BUFFER_E;
sPymbed 16:048e5e270a58 7669 }
sPymbed 16:048e5e270a58 7670
sPymbed 16:048e5e270a58 7671 finishSz = (word32)(bufferEnd - finish);
sPymbed 16:048e5e270a58 7672 newline = XSTRNSTR(finish, "\r", min(finishSz, PEM_LINE_LEN));
sPymbed 16:048e5e270a58 7673
sPymbed 16:048e5e270a58 7674 /* get cipher name */
sPymbed 16:048e5e270a58 7675 if (NAME_SZ < (finish - start)) /* buffer size of info->name */
sPymbed 16:048e5e270a58 7676 return BUFFER_E;
sPymbed 16:048e5e270a58 7677 if (XMEMCPY(info->name, start, finish - start) == NULL)
sPymbed 16:048e5e270a58 7678 return BUFFER_E;
sPymbed 16:048e5e270a58 7679 info->name[finish - start] = '\0'; /* null term */
sPymbed 16:048e5e270a58 7680
sPymbed 16:048e5e270a58 7681 /* get IV */
sPymbed 16:048e5e270a58 7682 if (finishSz < sizeof(info->iv) + 1)
sPymbed 16:048e5e270a58 7683 return BUFFER_E;
sPymbed 16:048e5e270a58 7684 if (XMEMCPY(info->iv, finish + 1, sizeof(info->iv)) == NULL)
sPymbed 16:048e5e270a58 7685 return BUFFER_E;
sPymbed 16:048e5e270a58 7686
sPymbed 16:048e5e270a58 7687 if (newline == NULL)
sPymbed 16:048e5e270a58 7688 newline = XSTRNSTR(finish, "\n", min(finishSz,
sPymbed 16:048e5e270a58 7689 PEM_LINE_LEN));
sPymbed 16:048e5e270a58 7690 if ((newline != NULL) && (newline > finish)) {
sPymbed 16:048e5e270a58 7691 info->ivSz = (word32)(newline - (finish + 1));
sPymbed 16:048e5e270a58 7692 info->set = 1;
sPymbed 16:048e5e270a58 7693 }
sPymbed 16:048e5e270a58 7694 else
sPymbed 16:048e5e270a58 7695 return BUFFER_E;
sPymbed 16:048e5e270a58 7696 }
sPymbed 16:048e5e270a58 7697 else
sPymbed 16:048e5e270a58 7698 return BUFFER_E;
sPymbed 16:048e5e270a58 7699
sPymbed 16:048e5e270a58 7700 /* eat blank line */
sPymbed 16:048e5e270a58 7701 while (newline < bufferEnd &&
sPymbed 16:048e5e270a58 7702 (*newline == '\r' || *newline == '\n')) {
sPymbed 16:048e5e270a58 7703 newline++;
sPymbed 16:048e5e270a58 7704 }
sPymbed 16:048e5e270a58 7705
sPymbed 16:048e5e270a58 7706 /* return new headerEnd */
sPymbed 16:048e5e270a58 7707 if (pBuffer)
sPymbed 16:048e5e270a58 7708 *pBuffer = newline;
sPymbed 16:048e5e270a58 7709
sPymbed 16:048e5e270a58 7710 /* populate info */
sPymbed 16:048e5e270a58 7711 err = wc_EncryptedInfoGet(info, info->name);
sPymbed 16:048e5e270a58 7712 }
sPymbed 16:048e5e270a58 7713
sPymbed 16:048e5e270a58 7714 return err;
sPymbed 16:048e5e270a58 7715 }
sPymbed 16:048e5e270a58 7716 #endif /* WOLFSSL_PEM_TO_DER */
sPymbed 16:048e5e270a58 7717
sPymbed 16:048e5e270a58 7718 #ifdef WOLFSSL_DER_TO_PEM
sPymbed 16:048e5e270a58 7719 static int wc_EncryptedInfoAppend(char* dest, char* cipherInfo)
sPymbed 16:048e5e270a58 7720 {
sPymbed 16:048e5e270a58 7721 if (cipherInfo != NULL) {
sPymbed 16:048e5e270a58 7722 size_t cipherInfoStrLen = XSTRLEN(cipherInfo);
sPymbed 16:048e5e270a58 7723 if (cipherInfoStrLen > HEADER_ENCRYPTED_KEY_SIZE - (9+14+10+3))
sPymbed 16:048e5e270a58 7724 cipherInfoStrLen = HEADER_ENCRYPTED_KEY_SIZE - (9+14+10+3);
sPymbed 16:048e5e270a58 7725
sPymbed 16:048e5e270a58 7726 XSTRNCAT(dest, kProcTypeHeader, 9);
sPymbed 16:048e5e270a58 7727 XSTRNCAT(dest, ": 4,ENCRYPTED\n", 14);
sPymbed 16:048e5e270a58 7728 XSTRNCAT(dest, kDecInfoHeader, 8);
sPymbed 16:048e5e270a58 7729 XSTRNCAT(dest, ": ", 2);
sPymbed 16:048e5e270a58 7730 XSTRNCAT(dest, cipherInfo, cipherInfoStrLen);
sPymbed 16:048e5e270a58 7731 XSTRNCAT(dest, "\n\n", 3);
sPymbed 16:048e5e270a58 7732 }
sPymbed 16:048e5e270a58 7733 return 0;
sPymbed 16:048e5e270a58 7734 }
sPymbed 16:048e5e270a58 7735 #endif /* WOLFSSL_DER_TO_PEM */
sPymbed 16:048e5e270a58 7736 #endif /* WOLFSSL_ENCRYPTED_KEYS */
sPymbed 16:048e5e270a58 7737
sPymbed 16:048e5e270a58 7738 #ifdef WOLFSSL_DER_TO_PEM
sPymbed 16:048e5e270a58 7739
sPymbed 16:048e5e270a58 7740 /* Used for compatibility API */
sPymbed 16:048e5e270a58 7741 int wc_DerToPem(const byte* der, word32 derSz,
sPymbed 16:048e5e270a58 7742 byte* output, word32 outSz, int type)
sPymbed 16:048e5e270a58 7743 {
sPymbed 16:048e5e270a58 7744 return wc_DerToPemEx(der, derSz, output, outSz, NULL, type);
sPymbed 16:048e5e270a58 7745 }
sPymbed 16:048e5e270a58 7746
sPymbed 16:048e5e270a58 7747 /* convert der buffer to pem into output, can't do inplace, der and output
sPymbed 16:048e5e270a58 7748 need to be different */
sPymbed 16:048e5e270a58 7749 int wc_DerToPemEx(const byte* der, word32 derSz, byte* output, word32 outSz,
sPymbed 16:048e5e270a58 7750 byte *cipher_info, int type)
sPymbed 16:048e5e270a58 7751 {
sPymbed 16:048e5e270a58 7752 const char* headerStr = NULL;
sPymbed 16:048e5e270a58 7753 const char* footerStr = NULL;
sPymbed 16:048e5e270a58 7754 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 7755 char* header = NULL;
sPymbed 16:048e5e270a58 7756 char* footer = NULL;
sPymbed 16:048e5e270a58 7757 #else
sPymbed 16:048e5e270a58 7758 char header[MAX_X509_HEADER_SZ + HEADER_ENCRYPTED_KEY_SIZE];
sPymbed 16:048e5e270a58 7759 char footer[MAX_X509_HEADER_SZ];
sPymbed 16:048e5e270a58 7760 #endif
sPymbed 16:048e5e270a58 7761 int headerLen = MAX_X509_HEADER_SZ + HEADER_ENCRYPTED_KEY_SIZE;
sPymbed 16:048e5e270a58 7762 int footerLen = MAX_X509_HEADER_SZ;
sPymbed 16:048e5e270a58 7763 int i;
sPymbed 16:048e5e270a58 7764 int err;
sPymbed 16:048e5e270a58 7765 int outLen; /* return length or error */
sPymbed 16:048e5e270a58 7766
sPymbed 16:048e5e270a58 7767 (void)cipher_info;
sPymbed 16:048e5e270a58 7768
sPymbed 16:048e5e270a58 7769 if (der == output) /* no in place conversion */
sPymbed 16:048e5e270a58 7770 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 7771
sPymbed 16:048e5e270a58 7772 err = wc_PemGetHeaderFooter(type, &headerStr, &footerStr);
sPymbed 16:048e5e270a58 7773 if (err != 0)
sPymbed 16:048e5e270a58 7774 return err;
sPymbed 16:048e5e270a58 7775
sPymbed 16:048e5e270a58 7776 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 7777 header = (char*)XMALLOC(headerLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 7778 if (header == NULL)
sPymbed 16:048e5e270a58 7779 return MEMORY_E;
sPymbed 16:048e5e270a58 7780
sPymbed 16:048e5e270a58 7781 footer = (char*)XMALLOC(footerLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 7782 if (footer == NULL) {
sPymbed 16:048e5e270a58 7783 XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 7784 return MEMORY_E;
sPymbed 16:048e5e270a58 7785 }
sPymbed 16:048e5e270a58 7786 #endif
sPymbed 16:048e5e270a58 7787
sPymbed 16:048e5e270a58 7788 /* null term and leave room for newline */
sPymbed 16:048e5e270a58 7789 header[--headerLen] = '\0'; header[--headerLen] = '\0';
sPymbed 16:048e5e270a58 7790 footer[--footerLen] = '\0'; footer[--footerLen] = '\0';
sPymbed 16:048e5e270a58 7791
sPymbed 16:048e5e270a58 7792 /* build header and footer based on type */
sPymbed 16:048e5e270a58 7793 XSTRNCPY(header, headerStr, headerLen);
sPymbed 16:048e5e270a58 7794 XSTRNCPY(footer, footerStr, footerLen);
sPymbed 16:048e5e270a58 7795
sPymbed 16:048e5e270a58 7796 /* add new line to end */
sPymbed 16:048e5e270a58 7797 XSTRNCAT(header, "\n", 2);
sPymbed 16:048e5e270a58 7798 XSTRNCAT(footer, "\n", 2);
sPymbed 16:048e5e270a58 7799
sPymbed 16:048e5e270a58 7800 #ifdef WOLFSSL_ENCRYPTED_KEYS
sPymbed 16:048e5e270a58 7801 err = wc_EncryptedInfoAppend(header, (char*)cipher_info);
sPymbed 16:048e5e270a58 7802 if (err != 0) {
sPymbed 16:048e5e270a58 7803 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 7804 XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 7805 XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 7806 #endif
sPymbed 16:048e5e270a58 7807 return err;
sPymbed 16:048e5e270a58 7808 }
sPymbed 16:048e5e270a58 7809 #endif
sPymbed 16:048e5e270a58 7810
sPymbed 16:048e5e270a58 7811 headerLen = (int)XSTRLEN(header);
sPymbed 16:048e5e270a58 7812 footerLen = (int)XSTRLEN(footer);
sPymbed 16:048e5e270a58 7813
sPymbed 16:048e5e270a58 7814 /* if null output and 0 size passed in then return size needed */
sPymbed 16:048e5e270a58 7815 if (!output && outSz == 0) {
sPymbed 16:048e5e270a58 7816 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 7817 XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 7818 XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 7819 #endif
sPymbed 16:048e5e270a58 7820 outLen = 0;
sPymbed 16:048e5e270a58 7821 if ((err = Base64_Encode(der, derSz, NULL, (word32*)&outLen))
sPymbed 16:048e5e270a58 7822 != LENGTH_ONLY_E) {
sPymbed 16:048e5e270a58 7823 return err;
sPymbed 16:048e5e270a58 7824 }
sPymbed 16:048e5e270a58 7825 return headerLen + footerLen + outLen;
sPymbed 16:048e5e270a58 7826 }
sPymbed 16:048e5e270a58 7827
sPymbed 16:048e5e270a58 7828 if (!der || !output) {
sPymbed 16:048e5e270a58 7829 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 7830 XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 7831 XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 7832 #endif
sPymbed 16:048e5e270a58 7833 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 7834 }
sPymbed 16:048e5e270a58 7835
sPymbed 16:048e5e270a58 7836 /* don't even try if outSz too short */
sPymbed 16:048e5e270a58 7837 if (outSz < headerLen + footerLen + derSz) {
sPymbed 16:048e5e270a58 7838 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 7839 XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 7840 XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 7841 #endif
sPymbed 16:048e5e270a58 7842 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 7843 }
sPymbed 16:048e5e270a58 7844
sPymbed 16:048e5e270a58 7845 /* header */
sPymbed 16:048e5e270a58 7846 XMEMCPY(output, header, headerLen);
sPymbed 16:048e5e270a58 7847 i = headerLen;
sPymbed 16:048e5e270a58 7848
sPymbed 16:048e5e270a58 7849 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 7850 XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 7851 #endif
sPymbed 16:048e5e270a58 7852
sPymbed 16:048e5e270a58 7853 /* body */
sPymbed 16:048e5e270a58 7854 outLen = outSz - (headerLen + footerLen); /* input to Base64_Encode */
sPymbed 16:048e5e270a58 7855 if ( (err = Base64_Encode(der, derSz, output + i, (word32*)&outLen)) < 0) {
sPymbed 16:048e5e270a58 7856 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 7857 XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 7858 #endif
sPymbed 16:048e5e270a58 7859 return err;
sPymbed 16:048e5e270a58 7860 }
sPymbed 16:048e5e270a58 7861 i += outLen;
sPymbed 16:048e5e270a58 7862
sPymbed 16:048e5e270a58 7863 /* footer */
sPymbed 16:048e5e270a58 7864 if ( (i + footerLen) > (int)outSz) {
sPymbed 16:048e5e270a58 7865 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 7866 XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 7867 #endif
sPymbed 16:048e5e270a58 7868 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 7869 }
sPymbed 16:048e5e270a58 7870 XMEMCPY(output + i, footer, footerLen);
sPymbed 16:048e5e270a58 7871
sPymbed 16:048e5e270a58 7872 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 7873 XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 7874 #endif
sPymbed 16:048e5e270a58 7875
sPymbed 16:048e5e270a58 7876 return outLen + headerLen + footerLen;
sPymbed 16:048e5e270a58 7877 }
sPymbed 16:048e5e270a58 7878
sPymbed 16:048e5e270a58 7879 #endif /* WOLFSSL_DER_TO_PEM */
sPymbed 16:048e5e270a58 7880
sPymbed 16:048e5e270a58 7881 #ifdef WOLFSSL_PEM_TO_DER
sPymbed 16:048e5e270a58 7882
sPymbed 16:048e5e270a58 7883 /* Remove PEM header/footer, convert to ASN1, store any encrypted data
sPymbed 16:048e5e270a58 7884 info->consumed tracks of PEM bytes consumed in case multiple parts */
sPymbed 16:048e5e270a58 7885 int PemToDer(const unsigned char* buff, long longSz, int type,
sPymbed 16:048e5e270a58 7886 DerBuffer** pDer, void* heap, EncryptedInfo* info, int* eccKey)
sPymbed 16:048e5e270a58 7887 {
sPymbed 16:048e5e270a58 7888 const char* header = NULL;
sPymbed 16:048e5e270a58 7889 const char* footer = NULL;
sPymbed 16:048e5e270a58 7890 char* headerEnd;
sPymbed 16:048e5e270a58 7891 char* footerEnd;
sPymbed 16:048e5e270a58 7892 char* consumedEnd;
sPymbed 16:048e5e270a58 7893 char* bufferEnd = (char*)(buff + longSz);
sPymbed 16:048e5e270a58 7894 long neededSz;
sPymbed 16:048e5e270a58 7895 int ret = 0;
sPymbed 16:048e5e270a58 7896 int sz = (int)longSz;
sPymbed 16:048e5e270a58 7897 int encrypted_key = 0;
sPymbed 16:048e5e270a58 7898 DerBuffer* der;
sPymbed 16:048e5e270a58 7899
sPymbed 16:048e5e270a58 7900 WOLFSSL_ENTER("PemToDer");
sPymbed 16:048e5e270a58 7901
sPymbed 16:048e5e270a58 7902 /* get PEM header and footer based on type */
sPymbed 16:048e5e270a58 7903 ret = wc_PemGetHeaderFooter(type, &header, &footer);
sPymbed 16:048e5e270a58 7904 if (ret != 0)
sPymbed 16:048e5e270a58 7905 return ret;
sPymbed 16:048e5e270a58 7906
sPymbed 16:048e5e270a58 7907 /* map header if not found for type */
sPymbed 16:048e5e270a58 7908 for (;;) {
sPymbed 16:048e5e270a58 7909 headerEnd = XSTRNSTR((char*)buff, header, sz);
sPymbed 16:048e5e270a58 7910
sPymbed 16:048e5e270a58 7911 if (headerEnd || type != PRIVATEKEY_TYPE) {
sPymbed 16:048e5e270a58 7912 break;
sPymbed 16:048e5e270a58 7913 } else
sPymbed 16:048e5e270a58 7914 if (header == BEGIN_RSA_PRIV) {
sPymbed 16:048e5e270a58 7915 header = BEGIN_PRIV_KEY; footer = END_PRIV_KEY;
sPymbed 16:048e5e270a58 7916 } else
sPymbed 16:048e5e270a58 7917 if (header == BEGIN_PRIV_KEY) {
sPymbed 16:048e5e270a58 7918 header = BEGIN_ENC_PRIV_KEY; footer = END_ENC_PRIV_KEY;
sPymbed 16:048e5e270a58 7919 } else
sPymbed 16:048e5e270a58 7920 #ifdef HAVE_ECC
sPymbed 16:048e5e270a58 7921 if (header == BEGIN_ENC_PRIV_KEY) {
sPymbed 16:048e5e270a58 7922 header = BEGIN_EC_PRIV; footer = END_EC_PRIV;
sPymbed 16:048e5e270a58 7923 } else
sPymbed 16:048e5e270a58 7924 if (header == BEGIN_EC_PRIV) {
sPymbed 16:048e5e270a58 7925 header = BEGIN_DSA_PRIV; footer = END_DSA_PRIV;
sPymbed 16:048e5e270a58 7926 } else
sPymbed 16:048e5e270a58 7927 #endif
sPymbed 16:048e5e270a58 7928 #ifdef HAVE_ED25519
sPymbed 16:048e5e270a58 7929 #ifdef HAVE_ECC
sPymbed 16:048e5e270a58 7930 if (header == BEGIN_DSA_PRIV)
sPymbed 16:048e5e270a58 7931 #else
sPymbed 16:048e5e270a58 7932 if (header == BEGIN_ENC_PRIV_KEY)
sPymbed 16:048e5e270a58 7933 #endif
sPymbed 16:048e5e270a58 7934 {
sPymbed 16:048e5e270a58 7935 header = BEGIN_EDDSA_PRIV; footer = END_EDDSA_PRIV;
sPymbed 16:048e5e270a58 7936 } else
sPymbed 16:048e5e270a58 7937 #endif
sPymbed 16:048e5e270a58 7938 #ifdef HAVE_CRL
sPymbed 16:048e5e270a58 7939 if (type == CRL_TYPE) {
sPymbed 16:048e5e270a58 7940 header = BEGIN_CRL; footer = END_CRL;
sPymbed 16:048e5e270a58 7941 } else
sPymbed 16:048e5e270a58 7942 #endif
sPymbed 16:048e5e270a58 7943 {
sPymbed 16:048e5e270a58 7944 break;
sPymbed 16:048e5e270a58 7945 }
sPymbed 16:048e5e270a58 7946 }
sPymbed 16:048e5e270a58 7947
sPymbed 16:048e5e270a58 7948 if (!headerEnd) {
sPymbed 16:048e5e270a58 7949 WOLFSSL_MSG("Couldn't find PEM header");
sPymbed 16:048e5e270a58 7950 return ASN_NO_PEM_HEADER;
sPymbed 16:048e5e270a58 7951 }
sPymbed 16:048e5e270a58 7952
sPymbed 16:048e5e270a58 7953 headerEnd += XSTRLEN(header);
sPymbed 16:048e5e270a58 7954
sPymbed 16:048e5e270a58 7955 if ((headerEnd + 1) >= bufferEnd)
sPymbed 16:048e5e270a58 7956 return BUFFER_E;
sPymbed 16:048e5e270a58 7957
sPymbed 16:048e5e270a58 7958 /* eat end of line */
sPymbed 16:048e5e270a58 7959 if (headerEnd[0] == '\n')
sPymbed 16:048e5e270a58 7960 headerEnd++;
sPymbed 16:048e5e270a58 7961 else if (headerEnd[1] == '\n')
sPymbed 16:048e5e270a58 7962 headerEnd += 2;
sPymbed 16:048e5e270a58 7963 else {
sPymbed 16:048e5e270a58 7964 if (info)
sPymbed 16:048e5e270a58 7965 info->consumed = (long)(headerEnd+2 - (char*)buff);
sPymbed 16:048e5e270a58 7966 return BUFFER_E;
sPymbed 16:048e5e270a58 7967 }
sPymbed 16:048e5e270a58 7968
sPymbed 16:048e5e270a58 7969 if (type == PRIVATEKEY_TYPE) {
sPymbed 16:048e5e270a58 7970 if (eccKey) {
sPymbed 16:048e5e270a58 7971 #ifdef HAVE_ECC
sPymbed 16:048e5e270a58 7972 *eccKey = (header == BEGIN_EC_PRIV) ? 1 : 0;
sPymbed 16:048e5e270a58 7973 #else
sPymbed 16:048e5e270a58 7974 *eccKey = 0;
sPymbed 16:048e5e270a58 7975 #endif
sPymbed 16:048e5e270a58 7976 }
sPymbed 16:048e5e270a58 7977 }
sPymbed 16:048e5e270a58 7978
sPymbed 16:048e5e270a58 7979 #ifdef WOLFSSL_ENCRYPTED_KEYS
sPymbed 16:048e5e270a58 7980 if (info) {
sPymbed 16:048e5e270a58 7981 ret = wc_EncryptedInfoParse(info, &headerEnd, bufferEnd - headerEnd);
sPymbed 16:048e5e270a58 7982 if (ret < 0)
sPymbed 16:048e5e270a58 7983 return ret;
sPymbed 16:048e5e270a58 7984 if (info->set)
sPymbed 16:048e5e270a58 7985 encrypted_key = 1;
sPymbed 16:048e5e270a58 7986 }
sPymbed 16:048e5e270a58 7987 #endif /* WOLFSSL_ENCRYPTED_KEYS */
sPymbed 16:048e5e270a58 7988
sPymbed 16:048e5e270a58 7989 /* find footer */
sPymbed 16:048e5e270a58 7990 footerEnd = XSTRNSTR((char*)buff, footer, sz);
sPymbed 16:048e5e270a58 7991 if (!footerEnd) {
sPymbed 16:048e5e270a58 7992 if (info)
sPymbed 16:048e5e270a58 7993 info->consumed = longSz; /* No more certs if no footer */
sPymbed 16:048e5e270a58 7994 return BUFFER_E;
sPymbed 16:048e5e270a58 7995 }
sPymbed 16:048e5e270a58 7996
sPymbed 16:048e5e270a58 7997 consumedEnd = footerEnd + XSTRLEN(footer);
sPymbed 16:048e5e270a58 7998
sPymbed 16:048e5e270a58 7999 if (consumedEnd < bufferEnd) { /* handle no end of line on last line */
sPymbed 16:048e5e270a58 8000 /* eat end of line */
sPymbed 16:048e5e270a58 8001 if (consumedEnd[0] == '\n')
sPymbed 16:048e5e270a58 8002 consumedEnd++;
sPymbed 16:048e5e270a58 8003 else if ((consumedEnd + 1 < bufferEnd) && consumedEnd[1] == '\n')
sPymbed 16:048e5e270a58 8004 consumedEnd += 2;
sPymbed 16:048e5e270a58 8005 else {
sPymbed 16:048e5e270a58 8006 if (info)
sPymbed 16:048e5e270a58 8007 info->consumed = (long)(consumedEnd+2 - (char*)buff);
sPymbed 16:048e5e270a58 8008 return BUFFER_E;
sPymbed 16:048e5e270a58 8009 }
sPymbed 16:048e5e270a58 8010 }
sPymbed 16:048e5e270a58 8011
sPymbed 16:048e5e270a58 8012 if (info)
sPymbed 16:048e5e270a58 8013 info->consumed = (long)(consumedEnd - (char*)buff);
sPymbed 16:048e5e270a58 8014
sPymbed 16:048e5e270a58 8015 /* set up der buffer */
sPymbed 16:048e5e270a58 8016 neededSz = (long)(footerEnd - headerEnd);
sPymbed 16:048e5e270a58 8017 if (neededSz > sz || neededSz <= 0)
sPymbed 16:048e5e270a58 8018 return BUFFER_E;
sPymbed 16:048e5e270a58 8019
sPymbed 16:048e5e270a58 8020 ret = AllocDer(pDer, (word32)neededSz, type, heap);
sPymbed 16:048e5e270a58 8021 if (ret < 0) {
sPymbed 16:048e5e270a58 8022 return ret;
sPymbed 16:048e5e270a58 8023 }
sPymbed 16:048e5e270a58 8024 der = *pDer;
sPymbed 16:048e5e270a58 8025
sPymbed 16:048e5e270a58 8026 if (Base64_Decode((byte*)headerEnd, (word32)neededSz,
sPymbed 16:048e5e270a58 8027 der->buffer, &der->length) < 0)
sPymbed 16:048e5e270a58 8028 return BUFFER_E;
sPymbed 16:048e5e270a58 8029
sPymbed 16:048e5e270a58 8030 if (header == BEGIN_PRIV_KEY && !encrypted_key) {
sPymbed 16:048e5e270a58 8031 /* pkcs8 key, convert and adjust length */
sPymbed 16:048e5e270a58 8032 if ((ret = ToTraditional(der->buffer, der->length)) < 0)
sPymbed 16:048e5e270a58 8033 return ret;
sPymbed 16:048e5e270a58 8034
sPymbed 16:048e5e270a58 8035 der->length = ret;
sPymbed 16:048e5e270a58 8036 return 0;
sPymbed 16:048e5e270a58 8037 }
sPymbed 16:048e5e270a58 8038
sPymbed 16:048e5e270a58 8039 #ifdef WOLFSSL_ENCRYPTED_KEYS
sPymbed 16:048e5e270a58 8040 if (encrypted_key || header == BEGIN_ENC_PRIV_KEY) {
sPymbed 16:048e5e270a58 8041 int passwordSz = NAME_SZ;
sPymbed 16:048e5e270a58 8042 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 8043 char* password = NULL;
sPymbed 16:048e5e270a58 8044 #else
sPymbed 16:048e5e270a58 8045 char password[NAME_SZ];
sPymbed 16:048e5e270a58 8046 #endif
sPymbed 16:048e5e270a58 8047
sPymbed 16:048e5e270a58 8048 if (!info || !info->passwd_cb) {
sPymbed 16:048e5e270a58 8049 WOLFSSL_MSG("No password callback set");
sPymbed 16:048e5e270a58 8050 return NO_PASSWORD;
sPymbed 16:048e5e270a58 8051 }
sPymbed 16:048e5e270a58 8052
sPymbed 16:048e5e270a58 8053 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 8054 password = (char*)XMALLOC(passwordSz, heap, DYNAMIC_TYPE_STRING);
sPymbed 16:048e5e270a58 8055 if (password == NULL)
sPymbed 16:048e5e270a58 8056 return MEMORY_E;
sPymbed 16:048e5e270a58 8057 #endif
sPymbed 16:048e5e270a58 8058
sPymbed 16:048e5e270a58 8059 /* get password */
sPymbed 16:048e5e270a58 8060 ret = info->passwd_cb(password, passwordSz, PEM_PASS_READ,
sPymbed 16:048e5e270a58 8061 info->passwd_userdata);
sPymbed 16:048e5e270a58 8062 if (ret >= 0) {
sPymbed 16:048e5e270a58 8063 passwordSz = ret;
sPymbed 16:048e5e270a58 8064
sPymbed 16:048e5e270a58 8065 /* convert and adjust length */
sPymbed 16:048e5e270a58 8066 if (header == BEGIN_ENC_PRIV_KEY) {
sPymbed 16:048e5e270a58 8067 #ifndef NO_PWDBASED
sPymbed 16:048e5e270a58 8068 ret = ToTraditionalEnc(der->buffer, der->length,
sPymbed 16:048e5e270a58 8069 password, passwordSz);
sPymbed 16:048e5e270a58 8070
sPymbed 16:048e5e270a58 8071 if (ret >= 0) {
sPymbed 16:048e5e270a58 8072 der->length = ret;
sPymbed 16:048e5e270a58 8073 }
sPymbed 16:048e5e270a58 8074 #else
sPymbed 16:048e5e270a58 8075 ret = NOT_COMPILED_IN;
sPymbed 16:048e5e270a58 8076 #endif
sPymbed 16:048e5e270a58 8077 }
sPymbed 16:048e5e270a58 8078 /* decrypt the key */
sPymbed 16:048e5e270a58 8079 else {
sPymbed 16:048e5e270a58 8080 ret = wc_BufferKeyDecrypt(info, der->buffer, der->length,
sPymbed 16:048e5e270a58 8081 (byte*)password, passwordSz, WC_MD5);
sPymbed 16:048e5e270a58 8082 }
sPymbed 16:048e5e270a58 8083 ForceZero(password, passwordSz);
sPymbed 16:048e5e270a58 8084 }
sPymbed 16:048e5e270a58 8085
sPymbed 16:048e5e270a58 8086 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 8087 XFREE(password, heap, DYNAMIC_TYPE_STRING);
sPymbed 16:048e5e270a58 8088 #endif
sPymbed 16:048e5e270a58 8089 }
sPymbed 16:048e5e270a58 8090 #endif /* WOLFSSL_ENCRYPTED_KEYS */
sPymbed 16:048e5e270a58 8091
sPymbed 16:048e5e270a58 8092 return ret;
sPymbed 16:048e5e270a58 8093 }
sPymbed 16:048e5e270a58 8094
sPymbed 16:048e5e270a58 8095 int wc_PemToDer(const unsigned char* buff, long longSz, int type,
sPymbed 16:048e5e270a58 8096 DerBuffer** pDer, void* heap, EncryptedInfo* info, int* eccKey)
sPymbed 16:048e5e270a58 8097 {
sPymbed 16:048e5e270a58 8098 return PemToDer(buff, longSz, type, pDer, heap, info, eccKey);
sPymbed 16:048e5e270a58 8099 }
sPymbed 16:048e5e270a58 8100
sPymbed 16:048e5e270a58 8101
sPymbed 16:048e5e270a58 8102 /* our KeyPemToDer password callback, password in userData */
sPymbed 16:048e5e270a58 8103 static WC_INLINE int OurPasswordCb(char* passwd, int sz, int rw, void* userdata)
sPymbed 16:048e5e270a58 8104 {
sPymbed 16:048e5e270a58 8105 (void)rw;
sPymbed 16:048e5e270a58 8106
sPymbed 16:048e5e270a58 8107 if (userdata == NULL)
sPymbed 16:048e5e270a58 8108 return 0;
sPymbed 16:048e5e270a58 8109
sPymbed 16:048e5e270a58 8110 XSTRNCPY(passwd, (char*)userdata, sz);
sPymbed 16:048e5e270a58 8111 return min((word32)sz, (word32)XSTRLEN((char*)userdata));
sPymbed 16:048e5e270a58 8112 }
sPymbed 16:048e5e270a58 8113
sPymbed 16:048e5e270a58 8114 /* Return bytes written to buff or < 0 for error */
sPymbed 16:048e5e270a58 8115 int wc_KeyPemToDer(const unsigned char* pem, int pemSz,
sPymbed 16:048e5e270a58 8116 unsigned char* buff, int buffSz, const char* pass)
sPymbed 16:048e5e270a58 8117 {
sPymbed 16:048e5e270a58 8118 int eccKey = 0;
sPymbed 16:048e5e270a58 8119 int ret;
sPymbed 16:048e5e270a58 8120 DerBuffer* der = NULL;
sPymbed 16:048e5e270a58 8121 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 8122 EncryptedInfo* info = NULL;
sPymbed 16:048e5e270a58 8123 #else
sPymbed 16:048e5e270a58 8124 EncryptedInfo info[1];
sPymbed 16:048e5e270a58 8125 #endif
sPymbed 16:048e5e270a58 8126
sPymbed 16:048e5e270a58 8127 WOLFSSL_ENTER("wc_KeyPemToDer");
sPymbed 16:048e5e270a58 8128
sPymbed 16:048e5e270a58 8129 if (pem == NULL || buff == NULL || buffSz <= 0) {
sPymbed 16:048e5e270a58 8130 WOLFSSL_MSG("Bad pem der args");
sPymbed 16:048e5e270a58 8131 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 8132 }
sPymbed 16:048e5e270a58 8133
sPymbed 16:048e5e270a58 8134 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 8135 info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
sPymbed 16:048e5e270a58 8136 DYNAMIC_TYPE_ENCRYPTEDINFO);
sPymbed 16:048e5e270a58 8137 if (info == NULL)
sPymbed 16:048e5e270a58 8138 return MEMORY_E;
sPymbed 16:048e5e270a58 8139 #endif
sPymbed 16:048e5e270a58 8140
sPymbed 16:048e5e270a58 8141 XMEMSET(info, 0, sizeof(EncryptedInfo));
sPymbed 16:048e5e270a58 8142 info->passwd_cb = OurPasswordCb;
sPymbed 16:048e5e270a58 8143 info->passwd_userdata = (void*)pass;
sPymbed 16:048e5e270a58 8144
sPymbed 16:048e5e270a58 8145 ret = PemToDer(pem, pemSz, PRIVATEKEY_TYPE, &der, NULL, info, &eccKey);
sPymbed 16:048e5e270a58 8146
sPymbed 16:048e5e270a58 8147 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 8148 XFREE(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO);
sPymbed 16:048e5e270a58 8149 #endif
sPymbed 16:048e5e270a58 8150
sPymbed 16:048e5e270a58 8151 if (ret < 0) {
sPymbed 16:048e5e270a58 8152 WOLFSSL_MSG("Bad Pem To Der");
sPymbed 16:048e5e270a58 8153 }
sPymbed 16:048e5e270a58 8154 else {
sPymbed 16:048e5e270a58 8155 if (der->length <= (word32)buffSz) {
sPymbed 16:048e5e270a58 8156 XMEMCPY(buff, der->buffer, der->length);
sPymbed 16:048e5e270a58 8157 ret = der->length;
sPymbed 16:048e5e270a58 8158 }
sPymbed 16:048e5e270a58 8159 else {
sPymbed 16:048e5e270a58 8160 WOLFSSL_MSG("Bad der length");
sPymbed 16:048e5e270a58 8161 ret = BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 8162 }
sPymbed 16:048e5e270a58 8163 }
sPymbed 16:048e5e270a58 8164
sPymbed 16:048e5e270a58 8165 FreeDer(&der);
sPymbed 16:048e5e270a58 8166 return ret;
sPymbed 16:048e5e270a58 8167 }
sPymbed 16:048e5e270a58 8168
sPymbed 16:048e5e270a58 8169
sPymbed 16:048e5e270a58 8170 /* Return bytes written to buff or < 0 for error */
sPymbed 16:048e5e270a58 8171 int wc_CertPemToDer(const unsigned char* pem, int pemSz,
sPymbed 16:048e5e270a58 8172 unsigned char* buff, int buffSz, int type)
sPymbed 16:048e5e270a58 8173 {
sPymbed 16:048e5e270a58 8174 int eccKey = 0;
sPymbed 16:048e5e270a58 8175 int ret;
sPymbed 16:048e5e270a58 8176 DerBuffer* der = NULL;
sPymbed 16:048e5e270a58 8177
sPymbed 16:048e5e270a58 8178 WOLFSSL_ENTER("wc_CertPemToDer");
sPymbed 16:048e5e270a58 8179
sPymbed 16:048e5e270a58 8180 if (pem == NULL || buff == NULL || buffSz <= 0) {
sPymbed 16:048e5e270a58 8181 WOLFSSL_MSG("Bad pem der args");
sPymbed 16:048e5e270a58 8182 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 8183 }
sPymbed 16:048e5e270a58 8184
sPymbed 16:048e5e270a58 8185 if (type != CERT_TYPE && type != CA_TYPE && type != CERTREQ_TYPE) {
sPymbed 16:048e5e270a58 8186 WOLFSSL_MSG("Bad cert type");
sPymbed 16:048e5e270a58 8187 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 8188 }
sPymbed 16:048e5e270a58 8189
sPymbed 16:048e5e270a58 8190
sPymbed 16:048e5e270a58 8191 ret = PemToDer(pem, pemSz, type, &der, NULL, NULL, &eccKey);
sPymbed 16:048e5e270a58 8192 if (ret < 0) {
sPymbed 16:048e5e270a58 8193 WOLFSSL_MSG("Bad Pem To Der");
sPymbed 16:048e5e270a58 8194 }
sPymbed 16:048e5e270a58 8195 else {
sPymbed 16:048e5e270a58 8196 if (der->length <= (word32)buffSz) {
sPymbed 16:048e5e270a58 8197 XMEMCPY(buff, der->buffer, der->length);
sPymbed 16:048e5e270a58 8198 ret = der->length;
sPymbed 16:048e5e270a58 8199 }
sPymbed 16:048e5e270a58 8200 else {
sPymbed 16:048e5e270a58 8201 WOLFSSL_MSG("Bad der length");
sPymbed 16:048e5e270a58 8202 ret = BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 8203 }
sPymbed 16:048e5e270a58 8204 }
sPymbed 16:048e5e270a58 8205
sPymbed 16:048e5e270a58 8206 FreeDer(&der);
sPymbed 16:048e5e270a58 8207 return ret;
sPymbed 16:048e5e270a58 8208 }
sPymbed 16:048e5e270a58 8209
sPymbed 16:048e5e270a58 8210 #endif /* WOLFSSL_PEM_TO_DER */
sPymbed 16:048e5e270a58 8211 #endif /* WOLFSSL_PEM_TO_DER || WOLFSSL_DER_TO_PEM */
sPymbed 16:048e5e270a58 8212
sPymbed 16:048e5e270a58 8213
sPymbed 16:048e5e270a58 8214 #ifdef WOLFSSL_PEM_TO_DER
sPymbed 16:048e5e270a58 8215 #if defined(WOLFSSL_CERT_EXT) || defined(WOLFSSL_PUB_PEM_TO_DER)
sPymbed 16:048e5e270a58 8216 /* Return bytes written to buff or < 0 for error */
sPymbed 16:048e5e270a58 8217 int wc_PubKeyPemToDer(const unsigned char* pem, int pemSz,
sPymbed 16:048e5e270a58 8218 unsigned char* buff, int buffSz)
sPymbed 16:048e5e270a58 8219 {
sPymbed 16:048e5e270a58 8220 int ret;
sPymbed 16:048e5e270a58 8221 DerBuffer* der = NULL;
sPymbed 16:048e5e270a58 8222
sPymbed 16:048e5e270a58 8223 WOLFSSL_ENTER("wc_PubKeyPemToDer");
sPymbed 16:048e5e270a58 8224
sPymbed 16:048e5e270a58 8225 if (pem == NULL || buff == NULL || buffSz <= 0) {
sPymbed 16:048e5e270a58 8226 WOLFSSL_MSG("Bad pem der args");
sPymbed 16:048e5e270a58 8227 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 8228 }
sPymbed 16:048e5e270a58 8229
sPymbed 16:048e5e270a58 8230 ret = PemToDer(pem, pemSz, PUBLICKEY_TYPE, &der, NULL, NULL, NULL);
sPymbed 16:048e5e270a58 8231 if (ret < 0) {
sPymbed 16:048e5e270a58 8232 WOLFSSL_MSG("Bad Pem To Der");
sPymbed 16:048e5e270a58 8233 }
sPymbed 16:048e5e270a58 8234 else {
sPymbed 16:048e5e270a58 8235 if (der->length <= (word32)buffSz) {
sPymbed 16:048e5e270a58 8236 XMEMCPY(buff, der->buffer, der->length);
sPymbed 16:048e5e270a58 8237 ret = der->length;
sPymbed 16:048e5e270a58 8238 }
sPymbed 16:048e5e270a58 8239 else {
sPymbed 16:048e5e270a58 8240 WOLFSSL_MSG("Bad der length");
sPymbed 16:048e5e270a58 8241 ret = BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 8242 }
sPymbed 16:048e5e270a58 8243 }
sPymbed 16:048e5e270a58 8244
sPymbed 16:048e5e270a58 8245 FreeDer(&der);
sPymbed 16:048e5e270a58 8246 return ret;
sPymbed 16:048e5e270a58 8247 }
sPymbed 16:048e5e270a58 8248 #endif /* WOLFSSL_CERT_EXT || WOLFSSL_PUB_PEM_TO_DER */
sPymbed 16:048e5e270a58 8249 #endif /* WOLFSSL_PEM_TO_DER */
sPymbed 16:048e5e270a58 8250
sPymbed 16:048e5e270a58 8251 #ifndef NO_FILESYSTEM
sPymbed 16:048e5e270a58 8252
sPymbed 16:048e5e270a58 8253 #ifdef WOLFSSL_CERT_GEN
sPymbed 16:048e5e270a58 8254 /* load pem cert from file into der buffer, return der size or error */
sPymbed 16:048e5e270a58 8255 int wc_PemCertToDer(const char* fileName, unsigned char* derBuf, int derSz)
sPymbed 16:048e5e270a58 8256 {
sPymbed 16:048e5e270a58 8257 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 8258 byte staticBuffer[1]; /* force XMALLOC */
sPymbed 16:048e5e270a58 8259 #else
sPymbed 16:048e5e270a58 8260 byte staticBuffer[FILE_BUFFER_SIZE];
sPymbed 16:048e5e270a58 8261 #endif
sPymbed 16:048e5e270a58 8262 byte* fileBuf = staticBuffer;
sPymbed 16:048e5e270a58 8263 int dynamic = 0;
sPymbed 16:048e5e270a58 8264 int ret = 0;
sPymbed 16:048e5e270a58 8265 long sz = 0;
sPymbed 16:048e5e270a58 8266 XFILE file = XFOPEN(fileName, "rb");
sPymbed 16:048e5e270a58 8267 DerBuffer* converted = NULL;
sPymbed 16:048e5e270a58 8268
sPymbed 16:048e5e270a58 8269 WOLFSSL_ENTER("wc_PemCertToDer");
sPymbed 16:048e5e270a58 8270
sPymbed 16:048e5e270a58 8271 if (file == XBADFILE) {
sPymbed 16:048e5e270a58 8272 ret = BUFFER_E;
sPymbed 16:048e5e270a58 8273 }
sPymbed 16:048e5e270a58 8274 else {
sPymbed 16:048e5e270a58 8275 XFSEEK(file, 0, XSEEK_END);
sPymbed 16:048e5e270a58 8276 sz = XFTELL(file);
sPymbed 16:048e5e270a58 8277 XREWIND(file);
sPymbed 16:048e5e270a58 8278
sPymbed 16:048e5e270a58 8279 if (sz <= 0) {
sPymbed 16:048e5e270a58 8280 ret = BUFFER_E;
sPymbed 16:048e5e270a58 8281 }
sPymbed 16:048e5e270a58 8282 else if (sz > (long)sizeof(staticBuffer)) {
sPymbed 16:048e5e270a58 8283 #ifdef WOLFSSL_STATIC_MEMORY
sPymbed 16:048e5e270a58 8284 WOLFSSL_MSG("File was larger then static buffer");
sPymbed 16:048e5e270a58 8285 return MEMORY_E;
sPymbed 16:048e5e270a58 8286 #endif
sPymbed 16:048e5e270a58 8287 fileBuf = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE);
sPymbed 16:048e5e270a58 8288 if (fileBuf == NULL)
sPymbed 16:048e5e270a58 8289 ret = MEMORY_E;
sPymbed 16:048e5e270a58 8290 else
sPymbed 16:048e5e270a58 8291 dynamic = 1;
sPymbed 16:048e5e270a58 8292 }
sPymbed 16:048e5e270a58 8293
sPymbed 16:048e5e270a58 8294 if (ret == 0) {
sPymbed 16:048e5e270a58 8295 if ( (ret = (int)XFREAD(fileBuf, 1, sz, file)) != sz) {
sPymbed 16:048e5e270a58 8296 ret = BUFFER_E;
sPymbed 16:048e5e270a58 8297 }
sPymbed 16:048e5e270a58 8298 #ifdef WOLFSSL_PEM_TO_DER
sPymbed 16:048e5e270a58 8299 else {
sPymbed 16:048e5e270a58 8300 ret = PemToDer(fileBuf, sz, CA_TYPE, &converted, 0, NULL,NULL);
sPymbed 16:048e5e270a58 8301 }
sPymbed 16:048e5e270a58 8302 #endif
sPymbed 16:048e5e270a58 8303
sPymbed 16:048e5e270a58 8304 if (ret == 0) {
sPymbed 16:048e5e270a58 8305 if (converted->length < (word32)derSz) {
sPymbed 16:048e5e270a58 8306 XMEMCPY(derBuf, converted->buffer, converted->length);
sPymbed 16:048e5e270a58 8307 ret = converted->length;
sPymbed 16:048e5e270a58 8308 }
sPymbed 16:048e5e270a58 8309 else
sPymbed 16:048e5e270a58 8310 ret = BUFFER_E;
sPymbed 16:048e5e270a58 8311 }
sPymbed 16:048e5e270a58 8312
sPymbed 16:048e5e270a58 8313 FreeDer(&converted);
sPymbed 16:048e5e270a58 8314 }
sPymbed 16:048e5e270a58 8315
sPymbed 16:048e5e270a58 8316 XFCLOSE(file);
sPymbed 16:048e5e270a58 8317 if (dynamic)
sPymbed 16:048e5e270a58 8318 XFREE(fileBuf, NULL, DYNAMIC_TYPE_FILE);
sPymbed 16:048e5e270a58 8319 }
sPymbed 16:048e5e270a58 8320
sPymbed 16:048e5e270a58 8321 return ret;
sPymbed 16:048e5e270a58 8322 }
sPymbed 16:048e5e270a58 8323 #endif /* WOLFSSL_CERT_GEN */
sPymbed 16:048e5e270a58 8324
sPymbed 16:048e5e270a58 8325 #if defined(WOLFSSL_CERT_EXT) || defined(WOLFSSL_PUB_PEM_TO_DER)
sPymbed 16:048e5e270a58 8326 /* load pem public key from file into der buffer, return der size or error */
sPymbed 16:048e5e270a58 8327 int wc_PemPubKeyToDer(const char* fileName,
sPymbed 16:048e5e270a58 8328 unsigned char* derBuf, int derSz)
sPymbed 16:048e5e270a58 8329 {
sPymbed 16:048e5e270a58 8330 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 8331 byte staticBuffer[1]; /* force XMALLOC */
sPymbed 16:048e5e270a58 8332 #else
sPymbed 16:048e5e270a58 8333 byte staticBuffer[FILE_BUFFER_SIZE];
sPymbed 16:048e5e270a58 8334 #endif
sPymbed 16:048e5e270a58 8335 byte* fileBuf = staticBuffer;
sPymbed 16:048e5e270a58 8336 int dynamic = 0;
sPymbed 16:048e5e270a58 8337 int ret = 0;
sPymbed 16:048e5e270a58 8338 long sz = 0;
sPymbed 16:048e5e270a58 8339 XFILE file = XFOPEN(fileName, "rb");
sPymbed 16:048e5e270a58 8340 DerBuffer* converted = NULL;
sPymbed 16:048e5e270a58 8341
sPymbed 16:048e5e270a58 8342 WOLFSSL_ENTER("wc_PemPubKeyToDer");
sPymbed 16:048e5e270a58 8343
sPymbed 16:048e5e270a58 8344 if (file == XBADFILE) {
sPymbed 16:048e5e270a58 8345 ret = BUFFER_E;
sPymbed 16:048e5e270a58 8346 }
sPymbed 16:048e5e270a58 8347 else {
sPymbed 16:048e5e270a58 8348 XFSEEK(file, 0, XSEEK_END);
sPymbed 16:048e5e270a58 8349 sz = XFTELL(file);
sPymbed 16:048e5e270a58 8350 XREWIND(file);
sPymbed 16:048e5e270a58 8351
sPymbed 16:048e5e270a58 8352 if (sz <= 0) {
sPymbed 16:048e5e270a58 8353 ret = BUFFER_E;
sPymbed 16:048e5e270a58 8354 }
sPymbed 16:048e5e270a58 8355 else if (sz > (long)sizeof(staticBuffer)) {
sPymbed 16:048e5e270a58 8356 #ifdef WOLFSSL_STATIC_MEMORY
sPymbed 16:048e5e270a58 8357 WOLFSSL_MSG("File was larger then static buffer");
sPymbed 16:048e5e270a58 8358 return MEMORY_E;
sPymbed 16:048e5e270a58 8359 #endif
sPymbed 16:048e5e270a58 8360 fileBuf = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE);
sPymbed 16:048e5e270a58 8361 if (fileBuf == NULL)
sPymbed 16:048e5e270a58 8362 ret = MEMORY_E;
sPymbed 16:048e5e270a58 8363 else
sPymbed 16:048e5e270a58 8364 dynamic = 1;
sPymbed 16:048e5e270a58 8365 }
sPymbed 16:048e5e270a58 8366 if (ret == 0) {
sPymbed 16:048e5e270a58 8367 if ( (ret = (int)XFREAD(fileBuf, 1, sz, file)) != sz) {
sPymbed 16:048e5e270a58 8368 ret = BUFFER_E;
sPymbed 16:048e5e270a58 8369 }
sPymbed 16:048e5e270a58 8370 #ifdef WOLFSSL_PEM_TO_DER
sPymbed 16:048e5e270a58 8371 else {
sPymbed 16:048e5e270a58 8372 ret = PemToDer(fileBuf, sz, PUBLICKEY_TYPE, &converted,
sPymbed 16:048e5e270a58 8373 0, NULL, NULL);
sPymbed 16:048e5e270a58 8374 }
sPymbed 16:048e5e270a58 8375 #endif
sPymbed 16:048e5e270a58 8376
sPymbed 16:048e5e270a58 8377 if (ret == 0) {
sPymbed 16:048e5e270a58 8378 if (converted->length < (word32)derSz) {
sPymbed 16:048e5e270a58 8379 XMEMCPY(derBuf, converted->buffer, converted->length);
sPymbed 16:048e5e270a58 8380 ret = converted->length;
sPymbed 16:048e5e270a58 8381 }
sPymbed 16:048e5e270a58 8382 else
sPymbed 16:048e5e270a58 8383 ret = BUFFER_E;
sPymbed 16:048e5e270a58 8384 }
sPymbed 16:048e5e270a58 8385
sPymbed 16:048e5e270a58 8386 FreeDer(&converted);
sPymbed 16:048e5e270a58 8387 }
sPymbed 16:048e5e270a58 8388
sPymbed 16:048e5e270a58 8389 XFCLOSE(file);
sPymbed 16:048e5e270a58 8390 if (dynamic)
sPymbed 16:048e5e270a58 8391 XFREE(fileBuf, NULL, DYNAMIC_TYPE_FILE);
sPymbed 16:048e5e270a58 8392 }
sPymbed 16:048e5e270a58 8393
sPymbed 16:048e5e270a58 8394 return ret;
sPymbed 16:048e5e270a58 8395 }
sPymbed 16:048e5e270a58 8396 #endif /* WOLFSSL_CERT_EXT || WOLFSSL_PUB_PEM_TO_DER */
sPymbed 16:048e5e270a58 8397
sPymbed 16:048e5e270a58 8398 #endif /* !NO_FILESYSTEM */
sPymbed 16:048e5e270a58 8399
sPymbed 16:048e5e270a58 8400
sPymbed 16:048e5e270a58 8401 #if !defined(NO_RSA) && (defined(WOLFSSL_CERT_GEN) || \
sPymbed 16:048e5e270a58 8402 ((defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)) && !defined(HAVE_USER_RSA)))
sPymbed 16:048e5e270a58 8403 /* USER RSA ifdef portions used instead of refactor in consideration for
sPymbed 16:048e5e270a58 8404 possible fips build */
sPymbed 16:048e5e270a58 8405 /* Write a public RSA key to output */
sPymbed 16:048e5e270a58 8406 static int SetRsaPublicKey(byte* output, RsaKey* key,
sPymbed 16:048e5e270a58 8407 int outLen, int with_header)
sPymbed 16:048e5e270a58 8408 {
sPymbed 16:048e5e270a58 8409 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 8410 byte* n = NULL;
sPymbed 16:048e5e270a58 8411 byte* e = NULL;
sPymbed 16:048e5e270a58 8412 #else
sPymbed 16:048e5e270a58 8413 byte n[MAX_RSA_INT_SZ];
sPymbed 16:048e5e270a58 8414 byte e[MAX_RSA_E_SZ];
sPymbed 16:048e5e270a58 8415 #endif
sPymbed 16:048e5e270a58 8416 byte seq[MAX_SEQ_SZ];
sPymbed 16:048e5e270a58 8417 byte bitString[1 + MAX_LENGTH_SZ + 1];
sPymbed 16:048e5e270a58 8418 int nSz;
sPymbed 16:048e5e270a58 8419 int eSz;
sPymbed 16:048e5e270a58 8420 int seqSz;
sPymbed 16:048e5e270a58 8421 int bitStringSz;
sPymbed 16:048e5e270a58 8422 int idx;
sPymbed 16:048e5e270a58 8423
sPymbed 16:048e5e270a58 8424 if (output == NULL || key == NULL || outLen < MAX_SEQ_SZ)
sPymbed 16:048e5e270a58 8425 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 8426
sPymbed 16:048e5e270a58 8427 /* n */
sPymbed 16:048e5e270a58 8428 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 8429 n = (byte*)XMALLOC(MAX_RSA_INT_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 8430 if (n == NULL)
sPymbed 16:048e5e270a58 8431 return MEMORY_E;
sPymbed 16:048e5e270a58 8432 #endif
sPymbed 16:048e5e270a58 8433
sPymbed 16:048e5e270a58 8434 #ifdef HAVE_USER_RSA
sPymbed 16:048e5e270a58 8435 nSz = SetASNIntRSA(key->n, n);
sPymbed 16:048e5e270a58 8436 #else
sPymbed 16:048e5e270a58 8437 nSz = SetASNIntMP(&key->n, MAX_RSA_INT_SZ, n);
sPymbed 16:048e5e270a58 8438 #endif
sPymbed 16:048e5e270a58 8439 if (nSz < 0) {
sPymbed 16:048e5e270a58 8440 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 8441 XFREE(n, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 8442 #endif
sPymbed 16:048e5e270a58 8443 return nSz;
sPymbed 16:048e5e270a58 8444 }
sPymbed 16:048e5e270a58 8445
sPymbed 16:048e5e270a58 8446 /* e */
sPymbed 16:048e5e270a58 8447 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 8448 e = (byte*)XMALLOC(MAX_RSA_E_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 8449 if (e == NULL) {
sPymbed 16:048e5e270a58 8450 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 8451 XFREE(n, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 8452 #endif
sPymbed 16:048e5e270a58 8453 return MEMORY_E;
sPymbed 16:048e5e270a58 8454 }
sPymbed 16:048e5e270a58 8455 #endif
sPymbed 16:048e5e270a58 8456
sPymbed 16:048e5e270a58 8457 #ifdef HAVE_USER_RSA
sPymbed 16:048e5e270a58 8458 eSz = SetASNIntRSA(key->e, e);
sPymbed 16:048e5e270a58 8459 #else
sPymbed 16:048e5e270a58 8460 eSz = SetASNIntMP(&key->e, MAX_RSA_INT_SZ, e);
sPymbed 16:048e5e270a58 8461 #endif
sPymbed 16:048e5e270a58 8462 if (eSz < 0) {
sPymbed 16:048e5e270a58 8463 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 8464 XFREE(n, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 8465 XFREE(e, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 8466 #endif
sPymbed 16:048e5e270a58 8467 return eSz;
sPymbed 16:048e5e270a58 8468 }
sPymbed 16:048e5e270a58 8469
sPymbed 16:048e5e270a58 8470 seqSz = SetSequence(nSz + eSz, seq);
sPymbed 16:048e5e270a58 8471
sPymbed 16:048e5e270a58 8472 /* check output size */
sPymbed 16:048e5e270a58 8473 if ( (seqSz + nSz + eSz) > outLen) {
sPymbed 16:048e5e270a58 8474 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 8475 XFREE(n, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 8476 XFREE(e, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 8477 #endif
sPymbed 16:048e5e270a58 8478 return BUFFER_E;
sPymbed 16:048e5e270a58 8479 }
sPymbed 16:048e5e270a58 8480
sPymbed 16:048e5e270a58 8481 /* headers */
sPymbed 16:048e5e270a58 8482 if (with_header) {
sPymbed 16:048e5e270a58 8483 int algoSz;
sPymbed 16:048e5e270a58 8484 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 8485 byte* algo = NULL;
sPymbed 16:048e5e270a58 8486
sPymbed 16:048e5e270a58 8487 algo = (byte*)XMALLOC(MAX_ALGO_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 8488 if (algo == NULL) {
sPymbed 16:048e5e270a58 8489 XFREE(n, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 8490 XFREE(e, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 8491 return MEMORY_E;
sPymbed 16:048e5e270a58 8492 }
sPymbed 16:048e5e270a58 8493 #else
sPymbed 16:048e5e270a58 8494 byte algo[MAX_ALGO_SZ];
sPymbed 16:048e5e270a58 8495 #endif
sPymbed 16:048e5e270a58 8496 algoSz = SetAlgoID(RSAk, algo, oidKeyType, 0);
sPymbed 16:048e5e270a58 8497 bitStringSz = SetBitString(seqSz + nSz + eSz, 0, bitString);
sPymbed 16:048e5e270a58 8498
sPymbed 16:048e5e270a58 8499 idx = SetSequence(nSz + eSz + seqSz + bitStringSz + algoSz, output);
sPymbed 16:048e5e270a58 8500
sPymbed 16:048e5e270a58 8501 /* check output size */
sPymbed 16:048e5e270a58 8502 if ( (idx + algoSz + bitStringSz + seqSz + nSz + eSz) > outLen) {
sPymbed 16:048e5e270a58 8503 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 8504 XFREE(n, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 8505 XFREE(e, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 8506 XFREE(algo, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 8507 #endif
sPymbed 16:048e5e270a58 8508
sPymbed 16:048e5e270a58 8509 return BUFFER_E;
sPymbed 16:048e5e270a58 8510 }
sPymbed 16:048e5e270a58 8511
sPymbed 16:048e5e270a58 8512 /* algo */
sPymbed 16:048e5e270a58 8513 XMEMCPY(output + idx, algo, algoSz);
sPymbed 16:048e5e270a58 8514 idx += algoSz;
sPymbed 16:048e5e270a58 8515 /* bit string */
sPymbed 16:048e5e270a58 8516 XMEMCPY(output + idx, bitString, bitStringSz);
sPymbed 16:048e5e270a58 8517 idx += bitStringSz;
sPymbed 16:048e5e270a58 8518 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 8519 XFREE(algo, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 8520 #endif
sPymbed 16:048e5e270a58 8521 }
sPymbed 16:048e5e270a58 8522 else
sPymbed 16:048e5e270a58 8523 idx = 0;
sPymbed 16:048e5e270a58 8524
sPymbed 16:048e5e270a58 8525 /* seq */
sPymbed 16:048e5e270a58 8526 XMEMCPY(output + idx, seq, seqSz);
sPymbed 16:048e5e270a58 8527 idx += seqSz;
sPymbed 16:048e5e270a58 8528 /* n */
sPymbed 16:048e5e270a58 8529 XMEMCPY(output + idx, n, nSz);
sPymbed 16:048e5e270a58 8530 idx += nSz;
sPymbed 16:048e5e270a58 8531 /* e */
sPymbed 16:048e5e270a58 8532 XMEMCPY(output + idx, e, eSz);
sPymbed 16:048e5e270a58 8533 idx += eSz;
sPymbed 16:048e5e270a58 8534
sPymbed 16:048e5e270a58 8535 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 8536 XFREE(n, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 8537 XFREE(e, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 8538 #endif
sPymbed 16:048e5e270a58 8539
sPymbed 16:048e5e270a58 8540 return idx;
sPymbed 16:048e5e270a58 8541 }
sPymbed 16:048e5e270a58 8542
sPymbed 16:048e5e270a58 8543 int RsaPublicKeyDerSize(RsaKey* key, int with_header)
sPymbed 16:048e5e270a58 8544 {
sPymbed 16:048e5e270a58 8545 byte* dummy = NULL;
sPymbed 16:048e5e270a58 8546 byte seq[MAX_SEQ_SZ];
sPymbed 16:048e5e270a58 8547 byte bitString[1 + MAX_LENGTH_SZ + 1];
sPymbed 16:048e5e270a58 8548 int nSz;
sPymbed 16:048e5e270a58 8549 int eSz;
sPymbed 16:048e5e270a58 8550 int seqSz;
sPymbed 16:048e5e270a58 8551 int bitStringSz;
sPymbed 16:048e5e270a58 8552 int idx;
sPymbed 16:048e5e270a58 8553
sPymbed 16:048e5e270a58 8554 if (key == NULL)
sPymbed 16:048e5e270a58 8555 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 8556
sPymbed 16:048e5e270a58 8557 /* n */
sPymbed 16:048e5e270a58 8558 dummy = (byte*)XMALLOC(MAX_RSA_INT_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 8559 if (dummy == NULL)
sPymbed 16:048e5e270a58 8560 return MEMORY_E;
sPymbed 16:048e5e270a58 8561
sPymbed 16:048e5e270a58 8562 #ifdef HAVE_USER_RSA
sPymbed 16:048e5e270a58 8563 nSz = SetASNIntRSA(key->n, dummy);
sPymbed 16:048e5e270a58 8564 #else
sPymbed 16:048e5e270a58 8565 nSz = SetASNIntMP(&key->n, MAX_RSA_INT_SZ, dummy);
sPymbed 16:048e5e270a58 8566 #endif
sPymbed 16:048e5e270a58 8567 XFREE(dummy, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 8568 if (nSz < 0) {
sPymbed 16:048e5e270a58 8569 return nSz;
sPymbed 16:048e5e270a58 8570 }
sPymbed 16:048e5e270a58 8571
sPymbed 16:048e5e270a58 8572 /* e */
sPymbed 16:048e5e270a58 8573 dummy = (byte*)XMALLOC(MAX_RSA_E_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 8574 if (dummy == NULL) {
sPymbed 16:048e5e270a58 8575 XFREE(dummy, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 8576 return MEMORY_E;
sPymbed 16:048e5e270a58 8577 }
sPymbed 16:048e5e270a58 8578
sPymbed 16:048e5e270a58 8579 #ifdef HAVE_USER_RSA
sPymbed 16:048e5e270a58 8580 eSz = SetASNIntRSA(key->e, dummy);
sPymbed 16:048e5e270a58 8581 #else
sPymbed 16:048e5e270a58 8582 eSz = SetASNIntMP(&key->e, MAX_RSA_INT_SZ, dummy);
sPymbed 16:048e5e270a58 8583 #endif
sPymbed 16:048e5e270a58 8584 XFREE(dummy, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 8585 if (eSz < 0) {
sPymbed 16:048e5e270a58 8586 return eSz;
sPymbed 16:048e5e270a58 8587 }
sPymbed 16:048e5e270a58 8588
sPymbed 16:048e5e270a58 8589 seqSz = SetSequence(nSz + eSz, seq);
sPymbed 16:048e5e270a58 8590
sPymbed 16:048e5e270a58 8591 /* headers */
sPymbed 16:048e5e270a58 8592 if (with_header) {
sPymbed 16:048e5e270a58 8593 int algoSz;
sPymbed 16:048e5e270a58 8594 dummy = (byte*)XMALLOC(MAX_RSA_INT_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 8595 if (dummy == NULL)
sPymbed 16:048e5e270a58 8596 return MEMORY_E;
sPymbed 16:048e5e270a58 8597
sPymbed 16:048e5e270a58 8598 algoSz = SetAlgoID(RSAk, dummy, oidKeyType, 0);
sPymbed 16:048e5e270a58 8599 bitStringSz = SetBitString(seqSz + nSz + eSz, 0, bitString);
sPymbed 16:048e5e270a58 8600
sPymbed 16:048e5e270a58 8601 idx = SetSequence(nSz + eSz + seqSz + bitStringSz + algoSz, dummy);
sPymbed 16:048e5e270a58 8602 XFREE(dummy, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 8603
sPymbed 16:048e5e270a58 8604 /* algo */
sPymbed 16:048e5e270a58 8605 idx += algoSz;
sPymbed 16:048e5e270a58 8606 /* bit string */
sPymbed 16:048e5e270a58 8607 idx += bitStringSz;
sPymbed 16:048e5e270a58 8608 }
sPymbed 16:048e5e270a58 8609 else
sPymbed 16:048e5e270a58 8610 idx = 0;
sPymbed 16:048e5e270a58 8611
sPymbed 16:048e5e270a58 8612 /* seq */
sPymbed 16:048e5e270a58 8613 idx += seqSz;
sPymbed 16:048e5e270a58 8614 /* n */
sPymbed 16:048e5e270a58 8615 idx += nSz;
sPymbed 16:048e5e270a58 8616 /* e */
sPymbed 16:048e5e270a58 8617 idx += eSz;
sPymbed 16:048e5e270a58 8618
sPymbed 16:048e5e270a58 8619 return idx;
sPymbed 16:048e5e270a58 8620 }
sPymbed 16:048e5e270a58 8621 #endif /* !NO_RSA && (WOLFSSL_CERT_GEN || (WOLFSSL_KEY_GEN &&
sPymbed 16:048e5e270a58 8622 !HAVE_USER_RSA))) */
sPymbed 16:048e5e270a58 8623
sPymbed 16:048e5e270a58 8624
sPymbed 16:048e5e270a58 8625 #if defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA) && !defined(HAVE_USER_RSA)
sPymbed 16:048e5e270a58 8626
sPymbed 16:048e5e270a58 8627
sPymbed 16:048e5e270a58 8628 static mp_int* GetRsaInt(RsaKey* key, int idx)
sPymbed 16:048e5e270a58 8629 {
sPymbed 16:048e5e270a58 8630 if (idx == 0)
sPymbed 16:048e5e270a58 8631 return &key->n;
sPymbed 16:048e5e270a58 8632 if (idx == 1)
sPymbed 16:048e5e270a58 8633 return &key->e;
sPymbed 16:048e5e270a58 8634 if (idx == 2)
sPymbed 16:048e5e270a58 8635 return &key->d;
sPymbed 16:048e5e270a58 8636 if (idx == 3)
sPymbed 16:048e5e270a58 8637 return &key->p;
sPymbed 16:048e5e270a58 8638 if (idx == 4)
sPymbed 16:048e5e270a58 8639 return &key->q;
sPymbed 16:048e5e270a58 8640 if (idx == 5)
sPymbed 16:048e5e270a58 8641 return &key->dP;
sPymbed 16:048e5e270a58 8642 if (idx == 6)
sPymbed 16:048e5e270a58 8643 return &key->dQ;
sPymbed 16:048e5e270a58 8644 if (idx == 7)
sPymbed 16:048e5e270a58 8645 return &key->u;
sPymbed 16:048e5e270a58 8646
sPymbed 16:048e5e270a58 8647 return NULL;
sPymbed 16:048e5e270a58 8648 }
sPymbed 16:048e5e270a58 8649
sPymbed 16:048e5e270a58 8650
sPymbed 16:048e5e270a58 8651 /* Release Tmp RSA resources */
sPymbed 16:048e5e270a58 8652 static WC_INLINE void FreeTmpRsas(byte** tmps, void* heap)
sPymbed 16:048e5e270a58 8653 {
sPymbed 16:048e5e270a58 8654 int i;
sPymbed 16:048e5e270a58 8655
sPymbed 16:048e5e270a58 8656 (void)heap;
sPymbed 16:048e5e270a58 8657
sPymbed 16:048e5e270a58 8658 for (i = 0; i < RSA_INTS; i++)
sPymbed 16:048e5e270a58 8659 XFREE(tmps[i], heap, DYNAMIC_TYPE_RSA);
sPymbed 16:048e5e270a58 8660 }
sPymbed 16:048e5e270a58 8661
sPymbed 16:048e5e270a58 8662
sPymbed 16:048e5e270a58 8663 /* Convert RsaKey key to DER format, write to output (inLen), return bytes
sPymbed 16:048e5e270a58 8664 written */
sPymbed 16:048e5e270a58 8665 int wc_RsaKeyToDer(RsaKey* key, byte* output, word32 inLen)
sPymbed 16:048e5e270a58 8666 {
sPymbed 16:048e5e270a58 8667 word32 seqSz, verSz, rawLen, intTotalLen = 0;
sPymbed 16:048e5e270a58 8668 word32 sizes[RSA_INTS];
sPymbed 16:048e5e270a58 8669 int i, j, outLen, ret = 0, mpSz;
sPymbed 16:048e5e270a58 8670
sPymbed 16:048e5e270a58 8671 byte seq[MAX_SEQ_SZ];
sPymbed 16:048e5e270a58 8672 byte ver[MAX_VERSION_SZ];
sPymbed 16:048e5e270a58 8673 byte* tmps[RSA_INTS];
sPymbed 16:048e5e270a58 8674
sPymbed 16:048e5e270a58 8675 if (!key || !output)
sPymbed 16:048e5e270a58 8676 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 8677
sPymbed 16:048e5e270a58 8678 if (key->type != RSA_PRIVATE)
sPymbed 16:048e5e270a58 8679 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 8680
sPymbed 16:048e5e270a58 8681 for (i = 0; i < RSA_INTS; i++)
sPymbed 16:048e5e270a58 8682 tmps[i] = NULL;
sPymbed 16:048e5e270a58 8683
sPymbed 16:048e5e270a58 8684 /* write all big ints from key to DER tmps */
sPymbed 16:048e5e270a58 8685 for (i = 0; i < RSA_INTS; i++) {
sPymbed 16:048e5e270a58 8686 mp_int* keyInt = GetRsaInt(key, i);
sPymbed 16:048e5e270a58 8687
sPymbed 16:048e5e270a58 8688 rawLen = mp_unsigned_bin_size(keyInt) + 1;
sPymbed 16:048e5e270a58 8689 tmps[i] = (byte*)XMALLOC(rawLen + MAX_SEQ_SZ, key->heap,
sPymbed 16:048e5e270a58 8690 DYNAMIC_TYPE_RSA);
sPymbed 16:048e5e270a58 8691 if (tmps[i] == NULL) {
sPymbed 16:048e5e270a58 8692 ret = MEMORY_E;
sPymbed 16:048e5e270a58 8693 break;
sPymbed 16:048e5e270a58 8694 }
sPymbed 16:048e5e270a58 8695
sPymbed 16:048e5e270a58 8696 mpSz = SetASNIntMP(keyInt, MAX_RSA_INT_SZ, tmps[i]);
sPymbed 16:048e5e270a58 8697 if (mpSz < 0) {
sPymbed 16:048e5e270a58 8698 ret = mpSz;
sPymbed 16:048e5e270a58 8699 break;
sPymbed 16:048e5e270a58 8700 }
sPymbed 16:048e5e270a58 8701 intTotalLen += (sizes[i] = mpSz);
sPymbed 16:048e5e270a58 8702 }
sPymbed 16:048e5e270a58 8703
sPymbed 16:048e5e270a58 8704 if (ret != 0) {
sPymbed 16:048e5e270a58 8705 FreeTmpRsas(tmps, key->heap);
sPymbed 16:048e5e270a58 8706 return ret;
sPymbed 16:048e5e270a58 8707 }
sPymbed 16:048e5e270a58 8708
sPymbed 16:048e5e270a58 8709 /* make headers */
sPymbed 16:048e5e270a58 8710 verSz = SetMyVersion(0, ver, FALSE);
sPymbed 16:048e5e270a58 8711 seqSz = SetSequence(verSz + intTotalLen, seq);
sPymbed 16:048e5e270a58 8712
sPymbed 16:048e5e270a58 8713 outLen = seqSz + verSz + intTotalLen;
sPymbed 16:048e5e270a58 8714 if (outLen > (int)inLen) {
sPymbed 16:048e5e270a58 8715 FreeTmpRsas(tmps, key->heap);
sPymbed 16:048e5e270a58 8716 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 8717 }
sPymbed 16:048e5e270a58 8718
sPymbed 16:048e5e270a58 8719 /* write to output */
sPymbed 16:048e5e270a58 8720 XMEMCPY(output, seq, seqSz);
sPymbed 16:048e5e270a58 8721 j = seqSz;
sPymbed 16:048e5e270a58 8722 XMEMCPY(output + j, ver, verSz);
sPymbed 16:048e5e270a58 8723 j += verSz;
sPymbed 16:048e5e270a58 8724
sPymbed 16:048e5e270a58 8725 for (i = 0; i < RSA_INTS; i++) {
sPymbed 16:048e5e270a58 8726 XMEMCPY(output + j, tmps[i], sizes[i]);
sPymbed 16:048e5e270a58 8727 j += sizes[i];
sPymbed 16:048e5e270a58 8728 }
sPymbed 16:048e5e270a58 8729 FreeTmpRsas(tmps, key->heap);
sPymbed 16:048e5e270a58 8730
sPymbed 16:048e5e270a58 8731 return outLen;
sPymbed 16:048e5e270a58 8732 }
sPymbed 16:048e5e270a58 8733 #endif
sPymbed 16:048e5e270a58 8734
sPymbed 16:048e5e270a58 8735 #if (defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)) && !defined(NO_RSA) && !defined(HAVE_USER_RSA)
sPymbed 16:048e5e270a58 8736 /* Convert Rsa Public key to DER format, write to output (inLen), return bytes
sPymbed 16:048e5e270a58 8737 written */
sPymbed 16:048e5e270a58 8738 int wc_RsaKeyToPublicDer(RsaKey* key, byte* output, word32 inLen)
sPymbed 16:048e5e270a58 8739 {
sPymbed 16:048e5e270a58 8740 return SetRsaPublicKey(output, key, inLen, 1);
sPymbed 16:048e5e270a58 8741 }
sPymbed 16:048e5e270a58 8742
sPymbed 16:048e5e270a58 8743 #endif /* WOLFSSL_KEY_GEN && !NO_RSA && !HAVE_USER_RSA */
sPymbed 16:048e5e270a58 8744
sPymbed 16:048e5e270a58 8745
sPymbed 16:048e5e270a58 8746 #ifdef WOLFSSL_CERT_GEN
sPymbed 16:048e5e270a58 8747
sPymbed 16:048e5e270a58 8748 /* Initialize and Set Certificate defaults:
sPymbed 16:048e5e270a58 8749 version = 3 (0x2)
sPymbed 16:048e5e270a58 8750 serial = 0
sPymbed 16:048e5e270a58 8751 sigType = SHA_WITH_RSA
sPymbed 16:048e5e270a58 8752 issuer = blank
sPymbed 16:048e5e270a58 8753 daysValid = 500
sPymbed 16:048e5e270a58 8754 selfSigned = 1 (true) use subject as issuer
sPymbed 16:048e5e270a58 8755 subject = blank
sPymbed 16:048e5e270a58 8756 */
sPymbed 16:048e5e270a58 8757 int wc_InitCert(Cert* cert)
sPymbed 16:048e5e270a58 8758 {
sPymbed 16:048e5e270a58 8759 #ifdef WOLFSSL_MULTI_ATTRIB
sPymbed 16:048e5e270a58 8760 int i = 0;
sPymbed 16:048e5e270a58 8761 #endif
sPymbed 16:048e5e270a58 8762 if (cert == NULL) {
sPymbed 16:048e5e270a58 8763 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 8764 }
sPymbed 16:048e5e270a58 8765
sPymbed 16:048e5e270a58 8766 XMEMSET(cert, 0, sizeof(Cert));
sPymbed 16:048e5e270a58 8767
sPymbed 16:048e5e270a58 8768 cert->version = 2; /* version 3 is hex 2 */
sPymbed 16:048e5e270a58 8769 #ifndef NO_SHA
sPymbed 16:048e5e270a58 8770 cert->sigType = CTC_SHAwRSA;
sPymbed 16:048e5e270a58 8771 #elif !defined(NO_SHA256)
sPymbed 16:048e5e270a58 8772 cert->sigType = CTC_SHA256wRSA;
sPymbed 16:048e5e270a58 8773 #else
sPymbed 16:048e5e270a58 8774 cert->sigType = 0;
sPymbed 16:048e5e270a58 8775 #endif
sPymbed 16:048e5e270a58 8776 cert->daysValid = 500;
sPymbed 16:048e5e270a58 8777 cert->selfSigned = 1;
sPymbed 16:048e5e270a58 8778 cert->keyType = RSA_KEY;
sPymbed 16:048e5e270a58 8779
sPymbed 16:048e5e270a58 8780 cert->issuer.countryEnc = CTC_PRINTABLE;
sPymbed 16:048e5e270a58 8781 cert->issuer.stateEnc = CTC_UTF8;
sPymbed 16:048e5e270a58 8782 cert->issuer.localityEnc = CTC_UTF8;
sPymbed 16:048e5e270a58 8783 cert->issuer.surEnc = CTC_UTF8;
sPymbed 16:048e5e270a58 8784 cert->issuer.orgEnc = CTC_UTF8;
sPymbed 16:048e5e270a58 8785 cert->issuer.unitEnc = CTC_UTF8;
sPymbed 16:048e5e270a58 8786 cert->issuer.commonNameEnc = CTC_UTF8;
sPymbed 16:048e5e270a58 8787
sPymbed 16:048e5e270a58 8788 cert->subject.countryEnc = CTC_PRINTABLE;
sPymbed 16:048e5e270a58 8789 cert->subject.stateEnc = CTC_UTF8;
sPymbed 16:048e5e270a58 8790 cert->subject.localityEnc = CTC_UTF8;
sPymbed 16:048e5e270a58 8791 cert->subject.surEnc = CTC_UTF8;
sPymbed 16:048e5e270a58 8792 cert->subject.orgEnc = CTC_UTF8;
sPymbed 16:048e5e270a58 8793 cert->subject.unitEnc = CTC_UTF8;
sPymbed 16:048e5e270a58 8794 cert->subject.commonNameEnc = CTC_UTF8;
sPymbed 16:048e5e270a58 8795
sPymbed 16:048e5e270a58 8796 #ifdef WOLFSSL_MULTI_ATTRIB
sPymbed 16:048e5e270a58 8797 for (i = 0; i < CTC_MAX_ATTRIB; i++) {
sPymbed 16:048e5e270a58 8798 cert->issuer.name[i].type = CTC_UTF8;
sPymbed 16:048e5e270a58 8799 cert->subject.name[i].type = CTC_UTF8;
sPymbed 16:048e5e270a58 8800 }
sPymbed 16:048e5e270a58 8801 #endif /* WOLFSSL_MULTI_ATTRIB */
sPymbed 16:048e5e270a58 8802
sPymbed 16:048e5e270a58 8803 #ifdef WOLFSSL_HEAP_TEST
sPymbed 16:048e5e270a58 8804 cert->heap = (void*)WOLFSSL_HEAP_TEST;
sPymbed 16:048e5e270a58 8805 #endif
sPymbed 16:048e5e270a58 8806
sPymbed 16:048e5e270a58 8807 return 0;
sPymbed 16:048e5e270a58 8808 }
sPymbed 16:048e5e270a58 8809
sPymbed 16:048e5e270a58 8810
sPymbed 16:048e5e270a58 8811 /* DER encoded x509 Certificate */
sPymbed 16:048e5e270a58 8812 typedef struct DerCert {
sPymbed 16:048e5e270a58 8813 byte size[MAX_LENGTH_SZ]; /* length encoded */
sPymbed 16:048e5e270a58 8814 byte version[MAX_VERSION_SZ]; /* version encoded */
sPymbed 16:048e5e270a58 8815 byte serial[(int)CTC_SERIAL_SIZE + (int)MAX_LENGTH_SZ]; /* serial number encoded */
sPymbed 16:048e5e270a58 8816 byte sigAlgo[MAX_ALGO_SZ]; /* signature algo encoded */
sPymbed 16:048e5e270a58 8817 byte issuer[ASN_NAME_MAX]; /* issuer encoded */
sPymbed 16:048e5e270a58 8818 byte subject[ASN_NAME_MAX]; /* subject encoded */
sPymbed 16:048e5e270a58 8819 byte validity[MAX_DATE_SIZE*2 + MAX_SEQ_SZ*2]; /* before and after dates */
sPymbed 16:048e5e270a58 8820 byte publicKey[MAX_PUBLIC_KEY_SZ]; /* rsa / ntru public key encoded */
sPymbed 16:048e5e270a58 8821 byte ca[MAX_CA_SZ]; /* basic constraint CA true size */
sPymbed 16:048e5e270a58 8822 byte extensions[MAX_EXTENSIONS_SZ]; /* all extensions */
sPymbed 16:048e5e270a58 8823 #ifdef WOLFSSL_CERT_EXT
sPymbed 16:048e5e270a58 8824 byte skid[MAX_KID_SZ]; /* Subject Key Identifier extension */
sPymbed 16:048e5e270a58 8825 byte akid[MAX_KID_SZ]; /* Authority Key Identifier extension */
sPymbed 16:048e5e270a58 8826 byte keyUsage[MAX_KEYUSAGE_SZ]; /* Key Usage extension */
sPymbed 16:048e5e270a58 8827 byte extKeyUsage[MAX_EXTKEYUSAGE_SZ]; /* Extended Key Usage extension */
sPymbed 16:048e5e270a58 8828 byte certPolicies[MAX_CERTPOL_NB*MAX_CERTPOL_SZ]; /* Certificate Policies */
sPymbed 16:048e5e270a58 8829 #endif
sPymbed 16:048e5e270a58 8830 #ifdef WOLFSSL_CERT_REQ
sPymbed 16:048e5e270a58 8831 byte attrib[MAX_ATTRIB_SZ]; /* Cert req attributes encoded */
sPymbed 16:048e5e270a58 8832 #endif
sPymbed 16:048e5e270a58 8833 #ifdef WOLFSSL_ALT_NAMES
sPymbed 16:048e5e270a58 8834 byte altNames[CTC_MAX_ALT_SIZE]; /* Alternative Names encoded */
sPymbed 16:048e5e270a58 8835 #endif
sPymbed 16:048e5e270a58 8836 int sizeSz; /* encoded size length */
sPymbed 16:048e5e270a58 8837 int versionSz; /* encoded version length */
sPymbed 16:048e5e270a58 8838 int serialSz; /* encoded serial length */
sPymbed 16:048e5e270a58 8839 int sigAlgoSz; /* encoded sig alog length */
sPymbed 16:048e5e270a58 8840 int issuerSz; /* encoded issuer length */
sPymbed 16:048e5e270a58 8841 int subjectSz; /* encoded subject length */
sPymbed 16:048e5e270a58 8842 int validitySz; /* encoded validity length */
sPymbed 16:048e5e270a58 8843 int publicKeySz; /* encoded public key length */
sPymbed 16:048e5e270a58 8844 int caSz; /* encoded CA extension length */
sPymbed 16:048e5e270a58 8845 #ifdef WOLFSSL_CERT_EXT
sPymbed 16:048e5e270a58 8846 int skidSz; /* encoded SKID extension length */
sPymbed 16:048e5e270a58 8847 int akidSz; /* encoded SKID extension length */
sPymbed 16:048e5e270a58 8848 int keyUsageSz; /* encoded KeyUsage extension length */
sPymbed 16:048e5e270a58 8849 int extKeyUsageSz; /* encoded ExtendedKeyUsage extension length */
sPymbed 16:048e5e270a58 8850 int certPoliciesSz; /* encoded CertPolicies extension length*/
sPymbed 16:048e5e270a58 8851 #endif
sPymbed 16:048e5e270a58 8852 #ifdef WOLFSSL_ALT_NAMES
sPymbed 16:048e5e270a58 8853 int altNamesSz; /* encoded AltNames extension length */
sPymbed 16:048e5e270a58 8854 #endif
sPymbed 16:048e5e270a58 8855 int extensionsSz; /* encoded extensions total length */
sPymbed 16:048e5e270a58 8856 int total; /* total encoded lengths */
sPymbed 16:048e5e270a58 8857 #ifdef WOLFSSL_CERT_REQ
sPymbed 16:048e5e270a58 8858 int attribSz;
sPymbed 16:048e5e270a58 8859 #endif
sPymbed 16:048e5e270a58 8860 } DerCert;
sPymbed 16:048e5e270a58 8861
sPymbed 16:048e5e270a58 8862
sPymbed 16:048e5e270a58 8863 #ifdef WOLFSSL_CERT_REQ
sPymbed 16:048e5e270a58 8864
sPymbed 16:048e5e270a58 8865 /* Write a set header to output */
sPymbed 16:048e5e270a58 8866 static word32 SetUTF8String(word32 len, byte* output)
sPymbed 16:048e5e270a58 8867 {
sPymbed 16:048e5e270a58 8868 output[0] = ASN_UTF8STRING;
sPymbed 16:048e5e270a58 8869 return SetLength(len, output + 1) + 1;
sPymbed 16:048e5e270a58 8870 }
sPymbed 16:048e5e270a58 8871
sPymbed 16:048e5e270a58 8872 #endif /* WOLFSSL_CERT_REQ */
sPymbed 16:048e5e270a58 8873
sPymbed 16:048e5e270a58 8874 #endif /*WOLFSSL_CERT_GEN */
sPymbed 16:048e5e270a58 8875
sPymbed 16:048e5e270a58 8876 #if defined(HAVE_ECC)
sPymbed 16:048e5e270a58 8877
sPymbed 16:048e5e270a58 8878 /* Write a public ECC key to output */
sPymbed 16:048e5e270a58 8879 static int SetEccPublicKey(byte* output, ecc_key* key, int with_header)
sPymbed 16:048e5e270a58 8880 {
sPymbed 16:048e5e270a58 8881 byte bitString[1 + MAX_LENGTH_SZ + 1];
sPymbed 16:048e5e270a58 8882 int algoSz;
sPymbed 16:048e5e270a58 8883 int curveSz;
sPymbed 16:048e5e270a58 8884 int bitStringSz;
sPymbed 16:048e5e270a58 8885 int idx;
sPymbed 16:048e5e270a58 8886 word32 pubSz = ECC_BUFSIZE;
sPymbed 16:048e5e270a58 8887 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 8888 byte* algo = NULL;
sPymbed 16:048e5e270a58 8889 byte* curve = NULL;
sPymbed 16:048e5e270a58 8890 byte* pub = NULL;
sPymbed 16:048e5e270a58 8891 #else
sPymbed 16:048e5e270a58 8892 byte algo[MAX_ALGO_SZ];
sPymbed 16:048e5e270a58 8893 byte curve[MAX_ALGO_SZ];
sPymbed 16:048e5e270a58 8894 byte pub[ECC_BUFSIZE];
sPymbed 16:048e5e270a58 8895 #endif
sPymbed 16:048e5e270a58 8896 int ret;
sPymbed 16:048e5e270a58 8897
sPymbed 16:048e5e270a58 8898 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 8899 pub = (byte*)XMALLOC(ECC_BUFSIZE, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 8900 if (pub == NULL)
sPymbed 16:048e5e270a58 8901 return MEMORY_E;
sPymbed 16:048e5e270a58 8902 #endif
sPymbed 16:048e5e270a58 8903
sPymbed 16:048e5e270a58 8904 ret = wc_ecc_export_x963(key, pub, &pubSz);
sPymbed 16:048e5e270a58 8905 if (ret != 0) {
sPymbed 16:048e5e270a58 8906 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 8907 XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 8908 #endif
sPymbed 16:048e5e270a58 8909 return ret;
sPymbed 16:048e5e270a58 8910 }
sPymbed 16:048e5e270a58 8911
sPymbed 16:048e5e270a58 8912 /* headers */
sPymbed 16:048e5e270a58 8913 if (with_header) {
sPymbed 16:048e5e270a58 8914 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 8915 curve = (byte*)XMALLOC(MAX_ALGO_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 8916 if (curve == NULL) {
sPymbed 16:048e5e270a58 8917 XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 8918 return MEMORY_E;
sPymbed 16:048e5e270a58 8919 }
sPymbed 16:048e5e270a58 8920 #endif
sPymbed 16:048e5e270a58 8921 curveSz = SetCurve(key, curve);
sPymbed 16:048e5e270a58 8922 if (curveSz <= 0) {
sPymbed 16:048e5e270a58 8923 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 8924 XFREE(curve, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 8925 XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 8926 #endif
sPymbed 16:048e5e270a58 8927 return curveSz;
sPymbed 16:048e5e270a58 8928 }
sPymbed 16:048e5e270a58 8929
sPymbed 16:048e5e270a58 8930 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 8931 algo = (byte*)XMALLOC(MAX_ALGO_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 8932 if (algo == NULL) {
sPymbed 16:048e5e270a58 8933 XFREE(curve, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 8934 XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 8935 return MEMORY_E;
sPymbed 16:048e5e270a58 8936 }
sPymbed 16:048e5e270a58 8937 #endif
sPymbed 16:048e5e270a58 8938 algoSz = SetAlgoID(ECDSAk, algo, oidKeyType, curveSz);
sPymbed 16:048e5e270a58 8939
sPymbed 16:048e5e270a58 8940 bitStringSz = SetBitString(pubSz, 0, bitString);
sPymbed 16:048e5e270a58 8941
sPymbed 16:048e5e270a58 8942 idx = SetSequence(pubSz + curveSz + bitStringSz + algoSz, output);
sPymbed 16:048e5e270a58 8943 /* algo */
sPymbed 16:048e5e270a58 8944 XMEMCPY(output + idx, algo, algoSz);
sPymbed 16:048e5e270a58 8945 idx += algoSz;
sPymbed 16:048e5e270a58 8946 /* curve */
sPymbed 16:048e5e270a58 8947 XMEMCPY(output + idx, curve, curveSz);
sPymbed 16:048e5e270a58 8948 idx += curveSz;
sPymbed 16:048e5e270a58 8949 /* bit string */
sPymbed 16:048e5e270a58 8950 XMEMCPY(output + idx, bitString, bitStringSz);
sPymbed 16:048e5e270a58 8951 idx += bitStringSz;
sPymbed 16:048e5e270a58 8952 }
sPymbed 16:048e5e270a58 8953 else
sPymbed 16:048e5e270a58 8954 idx = 0;
sPymbed 16:048e5e270a58 8955
sPymbed 16:048e5e270a58 8956 /* pub */
sPymbed 16:048e5e270a58 8957 XMEMCPY(output + idx, pub, pubSz);
sPymbed 16:048e5e270a58 8958 idx += pubSz;
sPymbed 16:048e5e270a58 8959
sPymbed 16:048e5e270a58 8960 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 8961 if (with_header) {
sPymbed 16:048e5e270a58 8962 XFREE(algo, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 8963 XFREE(curve, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 8964 }
sPymbed 16:048e5e270a58 8965 XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 8966 #endif
sPymbed 16:048e5e270a58 8967
sPymbed 16:048e5e270a58 8968 return idx;
sPymbed 16:048e5e270a58 8969 }
sPymbed 16:048e5e270a58 8970
sPymbed 16:048e5e270a58 8971
sPymbed 16:048e5e270a58 8972 /* returns the size of buffer used, the public ECC key in DER format is stored
sPymbed 16:048e5e270a58 8973 in output buffer
sPymbed 16:048e5e270a58 8974 with_AlgCurve is a flag for when to include a header that has the Algorithm
sPymbed 16:048e5e270a58 8975 and Curve infromation */
sPymbed 16:048e5e270a58 8976 int wc_EccPublicKeyToDer(ecc_key* key, byte* output, word32 inLen,
sPymbed 16:048e5e270a58 8977 int with_AlgCurve)
sPymbed 16:048e5e270a58 8978 {
sPymbed 16:048e5e270a58 8979 word32 infoSz = 0;
sPymbed 16:048e5e270a58 8980 word32 keySz = 0;
sPymbed 16:048e5e270a58 8981 int ret;
sPymbed 16:048e5e270a58 8982
sPymbed 16:048e5e270a58 8983 if (output == NULL || key == NULL) {
sPymbed 16:048e5e270a58 8984 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 8985 }
sPymbed 16:048e5e270a58 8986
sPymbed 16:048e5e270a58 8987 if (with_AlgCurve) {
sPymbed 16:048e5e270a58 8988 /* buffer space for algorithm/curve */
sPymbed 16:048e5e270a58 8989 infoSz += MAX_SEQ_SZ;
sPymbed 16:048e5e270a58 8990 infoSz += 2 * MAX_ALGO_SZ;
sPymbed 16:048e5e270a58 8991
sPymbed 16:048e5e270a58 8992 /* buffer space for public key sequence */
sPymbed 16:048e5e270a58 8993 infoSz += MAX_SEQ_SZ;
sPymbed 16:048e5e270a58 8994 infoSz += TRAILING_ZERO;
sPymbed 16:048e5e270a58 8995 }
sPymbed 16:048e5e270a58 8996
sPymbed 16:048e5e270a58 8997 if ((ret = wc_ecc_export_x963(key, NULL, &keySz)) != LENGTH_ONLY_E) {
sPymbed 16:048e5e270a58 8998 WOLFSSL_MSG("Error in getting ECC public key size");
sPymbed 16:048e5e270a58 8999 return ret;
sPymbed 16:048e5e270a58 9000 }
sPymbed 16:048e5e270a58 9001
sPymbed 16:048e5e270a58 9002 if (inLen < keySz + infoSz) {
sPymbed 16:048e5e270a58 9003 return BUFFER_E;
sPymbed 16:048e5e270a58 9004 }
sPymbed 16:048e5e270a58 9005
sPymbed 16:048e5e270a58 9006 return SetEccPublicKey(output, key, with_AlgCurve);
sPymbed 16:048e5e270a58 9007 }
sPymbed 16:048e5e270a58 9008 #endif /* HAVE_ECC */
sPymbed 16:048e5e270a58 9009
sPymbed 16:048e5e270a58 9010 #if defined(HAVE_ED25519) && (defined(WOLFSSL_CERT_GEN) || \
sPymbed 16:048e5e270a58 9011 defined(WOLFSSL_KEY_GEN))
sPymbed 16:048e5e270a58 9012
sPymbed 16:048e5e270a58 9013 /* Write a public ECC key to output */
sPymbed 16:048e5e270a58 9014 static int SetEd25519PublicKey(byte* output, ed25519_key* key, int with_header)
sPymbed 16:048e5e270a58 9015 {
sPymbed 16:048e5e270a58 9016 byte bitString[1 + MAX_LENGTH_SZ + 1];
sPymbed 16:048e5e270a58 9017 int algoSz;
sPymbed 16:048e5e270a58 9018 int bitStringSz;
sPymbed 16:048e5e270a58 9019 int idx;
sPymbed 16:048e5e270a58 9020 word32 pubSz = ED25519_PUB_KEY_SIZE;
sPymbed 16:048e5e270a58 9021 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 9022 byte* algo = NULL;
sPymbed 16:048e5e270a58 9023 byte* pub = NULL;
sPymbed 16:048e5e270a58 9024 #else
sPymbed 16:048e5e270a58 9025 byte algo[MAX_ALGO_SZ];
sPymbed 16:048e5e270a58 9026 byte pub[ED25519_PUB_KEY_SIZE];
sPymbed 16:048e5e270a58 9027 #endif
sPymbed 16:048e5e270a58 9028
sPymbed 16:048e5e270a58 9029 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 9030 pub = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 9031 if (pub == NULL)
sPymbed 16:048e5e270a58 9032 return MEMORY_E;
sPymbed 16:048e5e270a58 9033 #endif
sPymbed 16:048e5e270a58 9034
sPymbed 16:048e5e270a58 9035 int ret = wc_ed25519_export_public(key, pub, &pubSz);
sPymbed 16:048e5e270a58 9036 if (ret != 0) {
sPymbed 16:048e5e270a58 9037 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 9038 XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 9039 #endif
sPymbed 16:048e5e270a58 9040 return ret;
sPymbed 16:048e5e270a58 9041 }
sPymbed 16:048e5e270a58 9042
sPymbed 16:048e5e270a58 9043 /* headers */
sPymbed 16:048e5e270a58 9044 if (with_header) {
sPymbed 16:048e5e270a58 9045 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 9046 algo = (byte*)XMALLOC(MAX_ALGO_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 9047 if (algo == NULL) {
sPymbed 16:048e5e270a58 9048 XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 9049 return MEMORY_E;
sPymbed 16:048e5e270a58 9050 }
sPymbed 16:048e5e270a58 9051 #endif
sPymbed 16:048e5e270a58 9052 algoSz = SetAlgoID(ED25519k, algo, oidKeyType, 0);
sPymbed 16:048e5e270a58 9053
sPymbed 16:048e5e270a58 9054 bitStringSz = SetBitString(pubSz, 0, bitString);
sPymbed 16:048e5e270a58 9055
sPymbed 16:048e5e270a58 9056 idx = SetSequence(pubSz + bitStringSz + algoSz, output);
sPymbed 16:048e5e270a58 9057 /* algo */
sPymbed 16:048e5e270a58 9058 XMEMCPY(output + idx, algo, algoSz);
sPymbed 16:048e5e270a58 9059 idx += algoSz;
sPymbed 16:048e5e270a58 9060 /* bit string */
sPymbed 16:048e5e270a58 9061 XMEMCPY(output + idx, bitString, bitStringSz);
sPymbed 16:048e5e270a58 9062 idx += bitStringSz;
sPymbed 16:048e5e270a58 9063 }
sPymbed 16:048e5e270a58 9064 else
sPymbed 16:048e5e270a58 9065 idx = 0;
sPymbed 16:048e5e270a58 9066
sPymbed 16:048e5e270a58 9067 /* pub */
sPymbed 16:048e5e270a58 9068 XMEMCPY(output + idx, pub, pubSz);
sPymbed 16:048e5e270a58 9069 idx += pubSz;
sPymbed 16:048e5e270a58 9070
sPymbed 16:048e5e270a58 9071 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 9072 if (with_header) {
sPymbed 16:048e5e270a58 9073 XFREE(algo, NULL, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 9074 }
sPymbed 16:048e5e270a58 9075 XFREE(pub, NULL, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 9076 #endif
sPymbed 16:048e5e270a58 9077
sPymbed 16:048e5e270a58 9078 return idx;
sPymbed 16:048e5e270a58 9079 }
sPymbed 16:048e5e270a58 9080
sPymbed 16:048e5e270a58 9081 int wc_Ed25519PublicKeyToDer(ed25519_key* key, byte* output, word32 inLen,
sPymbed 16:048e5e270a58 9082 int withAlg)
sPymbed 16:048e5e270a58 9083 {
sPymbed 16:048e5e270a58 9084 word32 infoSz = 0;
sPymbed 16:048e5e270a58 9085 word32 keySz = 0;
sPymbed 16:048e5e270a58 9086 int ret;
sPymbed 16:048e5e270a58 9087
sPymbed 16:048e5e270a58 9088 if (output == NULL || key == NULL) {
sPymbed 16:048e5e270a58 9089 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 9090 }
sPymbed 16:048e5e270a58 9091
sPymbed 16:048e5e270a58 9092 if (withAlg) {
sPymbed 16:048e5e270a58 9093 /* buffer space for algorithm */
sPymbed 16:048e5e270a58 9094 infoSz += MAX_SEQ_SZ;
sPymbed 16:048e5e270a58 9095 infoSz += MAX_ALGO_SZ;
sPymbed 16:048e5e270a58 9096
sPymbed 16:048e5e270a58 9097 /* buffer space for public key sequence */
sPymbed 16:048e5e270a58 9098 infoSz += MAX_SEQ_SZ;
sPymbed 16:048e5e270a58 9099 infoSz += TRAILING_ZERO;
sPymbed 16:048e5e270a58 9100 }
sPymbed 16:048e5e270a58 9101
sPymbed 16:048e5e270a58 9102 if ((ret = wc_ed25519_export_public(key, output, &keySz)) != BUFFER_E) {
sPymbed 16:048e5e270a58 9103 WOLFSSL_MSG("Error in getting ECC public key size");
sPymbed 16:048e5e270a58 9104 return ret;
sPymbed 16:048e5e270a58 9105 }
sPymbed 16:048e5e270a58 9106
sPymbed 16:048e5e270a58 9107 if (inLen < keySz + infoSz) {
sPymbed 16:048e5e270a58 9108 return BUFFER_E;
sPymbed 16:048e5e270a58 9109 }
sPymbed 16:048e5e270a58 9110
sPymbed 16:048e5e270a58 9111 return SetEd25519PublicKey(output, key, withAlg);
sPymbed 16:048e5e270a58 9112 }
sPymbed 16:048e5e270a58 9113 #endif /* HAVE_ED25519 && (WOLFSSL_CERT_GEN || WOLFSSL_KEY_GEN) */
sPymbed 16:048e5e270a58 9114
sPymbed 16:048e5e270a58 9115
sPymbed 16:048e5e270a58 9116 #ifdef WOLFSSL_CERT_GEN
sPymbed 16:048e5e270a58 9117
sPymbed 16:048e5e270a58 9118 static WC_INLINE byte itob(int number)
sPymbed 16:048e5e270a58 9119 {
sPymbed 16:048e5e270a58 9120 return (byte)number + 0x30;
sPymbed 16:048e5e270a58 9121 }
sPymbed 16:048e5e270a58 9122
sPymbed 16:048e5e270a58 9123
sPymbed 16:048e5e270a58 9124 /* write time to output, format */
sPymbed 16:048e5e270a58 9125 static void SetTime(struct tm* date, byte* output)
sPymbed 16:048e5e270a58 9126 {
sPymbed 16:048e5e270a58 9127 int i = 0;
sPymbed 16:048e5e270a58 9128
sPymbed 16:048e5e270a58 9129 output[i++] = itob((date->tm_year % 10000) / 1000);
sPymbed 16:048e5e270a58 9130 output[i++] = itob((date->tm_year % 1000) / 100);
sPymbed 16:048e5e270a58 9131 output[i++] = itob((date->tm_year % 100) / 10);
sPymbed 16:048e5e270a58 9132 output[i++] = itob( date->tm_year % 10);
sPymbed 16:048e5e270a58 9133
sPymbed 16:048e5e270a58 9134 output[i++] = itob(date->tm_mon / 10);
sPymbed 16:048e5e270a58 9135 output[i++] = itob(date->tm_mon % 10);
sPymbed 16:048e5e270a58 9136
sPymbed 16:048e5e270a58 9137 output[i++] = itob(date->tm_mday / 10);
sPymbed 16:048e5e270a58 9138 output[i++] = itob(date->tm_mday % 10);
sPymbed 16:048e5e270a58 9139
sPymbed 16:048e5e270a58 9140 output[i++] = itob(date->tm_hour / 10);
sPymbed 16:048e5e270a58 9141 output[i++] = itob(date->tm_hour % 10);
sPymbed 16:048e5e270a58 9142
sPymbed 16:048e5e270a58 9143 output[i++] = itob(date->tm_min / 10);
sPymbed 16:048e5e270a58 9144 output[i++] = itob(date->tm_min % 10);
sPymbed 16:048e5e270a58 9145
sPymbed 16:048e5e270a58 9146 output[i++] = itob(date->tm_sec / 10);
sPymbed 16:048e5e270a58 9147 output[i++] = itob(date->tm_sec % 10);
sPymbed 16:048e5e270a58 9148
sPymbed 16:048e5e270a58 9149 output[i] = 'Z'; /* Zulu profile */
sPymbed 16:048e5e270a58 9150 }
sPymbed 16:048e5e270a58 9151
sPymbed 16:048e5e270a58 9152
sPymbed 16:048e5e270a58 9153 #ifdef WOLFSSL_ALT_NAMES
sPymbed 16:048e5e270a58 9154
sPymbed 16:048e5e270a58 9155 /* Copy Dates from cert, return bytes written */
sPymbed 16:048e5e270a58 9156 static int CopyValidity(byte* output, Cert* cert)
sPymbed 16:048e5e270a58 9157 {
sPymbed 16:048e5e270a58 9158 int seqSz;
sPymbed 16:048e5e270a58 9159
sPymbed 16:048e5e270a58 9160 WOLFSSL_ENTER("CopyValidity");
sPymbed 16:048e5e270a58 9161
sPymbed 16:048e5e270a58 9162 /* headers and output */
sPymbed 16:048e5e270a58 9163 seqSz = SetSequence(cert->beforeDateSz + cert->afterDateSz, output);
sPymbed 16:048e5e270a58 9164 XMEMCPY(output + seqSz, cert->beforeDate, cert->beforeDateSz);
sPymbed 16:048e5e270a58 9165 XMEMCPY(output + seqSz + cert->beforeDateSz, cert->afterDate,
sPymbed 16:048e5e270a58 9166 cert->afterDateSz);
sPymbed 16:048e5e270a58 9167 return seqSz + cert->beforeDateSz + cert->afterDateSz;
sPymbed 16:048e5e270a58 9168 }
sPymbed 16:048e5e270a58 9169
sPymbed 16:048e5e270a58 9170 #endif
sPymbed 16:048e5e270a58 9171
sPymbed 16:048e5e270a58 9172
sPymbed 16:048e5e270a58 9173 /* Set Date validity from now until now + daysValid
sPymbed 16:048e5e270a58 9174 * return size in bytes written to output, 0 on error */
sPymbed 16:048e5e270a58 9175 static int SetValidity(byte* output, int daysValid)
sPymbed 16:048e5e270a58 9176 {
sPymbed 16:048e5e270a58 9177 byte before[MAX_DATE_SIZE];
sPymbed 16:048e5e270a58 9178 byte after[MAX_DATE_SIZE];
sPymbed 16:048e5e270a58 9179
sPymbed 16:048e5e270a58 9180 int beforeSz;
sPymbed 16:048e5e270a58 9181 int afterSz;
sPymbed 16:048e5e270a58 9182 int seqSz;
sPymbed 16:048e5e270a58 9183
sPymbed 16:048e5e270a58 9184 time_t now;
sPymbed 16:048e5e270a58 9185 time_t then;
sPymbed 16:048e5e270a58 9186 struct tm* tmpTime = NULL;
sPymbed 16:048e5e270a58 9187 struct tm* expandedTime;
sPymbed 16:048e5e270a58 9188 struct tm localTime;
sPymbed 16:048e5e270a58 9189
sPymbed 16:048e5e270a58 9190 #if defined(NEED_TMP_TIME)
sPymbed 16:048e5e270a58 9191 /* for use with gmtime_r */
sPymbed 16:048e5e270a58 9192 struct tm tmpTimeStorage;
sPymbed 16:048e5e270a58 9193 tmpTime = &tmpTimeStorage;
sPymbed 16:048e5e270a58 9194 #else
sPymbed 16:048e5e270a58 9195 (void)tmpTime;
sPymbed 16:048e5e270a58 9196 #endif
sPymbed 16:048e5e270a58 9197
sPymbed 16:048e5e270a58 9198 now = XTIME(0);
sPymbed 16:048e5e270a58 9199
sPymbed 16:048e5e270a58 9200 /* before now */
sPymbed 16:048e5e270a58 9201 before[0] = ASN_GENERALIZED_TIME;
sPymbed 16:048e5e270a58 9202 beforeSz = SetLength(ASN_GEN_TIME_SZ, before + 1) + 1; /* gen tag */
sPymbed 16:048e5e270a58 9203
sPymbed 16:048e5e270a58 9204 /* subtract 1 day of seconds for more compliance */
sPymbed 16:048e5e270a58 9205 then = now - 86400;
sPymbed 16:048e5e270a58 9206 expandedTime = XGMTIME(&then, tmpTime);
sPymbed 16:048e5e270a58 9207 if (expandedTime == NULL) {
sPymbed 16:048e5e270a58 9208 WOLFSSL_MSG("XGMTIME failed");
sPymbed 16:048e5e270a58 9209 return 0; /* error */
sPymbed 16:048e5e270a58 9210 }
sPymbed 16:048e5e270a58 9211 localTime = *expandedTime;
sPymbed 16:048e5e270a58 9212
sPymbed 16:048e5e270a58 9213 /* adjust */
sPymbed 16:048e5e270a58 9214 localTime.tm_year += 1900;
sPymbed 16:048e5e270a58 9215 localTime.tm_mon += 1;
sPymbed 16:048e5e270a58 9216
sPymbed 16:048e5e270a58 9217 SetTime(&localTime, before + beforeSz);
sPymbed 16:048e5e270a58 9218 beforeSz += ASN_GEN_TIME_SZ;
sPymbed 16:048e5e270a58 9219
sPymbed 16:048e5e270a58 9220 after[0] = ASN_GENERALIZED_TIME;
sPymbed 16:048e5e270a58 9221 afterSz = SetLength(ASN_GEN_TIME_SZ, after + 1) + 1; /* gen tag */
sPymbed 16:048e5e270a58 9222
sPymbed 16:048e5e270a58 9223 /* add daysValid of seconds */
sPymbed 16:048e5e270a58 9224 then = now + (daysValid * 3600);
sPymbed 16:048e5e270a58 9225 expandedTime = XGMTIME(&then, tmpTime);
sPymbed 16:048e5e270a58 9226 if (expandedTime == NULL) {
sPymbed 16:048e5e270a58 9227 WOLFSSL_MSG("XGMTIME failed");
sPymbed 16:048e5e270a58 9228 return 0; /* error */
sPymbed 16:048e5e270a58 9229 }
sPymbed 16:048e5e270a58 9230 localTime = *expandedTime;
sPymbed 16:048e5e270a58 9231
sPymbed 16:048e5e270a58 9232 /* adjust */
sPymbed 16:048e5e270a58 9233 localTime.tm_year += 1900;
sPymbed 16:048e5e270a58 9234 localTime.tm_mon += 1;
sPymbed 16:048e5e270a58 9235
sPymbed 16:048e5e270a58 9236 SetTime(&localTime, after + afterSz);
sPymbed 16:048e5e270a58 9237 afterSz += ASN_GEN_TIME_SZ;
sPymbed 16:048e5e270a58 9238
sPymbed 16:048e5e270a58 9239 /* headers and output */
sPymbed 16:048e5e270a58 9240 seqSz = SetSequence(beforeSz + afterSz, output);
sPymbed 16:048e5e270a58 9241 XMEMCPY(output + seqSz, before, beforeSz);
sPymbed 16:048e5e270a58 9242 XMEMCPY(output + seqSz + beforeSz, after, afterSz);
sPymbed 16:048e5e270a58 9243
sPymbed 16:048e5e270a58 9244 return seqSz + beforeSz + afterSz;
sPymbed 16:048e5e270a58 9245 }
sPymbed 16:048e5e270a58 9246
sPymbed 16:048e5e270a58 9247
sPymbed 16:048e5e270a58 9248 /* ASN Encoded Name field */
sPymbed 16:048e5e270a58 9249 typedef struct EncodedName {
sPymbed 16:048e5e270a58 9250 int nameLen; /* actual string value length */
sPymbed 16:048e5e270a58 9251 int totalLen; /* total encoded length */
sPymbed 16:048e5e270a58 9252 int type; /* type of name */
sPymbed 16:048e5e270a58 9253 int used; /* are we actually using this one */
sPymbed 16:048e5e270a58 9254 byte encoded[CTC_NAME_SIZE * 2]; /* encoding */
sPymbed 16:048e5e270a58 9255 } EncodedName;
sPymbed 16:048e5e270a58 9256
sPymbed 16:048e5e270a58 9257
sPymbed 16:048e5e270a58 9258 /* Get Which Name from index */
sPymbed 16:048e5e270a58 9259 static const char* GetOneName(CertName* name, int idx)
sPymbed 16:048e5e270a58 9260 {
sPymbed 16:048e5e270a58 9261 switch (idx) {
sPymbed 16:048e5e270a58 9262 case 0:
sPymbed 16:048e5e270a58 9263 return name->country;
sPymbed 16:048e5e270a58 9264
sPymbed 16:048e5e270a58 9265 case 1:
sPymbed 16:048e5e270a58 9266 return name->state;
sPymbed 16:048e5e270a58 9267
sPymbed 16:048e5e270a58 9268 case 2:
sPymbed 16:048e5e270a58 9269 return name->locality;
sPymbed 16:048e5e270a58 9270
sPymbed 16:048e5e270a58 9271 case 3:
sPymbed 16:048e5e270a58 9272 return name->sur;
sPymbed 16:048e5e270a58 9273
sPymbed 16:048e5e270a58 9274 case 4:
sPymbed 16:048e5e270a58 9275 return name->org;
sPymbed 16:048e5e270a58 9276
sPymbed 16:048e5e270a58 9277 case 5:
sPymbed 16:048e5e270a58 9278 return name->unit;
sPymbed 16:048e5e270a58 9279
sPymbed 16:048e5e270a58 9280 case 6:
sPymbed 16:048e5e270a58 9281 return name->commonName;
sPymbed 16:048e5e270a58 9282
sPymbed 16:048e5e270a58 9283 case 7:
sPymbed 16:048e5e270a58 9284 return name->email;
sPymbed 16:048e5e270a58 9285
sPymbed 16:048e5e270a58 9286 default:
sPymbed 16:048e5e270a58 9287 return 0;
sPymbed 16:048e5e270a58 9288 }
sPymbed 16:048e5e270a58 9289 }
sPymbed 16:048e5e270a58 9290
sPymbed 16:048e5e270a58 9291
sPymbed 16:048e5e270a58 9292 /* Get Which Name Encoding from index */
sPymbed 16:048e5e270a58 9293 static char GetNameType(CertName* name, int idx)
sPymbed 16:048e5e270a58 9294 {
sPymbed 16:048e5e270a58 9295 switch (idx) {
sPymbed 16:048e5e270a58 9296 case 0:
sPymbed 16:048e5e270a58 9297 return name->countryEnc;
sPymbed 16:048e5e270a58 9298
sPymbed 16:048e5e270a58 9299 case 1:
sPymbed 16:048e5e270a58 9300 return name->stateEnc;
sPymbed 16:048e5e270a58 9301
sPymbed 16:048e5e270a58 9302 case 2:
sPymbed 16:048e5e270a58 9303 return name->localityEnc;
sPymbed 16:048e5e270a58 9304
sPymbed 16:048e5e270a58 9305 case 3:
sPymbed 16:048e5e270a58 9306 return name->surEnc;
sPymbed 16:048e5e270a58 9307
sPymbed 16:048e5e270a58 9308 case 4:
sPymbed 16:048e5e270a58 9309 return name->orgEnc;
sPymbed 16:048e5e270a58 9310
sPymbed 16:048e5e270a58 9311 case 5:
sPymbed 16:048e5e270a58 9312 return name->unitEnc;
sPymbed 16:048e5e270a58 9313
sPymbed 16:048e5e270a58 9314 case 6:
sPymbed 16:048e5e270a58 9315 return name->commonNameEnc;
sPymbed 16:048e5e270a58 9316
sPymbed 16:048e5e270a58 9317 default:
sPymbed 16:048e5e270a58 9318 return 0;
sPymbed 16:048e5e270a58 9319 }
sPymbed 16:048e5e270a58 9320 }
sPymbed 16:048e5e270a58 9321
sPymbed 16:048e5e270a58 9322
sPymbed 16:048e5e270a58 9323 /* Get ASN Name from index */
sPymbed 16:048e5e270a58 9324 static byte GetNameId(int idx)
sPymbed 16:048e5e270a58 9325 {
sPymbed 16:048e5e270a58 9326 switch (idx) {
sPymbed 16:048e5e270a58 9327 case 0:
sPymbed 16:048e5e270a58 9328 return ASN_COUNTRY_NAME;
sPymbed 16:048e5e270a58 9329
sPymbed 16:048e5e270a58 9330 case 1:
sPymbed 16:048e5e270a58 9331 return ASN_STATE_NAME;
sPymbed 16:048e5e270a58 9332
sPymbed 16:048e5e270a58 9333 case 2:
sPymbed 16:048e5e270a58 9334 return ASN_LOCALITY_NAME;
sPymbed 16:048e5e270a58 9335
sPymbed 16:048e5e270a58 9336 case 3:
sPymbed 16:048e5e270a58 9337 return ASN_SUR_NAME;
sPymbed 16:048e5e270a58 9338
sPymbed 16:048e5e270a58 9339 case 4:
sPymbed 16:048e5e270a58 9340 return ASN_ORG_NAME;
sPymbed 16:048e5e270a58 9341
sPymbed 16:048e5e270a58 9342 case 5:
sPymbed 16:048e5e270a58 9343 return ASN_ORGUNIT_NAME;
sPymbed 16:048e5e270a58 9344
sPymbed 16:048e5e270a58 9345 case 6:
sPymbed 16:048e5e270a58 9346 return ASN_COMMON_NAME;
sPymbed 16:048e5e270a58 9347
sPymbed 16:048e5e270a58 9348 case 7:
sPymbed 16:048e5e270a58 9349 return ASN_EMAIL_NAME;
sPymbed 16:048e5e270a58 9350
sPymbed 16:048e5e270a58 9351 default:
sPymbed 16:048e5e270a58 9352 return 0;
sPymbed 16:048e5e270a58 9353 }
sPymbed 16:048e5e270a58 9354 }
sPymbed 16:048e5e270a58 9355
sPymbed 16:048e5e270a58 9356 /*
sPymbed 16:048e5e270a58 9357 Extensions ::= SEQUENCE OF Extension
sPymbed 16:048e5e270a58 9358
sPymbed 16:048e5e270a58 9359 Extension ::= SEQUENCE {
sPymbed 16:048e5e270a58 9360 extnId OBJECT IDENTIFIER,
sPymbed 16:048e5e270a58 9361 critical BOOLEAN DEFAULT FALSE,
sPymbed 16:048e5e270a58 9362 extnValue OCTET STRING }
sPymbed 16:048e5e270a58 9363 */
sPymbed 16:048e5e270a58 9364
sPymbed 16:048e5e270a58 9365 /* encode all extensions, return total bytes written */
sPymbed 16:048e5e270a58 9366 static int SetExtensions(byte* out, word32 outSz, int *IdxInOut,
sPymbed 16:048e5e270a58 9367 const byte* ext, int extSz)
sPymbed 16:048e5e270a58 9368 {
sPymbed 16:048e5e270a58 9369 if (out == NULL || IdxInOut == NULL || ext == NULL)
sPymbed 16:048e5e270a58 9370 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 9371
sPymbed 16:048e5e270a58 9372 if (outSz < (word32)(*IdxInOut+extSz))
sPymbed 16:048e5e270a58 9373 return BUFFER_E;
sPymbed 16:048e5e270a58 9374
sPymbed 16:048e5e270a58 9375 XMEMCPY(&out[*IdxInOut], ext, extSz); /* extensions */
sPymbed 16:048e5e270a58 9376 *IdxInOut += extSz;
sPymbed 16:048e5e270a58 9377
sPymbed 16:048e5e270a58 9378 return *IdxInOut;
sPymbed 16:048e5e270a58 9379 }
sPymbed 16:048e5e270a58 9380
sPymbed 16:048e5e270a58 9381 /* encode extensions header, return total bytes written */
sPymbed 16:048e5e270a58 9382 static int SetExtensionsHeader(byte* out, word32 outSz, int extSz)
sPymbed 16:048e5e270a58 9383 {
sPymbed 16:048e5e270a58 9384 byte sequence[MAX_SEQ_SZ];
sPymbed 16:048e5e270a58 9385 byte len[MAX_LENGTH_SZ];
sPymbed 16:048e5e270a58 9386 int seqSz, lenSz, idx = 0;
sPymbed 16:048e5e270a58 9387
sPymbed 16:048e5e270a58 9388 if (out == NULL)
sPymbed 16:048e5e270a58 9389 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 9390
sPymbed 16:048e5e270a58 9391 if (outSz < 3)
sPymbed 16:048e5e270a58 9392 return BUFFER_E;
sPymbed 16:048e5e270a58 9393
sPymbed 16:048e5e270a58 9394 seqSz = SetSequence(extSz, sequence);
sPymbed 16:048e5e270a58 9395
sPymbed 16:048e5e270a58 9396 /* encode extensions length provided */
sPymbed 16:048e5e270a58 9397 lenSz = SetLength(extSz+seqSz, len);
sPymbed 16:048e5e270a58 9398
sPymbed 16:048e5e270a58 9399 if (outSz < (word32)(lenSz+seqSz+1))
sPymbed 16:048e5e270a58 9400 return BUFFER_E;
sPymbed 16:048e5e270a58 9401
sPymbed 16:048e5e270a58 9402 out[idx++] = ASN_EXTENSIONS; /* extensions id */
sPymbed 16:048e5e270a58 9403 XMEMCPY(&out[idx], len, lenSz); /* length */
sPymbed 16:048e5e270a58 9404 idx += lenSz;
sPymbed 16:048e5e270a58 9405
sPymbed 16:048e5e270a58 9406 XMEMCPY(&out[idx], sequence, seqSz); /* sequence */
sPymbed 16:048e5e270a58 9407 idx += seqSz;
sPymbed 16:048e5e270a58 9408
sPymbed 16:048e5e270a58 9409 return idx;
sPymbed 16:048e5e270a58 9410 }
sPymbed 16:048e5e270a58 9411
sPymbed 16:048e5e270a58 9412
sPymbed 16:048e5e270a58 9413 /* encode CA basic constraint true, return total bytes written */
sPymbed 16:048e5e270a58 9414 static int SetCa(byte* out, word32 outSz)
sPymbed 16:048e5e270a58 9415 {
sPymbed 16:048e5e270a58 9416 static const byte ca[] = { 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04,
sPymbed 16:048e5e270a58 9417 0x05, 0x30, 0x03, 0x01, 0x01, 0xff };
sPymbed 16:048e5e270a58 9418
sPymbed 16:048e5e270a58 9419 if (out == NULL)
sPymbed 16:048e5e270a58 9420 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 9421
sPymbed 16:048e5e270a58 9422 if (outSz < sizeof(ca))
sPymbed 16:048e5e270a58 9423 return BUFFER_E;
sPymbed 16:048e5e270a58 9424
sPymbed 16:048e5e270a58 9425 XMEMCPY(out, ca, sizeof(ca));
sPymbed 16:048e5e270a58 9426
sPymbed 16:048e5e270a58 9427 return (int)sizeof(ca);
sPymbed 16:048e5e270a58 9428 }
sPymbed 16:048e5e270a58 9429
sPymbed 16:048e5e270a58 9430
sPymbed 16:048e5e270a58 9431 #ifdef WOLFSSL_CERT_EXT
sPymbed 16:048e5e270a58 9432 /* encode OID and associated value, return total bytes written */
sPymbed 16:048e5e270a58 9433 static int SetOidValue(byte* out, word32 outSz, const byte *oid, word32 oidSz,
sPymbed 16:048e5e270a58 9434 byte *in, word32 inSz)
sPymbed 16:048e5e270a58 9435 {
sPymbed 16:048e5e270a58 9436 int idx = 0;
sPymbed 16:048e5e270a58 9437
sPymbed 16:048e5e270a58 9438 if (out == NULL || oid == NULL || in == NULL)
sPymbed 16:048e5e270a58 9439 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 9440
sPymbed 16:048e5e270a58 9441 if (outSz < 3)
sPymbed 16:048e5e270a58 9442 return BUFFER_E;
sPymbed 16:048e5e270a58 9443
sPymbed 16:048e5e270a58 9444 /* sequence, + 1 => byte to put value size */
sPymbed 16:048e5e270a58 9445 idx = SetSequence(inSz + oidSz + 1, out);
sPymbed 16:048e5e270a58 9446
sPymbed 16:048e5e270a58 9447 if ((idx + inSz + oidSz + 1) > outSz)
sPymbed 16:048e5e270a58 9448 return BUFFER_E;
sPymbed 16:048e5e270a58 9449
sPymbed 16:048e5e270a58 9450 XMEMCPY(out+idx, oid, oidSz);
sPymbed 16:048e5e270a58 9451 idx += oidSz;
sPymbed 16:048e5e270a58 9452 out[idx++] = (byte)inSz;
sPymbed 16:048e5e270a58 9453 XMEMCPY(out+idx, in, inSz);
sPymbed 16:048e5e270a58 9454
sPymbed 16:048e5e270a58 9455 return (idx+inSz);
sPymbed 16:048e5e270a58 9456 }
sPymbed 16:048e5e270a58 9457
sPymbed 16:048e5e270a58 9458 /* encode Subject Key Identifier, return total bytes written
sPymbed 16:048e5e270a58 9459 * RFC5280 : non-critical */
sPymbed 16:048e5e270a58 9460 static int SetSKID(byte* output, word32 outSz, const byte *input, word32 length)
sPymbed 16:048e5e270a58 9461 {
sPymbed 16:048e5e270a58 9462 byte skid_len[1 + MAX_LENGTH_SZ];
sPymbed 16:048e5e270a58 9463 byte skid_enc_len[MAX_LENGTH_SZ];
sPymbed 16:048e5e270a58 9464 int idx = 0, skid_lenSz, skid_enc_lenSz;
sPymbed 16:048e5e270a58 9465 static const byte skid_oid[] = { 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04 };
sPymbed 16:048e5e270a58 9466
sPymbed 16:048e5e270a58 9467 if (output == NULL || input == NULL)
sPymbed 16:048e5e270a58 9468 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 9469
sPymbed 16:048e5e270a58 9470 /* Octet String header */
sPymbed 16:048e5e270a58 9471 skid_lenSz = SetOctetString(length, skid_len);
sPymbed 16:048e5e270a58 9472
sPymbed 16:048e5e270a58 9473 /* length of encoded value */
sPymbed 16:048e5e270a58 9474 skid_enc_lenSz = SetLength(length + skid_lenSz, skid_enc_len);
sPymbed 16:048e5e270a58 9475
sPymbed 16:048e5e270a58 9476 if (outSz < 3)
sPymbed 16:048e5e270a58 9477 return BUFFER_E;
sPymbed 16:048e5e270a58 9478
sPymbed 16:048e5e270a58 9479 idx = SetSequence(length + sizeof(skid_oid) + skid_lenSz + skid_enc_lenSz,
sPymbed 16:048e5e270a58 9480 output);
sPymbed 16:048e5e270a58 9481
sPymbed 16:048e5e270a58 9482 if ((length + sizeof(skid_oid) + skid_lenSz + skid_enc_lenSz) > outSz)
sPymbed 16:048e5e270a58 9483 return BUFFER_E;
sPymbed 16:048e5e270a58 9484
sPymbed 16:048e5e270a58 9485 /* put oid */
sPymbed 16:048e5e270a58 9486 XMEMCPY(output+idx, skid_oid, sizeof(skid_oid));
sPymbed 16:048e5e270a58 9487 idx += sizeof(skid_oid);
sPymbed 16:048e5e270a58 9488
sPymbed 16:048e5e270a58 9489 /* put encoded len */
sPymbed 16:048e5e270a58 9490 XMEMCPY(output+idx, skid_enc_len, skid_enc_lenSz);
sPymbed 16:048e5e270a58 9491 idx += skid_enc_lenSz;
sPymbed 16:048e5e270a58 9492
sPymbed 16:048e5e270a58 9493 /* put octet header */
sPymbed 16:048e5e270a58 9494 XMEMCPY(output+idx, skid_len, skid_lenSz);
sPymbed 16:048e5e270a58 9495 idx += skid_lenSz;
sPymbed 16:048e5e270a58 9496
sPymbed 16:048e5e270a58 9497 /* put value */
sPymbed 16:048e5e270a58 9498 XMEMCPY(output+idx, input, length);
sPymbed 16:048e5e270a58 9499 idx += length;
sPymbed 16:048e5e270a58 9500
sPymbed 16:048e5e270a58 9501 return idx;
sPymbed 16:048e5e270a58 9502 }
sPymbed 16:048e5e270a58 9503
sPymbed 16:048e5e270a58 9504 /* encode Authority Key Identifier, return total bytes written
sPymbed 16:048e5e270a58 9505 * RFC5280 : non-critical */
sPymbed 16:048e5e270a58 9506 static int SetAKID(byte* output, word32 outSz,
sPymbed 16:048e5e270a58 9507 byte *input, word32 length, void* heap)
sPymbed 16:048e5e270a58 9508 {
sPymbed 16:048e5e270a58 9509 byte *enc_val;
sPymbed 16:048e5e270a58 9510 int ret, enc_valSz;
sPymbed 16:048e5e270a58 9511 static const byte akid_oid[] = { 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04 };
sPymbed 16:048e5e270a58 9512 static const byte akid_cs[] = { 0x80 };
sPymbed 16:048e5e270a58 9513
sPymbed 16:048e5e270a58 9514 if (output == NULL || input == NULL)
sPymbed 16:048e5e270a58 9515 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 9516
sPymbed 16:048e5e270a58 9517 enc_valSz = length + 3 + sizeof(akid_cs);
sPymbed 16:048e5e270a58 9518 enc_val = (byte *)XMALLOC(enc_valSz, heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 9519 if (enc_val == NULL)
sPymbed 16:048e5e270a58 9520 return MEMORY_E;
sPymbed 16:048e5e270a58 9521
sPymbed 16:048e5e270a58 9522 /* sequence for ContentSpec & value */
sPymbed 16:048e5e270a58 9523 ret = SetOidValue(enc_val, enc_valSz, akid_cs, sizeof(akid_cs),
sPymbed 16:048e5e270a58 9524 input, length);
sPymbed 16:048e5e270a58 9525 if (ret > 0) {
sPymbed 16:048e5e270a58 9526 enc_valSz = ret;
sPymbed 16:048e5e270a58 9527
sPymbed 16:048e5e270a58 9528 ret = SetOidValue(output, outSz, akid_oid, sizeof(akid_oid),
sPymbed 16:048e5e270a58 9529 enc_val, enc_valSz);
sPymbed 16:048e5e270a58 9530 }
sPymbed 16:048e5e270a58 9531
sPymbed 16:048e5e270a58 9532 XFREE(enc_val, heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 9533 return ret;
sPymbed 16:048e5e270a58 9534 }
sPymbed 16:048e5e270a58 9535
sPymbed 16:048e5e270a58 9536 /* encode Key Usage, return total bytes written
sPymbed 16:048e5e270a58 9537 * RFC5280 : critical */
sPymbed 16:048e5e270a58 9538 static int SetKeyUsage(byte* output, word32 outSz, word16 input)
sPymbed 16:048e5e270a58 9539 {
sPymbed 16:048e5e270a58 9540 byte ku[5];
sPymbed 16:048e5e270a58 9541 int idx;
sPymbed 16:048e5e270a58 9542 static const byte keyusage_oid[] = { 0x06, 0x03, 0x55, 0x1d, 0x0f,
sPymbed 16:048e5e270a58 9543 0x01, 0x01, 0xff, 0x04};
sPymbed 16:048e5e270a58 9544 if (output == NULL)
sPymbed 16:048e5e270a58 9545 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 9546
sPymbed 16:048e5e270a58 9547 idx = SetBitString16Bit(input, ku);
sPymbed 16:048e5e270a58 9548 return SetOidValue(output, outSz, keyusage_oid, sizeof(keyusage_oid),
sPymbed 16:048e5e270a58 9549 ku, idx);
sPymbed 16:048e5e270a58 9550 }
sPymbed 16:048e5e270a58 9551
sPymbed 16:048e5e270a58 9552 static int SetOjectIdValue(byte* output, word32 outSz, int* idx,
sPymbed 16:048e5e270a58 9553 const byte* oid, word32 oidSz)
sPymbed 16:048e5e270a58 9554 {
sPymbed 16:048e5e270a58 9555 /* verify room */
sPymbed 16:048e5e270a58 9556 if (*idx + 2 + oidSz >= outSz)
sPymbed 16:048e5e270a58 9557 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 9558
sPymbed 16:048e5e270a58 9559 *idx += SetObjectId(oidSz, &output[*idx]);
sPymbed 16:048e5e270a58 9560 XMEMCPY(&output[*idx], oid, oidSz);
sPymbed 16:048e5e270a58 9561 *idx += oidSz;
sPymbed 16:048e5e270a58 9562
sPymbed 16:048e5e270a58 9563 return 0;
sPymbed 16:048e5e270a58 9564 }
sPymbed 16:048e5e270a58 9565
sPymbed 16:048e5e270a58 9566 /* encode Extended Key Usage (RFC 5280 4.2.1.12), return total bytes written */
sPymbed 16:048e5e270a58 9567 static int SetExtKeyUsage(Cert* cert, byte* output, word32 outSz, byte input)
sPymbed 16:048e5e270a58 9568 {
sPymbed 16:048e5e270a58 9569 int idx = 0, oidListSz = 0, totalSz, ret = 0;
sPymbed 16:048e5e270a58 9570 static const byte extkeyusage_oid[] = { 0x06, 0x03, 0x55, 0x1d, 0x25 };
sPymbed 16:048e5e270a58 9571
sPymbed 16:048e5e270a58 9572 if (output == NULL)
sPymbed 16:048e5e270a58 9573 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 9574
sPymbed 16:048e5e270a58 9575 /* Skip to OID List */
sPymbed 16:048e5e270a58 9576 totalSz = 2 + sizeof(extkeyusage_oid) + 4;
sPymbed 16:048e5e270a58 9577 idx = totalSz;
sPymbed 16:048e5e270a58 9578
sPymbed 16:048e5e270a58 9579 /* Build OID List */
sPymbed 16:048e5e270a58 9580 /* If any set, then just use it */
sPymbed 16:048e5e270a58 9581 if (input & EXTKEYUSE_ANY) {
sPymbed 16:048e5e270a58 9582 ret |= SetOjectIdValue(output, outSz, &idx,
sPymbed 16:048e5e270a58 9583 extExtKeyUsageAnyOid, sizeof(extExtKeyUsageAnyOid));
sPymbed 16:048e5e270a58 9584 }
sPymbed 16:048e5e270a58 9585 else {
sPymbed 16:048e5e270a58 9586 if (input & EXTKEYUSE_SERVER_AUTH)
sPymbed 16:048e5e270a58 9587 ret |= SetOjectIdValue(output, outSz, &idx,
sPymbed 16:048e5e270a58 9588 extExtKeyUsageServerAuthOid, sizeof(extExtKeyUsageServerAuthOid));
sPymbed 16:048e5e270a58 9589 if (input & EXTKEYUSE_CLIENT_AUTH)
sPymbed 16:048e5e270a58 9590 ret |= SetOjectIdValue(output, outSz, &idx,
sPymbed 16:048e5e270a58 9591 extExtKeyUsageClientAuthOid, sizeof(extExtKeyUsageClientAuthOid));
sPymbed 16:048e5e270a58 9592 if (input & EXTKEYUSE_CODESIGN)
sPymbed 16:048e5e270a58 9593 ret |= SetOjectIdValue(output, outSz, &idx,
sPymbed 16:048e5e270a58 9594 extExtKeyUsageCodeSigningOid, sizeof(extExtKeyUsageCodeSigningOid));
sPymbed 16:048e5e270a58 9595 if (input & EXTKEYUSE_EMAILPROT)
sPymbed 16:048e5e270a58 9596 ret |= SetOjectIdValue(output, outSz, &idx,
sPymbed 16:048e5e270a58 9597 extExtKeyUsageEmailProtectOid, sizeof(extExtKeyUsageEmailProtectOid));
sPymbed 16:048e5e270a58 9598 if (input & EXTKEYUSE_TIMESTAMP)
sPymbed 16:048e5e270a58 9599 ret |= SetOjectIdValue(output, outSz, &idx,
sPymbed 16:048e5e270a58 9600 extExtKeyUsageTimestampOid, sizeof(extExtKeyUsageTimestampOid));
sPymbed 16:048e5e270a58 9601 if (input & EXTKEYUSE_OCSP_SIGN)
sPymbed 16:048e5e270a58 9602 ret |= SetOjectIdValue(output, outSz, &idx,
sPymbed 16:048e5e270a58 9603 extExtKeyUsageOcspSignOid, sizeof(extExtKeyUsageOcspSignOid));
sPymbed 16:048e5e270a58 9604 #ifdef WOLFSSL_EKU_OID
sPymbed 16:048e5e270a58 9605 /* iterate through OID values */
sPymbed 16:048e5e270a58 9606 if (input & EXTKEYUSE_USER) {
sPymbed 16:048e5e270a58 9607 int i, sz;
sPymbed 16:048e5e270a58 9608 for (i = 0; i < CTC_MAX_EKU_NB; i++) {
sPymbed 16:048e5e270a58 9609 sz = cert->extKeyUsageOIDSz[i];
sPymbed 16:048e5e270a58 9610 if (sz > 0) {
sPymbed 16:048e5e270a58 9611 ret |= SetOjectIdValue(output, outSz, &idx,
sPymbed 16:048e5e270a58 9612 cert->extKeyUsageOID[i], sz);
sPymbed 16:048e5e270a58 9613 }
sPymbed 16:048e5e270a58 9614 }
sPymbed 16:048e5e270a58 9615 }
sPymbed 16:048e5e270a58 9616 #endif /* WOLFSSL_EKU_OID */
sPymbed 16:048e5e270a58 9617 }
sPymbed 16:048e5e270a58 9618 if (ret != 0)
sPymbed 16:048e5e270a58 9619 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 9620
sPymbed 16:048e5e270a58 9621 /* Calculate Sizes */
sPymbed 16:048e5e270a58 9622 oidListSz = idx - totalSz;
sPymbed 16:048e5e270a58 9623 totalSz = idx - 2; /* exclude first seq/len (2) */
sPymbed 16:048e5e270a58 9624
sPymbed 16:048e5e270a58 9625 /* 1. Seq + Total Len (2) */
sPymbed 16:048e5e270a58 9626 idx = SetSequence(totalSz, output);
sPymbed 16:048e5e270a58 9627
sPymbed 16:048e5e270a58 9628 /* 2. Object ID (2) */
sPymbed 16:048e5e270a58 9629 XMEMCPY(&output[idx], extkeyusage_oid, sizeof(extkeyusage_oid));
sPymbed 16:048e5e270a58 9630 idx += sizeof(extkeyusage_oid);
sPymbed 16:048e5e270a58 9631
sPymbed 16:048e5e270a58 9632 /* 3. Octect String (2) */
sPymbed 16:048e5e270a58 9633 idx += SetOctetString(totalSz - idx, &output[idx]);
sPymbed 16:048e5e270a58 9634
sPymbed 16:048e5e270a58 9635 /* 4. Seq + OidListLen (2) */
sPymbed 16:048e5e270a58 9636 idx += SetSequence(oidListSz, &output[idx]);
sPymbed 16:048e5e270a58 9637
sPymbed 16:048e5e270a58 9638 /* 5. Oid List (already set in-place above) */
sPymbed 16:048e5e270a58 9639 idx += oidListSz;
sPymbed 16:048e5e270a58 9640
sPymbed 16:048e5e270a58 9641 (void)cert;
sPymbed 16:048e5e270a58 9642 return idx;
sPymbed 16:048e5e270a58 9643 }
sPymbed 16:048e5e270a58 9644
sPymbed 16:048e5e270a58 9645 /* Encode OID string representation to ITU-T X.690 format */
sPymbed 16:048e5e270a58 9646 static int EncodePolicyOID(byte *out, word32 *outSz, const char *in, void* heap)
sPymbed 16:048e5e270a58 9647 {
sPymbed 16:048e5e270a58 9648 word32 val, idx = 0, nb_val;
sPymbed 16:048e5e270a58 9649 char *token, *str, *ptr;
sPymbed 16:048e5e270a58 9650 word32 len;
sPymbed 16:048e5e270a58 9651
sPymbed 16:048e5e270a58 9652 if (out == NULL || outSz == NULL || *outSz < 2 || in == NULL)
sPymbed 16:048e5e270a58 9653 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 9654
sPymbed 16:048e5e270a58 9655 len = (word32)XSTRLEN(in);
sPymbed 16:048e5e270a58 9656
sPymbed 16:048e5e270a58 9657 str = (char *)XMALLOC(len+1, heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 9658 if (str == NULL)
sPymbed 16:048e5e270a58 9659 return MEMORY_E;
sPymbed 16:048e5e270a58 9660
sPymbed 16:048e5e270a58 9661 XSTRNCPY(str, in, len);
sPymbed 16:048e5e270a58 9662 str[len] = '\0';
sPymbed 16:048e5e270a58 9663
sPymbed 16:048e5e270a58 9664 nb_val = 0;
sPymbed 16:048e5e270a58 9665
sPymbed 16:048e5e270a58 9666 /* parse value, and set corresponding Policy OID value */
sPymbed 16:048e5e270a58 9667 token = XSTRTOK(str, ".", &ptr);
sPymbed 16:048e5e270a58 9668 while (token != NULL)
sPymbed 16:048e5e270a58 9669 {
sPymbed 16:048e5e270a58 9670 val = (word32)atoi(token);
sPymbed 16:048e5e270a58 9671
sPymbed 16:048e5e270a58 9672 if (nb_val == 0) {
sPymbed 16:048e5e270a58 9673 if (val > 2) {
sPymbed 16:048e5e270a58 9674 XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 9675 return ASN_OBJECT_ID_E;
sPymbed 16:048e5e270a58 9676 }
sPymbed 16:048e5e270a58 9677
sPymbed 16:048e5e270a58 9678 out[idx] = (byte)(40 * val);
sPymbed 16:048e5e270a58 9679 }
sPymbed 16:048e5e270a58 9680 else if (nb_val == 1) {
sPymbed 16:048e5e270a58 9681 if (val > 127) {
sPymbed 16:048e5e270a58 9682 XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 9683 return ASN_OBJECT_ID_E;
sPymbed 16:048e5e270a58 9684 }
sPymbed 16:048e5e270a58 9685
sPymbed 16:048e5e270a58 9686 if (idx > *outSz) {
sPymbed 16:048e5e270a58 9687 XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 9688 return BUFFER_E;
sPymbed 16:048e5e270a58 9689 }
sPymbed 16:048e5e270a58 9690
sPymbed 16:048e5e270a58 9691 out[idx++] += (byte)val;
sPymbed 16:048e5e270a58 9692 }
sPymbed 16:048e5e270a58 9693 else {
sPymbed 16:048e5e270a58 9694 word32 tb = 0, x;
sPymbed 16:048e5e270a58 9695 int i = 0;
sPymbed 16:048e5e270a58 9696 byte oid[MAX_OID_SZ];
sPymbed 16:048e5e270a58 9697
sPymbed 16:048e5e270a58 9698 while (val >= 128) {
sPymbed 16:048e5e270a58 9699 x = val % 128;
sPymbed 16:048e5e270a58 9700 val /= 128;
sPymbed 16:048e5e270a58 9701 oid[i++] = (byte) (((tb++) ? 0x80 : 0) | x);
sPymbed 16:048e5e270a58 9702 }
sPymbed 16:048e5e270a58 9703
sPymbed 16:048e5e270a58 9704 if ((idx+(word32)i) > *outSz) {
sPymbed 16:048e5e270a58 9705 XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 9706 return BUFFER_E;
sPymbed 16:048e5e270a58 9707 }
sPymbed 16:048e5e270a58 9708
sPymbed 16:048e5e270a58 9709 oid[i] = (byte) (((tb++) ? 0x80 : 0) | val);
sPymbed 16:048e5e270a58 9710
sPymbed 16:048e5e270a58 9711 /* push value in the right order */
sPymbed 16:048e5e270a58 9712 while (i >= 0)
sPymbed 16:048e5e270a58 9713 out[idx++] = oid[i--];
sPymbed 16:048e5e270a58 9714 }
sPymbed 16:048e5e270a58 9715
sPymbed 16:048e5e270a58 9716 token = XSTRTOK(NULL, ".", &ptr);
sPymbed 16:048e5e270a58 9717 nb_val++;
sPymbed 16:048e5e270a58 9718 }
sPymbed 16:048e5e270a58 9719
sPymbed 16:048e5e270a58 9720 *outSz = idx;
sPymbed 16:048e5e270a58 9721
sPymbed 16:048e5e270a58 9722 XFREE(str, heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 9723 return 0;
sPymbed 16:048e5e270a58 9724 }
sPymbed 16:048e5e270a58 9725
sPymbed 16:048e5e270a58 9726 /* encode Certificate Policies, return total bytes written
sPymbed 16:048e5e270a58 9727 * each input value must be ITU-T X.690 formatted : a.b.c...
sPymbed 16:048e5e270a58 9728 * input must be an array of values with a NULL terminated for the latest
sPymbed 16:048e5e270a58 9729 * RFC5280 : non-critical */
sPymbed 16:048e5e270a58 9730 static int SetCertificatePolicies(byte *output,
sPymbed 16:048e5e270a58 9731 word32 outputSz,
sPymbed 16:048e5e270a58 9732 char input[MAX_CERTPOL_NB][MAX_CERTPOL_SZ],
sPymbed 16:048e5e270a58 9733 word16 nb_certpol,
sPymbed 16:048e5e270a58 9734 void* heap)
sPymbed 16:048e5e270a58 9735 {
sPymbed 16:048e5e270a58 9736 byte oid[MAX_OID_SZ],
sPymbed 16:048e5e270a58 9737 der_oid[MAX_CERTPOL_NB][MAX_OID_SZ],
sPymbed 16:048e5e270a58 9738 out[MAX_CERTPOL_SZ];
sPymbed 16:048e5e270a58 9739 word32 oidSz;
sPymbed 16:048e5e270a58 9740 word32 outSz, i = 0, der_oidSz[MAX_CERTPOL_NB];
sPymbed 16:048e5e270a58 9741 int ret;
sPymbed 16:048e5e270a58 9742
sPymbed 16:048e5e270a58 9743 static const byte certpol_oid[] = { 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04 };
sPymbed 16:048e5e270a58 9744 static const byte oid_oid[] = { 0x06 };
sPymbed 16:048e5e270a58 9745
sPymbed 16:048e5e270a58 9746 if (output == NULL || input == NULL || nb_certpol > MAX_CERTPOL_NB)
sPymbed 16:048e5e270a58 9747 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 9748
sPymbed 16:048e5e270a58 9749 for (i = 0; i < nb_certpol; i++) {
sPymbed 16:048e5e270a58 9750 oidSz = sizeof(oid);
sPymbed 16:048e5e270a58 9751 XMEMSET(oid, 0, oidSz);
sPymbed 16:048e5e270a58 9752
sPymbed 16:048e5e270a58 9753 ret = EncodePolicyOID(oid, &oidSz, input[i], heap);
sPymbed 16:048e5e270a58 9754 if (ret != 0)
sPymbed 16:048e5e270a58 9755 return ret;
sPymbed 16:048e5e270a58 9756
sPymbed 16:048e5e270a58 9757 /* compute sequence value for the oid */
sPymbed 16:048e5e270a58 9758 ret = SetOidValue(der_oid[i], MAX_OID_SZ, oid_oid,
sPymbed 16:048e5e270a58 9759 sizeof(oid_oid), oid, oidSz);
sPymbed 16:048e5e270a58 9760 if (ret <= 0)
sPymbed 16:048e5e270a58 9761 return ret;
sPymbed 16:048e5e270a58 9762 else
sPymbed 16:048e5e270a58 9763 der_oidSz[i] = (word32)ret;
sPymbed 16:048e5e270a58 9764 }
sPymbed 16:048e5e270a58 9765
sPymbed 16:048e5e270a58 9766 /* concatenate oid, keep two byte for sequence/size of the created value */
sPymbed 16:048e5e270a58 9767 for (i = 0, outSz = 2; i < nb_certpol; i++) {
sPymbed 16:048e5e270a58 9768 XMEMCPY(out+outSz, der_oid[i], der_oidSz[i]);
sPymbed 16:048e5e270a58 9769 outSz += der_oidSz[i];
sPymbed 16:048e5e270a58 9770 }
sPymbed 16:048e5e270a58 9771
sPymbed 16:048e5e270a58 9772 /* add sequence */
sPymbed 16:048e5e270a58 9773 ret = SetSequence(outSz-2, out);
sPymbed 16:048e5e270a58 9774 if (ret <= 0)
sPymbed 16:048e5e270a58 9775 return ret;
sPymbed 16:048e5e270a58 9776
sPymbed 16:048e5e270a58 9777 /* add Policy OID to compute final value */
sPymbed 16:048e5e270a58 9778 return SetOidValue(output, outputSz, certpol_oid, sizeof(certpol_oid),
sPymbed 16:048e5e270a58 9779 out, outSz);
sPymbed 16:048e5e270a58 9780 }
sPymbed 16:048e5e270a58 9781 #endif /* WOLFSSL_CERT_EXT */
sPymbed 16:048e5e270a58 9782
sPymbed 16:048e5e270a58 9783 #ifdef WOLFSSL_ALT_NAMES
sPymbed 16:048e5e270a58 9784 /* encode Alternative Names, return total bytes written */
sPymbed 16:048e5e270a58 9785 static int SetAltNames(byte *out, word32 outSz, byte *input, word32 length)
sPymbed 16:048e5e270a58 9786 {
sPymbed 16:048e5e270a58 9787 if (out == NULL || input == NULL)
sPymbed 16:048e5e270a58 9788 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 9789
sPymbed 16:048e5e270a58 9790 if (outSz < length)
sPymbed 16:048e5e270a58 9791 return BUFFER_E;
sPymbed 16:048e5e270a58 9792
sPymbed 16:048e5e270a58 9793 /* Alternative Names come from certificate or computed by
sPymbed 16:048e5e270a58 9794 * external function, so already encoded. Just copy value */
sPymbed 16:048e5e270a58 9795 XMEMCPY(out, input, length);
sPymbed 16:048e5e270a58 9796 return length;
sPymbed 16:048e5e270a58 9797 }
sPymbed 16:048e5e270a58 9798 #endif /* WOLFSL_ALT_NAMES */
sPymbed 16:048e5e270a58 9799
sPymbed 16:048e5e270a58 9800 /* Encodes one attribute of the name (issuer/subject)
sPymbed 16:048e5e270a58 9801 *
sPymbed 16:048e5e270a58 9802 * name structure to hold result of encoding
sPymbed 16:048e5e270a58 9803 * nameStr value to be encoded
sPymbed 16:048e5e270a58 9804 * nameType type of encoding i.e CTC_UTF8
sPymbed 16:048e5e270a58 9805 * type id of attribute i.e ASN_COMMON_NAME
sPymbed 16:048e5e270a58 9806 *
sPymbed 16:048e5e270a58 9807 * returns length on success
sPymbed 16:048e5e270a58 9808 */
sPymbed 16:048e5e270a58 9809 static int wc_EncodeName(EncodedName* name, const char* nameStr, char nameType,
sPymbed 16:048e5e270a58 9810 byte type)
sPymbed 16:048e5e270a58 9811 {
sPymbed 16:048e5e270a58 9812 word32 idx = 0;
sPymbed 16:048e5e270a58 9813
sPymbed 16:048e5e270a58 9814 if (nameStr) {
sPymbed 16:048e5e270a58 9815 /* bottom up */
sPymbed 16:048e5e270a58 9816 byte firstLen[1 + MAX_LENGTH_SZ];
sPymbed 16:048e5e270a58 9817 byte secondLen[MAX_LENGTH_SZ];
sPymbed 16:048e5e270a58 9818 byte sequence[MAX_SEQ_SZ];
sPymbed 16:048e5e270a58 9819 byte set[MAX_SET_SZ];
sPymbed 16:048e5e270a58 9820
sPymbed 16:048e5e270a58 9821 int strLen = (int)XSTRLEN(nameStr);
sPymbed 16:048e5e270a58 9822 int thisLen = strLen;
sPymbed 16:048e5e270a58 9823 int firstSz, secondSz, seqSz, setSz;
sPymbed 16:048e5e270a58 9824
sPymbed 16:048e5e270a58 9825 if (strLen == 0) { /* no user data for this item */
sPymbed 16:048e5e270a58 9826 name->used = 0;
sPymbed 16:048e5e270a58 9827 return 0;
sPymbed 16:048e5e270a58 9828 }
sPymbed 16:048e5e270a58 9829
sPymbed 16:048e5e270a58 9830 /* Restrict country code size */
sPymbed 16:048e5e270a58 9831 if (ASN_COUNTRY_NAME == type && strLen != CTC_COUNTRY_SIZE) {
sPymbed 16:048e5e270a58 9832 return ASN_COUNTRY_SIZE_E;
sPymbed 16:048e5e270a58 9833 }
sPymbed 16:048e5e270a58 9834
sPymbed 16:048e5e270a58 9835 secondSz = SetLength(strLen, secondLen);
sPymbed 16:048e5e270a58 9836 thisLen += secondSz;
sPymbed 16:048e5e270a58 9837 switch (type) {
sPymbed 16:048e5e270a58 9838 case ASN_EMAIL_NAME: /* email */
sPymbed 16:048e5e270a58 9839 thisLen += EMAIL_JOINT_LEN;
sPymbed 16:048e5e270a58 9840 firstSz = EMAIL_JOINT_LEN;
sPymbed 16:048e5e270a58 9841 break;
sPymbed 16:048e5e270a58 9842
sPymbed 16:048e5e270a58 9843 case ASN_DOMAIN_COMPONENT:
sPymbed 16:048e5e270a58 9844 thisLen += PILOT_JOINT_LEN;
sPymbed 16:048e5e270a58 9845 firstSz = PILOT_JOINT_LEN;
sPymbed 16:048e5e270a58 9846 break;
sPymbed 16:048e5e270a58 9847
sPymbed 16:048e5e270a58 9848 default:
sPymbed 16:048e5e270a58 9849 thisLen++; /* str type */
sPymbed 16:048e5e270a58 9850 thisLen += JOINT_LEN;
sPymbed 16:048e5e270a58 9851 firstSz = JOINT_LEN + 1;
sPymbed 16:048e5e270a58 9852 }
sPymbed 16:048e5e270a58 9853 thisLen++; /* id type */
sPymbed 16:048e5e270a58 9854 firstSz = SetObjectId(firstSz, firstLen);
sPymbed 16:048e5e270a58 9855 thisLen += firstSz;
sPymbed 16:048e5e270a58 9856
sPymbed 16:048e5e270a58 9857 seqSz = SetSequence(thisLen, sequence);
sPymbed 16:048e5e270a58 9858 thisLen += seqSz;
sPymbed 16:048e5e270a58 9859 setSz = SetSet(thisLen, set);
sPymbed 16:048e5e270a58 9860 thisLen += setSz;
sPymbed 16:048e5e270a58 9861
sPymbed 16:048e5e270a58 9862 if (thisLen > (int)sizeof(name->encoded)) {
sPymbed 16:048e5e270a58 9863 return BUFFER_E;
sPymbed 16:048e5e270a58 9864 }
sPymbed 16:048e5e270a58 9865
sPymbed 16:048e5e270a58 9866 /* store it */
sPymbed 16:048e5e270a58 9867 idx = 0;
sPymbed 16:048e5e270a58 9868 /* set */
sPymbed 16:048e5e270a58 9869 XMEMCPY(name->encoded, set, setSz);
sPymbed 16:048e5e270a58 9870 idx += setSz;
sPymbed 16:048e5e270a58 9871 /* seq */
sPymbed 16:048e5e270a58 9872 XMEMCPY(name->encoded + idx, sequence, seqSz);
sPymbed 16:048e5e270a58 9873 idx += seqSz;
sPymbed 16:048e5e270a58 9874 /* asn object id */
sPymbed 16:048e5e270a58 9875 XMEMCPY(name->encoded + idx, firstLen, firstSz);
sPymbed 16:048e5e270a58 9876 idx += firstSz;
sPymbed 16:048e5e270a58 9877 switch (type) {
sPymbed 16:048e5e270a58 9878 case ASN_EMAIL_NAME:
sPymbed 16:048e5e270a58 9879 {
sPymbed 16:048e5e270a58 9880 const byte EMAIL_OID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
sPymbed 16:048e5e270a58 9881 0x01, 0x09, 0x01, 0x16 };
sPymbed 16:048e5e270a58 9882 /* email joint id */
sPymbed 16:048e5e270a58 9883 XMEMCPY(name->encoded + idx, EMAIL_OID, sizeof(EMAIL_OID));
sPymbed 16:048e5e270a58 9884 idx += (int)sizeof(EMAIL_OID);
sPymbed 16:048e5e270a58 9885 }
sPymbed 16:048e5e270a58 9886 break;
sPymbed 16:048e5e270a58 9887
sPymbed 16:048e5e270a58 9888 case ASN_DOMAIN_COMPONENT:
sPymbed 16:048e5e270a58 9889 {
sPymbed 16:048e5e270a58 9890 const byte PILOT_OID[] = { 0x09, 0x92, 0x26, 0x89,
sPymbed 16:048e5e270a58 9891 0x93, 0xF2, 0x2C, 0x64, 0x01
sPymbed 16:048e5e270a58 9892 };
sPymbed 16:048e5e270a58 9893
sPymbed 16:048e5e270a58 9894 XMEMCPY(name->encoded + idx, PILOT_OID,
sPymbed 16:048e5e270a58 9895 sizeof(PILOT_OID));
sPymbed 16:048e5e270a58 9896 idx += (int)sizeof(PILOT_OID);
sPymbed 16:048e5e270a58 9897 /* id type */
sPymbed 16:048e5e270a58 9898 name->encoded[idx++] = type;
sPymbed 16:048e5e270a58 9899 /* str type */
sPymbed 16:048e5e270a58 9900 name->encoded[idx++] = nameType;
sPymbed 16:048e5e270a58 9901 }
sPymbed 16:048e5e270a58 9902 break;
sPymbed 16:048e5e270a58 9903
sPymbed 16:048e5e270a58 9904 default:
sPymbed 16:048e5e270a58 9905 name->encoded[idx++] = 0x55;
sPymbed 16:048e5e270a58 9906 name->encoded[idx++] = 0x04;
sPymbed 16:048e5e270a58 9907 /* id type */
sPymbed 16:048e5e270a58 9908 name->encoded[idx++] = type;
sPymbed 16:048e5e270a58 9909 /* str type */
sPymbed 16:048e5e270a58 9910 name->encoded[idx++] = nameType;
sPymbed 16:048e5e270a58 9911 }
sPymbed 16:048e5e270a58 9912 /* second length */
sPymbed 16:048e5e270a58 9913 XMEMCPY(name->encoded + idx, secondLen, secondSz);
sPymbed 16:048e5e270a58 9914 idx += secondSz;
sPymbed 16:048e5e270a58 9915 /* str value */
sPymbed 16:048e5e270a58 9916 XMEMCPY(name->encoded + idx, nameStr, strLen);
sPymbed 16:048e5e270a58 9917 idx += strLen;
sPymbed 16:048e5e270a58 9918
sPymbed 16:048e5e270a58 9919 name->type = type;
sPymbed 16:048e5e270a58 9920 name->totalLen = idx;
sPymbed 16:048e5e270a58 9921 name->used = 1;
sPymbed 16:048e5e270a58 9922 }
sPymbed 16:048e5e270a58 9923 else
sPymbed 16:048e5e270a58 9924 name->used = 0;
sPymbed 16:048e5e270a58 9925
sPymbed 16:048e5e270a58 9926 return idx;
sPymbed 16:048e5e270a58 9927 }
sPymbed 16:048e5e270a58 9928
sPymbed 16:048e5e270a58 9929 /* encode CertName into output, return total bytes written */
sPymbed 16:048e5e270a58 9930 int SetName(byte* output, word32 outputSz, CertName* name)
sPymbed 16:048e5e270a58 9931 {
sPymbed 16:048e5e270a58 9932 int totalBytes = 0, i, idx;
sPymbed 16:048e5e270a58 9933 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 9934 EncodedName* names = NULL;
sPymbed 16:048e5e270a58 9935 #else
sPymbed 16:048e5e270a58 9936 EncodedName names[NAME_ENTRIES];
sPymbed 16:048e5e270a58 9937 #endif
sPymbed 16:048e5e270a58 9938 #ifdef WOLFSSL_MULTI_ATTRIB
sPymbed 16:048e5e270a58 9939 EncodedName addNames[CTC_MAX_ATTRIB];
sPymbed 16:048e5e270a58 9940 int j, type;
sPymbed 16:048e5e270a58 9941 #endif
sPymbed 16:048e5e270a58 9942
sPymbed 16:048e5e270a58 9943 if (output == NULL || name == NULL)
sPymbed 16:048e5e270a58 9944 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 9945
sPymbed 16:048e5e270a58 9946 if (outputSz < 3)
sPymbed 16:048e5e270a58 9947 return BUFFER_E;
sPymbed 16:048e5e270a58 9948
sPymbed 16:048e5e270a58 9949 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 9950 names = (EncodedName*)XMALLOC(sizeof(EncodedName) * NAME_ENTRIES, NULL,
sPymbed 16:048e5e270a58 9951 DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 9952 if (names == NULL)
sPymbed 16:048e5e270a58 9953 return MEMORY_E;
sPymbed 16:048e5e270a58 9954 #endif
sPymbed 16:048e5e270a58 9955
sPymbed 16:048e5e270a58 9956 for (i = 0; i < NAME_ENTRIES; i++) {
sPymbed 16:048e5e270a58 9957 int ret;
sPymbed 16:048e5e270a58 9958 const char* nameStr = GetOneName(name, i);
sPymbed 16:048e5e270a58 9959
sPymbed 16:048e5e270a58 9960 ret = wc_EncodeName(&names[i], nameStr, GetNameType(name, i),
sPymbed 16:048e5e270a58 9961 GetNameId(i));
sPymbed 16:048e5e270a58 9962 if (ret < 0) {
sPymbed 16:048e5e270a58 9963 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 9964 XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 9965 #endif
sPymbed 16:048e5e270a58 9966 return BUFFER_E;
sPymbed 16:048e5e270a58 9967 }
sPymbed 16:048e5e270a58 9968 totalBytes += ret;
sPymbed 16:048e5e270a58 9969 }
sPymbed 16:048e5e270a58 9970 #ifdef WOLFSSL_MULTI_ATTRIB
sPymbed 16:048e5e270a58 9971 for (i = 0; i < CTC_MAX_ATTRIB; i++) {
sPymbed 16:048e5e270a58 9972 if (name->name[i].sz > 0) {
sPymbed 16:048e5e270a58 9973 int ret;
sPymbed 16:048e5e270a58 9974 ret = wc_EncodeName(&addNames[i], name->name[i].value,
sPymbed 16:048e5e270a58 9975 name->name[i].type, name->name[i].id);
sPymbed 16:048e5e270a58 9976 if (ret < 0) {
sPymbed 16:048e5e270a58 9977 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 9978 XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 9979 #endif
sPymbed 16:048e5e270a58 9980 return BUFFER_E;
sPymbed 16:048e5e270a58 9981 }
sPymbed 16:048e5e270a58 9982 totalBytes += ret;
sPymbed 16:048e5e270a58 9983 }
sPymbed 16:048e5e270a58 9984 else {
sPymbed 16:048e5e270a58 9985 addNames[i].used = 0;
sPymbed 16:048e5e270a58 9986 }
sPymbed 16:048e5e270a58 9987 }
sPymbed 16:048e5e270a58 9988 #endif /* WOLFSSL_MULTI_ATTRIB */
sPymbed 16:048e5e270a58 9989
sPymbed 16:048e5e270a58 9990 /* header */
sPymbed 16:048e5e270a58 9991 idx = SetSequence(totalBytes, output);
sPymbed 16:048e5e270a58 9992 totalBytes += idx;
sPymbed 16:048e5e270a58 9993 if (totalBytes > ASN_NAME_MAX) {
sPymbed 16:048e5e270a58 9994 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 9995 XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 9996 #endif
sPymbed 16:048e5e270a58 9997 return BUFFER_E;
sPymbed 16:048e5e270a58 9998 }
sPymbed 16:048e5e270a58 9999
sPymbed 16:048e5e270a58 10000 for (i = 0; i < NAME_ENTRIES; i++) {
sPymbed 16:048e5e270a58 10001 #ifdef WOLFSSL_MULTI_ATTRIB
sPymbed 16:048e5e270a58 10002 type = GetNameId(i);
sPymbed 16:048e5e270a58 10003
sPymbed 16:048e5e270a58 10004 /* list all DC values before OUs */
sPymbed 16:048e5e270a58 10005 if (type == ASN_ORGUNIT_NAME) {
sPymbed 16:048e5e270a58 10006 type = ASN_DOMAIN_COMPONENT;
sPymbed 16:048e5e270a58 10007 for (j = 0; j < CTC_MAX_ATTRIB; j++) {
sPymbed 16:048e5e270a58 10008 if (name->name[j].sz > 0 && type == name->name[j].id) {
sPymbed 16:048e5e270a58 10009 if (outputSz < (word32)(idx+addNames[j].totalLen)) {
sPymbed 16:048e5e270a58 10010 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 10011 XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 10012 #endif
sPymbed 16:048e5e270a58 10013 return BUFFER_E;
sPymbed 16:048e5e270a58 10014 }
sPymbed 16:048e5e270a58 10015
sPymbed 16:048e5e270a58 10016 XMEMCPY(output + idx, addNames[j].encoded,
sPymbed 16:048e5e270a58 10017 addNames[j].totalLen);
sPymbed 16:048e5e270a58 10018 idx += addNames[j].totalLen;
sPymbed 16:048e5e270a58 10019 }
sPymbed 16:048e5e270a58 10020 }
sPymbed 16:048e5e270a58 10021 type = ASN_ORGUNIT_NAME;
sPymbed 16:048e5e270a58 10022 }
sPymbed 16:048e5e270a58 10023
sPymbed 16:048e5e270a58 10024 /* write all similar types to the buffer */
sPymbed 16:048e5e270a58 10025 for (j = 0; j < CTC_MAX_ATTRIB; j++) {
sPymbed 16:048e5e270a58 10026 if (name->name[j].sz > 0 && type == name->name[j].id) {
sPymbed 16:048e5e270a58 10027 if (outputSz < (word32)(idx+addNames[j].totalLen)) {
sPymbed 16:048e5e270a58 10028 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 10029 XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 10030 #endif
sPymbed 16:048e5e270a58 10031 return BUFFER_E;
sPymbed 16:048e5e270a58 10032 }
sPymbed 16:048e5e270a58 10033
sPymbed 16:048e5e270a58 10034 XMEMCPY(output + idx, addNames[j].encoded,
sPymbed 16:048e5e270a58 10035 addNames[j].totalLen);
sPymbed 16:048e5e270a58 10036 idx += addNames[j].totalLen;
sPymbed 16:048e5e270a58 10037 }
sPymbed 16:048e5e270a58 10038 }
sPymbed 16:048e5e270a58 10039 #endif /* WOLFSSL_MULTI_ATTRIB */
sPymbed 16:048e5e270a58 10040
sPymbed 16:048e5e270a58 10041 if (names[i].used) {
sPymbed 16:048e5e270a58 10042 if (outputSz < (word32)(idx+names[i].totalLen)) {
sPymbed 16:048e5e270a58 10043 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 10044 XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 10045 #endif
sPymbed 16:048e5e270a58 10046 return BUFFER_E;
sPymbed 16:048e5e270a58 10047 }
sPymbed 16:048e5e270a58 10048
sPymbed 16:048e5e270a58 10049 XMEMCPY(output + idx, names[i].encoded, names[i].totalLen);
sPymbed 16:048e5e270a58 10050 idx += names[i].totalLen;
sPymbed 16:048e5e270a58 10051 }
sPymbed 16:048e5e270a58 10052 }
sPymbed 16:048e5e270a58 10053
sPymbed 16:048e5e270a58 10054 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 10055 XFREE(names, NULL, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 10056 #endif
sPymbed 16:048e5e270a58 10057
sPymbed 16:048e5e270a58 10058 return totalBytes;
sPymbed 16:048e5e270a58 10059 }
sPymbed 16:048e5e270a58 10060
sPymbed 16:048e5e270a58 10061 /* encode info from cert into DER encoded format */
sPymbed 16:048e5e270a58 10062 static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, ecc_key* eccKey,
sPymbed 16:048e5e270a58 10063 WC_RNG* rng, const byte* ntruKey, word16 ntruSz,
sPymbed 16:048e5e270a58 10064 ed25519_key* ed25519Key)
sPymbed 16:048e5e270a58 10065 {
sPymbed 16:048e5e270a58 10066 int ret;
sPymbed 16:048e5e270a58 10067
sPymbed 16:048e5e270a58 10068 if (cert == NULL || der == NULL || rng == NULL)
sPymbed 16:048e5e270a58 10069 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 10070
sPymbed 16:048e5e270a58 10071 /* make sure at least one key type is provided */
sPymbed 16:048e5e270a58 10072 if (rsaKey == NULL && eccKey == NULL && ed25519Key == NULL && ntruKey == NULL)
sPymbed 16:048e5e270a58 10073 return PUBLIC_KEY_E;
sPymbed 16:048e5e270a58 10074
sPymbed 16:048e5e270a58 10075 /* init */
sPymbed 16:048e5e270a58 10076 XMEMSET(der, 0, sizeof(DerCert));
sPymbed 16:048e5e270a58 10077
sPymbed 16:048e5e270a58 10078 /* version */
sPymbed 16:048e5e270a58 10079 der->versionSz = SetMyVersion(cert->version, der->version, TRUE);
sPymbed 16:048e5e270a58 10080
sPymbed 16:048e5e270a58 10081 /* serial number (must be positive) */
sPymbed 16:048e5e270a58 10082 if (cert->serialSz == 0) {
sPymbed 16:048e5e270a58 10083 /* generate random serial */
sPymbed 16:048e5e270a58 10084 cert->serialSz = CTC_SERIAL_SIZE;
sPymbed 16:048e5e270a58 10085 ret = wc_RNG_GenerateBlock(rng, cert->serial, cert->serialSz);
sPymbed 16:048e5e270a58 10086 if (ret != 0)
sPymbed 16:048e5e270a58 10087 return ret;
sPymbed 16:048e5e270a58 10088 }
sPymbed 16:048e5e270a58 10089 der->serialSz = SetSerialNumber(cert->serial, cert->serialSz, der->serial,
sPymbed 16:048e5e270a58 10090 CTC_SERIAL_SIZE);
sPymbed 16:048e5e270a58 10091 if (der->serialSz < 0)
sPymbed 16:048e5e270a58 10092 return der->serialSz;
sPymbed 16:048e5e270a58 10093
sPymbed 16:048e5e270a58 10094 /* signature algo */
sPymbed 16:048e5e270a58 10095 der->sigAlgoSz = SetAlgoID(cert->sigType, der->sigAlgo, oidSigType, 0);
sPymbed 16:048e5e270a58 10096 if (der->sigAlgoSz <= 0)
sPymbed 16:048e5e270a58 10097 return ALGO_ID_E;
sPymbed 16:048e5e270a58 10098
sPymbed 16:048e5e270a58 10099 /* public key */
sPymbed 16:048e5e270a58 10100 #ifndef NO_RSA
sPymbed 16:048e5e270a58 10101 if (cert->keyType == RSA_KEY) {
sPymbed 16:048e5e270a58 10102 if (rsaKey == NULL)
sPymbed 16:048e5e270a58 10103 return PUBLIC_KEY_E;
sPymbed 16:048e5e270a58 10104 der->publicKeySz = SetRsaPublicKey(der->publicKey, rsaKey,
sPymbed 16:048e5e270a58 10105 sizeof(der->publicKey), 1);
sPymbed 16:048e5e270a58 10106 }
sPymbed 16:048e5e270a58 10107 #endif
sPymbed 16:048e5e270a58 10108
sPymbed 16:048e5e270a58 10109 #ifdef HAVE_ECC
sPymbed 16:048e5e270a58 10110 if (cert->keyType == ECC_KEY) {
sPymbed 16:048e5e270a58 10111 if (eccKey == NULL)
sPymbed 16:048e5e270a58 10112 return PUBLIC_KEY_E;
sPymbed 16:048e5e270a58 10113 der->publicKeySz = SetEccPublicKey(der->publicKey, eccKey, 1);
sPymbed 16:048e5e270a58 10114 }
sPymbed 16:048e5e270a58 10115 #endif
sPymbed 16:048e5e270a58 10116
sPymbed 16:048e5e270a58 10117 #ifdef HAVE_ED25519
sPymbed 16:048e5e270a58 10118 if (cert->keyType == ED25519_KEY) {
sPymbed 16:048e5e270a58 10119 if (ed25519Key == NULL)
sPymbed 16:048e5e270a58 10120 return PUBLIC_KEY_E;
sPymbed 16:048e5e270a58 10121 der->publicKeySz = SetEd25519PublicKey(der->publicKey, ed25519Key, 1);
sPymbed 16:048e5e270a58 10122 }
sPymbed 16:048e5e270a58 10123 #endif
sPymbed 16:048e5e270a58 10124
sPymbed 16:048e5e270a58 10125 #ifdef HAVE_NTRU
sPymbed 16:048e5e270a58 10126 if (cert->keyType == NTRU_KEY) {
sPymbed 16:048e5e270a58 10127 word32 rc;
sPymbed 16:048e5e270a58 10128 word16 encodedSz;
sPymbed 16:048e5e270a58 10129
sPymbed 16:048e5e270a58 10130 if (ntruKey == NULL)
sPymbed 16:048e5e270a58 10131 return PUBLIC_KEY_E;
sPymbed 16:048e5e270a58 10132
sPymbed 16:048e5e270a58 10133 rc = ntru_crypto_ntru_encrypt_publicKey2SubjectPublicKeyInfo(ntruSz,
sPymbed 16:048e5e270a58 10134 ntruKey, &encodedSz, NULL);
sPymbed 16:048e5e270a58 10135 if (rc != NTRU_OK)
sPymbed 16:048e5e270a58 10136 return PUBLIC_KEY_E;
sPymbed 16:048e5e270a58 10137 if (encodedSz > MAX_PUBLIC_KEY_SZ)
sPymbed 16:048e5e270a58 10138 return PUBLIC_KEY_E;
sPymbed 16:048e5e270a58 10139
sPymbed 16:048e5e270a58 10140 rc = ntru_crypto_ntru_encrypt_publicKey2SubjectPublicKeyInfo(ntruSz,
sPymbed 16:048e5e270a58 10141 ntruKey, &encodedSz, der->publicKey);
sPymbed 16:048e5e270a58 10142 if (rc != NTRU_OK)
sPymbed 16:048e5e270a58 10143 return PUBLIC_KEY_E;
sPymbed 16:048e5e270a58 10144
sPymbed 16:048e5e270a58 10145 der->publicKeySz = encodedSz;
sPymbed 16:048e5e270a58 10146 }
sPymbed 16:048e5e270a58 10147 #else
sPymbed 16:048e5e270a58 10148 (void)ntruSz;
sPymbed 16:048e5e270a58 10149 #endif /* HAVE_NTRU */
sPymbed 16:048e5e270a58 10150
sPymbed 16:048e5e270a58 10151 if (der->publicKeySz <= 0)
sPymbed 16:048e5e270a58 10152 return PUBLIC_KEY_E;
sPymbed 16:048e5e270a58 10153
sPymbed 16:048e5e270a58 10154 der->validitySz = 0;
sPymbed 16:048e5e270a58 10155 #ifdef WOLFSSL_ALT_NAMES
sPymbed 16:048e5e270a58 10156 /* date validity copy ? */
sPymbed 16:048e5e270a58 10157 if (cert->beforeDateSz && cert->afterDateSz) {
sPymbed 16:048e5e270a58 10158 der->validitySz = CopyValidity(der->validity, cert);
sPymbed 16:048e5e270a58 10159 if (der->validitySz <= 0)
sPymbed 16:048e5e270a58 10160 return DATE_E;
sPymbed 16:048e5e270a58 10161 }
sPymbed 16:048e5e270a58 10162 #endif
sPymbed 16:048e5e270a58 10163
sPymbed 16:048e5e270a58 10164 /* date validity */
sPymbed 16:048e5e270a58 10165 if (der->validitySz == 0) {
sPymbed 16:048e5e270a58 10166 der->validitySz = SetValidity(der->validity, cert->daysValid);
sPymbed 16:048e5e270a58 10167 if (der->validitySz <= 0)
sPymbed 16:048e5e270a58 10168 return DATE_E;
sPymbed 16:048e5e270a58 10169 }
sPymbed 16:048e5e270a58 10170
sPymbed 16:048e5e270a58 10171 /* subject name */
sPymbed 16:048e5e270a58 10172 der->subjectSz = SetName(der->subject, sizeof(der->subject), &cert->subject);
sPymbed 16:048e5e270a58 10173 if (der->subjectSz <= 0)
sPymbed 16:048e5e270a58 10174 return SUBJECT_E;
sPymbed 16:048e5e270a58 10175
sPymbed 16:048e5e270a58 10176 /* issuer name */
sPymbed 16:048e5e270a58 10177 der->issuerSz = SetName(der->issuer, sizeof(der->issuer), cert->selfSigned ?
sPymbed 16:048e5e270a58 10178 &cert->subject : &cert->issuer);
sPymbed 16:048e5e270a58 10179 if (der->issuerSz <= 0)
sPymbed 16:048e5e270a58 10180 return ISSUER_E;
sPymbed 16:048e5e270a58 10181
sPymbed 16:048e5e270a58 10182 /* set the extensions */
sPymbed 16:048e5e270a58 10183 der->extensionsSz = 0;
sPymbed 16:048e5e270a58 10184
sPymbed 16:048e5e270a58 10185 /* CA */
sPymbed 16:048e5e270a58 10186 if (cert->isCA) {
sPymbed 16:048e5e270a58 10187 der->caSz = SetCa(der->ca, sizeof(der->ca));
sPymbed 16:048e5e270a58 10188 if (der->caSz <= 0)
sPymbed 16:048e5e270a58 10189 return CA_TRUE_E;
sPymbed 16:048e5e270a58 10190
sPymbed 16:048e5e270a58 10191 der->extensionsSz += der->caSz;
sPymbed 16:048e5e270a58 10192 }
sPymbed 16:048e5e270a58 10193 else
sPymbed 16:048e5e270a58 10194 der->caSz = 0;
sPymbed 16:048e5e270a58 10195
sPymbed 16:048e5e270a58 10196 #ifdef WOLFSSL_ALT_NAMES
sPymbed 16:048e5e270a58 10197 /* Alternative Name */
sPymbed 16:048e5e270a58 10198 if (cert->altNamesSz) {
sPymbed 16:048e5e270a58 10199 der->altNamesSz = SetAltNames(der->altNames, sizeof(der->altNames),
sPymbed 16:048e5e270a58 10200 cert->altNames, cert->altNamesSz);
sPymbed 16:048e5e270a58 10201 if (der->altNamesSz <= 0)
sPymbed 16:048e5e270a58 10202 return ALT_NAME_E;
sPymbed 16:048e5e270a58 10203
sPymbed 16:048e5e270a58 10204 der->extensionsSz += der->altNamesSz;
sPymbed 16:048e5e270a58 10205 }
sPymbed 16:048e5e270a58 10206 else
sPymbed 16:048e5e270a58 10207 der->altNamesSz = 0;
sPymbed 16:048e5e270a58 10208 #endif
sPymbed 16:048e5e270a58 10209
sPymbed 16:048e5e270a58 10210 #ifdef WOLFSSL_CERT_EXT
sPymbed 16:048e5e270a58 10211 /* SKID */
sPymbed 16:048e5e270a58 10212 if (cert->skidSz) {
sPymbed 16:048e5e270a58 10213 /* check the provided SKID size */
sPymbed 16:048e5e270a58 10214 if (cert->skidSz > (int)min(CTC_MAX_SKID_SIZE, sizeof(der->skid)))
sPymbed 16:048e5e270a58 10215 return SKID_E;
sPymbed 16:048e5e270a58 10216
sPymbed 16:048e5e270a58 10217 /* Note: different skid buffers sizes for der (MAX_KID_SZ) and
sPymbed 16:048e5e270a58 10218 cert (CTC_MAX_SKID_SIZE). */
sPymbed 16:048e5e270a58 10219 der->skidSz = SetSKID(der->skid, sizeof(der->skid),
sPymbed 16:048e5e270a58 10220 cert->skid, cert->skidSz);
sPymbed 16:048e5e270a58 10221 if (der->skidSz <= 0)
sPymbed 16:048e5e270a58 10222 return SKID_E;
sPymbed 16:048e5e270a58 10223
sPymbed 16:048e5e270a58 10224 der->extensionsSz += der->skidSz;
sPymbed 16:048e5e270a58 10225 }
sPymbed 16:048e5e270a58 10226 else
sPymbed 16:048e5e270a58 10227 der->skidSz = 0;
sPymbed 16:048e5e270a58 10228
sPymbed 16:048e5e270a58 10229 /* AKID */
sPymbed 16:048e5e270a58 10230 if (cert->akidSz) {
sPymbed 16:048e5e270a58 10231 /* check the provided AKID size */
sPymbed 16:048e5e270a58 10232 if (cert->akidSz > (int)min(CTC_MAX_AKID_SIZE, sizeof(der->akid)))
sPymbed 16:048e5e270a58 10233 return AKID_E;
sPymbed 16:048e5e270a58 10234
sPymbed 16:048e5e270a58 10235 der->akidSz = SetAKID(der->akid, sizeof(der->akid),
sPymbed 16:048e5e270a58 10236 cert->akid, cert->akidSz, cert->heap);
sPymbed 16:048e5e270a58 10237 if (der->akidSz <= 0)
sPymbed 16:048e5e270a58 10238 return AKID_E;
sPymbed 16:048e5e270a58 10239
sPymbed 16:048e5e270a58 10240 der->extensionsSz += der->akidSz;
sPymbed 16:048e5e270a58 10241 }
sPymbed 16:048e5e270a58 10242 else
sPymbed 16:048e5e270a58 10243 der->akidSz = 0;
sPymbed 16:048e5e270a58 10244
sPymbed 16:048e5e270a58 10245 /* Key Usage */
sPymbed 16:048e5e270a58 10246 if (cert->keyUsage != 0){
sPymbed 16:048e5e270a58 10247 der->keyUsageSz = SetKeyUsage(der->keyUsage, sizeof(der->keyUsage),
sPymbed 16:048e5e270a58 10248 cert->keyUsage);
sPymbed 16:048e5e270a58 10249 if (der->keyUsageSz <= 0)
sPymbed 16:048e5e270a58 10250 return KEYUSAGE_E;
sPymbed 16:048e5e270a58 10251
sPymbed 16:048e5e270a58 10252 der->extensionsSz += der->keyUsageSz;
sPymbed 16:048e5e270a58 10253 }
sPymbed 16:048e5e270a58 10254 else
sPymbed 16:048e5e270a58 10255 der->keyUsageSz = 0;
sPymbed 16:048e5e270a58 10256
sPymbed 16:048e5e270a58 10257 /* Extended Key Usage */
sPymbed 16:048e5e270a58 10258 if (cert->extKeyUsage != 0){
sPymbed 16:048e5e270a58 10259 der->extKeyUsageSz = SetExtKeyUsage(cert, der->extKeyUsage,
sPymbed 16:048e5e270a58 10260 sizeof(der->extKeyUsage), cert->extKeyUsage);
sPymbed 16:048e5e270a58 10261 if (der->extKeyUsageSz <= 0)
sPymbed 16:048e5e270a58 10262 return EXTKEYUSAGE_E;
sPymbed 16:048e5e270a58 10263
sPymbed 16:048e5e270a58 10264 der->extensionsSz += der->extKeyUsageSz;
sPymbed 16:048e5e270a58 10265 }
sPymbed 16:048e5e270a58 10266 else
sPymbed 16:048e5e270a58 10267 der->extKeyUsageSz = 0;
sPymbed 16:048e5e270a58 10268
sPymbed 16:048e5e270a58 10269 /* Certificate Policies */
sPymbed 16:048e5e270a58 10270 if (cert->certPoliciesNb != 0) {
sPymbed 16:048e5e270a58 10271 der->certPoliciesSz = SetCertificatePolicies(der->certPolicies,
sPymbed 16:048e5e270a58 10272 sizeof(der->certPolicies),
sPymbed 16:048e5e270a58 10273 cert->certPolicies,
sPymbed 16:048e5e270a58 10274 cert->certPoliciesNb,
sPymbed 16:048e5e270a58 10275 cert->heap);
sPymbed 16:048e5e270a58 10276 if (der->certPoliciesSz <= 0)
sPymbed 16:048e5e270a58 10277 return CERTPOLICIES_E;
sPymbed 16:048e5e270a58 10278
sPymbed 16:048e5e270a58 10279 der->extensionsSz += der->certPoliciesSz;
sPymbed 16:048e5e270a58 10280 }
sPymbed 16:048e5e270a58 10281 else
sPymbed 16:048e5e270a58 10282 der->certPoliciesSz = 0;
sPymbed 16:048e5e270a58 10283 #endif /* WOLFSSL_CERT_EXT */
sPymbed 16:048e5e270a58 10284
sPymbed 16:048e5e270a58 10285 /* put extensions */
sPymbed 16:048e5e270a58 10286 if (der->extensionsSz > 0) {
sPymbed 16:048e5e270a58 10287
sPymbed 16:048e5e270a58 10288 /* put the start of extensions sequence (ID, Size) */
sPymbed 16:048e5e270a58 10289 der->extensionsSz = SetExtensionsHeader(der->extensions,
sPymbed 16:048e5e270a58 10290 sizeof(der->extensions),
sPymbed 16:048e5e270a58 10291 der->extensionsSz);
sPymbed 16:048e5e270a58 10292 if (der->extensionsSz <= 0)
sPymbed 16:048e5e270a58 10293 return EXTENSIONS_E;
sPymbed 16:048e5e270a58 10294
sPymbed 16:048e5e270a58 10295 /* put CA */
sPymbed 16:048e5e270a58 10296 if (der->caSz) {
sPymbed 16:048e5e270a58 10297 ret = SetExtensions(der->extensions, sizeof(der->extensions),
sPymbed 16:048e5e270a58 10298 &der->extensionsSz,
sPymbed 16:048e5e270a58 10299 der->ca, der->caSz);
sPymbed 16:048e5e270a58 10300 if (ret == 0)
sPymbed 16:048e5e270a58 10301 return EXTENSIONS_E;
sPymbed 16:048e5e270a58 10302 }
sPymbed 16:048e5e270a58 10303
sPymbed 16:048e5e270a58 10304 #ifdef WOLFSSL_ALT_NAMES
sPymbed 16:048e5e270a58 10305 /* put Alternative Names */
sPymbed 16:048e5e270a58 10306 if (der->altNamesSz) {
sPymbed 16:048e5e270a58 10307 ret = SetExtensions(der->extensions, sizeof(der->extensions),
sPymbed 16:048e5e270a58 10308 &der->extensionsSz,
sPymbed 16:048e5e270a58 10309 der->altNames, der->altNamesSz);
sPymbed 16:048e5e270a58 10310 if (ret <= 0)
sPymbed 16:048e5e270a58 10311 return EXTENSIONS_E;
sPymbed 16:048e5e270a58 10312 }
sPymbed 16:048e5e270a58 10313 #endif
sPymbed 16:048e5e270a58 10314
sPymbed 16:048e5e270a58 10315 #ifdef WOLFSSL_CERT_EXT
sPymbed 16:048e5e270a58 10316 /* put SKID */
sPymbed 16:048e5e270a58 10317 if (der->skidSz) {
sPymbed 16:048e5e270a58 10318 ret = SetExtensions(der->extensions, sizeof(der->extensions),
sPymbed 16:048e5e270a58 10319 &der->extensionsSz,
sPymbed 16:048e5e270a58 10320 der->skid, der->skidSz);
sPymbed 16:048e5e270a58 10321 if (ret <= 0)
sPymbed 16:048e5e270a58 10322 return EXTENSIONS_E;
sPymbed 16:048e5e270a58 10323 }
sPymbed 16:048e5e270a58 10324
sPymbed 16:048e5e270a58 10325 /* put AKID */
sPymbed 16:048e5e270a58 10326 if (der->akidSz) {
sPymbed 16:048e5e270a58 10327 ret = SetExtensions(der->extensions, sizeof(der->extensions),
sPymbed 16:048e5e270a58 10328 &der->extensionsSz,
sPymbed 16:048e5e270a58 10329 der->akid, der->akidSz);
sPymbed 16:048e5e270a58 10330 if (ret <= 0)
sPymbed 16:048e5e270a58 10331 return EXTENSIONS_E;
sPymbed 16:048e5e270a58 10332 }
sPymbed 16:048e5e270a58 10333
sPymbed 16:048e5e270a58 10334 /* put KeyUsage */
sPymbed 16:048e5e270a58 10335 if (der->keyUsageSz) {
sPymbed 16:048e5e270a58 10336 ret = SetExtensions(der->extensions, sizeof(der->extensions),
sPymbed 16:048e5e270a58 10337 &der->extensionsSz,
sPymbed 16:048e5e270a58 10338 der->keyUsage, der->keyUsageSz);
sPymbed 16:048e5e270a58 10339 if (ret <= 0)
sPymbed 16:048e5e270a58 10340 return EXTENSIONS_E;
sPymbed 16:048e5e270a58 10341 }
sPymbed 16:048e5e270a58 10342
sPymbed 16:048e5e270a58 10343 /* put ExtendedKeyUsage */
sPymbed 16:048e5e270a58 10344 if (der->extKeyUsageSz) {
sPymbed 16:048e5e270a58 10345 ret = SetExtensions(der->extensions, sizeof(der->extensions),
sPymbed 16:048e5e270a58 10346 &der->extensionsSz,
sPymbed 16:048e5e270a58 10347 der->extKeyUsage, der->extKeyUsageSz);
sPymbed 16:048e5e270a58 10348 if (ret <= 0)
sPymbed 16:048e5e270a58 10349 return EXTENSIONS_E;
sPymbed 16:048e5e270a58 10350 }
sPymbed 16:048e5e270a58 10351
sPymbed 16:048e5e270a58 10352 /* put Certificate Policies */
sPymbed 16:048e5e270a58 10353 if (der->certPoliciesSz) {
sPymbed 16:048e5e270a58 10354 ret = SetExtensions(der->extensions, sizeof(der->extensions),
sPymbed 16:048e5e270a58 10355 &der->extensionsSz,
sPymbed 16:048e5e270a58 10356 der->certPolicies, der->certPoliciesSz);
sPymbed 16:048e5e270a58 10357 if (ret <= 0)
sPymbed 16:048e5e270a58 10358 return EXTENSIONS_E;
sPymbed 16:048e5e270a58 10359 }
sPymbed 16:048e5e270a58 10360 #endif /* WOLFSSL_CERT_EXT */
sPymbed 16:048e5e270a58 10361 }
sPymbed 16:048e5e270a58 10362
sPymbed 16:048e5e270a58 10363 der->total = der->versionSz + der->serialSz + der->sigAlgoSz +
sPymbed 16:048e5e270a58 10364 der->publicKeySz + der->validitySz + der->subjectSz + der->issuerSz +
sPymbed 16:048e5e270a58 10365 der->extensionsSz;
sPymbed 16:048e5e270a58 10366
sPymbed 16:048e5e270a58 10367 return 0;
sPymbed 16:048e5e270a58 10368 }
sPymbed 16:048e5e270a58 10369
sPymbed 16:048e5e270a58 10370
sPymbed 16:048e5e270a58 10371 /* write DER encoded cert to buffer, size already checked */
sPymbed 16:048e5e270a58 10372 static int WriteCertBody(DerCert* der, byte* buffer)
sPymbed 16:048e5e270a58 10373 {
sPymbed 16:048e5e270a58 10374 int idx;
sPymbed 16:048e5e270a58 10375
sPymbed 16:048e5e270a58 10376 /* signed part header */
sPymbed 16:048e5e270a58 10377 idx = SetSequence(der->total, buffer);
sPymbed 16:048e5e270a58 10378 /* version */
sPymbed 16:048e5e270a58 10379 XMEMCPY(buffer + idx, der->version, der->versionSz);
sPymbed 16:048e5e270a58 10380 idx += der->versionSz;
sPymbed 16:048e5e270a58 10381 /* serial */
sPymbed 16:048e5e270a58 10382 XMEMCPY(buffer + idx, der->serial, der->serialSz);
sPymbed 16:048e5e270a58 10383 idx += der->serialSz;
sPymbed 16:048e5e270a58 10384 /* sig algo */
sPymbed 16:048e5e270a58 10385 XMEMCPY(buffer + idx, der->sigAlgo, der->sigAlgoSz);
sPymbed 16:048e5e270a58 10386 idx += der->sigAlgoSz;
sPymbed 16:048e5e270a58 10387 /* issuer */
sPymbed 16:048e5e270a58 10388 XMEMCPY(buffer + idx, der->issuer, der->issuerSz);
sPymbed 16:048e5e270a58 10389 idx += der->issuerSz;
sPymbed 16:048e5e270a58 10390 /* validity */
sPymbed 16:048e5e270a58 10391 XMEMCPY(buffer + idx, der->validity, der->validitySz);
sPymbed 16:048e5e270a58 10392 idx += der->validitySz;
sPymbed 16:048e5e270a58 10393 /* subject */
sPymbed 16:048e5e270a58 10394 XMEMCPY(buffer + idx, der->subject, der->subjectSz);
sPymbed 16:048e5e270a58 10395 idx += der->subjectSz;
sPymbed 16:048e5e270a58 10396 /* public key */
sPymbed 16:048e5e270a58 10397 XMEMCPY(buffer + idx, der->publicKey, der->publicKeySz);
sPymbed 16:048e5e270a58 10398 idx += der->publicKeySz;
sPymbed 16:048e5e270a58 10399 if (der->extensionsSz) {
sPymbed 16:048e5e270a58 10400 /* extensions */
sPymbed 16:048e5e270a58 10401 XMEMCPY(buffer + idx, der->extensions, min(der->extensionsSz,
sPymbed 16:048e5e270a58 10402 (int)sizeof(der->extensions)));
sPymbed 16:048e5e270a58 10403 idx += der->extensionsSz;
sPymbed 16:048e5e270a58 10404 }
sPymbed 16:048e5e270a58 10405
sPymbed 16:048e5e270a58 10406 return idx;
sPymbed 16:048e5e270a58 10407 }
sPymbed 16:048e5e270a58 10408
sPymbed 16:048e5e270a58 10409
sPymbed 16:048e5e270a58 10410 /* Make RSA signature from buffer (sz), write to sig (sigSz) */
sPymbed 16:048e5e270a58 10411 static int MakeSignature(CertSignCtx* certSignCtx, const byte* buffer, int sz,
sPymbed 16:048e5e270a58 10412 byte* sig, int sigSz, RsaKey* rsaKey, ecc_key* eccKey,
sPymbed 16:048e5e270a58 10413 ed25519_key* ed25519Key, WC_RNG* rng, int sigAlgoType, void* heap)
sPymbed 16:048e5e270a58 10414 {
sPymbed 16:048e5e270a58 10415 int digestSz = 0, typeH = 0, ret = 0;
sPymbed 16:048e5e270a58 10416
sPymbed 16:048e5e270a58 10417 (void)digestSz;
sPymbed 16:048e5e270a58 10418 (void)typeH;
sPymbed 16:048e5e270a58 10419 (void)buffer;
sPymbed 16:048e5e270a58 10420 (void)sz;
sPymbed 16:048e5e270a58 10421 (void)sig;
sPymbed 16:048e5e270a58 10422 (void)sigSz;
sPymbed 16:048e5e270a58 10423 (void)rsaKey;
sPymbed 16:048e5e270a58 10424 (void)eccKey;
sPymbed 16:048e5e270a58 10425 (void)ed25519Key;
sPymbed 16:048e5e270a58 10426 (void)rng;
sPymbed 16:048e5e270a58 10427
sPymbed 16:048e5e270a58 10428 switch (certSignCtx->state) {
sPymbed 16:048e5e270a58 10429 case CERTSIGN_STATE_BEGIN:
sPymbed 16:048e5e270a58 10430 case CERTSIGN_STATE_DIGEST:
sPymbed 16:048e5e270a58 10431
sPymbed 16:048e5e270a58 10432 certSignCtx->state = CERTSIGN_STATE_DIGEST;
sPymbed 16:048e5e270a58 10433 certSignCtx->digest = (byte*)XMALLOC(WC_MAX_DIGEST_SIZE, heap,
sPymbed 16:048e5e270a58 10434 DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 10435 if (certSignCtx->digest == NULL) {
sPymbed 16:048e5e270a58 10436 ret = MEMORY_E; goto exit_ms;
sPymbed 16:048e5e270a58 10437 }
sPymbed 16:048e5e270a58 10438
sPymbed 16:048e5e270a58 10439 ret = HashForSignature(buffer, sz, sigAlgoType, certSignCtx->digest,
sPymbed 16:048e5e270a58 10440 &typeH, &digestSz, 0);
sPymbed 16:048e5e270a58 10441 /* set next state, since WC_PENDING rentry for these are not "call again" */
sPymbed 16:048e5e270a58 10442 certSignCtx->state = CERTSIGN_STATE_ENCODE;
sPymbed 16:048e5e270a58 10443 if (ret != 0) {
sPymbed 16:048e5e270a58 10444 goto exit_ms;
sPymbed 16:048e5e270a58 10445 }
sPymbed 16:048e5e270a58 10446 FALL_THROUGH;
sPymbed 16:048e5e270a58 10447
sPymbed 16:048e5e270a58 10448 case CERTSIGN_STATE_ENCODE:
sPymbed 16:048e5e270a58 10449 #ifndef NO_RSA
sPymbed 16:048e5e270a58 10450 if (rsaKey) {
sPymbed 16:048e5e270a58 10451 certSignCtx->encSig = (byte*)XMALLOC(MAX_DER_DIGEST_SZ, heap,
sPymbed 16:048e5e270a58 10452 DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 10453 if (certSignCtx->encSig == NULL) {
sPymbed 16:048e5e270a58 10454 ret = MEMORY_E; goto exit_ms;
sPymbed 16:048e5e270a58 10455 }
sPymbed 16:048e5e270a58 10456
sPymbed 16:048e5e270a58 10457 /* signature */
sPymbed 16:048e5e270a58 10458 certSignCtx->encSigSz = wc_EncodeSignature(certSignCtx->encSig,
sPymbed 16:048e5e270a58 10459 certSignCtx->digest, digestSz, typeH);
sPymbed 16:048e5e270a58 10460 }
sPymbed 16:048e5e270a58 10461 #endif /* !NO_RSA */
sPymbed 16:048e5e270a58 10462 FALL_THROUGH;
sPymbed 16:048e5e270a58 10463
sPymbed 16:048e5e270a58 10464 case CERTSIGN_STATE_DO:
sPymbed 16:048e5e270a58 10465 certSignCtx->state = CERTSIGN_STATE_DO;
sPymbed 16:048e5e270a58 10466 ret = ALGO_ID_E; /* default to error */
sPymbed 16:048e5e270a58 10467
sPymbed 16:048e5e270a58 10468 #ifndef NO_RSA
sPymbed 16:048e5e270a58 10469 if (rsaKey) {
sPymbed 16:048e5e270a58 10470 /* signature */
sPymbed 16:048e5e270a58 10471 ret = wc_RsaSSL_Sign(certSignCtx->encSig, certSignCtx->encSigSz,
sPymbed 16:048e5e270a58 10472 sig, sigSz, rsaKey, rng);
sPymbed 16:048e5e270a58 10473 }
sPymbed 16:048e5e270a58 10474 #endif /* !NO_RSA */
sPymbed 16:048e5e270a58 10475
sPymbed 16:048e5e270a58 10476 #ifdef HAVE_ECC
sPymbed 16:048e5e270a58 10477 if (!rsaKey && eccKey) {
sPymbed 16:048e5e270a58 10478 word32 outSz = sigSz;
sPymbed 16:048e5e270a58 10479
sPymbed 16:048e5e270a58 10480 ret = wc_ecc_sign_hash(certSignCtx->digest, digestSz,
sPymbed 16:048e5e270a58 10481 sig, &outSz, rng, eccKey);
sPymbed 16:048e5e270a58 10482 if (ret == 0)
sPymbed 16:048e5e270a58 10483 ret = outSz;
sPymbed 16:048e5e270a58 10484 }
sPymbed 16:048e5e270a58 10485 #endif /* HAVE_ECC */
sPymbed 16:048e5e270a58 10486
sPymbed 16:048e5e270a58 10487 #ifdef HAVE_ED25519
sPymbed 16:048e5e270a58 10488 if (!rsaKey && !eccKey && ed25519Key) {
sPymbed 16:048e5e270a58 10489 word32 outSz = sigSz;
sPymbed 16:048e5e270a58 10490
sPymbed 16:048e5e270a58 10491 ret = wc_ed25519_sign_msg(buffer, sz, sig, &outSz, ed25519Key);
sPymbed 16:048e5e270a58 10492 if (ret == 0)
sPymbed 16:048e5e270a58 10493 ret = outSz;
sPymbed 16:048e5e270a58 10494 }
sPymbed 16:048e5e270a58 10495 #endif /* HAVE_ECC */
sPymbed 16:048e5e270a58 10496 break;
sPymbed 16:048e5e270a58 10497 }
sPymbed 16:048e5e270a58 10498
sPymbed 16:048e5e270a58 10499 exit_ms:
sPymbed 16:048e5e270a58 10500
sPymbed 16:048e5e270a58 10501 if (ret == WC_PENDING_E) {
sPymbed 16:048e5e270a58 10502 return ret;
sPymbed 16:048e5e270a58 10503 }
sPymbed 16:048e5e270a58 10504
sPymbed 16:048e5e270a58 10505 #ifndef NO_RSA
sPymbed 16:048e5e270a58 10506 if (rsaKey) {
sPymbed 16:048e5e270a58 10507 XFREE(certSignCtx->encSig, heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 10508 }
sPymbed 16:048e5e270a58 10509 #endif /* !NO_RSA */
sPymbed 16:048e5e270a58 10510
sPymbed 16:048e5e270a58 10511 XFREE(certSignCtx->digest, heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 10512 certSignCtx->digest = NULL;
sPymbed 16:048e5e270a58 10513
sPymbed 16:048e5e270a58 10514 /* reset state */
sPymbed 16:048e5e270a58 10515 certSignCtx->state = CERTSIGN_STATE_BEGIN;
sPymbed 16:048e5e270a58 10516
sPymbed 16:048e5e270a58 10517 return ret;
sPymbed 16:048e5e270a58 10518 }
sPymbed 16:048e5e270a58 10519
sPymbed 16:048e5e270a58 10520
sPymbed 16:048e5e270a58 10521 /* add signature to end of buffer, size of buffer assumed checked, return
sPymbed 16:048e5e270a58 10522 new length */
sPymbed 16:048e5e270a58 10523 static int AddSignature(byte* buffer, int bodySz, const byte* sig, int sigSz,
sPymbed 16:048e5e270a58 10524 int sigAlgoType)
sPymbed 16:048e5e270a58 10525 {
sPymbed 16:048e5e270a58 10526 byte seq[MAX_SEQ_SZ];
sPymbed 16:048e5e270a58 10527 int idx = bodySz, seqSz;
sPymbed 16:048e5e270a58 10528
sPymbed 16:048e5e270a58 10529 /* algo */
sPymbed 16:048e5e270a58 10530 idx += SetAlgoID(sigAlgoType, buffer + idx, oidSigType, 0);
sPymbed 16:048e5e270a58 10531 /* bit string */
sPymbed 16:048e5e270a58 10532 idx += SetBitString(sigSz, 0, buffer + idx);
sPymbed 16:048e5e270a58 10533 /* signature */
sPymbed 16:048e5e270a58 10534 XMEMCPY(buffer + idx, sig, sigSz);
sPymbed 16:048e5e270a58 10535 idx += sigSz;
sPymbed 16:048e5e270a58 10536
sPymbed 16:048e5e270a58 10537 /* make room for overall header */
sPymbed 16:048e5e270a58 10538 seqSz = SetSequence(idx, seq);
sPymbed 16:048e5e270a58 10539 XMEMMOVE(buffer + seqSz, buffer, idx);
sPymbed 16:048e5e270a58 10540 XMEMCPY(buffer, seq, seqSz);
sPymbed 16:048e5e270a58 10541
sPymbed 16:048e5e270a58 10542 return idx + seqSz;
sPymbed 16:048e5e270a58 10543 }
sPymbed 16:048e5e270a58 10544
sPymbed 16:048e5e270a58 10545
sPymbed 16:048e5e270a58 10546 /* Make an x509 Certificate v3 any key type from cert input, write to buffer */
sPymbed 16:048e5e270a58 10547 static int MakeAnyCert(Cert* cert, byte* derBuffer, word32 derSz,
sPymbed 16:048e5e270a58 10548 RsaKey* rsaKey, ecc_key* eccKey, WC_RNG* rng,
sPymbed 16:048e5e270a58 10549 const byte* ntruKey, word16 ntruSz,
sPymbed 16:048e5e270a58 10550 ed25519_key* ed25519Key)
sPymbed 16:048e5e270a58 10551 {
sPymbed 16:048e5e270a58 10552 int ret;
sPymbed 16:048e5e270a58 10553 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 10554 DerCert* der;
sPymbed 16:048e5e270a58 10555 #else
sPymbed 16:048e5e270a58 10556 DerCert der[1];
sPymbed 16:048e5e270a58 10557 #endif
sPymbed 16:048e5e270a58 10558
sPymbed 16:048e5e270a58 10559 cert->keyType = eccKey ? ECC_KEY : (rsaKey ? RSA_KEY :
sPymbed 16:048e5e270a58 10560 (ed25519Key ? ED25519_KEY : NTRU_KEY));
sPymbed 16:048e5e270a58 10561
sPymbed 16:048e5e270a58 10562 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 10563 der = (DerCert*)XMALLOC(sizeof(DerCert), cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 10564 if (der == NULL)
sPymbed 16:048e5e270a58 10565 return MEMORY_E;
sPymbed 16:048e5e270a58 10566 #endif
sPymbed 16:048e5e270a58 10567
sPymbed 16:048e5e270a58 10568 ret = EncodeCert(cert, der, rsaKey, eccKey, rng, ntruKey, ntruSz,
sPymbed 16:048e5e270a58 10569 ed25519Key);
sPymbed 16:048e5e270a58 10570 if (ret == 0) {
sPymbed 16:048e5e270a58 10571 if (der->total + MAX_SEQ_SZ * 2 > (int)derSz)
sPymbed 16:048e5e270a58 10572 ret = BUFFER_E;
sPymbed 16:048e5e270a58 10573 else
sPymbed 16:048e5e270a58 10574 ret = cert->bodySz = WriteCertBody(der, derBuffer);
sPymbed 16:048e5e270a58 10575 }
sPymbed 16:048e5e270a58 10576
sPymbed 16:048e5e270a58 10577 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 10578 XFREE(der, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 10579 #endif
sPymbed 16:048e5e270a58 10580
sPymbed 16:048e5e270a58 10581 return ret;
sPymbed 16:048e5e270a58 10582 }
sPymbed 16:048e5e270a58 10583
sPymbed 16:048e5e270a58 10584
sPymbed 16:048e5e270a58 10585 /* Make an x509 Certificate v3 RSA or ECC from cert input, write to buffer */
sPymbed 16:048e5e270a58 10586 int wc_MakeCert_ex(Cert* cert, byte* derBuffer, word32 derSz, int keyType,
sPymbed 16:048e5e270a58 10587 void* key, WC_RNG* rng)
sPymbed 16:048e5e270a58 10588 {
sPymbed 16:048e5e270a58 10589 RsaKey* rsaKey = NULL;
sPymbed 16:048e5e270a58 10590 ecc_key* eccKey = NULL;
sPymbed 16:048e5e270a58 10591 ed25519_key* ed25519Key = NULL;
sPymbed 16:048e5e270a58 10592
sPymbed 16:048e5e270a58 10593 if (keyType == RSA_TYPE)
sPymbed 16:048e5e270a58 10594 rsaKey = (RsaKey*)key;
sPymbed 16:048e5e270a58 10595 else if (keyType == ECC_TYPE)
sPymbed 16:048e5e270a58 10596 eccKey = (ecc_key*)key;
sPymbed 16:048e5e270a58 10597 else if (keyType == ED25519_TYPE)
sPymbed 16:048e5e270a58 10598 ed25519Key = (ed25519_key*)key;
sPymbed 16:048e5e270a58 10599
sPymbed 16:048e5e270a58 10600 return MakeAnyCert(cert, derBuffer, derSz, rsaKey, eccKey, rng, NULL, 0,
sPymbed 16:048e5e270a58 10601 ed25519Key);
sPymbed 16:048e5e270a58 10602 }
sPymbed 16:048e5e270a58 10603 /* Make an x509 Certificate v3 RSA or ECC from cert input, write to buffer */
sPymbed 16:048e5e270a58 10604 int wc_MakeCert(Cert* cert, byte* derBuffer, word32 derSz, RsaKey* rsaKey,
sPymbed 16:048e5e270a58 10605 ecc_key* eccKey, WC_RNG* rng)
sPymbed 16:048e5e270a58 10606 {
sPymbed 16:048e5e270a58 10607 return MakeAnyCert(cert, derBuffer, derSz, rsaKey, eccKey, rng, NULL, 0,
sPymbed 16:048e5e270a58 10608 NULL);
sPymbed 16:048e5e270a58 10609 }
sPymbed 16:048e5e270a58 10610
sPymbed 16:048e5e270a58 10611
sPymbed 16:048e5e270a58 10612 #ifdef HAVE_NTRU
sPymbed 16:048e5e270a58 10613
sPymbed 16:048e5e270a58 10614 int wc_MakeNtruCert(Cert* cert, byte* derBuffer, word32 derSz,
sPymbed 16:048e5e270a58 10615 const byte* ntruKey, word16 keySz, WC_RNG* rng)
sPymbed 16:048e5e270a58 10616 {
sPymbed 16:048e5e270a58 10617 return MakeAnyCert(cert, derBuffer, derSz, NULL, NULL, rng, ntruKey, keySz, NULL);
sPymbed 16:048e5e270a58 10618 }
sPymbed 16:048e5e270a58 10619
sPymbed 16:048e5e270a58 10620 #endif /* HAVE_NTRU */
sPymbed 16:048e5e270a58 10621
sPymbed 16:048e5e270a58 10622
sPymbed 16:048e5e270a58 10623 #ifdef WOLFSSL_CERT_REQ
sPymbed 16:048e5e270a58 10624
sPymbed 16:048e5e270a58 10625 static int SetReqAttrib(byte* output, char* pw, int extSz)
sPymbed 16:048e5e270a58 10626 {
sPymbed 16:048e5e270a58 10627 static const byte cpOid[] =
sPymbed 16:048e5e270a58 10628 { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
sPymbed 16:048e5e270a58 10629 0x09, 0x07 };
sPymbed 16:048e5e270a58 10630 static const byte erOid[] =
sPymbed 16:048e5e270a58 10631 { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
sPymbed 16:048e5e270a58 10632 0x09, 0x0e };
sPymbed 16:048e5e270a58 10633
sPymbed 16:048e5e270a58 10634 int sz = 0; /* overall size */
sPymbed 16:048e5e270a58 10635 int cpSz = 0; /* Challenge Password section size */
sPymbed 16:048e5e270a58 10636 int cpSeqSz = 0;
sPymbed 16:048e5e270a58 10637 int cpSetSz = 0;
sPymbed 16:048e5e270a58 10638 int cpStrSz = 0;
sPymbed 16:048e5e270a58 10639 int pwSz = 0;
sPymbed 16:048e5e270a58 10640 int erSz = 0; /* Extension Request section size */
sPymbed 16:048e5e270a58 10641 int erSeqSz = 0;
sPymbed 16:048e5e270a58 10642 int erSetSz = 0;
sPymbed 16:048e5e270a58 10643 byte cpSeq[MAX_SEQ_SZ];
sPymbed 16:048e5e270a58 10644 byte cpSet[MAX_SET_SZ];
sPymbed 16:048e5e270a58 10645 byte cpStr[MAX_PRSTR_SZ];
sPymbed 16:048e5e270a58 10646 byte erSeq[MAX_SEQ_SZ];
sPymbed 16:048e5e270a58 10647 byte erSet[MAX_SET_SZ];
sPymbed 16:048e5e270a58 10648
sPymbed 16:048e5e270a58 10649 output[0] = 0xa0;
sPymbed 16:048e5e270a58 10650 sz++;
sPymbed 16:048e5e270a58 10651
sPymbed 16:048e5e270a58 10652 if (pw && pw[0]) {
sPymbed 16:048e5e270a58 10653 pwSz = (int)XSTRLEN(pw);
sPymbed 16:048e5e270a58 10654 cpStrSz = SetUTF8String(pwSz, cpStr);
sPymbed 16:048e5e270a58 10655 cpSetSz = SetSet(cpStrSz + pwSz, cpSet);
sPymbed 16:048e5e270a58 10656 cpSeqSz = SetSequence(sizeof(cpOid) + cpSetSz + cpStrSz + pwSz, cpSeq);
sPymbed 16:048e5e270a58 10657 cpSz = cpSeqSz + sizeof(cpOid) + cpSetSz + cpStrSz + pwSz;
sPymbed 16:048e5e270a58 10658 }
sPymbed 16:048e5e270a58 10659
sPymbed 16:048e5e270a58 10660 if (extSz) {
sPymbed 16:048e5e270a58 10661 erSetSz = SetSet(extSz, erSet);
sPymbed 16:048e5e270a58 10662 erSeqSz = SetSequence(erSetSz + sizeof(erOid) + extSz, erSeq);
sPymbed 16:048e5e270a58 10663 erSz = extSz + erSetSz + erSeqSz + sizeof(erOid);
sPymbed 16:048e5e270a58 10664 }
sPymbed 16:048e5e270a58 10665
sPymbed 16:048e5e270a58 10666 /* Put the pieces together. */
sPymbed 16:048e5e270a58 10667 sz += SetLength(cpSz + erSz, &output[sz]);
sPymbed 16:048e5e270a58 10668
sPymbed 16:048e5e270a58 10669 if (cpSz) {
sPymbed 16:048e5e270a58 10670 XMEMCPY(&output[sz], cpSeq, cpSeqSz);
sPymbed 16:048e5e270a58 10671 sz += cpSeqSz;
sPymbed 16:048e5e270a58 10672 XMEMCPY(&output[sz], cpOid, sizeof(cpOid));
sPymbed 16:048e5e270a58 10673 sz += sizeof(cpOid);
sPymbed 16:048e5e270a58 10674 XMEMCPY(&output[sz], cpSet, cpSetSz);
sPymbed 16:048e5e270a58 10675 sz += cpSetSz;
sPymbed 16:048e5e270a58 10676 XMEMCPY(&output[sz], cpStr, cpStrSz);
sPymbed 16:048e5e270a58 10677 sz += cpStrSz;
sPymbed 16:048e5e270a58 10678 XMEMCPY(&output[sz], pw, pwSz);
sPymbed 16:048e5e270a58 10679 sz += pwSz;
sPymbed 16:048e5e270a58 10680 }
sPymbed 16:048e5e270a58 10681
sPymbed 16:048e5e270a58 10682 if (erSz) {
sPymbed 16:048e5e270a58 10683 XMEMCPY(&output[sz], erSeq, erSeqSz);
sPymbed 16:048e5e270a58 10684 sz += erSeqSz;
sPymbed 16:048e5e270a58 10685 XMEMCPY(&output[sz], erOid, sizeof(erOid));
sPymbed 16:048e5e270a58 10686 sz += sizeof(erOid);
sPymbed 16:048e5e270a58 10687 XMEMCPY(&output[sz], erSet, erSetSz);
sPymbed 16:048e5e270a58 10688 sz += erSetSz;
sPymbed 16:048e5e270a58 10689 /* The actual extension data will be tacked onto the output later. */
sPymbed 16:048e5e270a58 10690 }
sPymbed 16:048e5e270a58 10691
sPymbed 16:048e5e270a58 10692 return sz;
sPymbed 16:048e5e270a58 10693 }
sPymbed 16:048e5e270a58 10694
sPymbed 16:048e5e270a58 10695
sPymbed 16:048e5e270a58 10696 /* encode info from cert into DER encoded format */
sPymbed 16:048e5e270a58 10697 static int EncodeCertReq(Cert* cert, DerCert* der, RsaKey* rsaKey,
sPymbed 16:048e5e270a58 10698 ecc_key* eccKey, ed25519_key* ed25519Key)
sPymbed 16:048e5e270a58 10699 {
sPymbed 16:048e5e270a58 10700 (void)eccKey;
sPymbed 16:048e5e270a58 10701 (void)ed25519Key;
sPymbed 16:048e5e270a58 10702
sPymbed 16:048e5e270a58 10703 if (cert == NULL || der == NULL)
sPymbed 16:048e5e270a58 10704 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 10705
sPymbed 16:048e5e270a58 10706 if (rsaKey == NULL && eccKey == NULL && ed25519Key == NULL)
sPymbed 16:048e5e270a58 10707 return PUBLIC_KEY_E;
sPymbed 16:048e5e270a58 10708
sPymbed 16:048e5e270a58 10709 /* init */
sPymbed 16:048e5e270a58 10710 XMEMSET(der, 0, sizeof(DerCert));
sPymbed 16:048e5e270a58 10711
sPymbed 16:048e5e270a58 10712 /* version */
sPymbed 16:048e5e270a58 10713 der->versionSz = SetMyVersion(cert->version, der->version, FALSE);
sPymbed 16:048e5e270a58 10714
sPymbed 16:048e5e270a58 10715 /* subject name */
sPymbed 16:048e5e270a58 10716 der->subjectSz = SetName(der->subject, sizeof(der->subject), &cert->subject);
sPymbed 16:048e5e270a58 10717 if (der->subjectSz <= 0)
sPymbed 16:048e5e270a58 10718 return SUBJECT_E;
sPymbed 16:048e5e270a58 10719
sPymbed 16:048e5e270a58 10720 /* public key */
sPymbed 16:048e5e270a58 10721 #ifndef NO_RSA
sPymbed 16:048e5e270a58 10722 if (cert->keyType == RSA_KEY) {
sPymbed 16:048e5e270a58 10723 if (rsaKey == NULL)
sPymbed 16:048e5e270a58 10724 return PUBLIC_KEY_E;
sPymbed 16:048e5e270a58 10725 der->publicKeySz = SetRsaPublicKey(der->publicKey, rsaKey,
sPymbed 16:048e5e270a58 10726 sizeof(der->publicKey), 1);
sPymbed 16:048e5e270a58 10727 }
sPymbed 16:048e5e270a58 10728 #endif
sPymbed 16:048e5e270a58 10729
sPymbed 16:048e5e270a58 10730 #ifdef HAVE_ECC
sPymbed 16:048e5e270a58 10731 if (cert->keyType == ECC_KEY) {
sPymbed 16:048e5e270a58 10732 der->publicKeySz = SetEccPublicKey(der->publicKey, eccKey, 1);
sPymbed 16:048e5e270a58 10733 }
sPymbed 16:048e5e270a58 10734 #endif
sPymbed 16:048e5e270a58 10735
sPymbed 16:048e5e270a58 10736 #ifdef HAVE_ED25519
sPymbed 16:048e5e270a58 10737 if (cert->keyType == ED25519_KEY) {
sPymbed 16:048e5e270a58 10738 if (ed25519Key == NULL)
sPymbed 16:048e5e270a58 10739 return PUBLIC_KEY_E;
sPymbed 16:048e5e270a58 10740 der->publicKeySz = SetEd25519PublicKey(der->publicKey, ed25519Key, 1);
sPymbed 16:048e5e270a58 10741 }
sPymbed 16:048e5e270a58 10742 #endif
sPymbed 16:048e5e270a58 10743
sPymbed 16:048e5e270a58 10744 if (der->publicKeySz <= 0)
sPymbed 16:048e5e270a58 10745 return PUBLIC_KEY_E;
sPymbed 16:048e5e270a58 10746
sPymbed 16:048e5e270a58 10747 /* set the extensions */
sPymbed 16:048e5e270a58 10748 der->extensionsSz = 0;
sPymbed 16:048e5e270a58 10749
sPymbed 16:048e5e270a58 10750 /* CA */
sPymbed 16:048e5e270a58 10751 if (cert->isCA) {
sPymbed 16:048e5e270a58 10752 der->caSz = SetCa(der->ca, sizeof(der->ca));
sPymbed 16:048e5e270a58 10753 if (der->caSz <= 0)
sPymbed 16:048e5e270a58 10754 return CA_TRUE_E;
sPymbed 16:048e5e270a58 10755
sPymbed 16:048e5e270a58 10756 der->extensionsSz += der->caSz;
sPymbed 16:048e5e270a58 10757 }
sPymbed 16:048e5e270a58 10758 else
sPymbed 16:048e5e270a58 10759 der->caSz = 0;
sPymbed 16:048e5e270a58 10760
sPymbed 16:048e5e270a58 10761 #ifdef WOLFSSL_CERT_EXT
sPymbed 16:048e5e270a58 10762 /* SKID */
sPymbed 16:048e5e270a58 10763 if (cert->skidSz) {
sPymbed 16:048e5e270a58 10764 /* check the provided SKID size */
sPymbed 16:048e5e270a58 10765 if (cert->skidSz > (int)min(CTC_MAX_SKID_SIZE, sizeof(der->skid)))
sPymbed 16:048e5e270a58 10766 return SKID_E;
sPymbed 16:048e5e270a58 10767
sPymbed 16:048e5e270a58 10768 der->skidSz = SetSKID(der->skid, sizeof(der->skid),
sPymbed 16:048e5e270a58 10769 cert->skid, cert->skidSz);
sPymbed 16:048e5e270a58 10770 if (der->skidSz <= 0)
sPymbed 16:048e5e270a58 10771 return SKID_E;
sPymbed 16:048e5e270a58 10772
sPymbed 16:048e5e270a58 10773 der->extensionsSz += der->skidSz;
sPymbed 16:048e5e270a58 10774 }
sPymbed 16:048e5e270a58 10775 else
sPymbed 16:048e5e270a58 10776 der->skidSz = 0;
sPymbed 16:048e5e270a58 10777
sPymbed 16:048e5e270a58 10778 /* Key Usage */
sPymbed 16:048e5e270a58 10779 if (cert->keyUsage != 0){
sPymbed 16:048e5e270a58 10780 der->keyUsageSz = SetKeyUsage(der->keyUsage, sizeof(der->keyUsage),
sPymbed 16:048e5e270a58 10781 cert->keyUsage);
sPymbed 16:048e5e270a58 10782 if (der->keyUsageSz <= 0)
sPymbed 16:048e5e270a58 10783 return KEYUSAGE_E;
sPymbed 16:048e5e270a58 10784
sPymbed 16:048e5e270a58 10785 der->extensionsSz += der->keyUsageSz;
sPymbed 16:048e5e270a58 10786 }
sPymbed 16:048e5e270a58 10787 else
sPymbed 16:048e5e270a58 10788 der->keyUsageSz = 0;
sPymbed 16:048e5e270a58 10789
sPymbed 16:048e5e270a58 10790 /* Extended Key Usage */
sPymbed 16:048e5e270a58 10791 if (cert->extKeyUsage != 0){
sPymbed 16:048e5e270a58 10792 der->extKeyUsageSz = SetExtKeyUsage(cert, der->extKeyUsage,
sPymbed 16:048e5e270a58 10793 sizeof(der->extKeyUsage), cert->extKeyUsage);
sPymbed 16:048e5e270a58 10794 if (der->extKeyUsageSz <= 0)
sPymbed 16:048e5e270a58 10795 return EXTKEYUSAGE_E;
sPymbed 16:048e5e270a58 10796
sPymbed 16:048e5e270a58 10797 der->extensionsSz += der->extKeyUsageSz;
sPymbed 16:048e5e270a58 10798 }
sPymbed 16:048e5e270a58 10799 else
sPymbed 16:048e5e270a58 10800 der->extKeyUsageSz = 0;
sPymbed 16:048e5e270a58 10801
sPymbed 16:048e5e270a58 10802 #endif /* WOLFSSL_CERT_EXT */
sPymbed 16:048e5e270a58 10803
sPymbed 16:048e5e270a58 10804 /* put extensions */
sPymbed 16:048e5e270a58 10805 if (der->extensionsSz > 0) {
sPymbed 16:048e5e270a58 10806 int ret;
sPymbed 16:048e5e270a58 10807
sPymbed 16:048e5e270a58 10808 /* put the start of sequence (ID, Size) */
sPymbed 16:048e5e270a58 10809 der->extensionsSz = SetSequence(der->extensionsSz, der->extensions);
sPymbed 16:048e5e270a58 10810 if (der->extensionsSz <= 0)
sPymbed 16:048e5e270a58 10811 return EXTENSIONS_E;
sPymbed 16:048e5e270a58 10812
sPymbed 16:048e5e270a58 10813 /* put CA */
sPymbed 16:048e5e270a58 10814 if (der->caSz) {
sPymbed 16:048e5e270a58 10815 ret = SetExtensions(der->extensions, sizeof(der->extensions),
sPymbed 16:048e5e270a58 10816 &der->extensionsSz,
sPymbed 16:048e5e270a58 10817 der->ca, der->caSz);
sPymbed 16:048e5e270a58 10818 if (ret <= 0)
sPymbed 16:048e5e270a58 10819 return EXTENSIONS_E;
sPymbed 16:048e5e270a58 10820 }
sPymbed 16:048e5e270a58 10821
sPymbed 16:048e5e270a58 10822 #ifdef WOLFSSL_CERT_EXT
sPymbed 16:048e5e270a58 10823 /* put SKID */
sPymbed 16:048e5e270a58 10824 if (der->skidSz) {
sPymbed 16:048e5e270a58 10825 ret = SetExtensions(der->extensions, sizeof(der->extensions),
sPymbed 16:048e5e270a58 10826 &der->extensionsSz,
sPymbed 16:048e5e270a58 10827 der->skid, der->skidSz);
sPymbed 16:048e5e270a58 10828 if (ret <= 0)
sPymbed 16:048e5e270a58 10829 return EXTENSIONS_E;
sPymbed 16:048e5e270a58 10830 }
sPymbed 16:048e5e270a58 10831
sPymbed 16:048e5e270a58 10832 /* put AKID */
sPymbed 16:048e5e270a58 10833 if (der->akidSz) {
sPymbed 16:048e5e270a58 10834 ret = SetExtensions(der->extensions, sizeof(der->extensions),
sPymbed 16:048e5e270a58 10835 &der->extensionsSz,
sPymbed 16:048e5e270a58 10836 der->akid, der->akidSz);
sPymbed 16:048e5e270a58 10837 if (ret <= 0)
sPymbed 16:048e5e270a58 10838 return EXTENSIONS_E;
sPymbed 16:048e5e270a58 10839 }
sPymbed 16:048e5e270a58 10840
sPymbed 16:048e5e270a58 10841 /* put KeyUsage */
sPymbed 16:048e5e270a58 10842 if (der->keyUsageSz) {
sPymbed 16:048e5e270a58 10843 ret = SetExtensions(der->extensions, sizeof(der->extensions),
sPymbed 16:048e5e270a58 10844 &der->extensionsSz,
sPymbed 16:048e5e270a58 10845 der->keyUsage, der->keyUsageSz);
sPymbed 16:048e5e270a58 10846 if (ret <= 0)
sPymbed 16:048e5e270a58 10847 return EXTENSIONS_E;
sPymbed 16:048e5e270a58 10848 }
sPymbed 16:048e5e270a58 10849
sPymbed 16:048e5e270a58 10850 /* put ExtendedKeyUsage */
sPymbed 16:048e5e270a58 10851 if (der->extKeyUsageSz) {
sPymbed 16:048e5e270a58 10852 ret = SetExtensions(der->extensions, sizeof(der->extensions),
sPymbed 16:048e5e270a58 10853 &der->extensionsSz,
sPymbed 16:048e5e270a58 10854 der->extKeyUsage, der->extKeyUsageSz);
sPymbed 16:048e5e270a58 10855 if (ret <= 0)
sPymbed 16:048e5e270a58 10856 return EXTENSIONS_E;
sPymbed 16:048e5e270a58 10857 }
sPymbed 16:048e5e270a58 10858
sPymbed 16:048e5e270a58 10859 #endif /* WOLFSSL_CERT_EXT */
sPymbed 16:048e5e270a58 10860 }
sPymbed 16:048e5e270a58 10861
sPymbed 16:048e5e270a58 10862 der->attribSz = SetReqAttrib(der->attrib,
sPymbed 16:048e5e270a58 10863 cert->challengePw, der->extensionsSz);
sPymbed 16:048e5e270a58 10864 if (der->attribSz <= 0)
sPymbed 16:048e5e270a58 10865 return REQ_ATTRIBUTE_E;
sPymbed 16:048e5e270a58 10866
sPymbed 16:048e5e270a58 10867 der->total = der->versionSz + der->subjectSz + der->publicKeySz +
sPymbed 16:048e5e270a58 10868 der->extensionsSz + der->attribSz;
sPymbed 16:048e5e270a58 10869
sPymbed 16:048e5e270a58 10870 return 0;
sPymbed 16:048e5e270a58 10871 }
sPymbed 16:048e5e270a58 10872
sPymbed 16:048e5e270a58 10873
sPymbed 16:048e5e270a58 10874 /* write DER encoded cert req to buffer, size already checked */
sPymbed 16:048e5e270a58 10875 static int WriteCertReqBody(DerCert* der, byte* buffer)
sPymbed 16:048e5e270a58 10876 {
sPymbed 16:048e5e270a58 10877 int idx;
sPymbed 16:048e5e270a58 10878
sPymbed 16:048e5e270a58 10879 /* signed part header */
sPymbed 16:048e5e270a58 10880 idx = SetSequence(der->total, buffer);
sPymbed 16:048e5e270a58 10881 /* version */
sPymbed 16:048e5e270a58 10882 XMEMCPY(buffer + idx, der->version, der->versionSz);
sPymbed 16:048e5e270a58 10883 idx += der->versionSz;
sPymbed 16:048e5e270a58 10884 /* subject */
sPymbed 16:048e5e270a58 10885 XMEMCPY(buffer + idx, der->subject, der->subjectSz);
sPymbed 16:048e5e270a58 10886 idx += der->subjectSz;
sPymbed 16:048e5e270a58 10887 /* public key */
sPymbed 16:048e5e270a58 10888 XMEMCPY(buffer + idx, der->publicKey, der->publicKeySz);
sPymbed 16:048e5e270a58 10889 idx += der->publicKeySz;
sPymbed 16:048e5e270a58 10890 /* attributes */
sPymbed 16:048e5e270a58 10891 XMEMCPY(buffer + idx, der->attrib, der->attribSz);
sPymbed 16:048e5e270a58 10892 idx += der->attribSz;
sPymbed 16:048e5e270a58 10893 /* extensions */
sPymbed 16:048e5e270a58 10894 if (der->extensionsSz) {
sPymbed 16:048e5e270a58 10895 XMEMCPY(buffer + idx, der->extensions, min(der->extensionsSz,
sPymbed 16:048e5e270a58 10896 (int)sizeof(der->extensions)));
sPymbed 16:048e5e270a58 10897 idx += der->extensionsSz;
sPymbed 16:048e5e270a58 10898 }
sPymbed 16:048e5e270a58 10899
sPymbed 16:048e5e270a58 10900 return idx;
sPymbed 16:048e5e270a58 10901 }
sPymbed 16:048e5e270a58 10902
sPymbed 16:048e5e270a58 10903
sPymbed 16:048e5e270a58 10904 static int MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz,
sPymbed 16:048e5e270a58 10905 RsaKey* rsaKey, ecc_key* eccKey, ed25519_key* ed25519Key)
sPymbed 16:048e5e270a58 10906 {
sPymbed 16:048e5e270a58 10907 int ret;
sPymbed 16:048e5e270a58 10908 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 10909 DerCert* der;
sPymbed 16:048e5e270a58 10910 #else
sPymbed 16:048e5e270a58 10911 DerCert der[1];
sPymbed 16:048e5e270a58 10912 #endif
sPymbed 16:048e5e270a58 10913
sPymbed 16:048e5e270a58 10914 cert->keyType = eccKey ? ECC_KEY : (ed25519Key ? ED25519_KEY : RSA_KEY);
sPymbed 16:048e5e270a58 10915
sPymbed 16:048e5e270a58 10916 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 10917 der = (DerCert*)XMALLOC(sizeof(DerCert), cert->heap,
sPymbed 16:048e5e270a58 10918 DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 10919 if (der == NULL)
sPymbed 16:048e5e270a58 10920 return MEMORY_E;
sPymbed 16:048e5e270a58 10921 #endif
sPymbed 16:048e5e270a58 10922
sPymbed 16:048e5e270a58 10923 ret = EncodeCertReq(cert, der, rsaKey, eccKey, ed25519Key);
sPymbed 16:048e5e270a58 10924
sPymbed 16:048e5e270a58 10925 if (ret == 0) {
sPymbed 16:048e5e270a58 10926 if (der->total + MAX_SEQ_SZ * 2 > (int)derSz)
sPymbed 16:048e5e270a58 10927 ret = BUFFER_E;
sPymbed 16:048e5e270a58 10928 else
sPymbed 16:048e5e270a58 10929 ret = cert->bodySz = WriteCertReqBody(der, derBuffer);
sPymbed 16:048e5e270a58 10930 }
sPymbed 16:048e5e270a58 10931
sPymbed 16:048e5e270a58 10932 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 10933 XFREE(der, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 10934 #endif
sPymbed 16:048e5e270a58 10935
sPymbed 16:048e5e270a58 10936 return ret;
sPymbed 16:048e5e270a58 10937 }
sPymbed 16:048e5e270a58 10938
sPymbed 16:048e5e270a58 10939 int wc_MakeCertReq_ex(Cert* cert, byte* derBuffer, word32 derSz, int keyType,
sPymbed 16:048e5e270a58 10940 void* key)
sPymbed 16:048e5e270a58 10941 {
sPymbed 16:048e5e270a58 10942 RsaKey* rsaKey = NULL;
sPymbed 16:048e5e270a58 10943 ecc_key* eccKey = NULL;
sPymbed 16:048e5e270a58 10944 ed25519_key* ed25519Key = NULL;
sPymbed 16:048e5e270a58 10945
sPymbed 16:048e5e270a58 10946 if (keyType == RSA_TYPE)
sPymbed 16:048e5e270a58 10947 rsaKey = (RsaKey*)key;
sPymbed 16:048e5e270a58 10948 else if (keyType == ECC_TYPE)
sPymbed 16:048e5e270a58 10949 eccKey = (ecc_key*)key;
sPymbed 16:048e5e270a58 10950 else if (keyType == ED25519_TYPE)
sPymbed 16:048e5e270a58 10951 ed25519Key = (ed25519_key*)key;
sPymbed 16:048e5e270a58 10952
sPymbed 16:048e5e270a58 10953 return MakeCertReq(cert, derBuffer, derSz, rsaKey, eccKey, ed25519Key);
sPymbed 16:048e5e270a58 10954 }
sPymbed 16:048e5e270a58 10955
sPymbed 16:048e5e270a58 10956 int wc_MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz,
sPymbed 16:048e5e270a58 10957 RsaKey* rsaKey, ecc_key* eccKey)
sPymbed 16:048e5e270a58 10958 {
sPymbed 16:048e5e270a58 10959 return MakeCertReq(cert, derBuffer, derSz, rsaKey, eccKey, NULL);
sPymbed 16:048e5e270a58 10960 }
sPymbed 16:048e5e270a58 10961 #endif /* WOLFSSL_CERT_REQ */
sPymbed 16:048e5e270a58 10962
sPymbed 16:048e5e270a58 10963
sPymbed 16:048e5e270a58 10964 static int SignCert(int requestSz, int sType, byte* buffer, word32 buffSz,
sPymbed 16:048e5e270a58 10965 RsaKey* rsaKey, ecc_key* eccKey, ed25519_key* ed25519Key,
sPymbed 16:048e5e270a58 10966 WC_RNG* rng)
sPymbed 16:048e5e270a58 10967 {
sPymbed 16:048e5e270a58 10968 int sigSz = 0;
sPymbed 16:048e5e270a58 10969 void* heap = NULL;
sPymbed 16:048e5e270a58 10970 CertSignCtx* certSignCtx = NULL;
sPymbed 16:048e5e270a58 10971 #ifndef WOLFSSL_ASYNC_CRYPT
sPymbed 16:048e5e270a58 10972 CertSignCtx certSignCtx_lcl;
sPymbed 16:048e5e270a58 10973 certSignCtx = &certSignCtx_lcl;
sPymbed 16:048e5e270a58 10974 XMEMSET(certSignCtx, 0, sizeof(CertSignCtx));
sPymbed 16:048e5e270a58 10975 #endif
sPymbed 16:048e5e270a58 10976
sPymbed 16:048e5e270a58 10977 if (requestSz < 0)
sPymbed 16:048e5e270a58 10978 return requestSz;
sPymbed 16:048e5e270a58 10979
sPymbed 16:048e5e270a58 10980 /* locate ctx */
sPymbed 16:048e5e270a58 10981 if (rsaKey) {
sPymbed 16:048e5e270a58 10982 #ifndef NO_RSA
sPymbed 16:048e5e270a58 10983 #ifdef WOLFSSL_ASYNC_CRYPT
sPymbed 16:048e5e270a58 10984 certSignCtx = &rsaKey->certSignCtx;
sPymbed 16:048e5e270a58 10985 #endif
sPymbed 16:048e5e270a58 10986 heap = rsaKey->heap;
sPymbed 16:048e5e270a58 10987 #else
sPymbed 16:048e5e270a58 10988 return NOT_COMPILED_IN;
sPymbed 16:048e5e270a58 10989 #endif /* NO_RSA */
sPymbed 16:048e5e270a58 10990 }
sPymbed 16:048e5e270a58 10991 else if (eccKey) {
sPymbed 16:048e5e270a58 10992 #ifdef HAVE_ECC
sPymbed 16:048e5e270a58 10993 #ifdef WOLFSSL_ASYNC_CRYPT
sPymbed 16:048e5e270a58 10994 certSignCtx = &eccKey->certSignCtx;
sPymbed 16:048e5e270a58 10995 #endif
sPymbed 16:048e5e270a58 10996 heap = eccKey->heap;
sPymbed 16:048e5e270a58 10997 #else
sPymbed 16:048e5e270a58 10998 return NOT_COMPILED_IN;
sPymbed 16:048e5e270a58 10999 #endif /* HAVE_ECC */
sPymbed 16:048e5e270a58 11000 }
sPymbed 16:048e5e270a58 11001
sPymbed 16:048e5e270a58 11002 #ifdef WOLFSSL_ASYNC_CRYPT
sPymbed 16:048e5e270a58 11003 if (certSignCtx == NULL) {
sPymbed 16:048e5e270a58 11004 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 11005 }
sPymbed 16:048e5e270a58 11006 #endif
sPymbed 16:048e5e270a58 11007
sPymbed 16:048e5e270a58 11008 if (certSignCtx->sig == NULL) {
sPymbed 16:048e5e270a58 11009 certSignCtx->sig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, heap,
sPymbed 16:048e5e270a58 11010 DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 11011 if (certSignCtx->sig == NULL)
sPymbed 16:048e5e270a58 11012 return MEMORY_E;
sPymbed 16:048e5e270a58 11013 }
sPymbed 16:048e5e270a58 11014
sPymbed 16:048e5e270a58 11015 sigSz = MakeSignature(certSignCtx, buffer, requestSz, certSignCtx->sig,
sPymbed 16:048e5e270a58 11016 MAX_ENCODED_SIG_SZ, rsaKey, eccKey, ed25519Key, rng, sType, heap);
sPymbed 16:048e5e270a58 11017 if (sigSz == WC_PENDING_E) {
sPymbed 16:048e5e270a58 11018 /* Not free'ing certSignCtx->sig here because it could still be in use
sPymbed 16:048e5e270a58 11019 * with async operations. */
sPymbed 16:048e5e270a58 11020 return sigSz;
sPymbed 16:048e5e270a58 11021 }
sPymbed 16:048e5e270a58 11022
sPymbed 16:048e5e270a58 11023 if (sigSz >= 0) {
sPymbed 16:048e5e270a58 11024 if (requestSz + MAX_SEQ_SZ * 2 + sigSz > (int)buffSz)
sPymbed 16:048e5e270a58 11025 sigSz = BUFFER_E;
sPymbed 16:048e5e270a58 11026 else
sPymbed 16:048e5e270a58 11027 sigSz = AddSignature(buffer, requestSz, certSignCtx->sig, sigSz,
sPymbed 16:048e5e270a58 11028 sType);
sPymbed 16:048e5e270a58 11029 }
sPymbed 16:048e5e270a58 11030
sPymbed 16:048e5e270a58 11031 XFREE(certSignCtx->sig, heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 11032 certSignCtx->sig = NULL;
sPymbed 16:048e5e270a58 11033
sPymbed 16:048e5e270a58 11034 return sigSz;
sPymbed 16:048e5e270a58 11035 }
sPymbed 16:048e5e270a58 11036
sPymbed 16:048e5e270a58 11037 int wc_SignCert_ex(int requestSz, int sType, byte* buffer, word32 buffSz,
sPymbed 16:048e5e270a58 11038 int keyType, void* key, WC_RNG* rng)
sPymbed 16:048e5e270a58 11039 {
sPymbed 16:048e5e270a58 11040 RsaKey* rsaKey = NULL;
sPymbed 16:048e5e270a58 11041 ecc_key* eccKey = NULL;
sPymbed 16:048e5e270a58 11042 ed25519_key* ed25519Key = NULL;
sPymbed 16:048e5e270a58 11043
sPymbed 16:048e5e270a58 11044 if (keyType == RSA_TYPE)
sPymbed 16:048e5e270a58 11045 rsaKey = (RsaKey*)key;
sPymbed 16:048e5e270a58 11046 else if (keyType == ECC_TYPE)
sPymbed 16:048e5e270a58 11047 eccKey = (ecc_key*)key;
sPymbed 16:048e5e270a58 11048 else if (keyType == ED25519_TYPE)
sPymbed 16:048e5e270a58 11049 ed25519Key = (ed25519_key*)key;
sPymbed 16:048e5e270a58 11050
sPymbed 16:048e5e270a58 11051 return SignCert(requestSz, sType, buffer, buffSz, rsaKey, eccKey,
sPymbed 16:048e5e270a58 11052 ed25519Key, rng);
sPymbed 16:048e5e270a58 11053 }
sPymbed 16:048e5e270a58 11054
sPymbed 16:048e5e270a58 11055 int wc_SignCert(int requestSz, int sType, byte* buffer, word32 buffSz,
sPymbed 16:048e5e270a58 11056 RsaKey* rsaKey, ecc_key* eccKey, WC_RNG* rng)
sPymbed 16:048e5e270a58 11057 {
sPymbed 16:048e5e270a58 11058 return SignCert(requestSz, sType, buffer, buffSz, rsaKey, eccKey, NULL,
sPymbed 16:048e5e270a58 11059 rng);
sPymbed 16:048e5e270a58 11060 }
sPymbed 16:048e5e270a58 11061
sPymbed 16:048e5e270a58 11062 int wc_MakeSelfCert(Cert* cert, byte* buffer, word32 buffSz,
sPymbed 16:048e5e270a58 11063 RsaKey* key, WC_RNG* rng)
sPymbed 16:048e5e270a58 11064 {
sPymbed 16:048e5e270a58 11065 int ret;
sPymbed 16:048e5e270a58 11066
sPymbed 16:048e5e270a58 11067 ret = wc_MakeCert(cert, buffer, buffSz, key, NULL, rng);
sPymbed 16:048e5e270a58 11068 if (ret < 0)
sPymbed 16:048e5e270a58 11069 return ret;
sPymbed 16:048e5e270a58 11070
sPymbed 16:048e5e270a58 11071 return wc_SignCert(cert->bodySz, cert->sigType,
sPymbed 16:048e5e270a58 11072 buffer, buffSz, key, NULL, rng);
sPymbed 16:048e5e270a58 11073 }
sPymbed 16:048e5e270a58 11074
sPymbed 16:048e5e270a58 11075
sPymbed 16:048e5e270a58 11076 #ifdef WOLFSSL_CERT_EXT
sPymbed 16:048e5e270a58 11077
sPymbed 16:048e5e270a58 11078 /* Set KID from public key */
sPymbed 16:048e5e270a58 11079 static int SetKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, ecc_key *eckey,
sPymbed 16:048e5e270a58 11080 byte *ntruKey, word16 ntruKeySz,
sPymbed 16:048e5e270a58 11081 ed25519_key* ed25519Key, int kid_type)
sPymbed 16:048e5e270a58 11082 {
sPymbed 16:048e5e270a58 11083 byte *buffer;
sPymbed 16:048e5e270a58 11084 int bufferSz, ret;
sPymbed 16:048e5e270a58 11085
sPymbed 16:048e5e270a58 11086 if (cert == NULL ||
sPymbed 16:048e5e270a58 11087 (rsakey == NULL && eckey == NULL && ntruKey == NULL &&
sPymbed 16:048e5e270a58 11088 ed25519Key == NULL) ||
sPymbed 16:048e5e270a58 11089 (kid_type != SKID_TYPE && kid_type != AKID_TYPE))
sPymbed 16:048e5e270a58 11090 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 11091
sPymbed 16:048e5e270a58 11092 buffer = (byte *)XMALLOC(MAX_PUBLIC_KEY_SZ, cert->heap,
sPymbed 16:048e5e270a58 11093 DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 11094 if (buffer == NULL)
sPymbed 16:048e5e270a58 11095 return MEMORY_E;
sPymbed 16:048e5e270a58 11096
sPymbed 16:048e5e270a58 11097 /* Public Key */
sPymbed 16:048e5e270a58 11098 bufferSz = -1;
sPymbed 16:048e5e270a58 11099 #ifndef NO_RSA
sPymbed 16:048e5e270a58 11100 /* RSA public key */
sPymbed 16:048e5e270a58 11101 if (rsakey != NULL)
sPymbed 16:048e5e270a58 11102 bufferSz = SetRsaPublicKey(buffer, rsakey, MAX_PUBLIC_KEY_SZ, 0);
sPymbed 16:048e5e270a58 11103 #endif
sPymbed 16:048e5e270a58 11104 #ifdef HAVE_ECC
sPymbed 16:048e5e270a58 11105 /* ECC public key */
sPymbed 16:048e5e270a58 11106 if (eckey != NULL)
sPymbed 16:048e5e270a58 11107 bufferSz = SetEccPublicKey(buffer, eckey, 0);
sPymbed 16:048e5e270a58 11108 #endif
sPymbed 16:048e5e270a58 11109 #ifdef HAVE_NTRU
sPymbed 16:048e5e270a58 11110 /* NTRU public key */
sPymbed 16:048e5e270a58 11111 if (ntruKey != NULL) {
sPymbed 16:048e5e270a58 11112 bufferSz = MAX_PUBLIC_KEY_SZ;
sPymbed 16:048e5e270a58 11113 ret = ntru_crypto_ntru_encrypt_publicKey2SubjectPublicKeyInfo(
sPymbed 16:048e5e270a58 11114 ntruKeySz, ntruKey, (word16 *)(&bufferSz), buffer);
sPymbed 16:048e5e270a58 11115 if (ret != NTRU_OK)
sPymbed 16:048e5e270a58 11116 bufferSz = -1;
sPymbed 16:048e5e270a58 11117 }
sPymbed 16:048e5e270a58 11118 #else
sPymbed 16:048e5e270a58 11119 (void)ntruKeySz;
sPymbed 16:048e5e270a58 11120 #endif
sPymbed 16:048e5e270a58 11121 #ifdef HAVE_ED25519
sPymbed 16:048e5e270a58 11122 /* ED25519 public key */
sPymbed 16:048e5e270a58 11123 if (ed25519Key != NULL)
sPymbed 16:048e5e270a58 11124 bufferSz = SetEd25519PublicKey(buffer, ed25519Key, 0);
sPymbed 16:048e5e270a58 11125 #endif
sPymbed 16:048e5e270a58 11126
sPymbed 16:048e5e270a58 11127 if (bufferSz <= 0) {
sPymbed 16:048e5e270a58 11128 XFREE(buffer, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 11129 return PUBLIC_KEY_E;
sPymbed 16:048e5e270a58 11130 }
sPymbed 16:048e5e270a58 11131
sPymbed 16:048e5e270a58 11132 /* Compute SKID by hashing public key */
sPymbed 16:048e5e270a58 11133 #ifdef NO_SHA
sPymbed 16:048e5e270a58 11134 if (kid_type == SKID_TYPE) {
sPymbed 16:048e5e270a58 11135 ret = wc_Sha256Hash(buffer, bufferSz, cert->skid);
sPymbed 16:048e5e270a58 11136 cert->skidSz = WC_SHA256_DIGEST_SIZE;
sPymbed 16:048e5e270a58 11137 }
sPymbed 16:048e5e270a58 11138 else if (kid_type == AKID_TYPE) {
sPymbed 16:048e5e270a58 11139 ret = wc_Sha256Hash(buffer, bufferSz, cert->akid);
sPymbed 16:048e5e270a58 11140 cert->akidSz = WC_SHA256_DIGEST_SIZE;
sPymbed 16:048e5e270a58 11141 }
sPymbed 16:048e5e270a58 11142 else
sPymbed 16:048e5e270a58 11143 ret = BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 11144 #else /* NO_SHA */
sPymbed 16:048e5e270a58 11145 if (kid_type == SKID_TYPE) {
sPymbed 16:048e5e270a58 11146 ret = wc_ShaHash(buffer, bufferSz, cert->skid);
sPymbed 16:048e5e270a58 11147 cert->skidSz = WC_SHA_DIGEST_SIZE;
sPymbed 16:048e5e270a58 11148 }
sPymbed 16:048e5e270a58 11149 else if (kid_type == AKID_TYPE) {
sPymbed 16:048e5e270a58 11150 ret = wc_ShaHash(buffer, bufferSz, cert->akid);
sPymbed 16:048e5e270a58 11151 cert->akidSz = WC_SHA_DIGEST_SIZE;
sPymbed 16:048e5e270a58 11152 }
sPymbed 16:048e5e270a58 11153 else
sPymbed 16:048e5e270a58 11154 ret = BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 11155 #endif /* NO_SHA */
sPymbed 16:048e5e270a58 11156
sPymbed 16:048e5e270a58 11157 XFREE(buffer, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 11158 return ret;
sPymbed 16:048e5e270a58 11159 }
sPymbed 16:048e5e270a58 11160
sPymbed 16:048e5e270a58 11161 int wc_SetSubjectKeyIdFromPublicKey_ex(Cert *cert, int keyType, void* key)
sPymbed 16:048e5e270a58 11162 {
sPymbed 16:048e5e270a58 11163 RsaKey* rsaKey = NULL;
sPymbed 16:048e5e270a58 11164 ecc_key* eccKey = NULL;
sPymbed 16:048e5e270a58 11165 ed25519_key* ed25519Key = NULL;
sPymbed 16:048e5e270a58 11166
sPymbed 16:048e5e270a58 11167 if (keyType == RSA_TYPE)
sPymbed 16:048e5e270a58 11168 rsaKey = (RsaKey*)key;
sPymbed 16:048e5e270a58 11169 else if (keyType == ECC_TYPE)
sPymbed 16:048e5e270a58 11170 eccKey = (ecc_key*)key;
sPymbed 16:048e5e270a58 11171 else if (keyType == ED25519_TYPE)
sPymbed 16:048e5e270a58 11172 ed25519Key = (ed25519_key*)key;
sPymbed 16:048e5e270a58 11173
sPymbed 16:048e5e270a58 11174 return SetKeyIdFromPublicKey(cert, rsaKey, eccKey, NULL, 0, ed25519Key,
sPymbed 16:048e5e270a58 11175 SKID_TYPE);
sPymbed 16:048e5e270a58 11176 }
sPymbed 16:048e5e270a58 11177
sPymbed 16:048e5e270a58 11178 /* Set SKID from RSA or ECC public key */
sPymbed 16:048e5e270a58 11179 int wc_SetSubjectKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, ecc_key *eckey)
sPymbed 16:048e5e270a58 11180 {
sPymbed 16:048e5e270a58 11181 return SetKeyIdFromPublicKey(cert, rsakey, eckey, NULL, 0, NULL, SKID_TYPE);
sPymbed 16:048e5e270a58 11182 }
sPymbed 16:048e5e270a58 11183
sPymbed 16:048e5e270a58 11184 #ifdef HAVE_NTRU
sPymbed 16:048e5e270a58 11185 /* Set SKID from NTRU public key */
sPymbed 16:048e5e270a58 11186 int wc_SetSubjectKeyIdFromNtruPublicKey(Cert *cert,
sPymbed 16:048e5e270a58 11187 byte *ntruKey, word16 ntruKeySz)
sPymbed 16:048e5e270a58 11188 {
sPymbed 16:048e5e270a58 11189 return SetKeyIdFromPublicKey(cert, NULL,NULL,ntruKey, ntruKeySz, NULL,
sPymbed 16:048e5e270a58 11190 SKID_TYPE);
sPymbed 16:048e5e270a58 11191 }
sPymbed 16:048e5e270a58 11192 #endif
sPymbed 16:048e5e270a58 11193
sPymbed 16:048e5e270a58 11194 int wc_SetAuthKeyIdFromPublicKey_ex(Cert *cert, int keyType, void* key)
sPymbed 16:048e5e270a58 11195 {
sPymbed 16:048e5e270a58 11196 RsaKey* rsaKey = NULL;
sPymbed 16:048e5e270a58 11197 ecc_key* eccKey = NULL;
sPymbed 16:048e5e270a58 11198 ed25519_key* ed25519Key = NULL;
sPymbed 16:048e5e270a58 11199
sPymbed 16:048e5e270a58 11200 if (keyType == RSA_TYPE)
sPymbed 16:048e5e270a58 11201 rsaKey = (RsaKey*)key;
sPymbed 16:048e5e270a58 11202 else if (keyType == ECC_TYPE)
sPymbed 16:048e5e270a58 11203 eccKey = (ecc_key*)key;
sPymbed 16:048e5e270a58 11204 else if (keyType == ED25519_TYPE)
sPymbed 16:048e5e270a58 11205 ed25519Key = (ed25519_key*)key;
sPymbed 16:048e5e270a58 11206
sPymbed 16:048e5e270a58 11207 return SetKeyIdFromPublicKey(cert, rsaKey, eccKey, NULL, 0, ed25519Key,
sPymbed 16:048e5e270a58 11208 AKID_TYPE);
sPymbed 16:048e5e270a58 11209 }
sPymbed 16:048e5e270a58 11210
sPymbed 16:048e5e270a58 11211 /* Set SKID from RSA or ECC public key */
sPymbed 16:048e5e270a58 11212 int wc_SetAuthKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, ecc_key *eckey)
sPymbed 16:048e5e270a58 11213 {
sPymbed 16:048e5e270a58 11214 return SetKeyIdFromPublicKey(cert, rsakey, eckey, NULL, 0, NULL, AKID_TYPE);
sPymbed 16:048e5e270a58 11215 }
sPymbed 16:048e5e270a58 11216
sPymbed 16:048e5e270a58 11217
sPymbed 16:048e5e270a58 11218 #ifndef NO_FILESYSTEM
sPymbed 16:048e5e270a58 11219
sPymbed 16:048e5e270a58 11220 /* Set SKID from public key file in PEM */
sPymbed 16:048e5e270a58 11221 int wc_SetSubjectKeyId(Cert *cert, const char* file)
sPymbed 16:048e5e270a58 11222 {
sPymbed 16:048e5e270a58 11223 int ret, derSz;
sPymbed 16:048e5e270a58 11224 byte* der;
sPymbed 16:048e5e270a58 11225 word32 idx;
sPymbed 16:048e5e270a58 11226 RsaKey *rsakey = NULL;
sPymbed 16:048e5e270a58 11227 ecc_key *eckey = NULL;
sPymbed 16:048e5e270a58 11228
sPymbed 16:048e5e270a58 11229 if (cert == NULL || file == NULL)
sPymbed 16:048e5e270a58 11230 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 11231
sPymbed 16:048e5e270a58 11232 der = (byte*)XMALLOC(MAX_PUBLIC_KEY_SZ, cert->heap, DYNAMIC_TYPE_CERT);
sPymbed 16:048e5e270a58 11233 if (der == NULL) {
sPymbed 16:048e5e270a58 11234 WOLFSSL_MSG("wc_SetSubjectKeyId memory Problem");
sPymbed 16:048e5e270a58 11235 return MEMORY_E;
sPymbed 16:048e5e270a58 11236 }
sPymbed 16:048e5e270a58 11237
sPymbed 16:048e5e270a58 11238 derSz = wc_PemPubKeyToDer(file, der, MAX_PUBLIC_KEY_SZ);
sPymbed 16:048e5e270a58 11239 if (derSz <= 0)
sPymbed 16:048e5e270a58 11240 {
sPymbed 16:048e5e270a58 11241 XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
sPymbed 16:048e5e270a58 11242 return derSz;
sPymbed 16:048e5e270a58 11243 }
sPymbed 16:048e5e270a58 11244
sPymbed 16:048e5e270a58 11245 /* Load PubKey in internal structure */
sPymbed 16:048e5e270a58 11246 #ifndef NO_RSA
sPymbed 16:048e5e270a58 11247 rsakey = (RsaKey*) XMALLOC(sizeof(RsaKey), cert->heap, DYNAMIC_TYPE_RSA);
sPymbed 16:048e5e270a58 11248 if (rsakey == NULL) {
sPymbed 16:048e5e270a58 11249 XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
sPymbed 16:048e5e270a58 11250 return MEMORY_E;
sPymbed 16:048e5e270a58 11251 }
sPymbed 16:048e5e270a58 11252
sPymbed 16:048e5e270a58 11253 if (wc_InitRsaKey(rsakey, cert->heap) != 0) {
sPymbed 16:048e5e270a58 11254 WOLFSSL_MSG("wc_InitRsaKey failure");
sPymbed 16:048e5e270a58 11255 XFREE(rsakey, cert->heap, DYNAMIC_TYPE_RSA);
sPymbed 16:048e5e270a58 11256 XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
sPymbed 16:048e5e270a58 11257 return MEMORY_E;
sPymbed 16:048e5e270a58 11258 }
sPymbed 16:048e5e270a58 11259
sPymbed 16:048e5e270a58 11260 idx = 0;
sPymbed 16:048e5e270a58 11261 ret = wc_RsaPublicKeyDecode(der, &idx, rsakey, derSz);
sPymbed 16:048e5e270a58 11262 if (ret != 0)
sPymbed 16:048e5e270a58 11263 #endif
sPymbed 16:048e5e270a58 11264 {
sPymbed 16:048e5e270a58 11265 #ifndef NO_RSA
sPymbed 16:048e5e270a58 11266 WOLFSSL_MSG("wc_RsaPublicKeyDecode failed");
sPymbed 16:048e5e270a58 11267 wc_FreeRsaKey(rsakey);
sPymbed 16:048e5e270a58 11268 XFREE(rsakey, cert->heap, DYNAMIC_TYPE_RSA);
sPymbed 16:048e5e270a58 11269 rsakey = NULL;
sPymbed 16:048e5e270a58 11270 #endif
sPymbed 16:048e5e270a58 11271 #ifdef HAVE_ECC
sPymbed 16:048e5e270a58 11272 /* Check to load ecc public key */
sPymbed 16:048e5e270a58 11273 eckey = (ecc_key*) XMALLOC(sizeof(ecc_key), cert->heap,
sPymbed 16:048e5e270a58 11274 DYNAMIC_TYPE_ECC);
sPymbed 16:048e5e270a58 11275 if (eckey == NULL) {
sPymbed 16:048e5e270a58 11276 XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
sPymbed 16:048e5e270a58 11277 return MEMORY_E;
sPymbed 16:048e5e270a58 11278 }
sPymbed 16:048e5e270a58 11279
sPymbed 16:048e5e270a58 11280 if (wc_ecc_init(eckey) != 0) {
sPymbed 16:048e5e270a58 11281 WOLFSSL_MSG("wc_ecc_init failure");
sPymbed 16:048e5e270a58 11282 wc_ecc_free(eckey);
sPymbed 16:048e5e270a58 11283 XFREE(eckey, cert->heap, DYNAMIC_TYPE_ECC);
sPymbed 16:048e5e270a58 11284 XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
sPymbed 16:048e5e270a58 11285 return MEMORY_E;
sPymbed 16:048e5e270a58 11286 }
sPymbed 16:048e5e270a58 11287
sPymbed 16:048e5e270a58 11288 idx = 0;
sPymbed 16:048e5e270a58 11289 ret = wc_EccPublicKeyDecode(der, &idx, eckey, derSz);
sPymbed 16:048e5e270a58 11290 if (ret != 0) {
sPymbed 16:048e5e270a58 11291 WOLFSSL_MSG("wc_EccPublicKeyDecode failed");
sPymbed 16:048e5e270a58 11292 XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
sPymbed 16:048e5e270a58 11293 wc_ecc_free(eckey);
sPymbed 16:048e5e270a58 11294 XFREE(eckey, cert->heap, DYNAMIC_TYPE_ECC);
sPymbed 16:048e5e270a58 11295 return PUBLIC_KEY_E;
sPymbed 16:048e5e270a58 11296 }
sPymbed 16:048e5e270a58 11297 #else
sPymbed 16:048e5e270a58 11298 XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
sPymbed 16:048e5e270a58 11299 return PUBLIC_KEY_E;
sPymbed 16:048e5e270a58 11300 #endif /* HAVE_ECC */
sPymbed 16:048e5e270a58 11301 }
sPymbed 16:048e5e270a58 11302
sPymbed 16:048e5e270a58 11303 XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
sPymbed 16:048e5e270a58 11304
sPymbed 16:048e5e270a58 11305 ret = wc_SetSubjectKeyIdFromPublicKey(cert, rsakey, eckey);
sPymbed 16:048e5e270a58 11306
sPymbed 16:048e5e270a58 11307 #ifndef NO_RSA
sPymbed 16:048e5e270a58 11308 wc_FreeRsaKey(rsakey);
sPymbed 16:048e5e270a58 11309 XFREE(rsakey, cert->heap, DYNAMIC_TYPE_RSA);
sPymbed 16:048e5e270a58 11310 #endif
sPymbed 16:048e5e270a58 11311 #ifdef HAVE_ECC
sPymbed 16:048e5e270a58 11312 wc_ecc_free(eckey);
sPymbed 16:048e5e270a58 11313 XFREE(eckey, cert->heap, DYNAMIC_TYPE_ECC);
sPymbed 16:048e5e270a58 11314 #endif
sPymbed 16:048e5e270a58 11315 return ret;
sPymbed 16:048e5e270a58 11316 }
sPymbed 16:048e5e270a58 11317
sPymbed 16:048e5e270a58 11318 #endif /* NO_FILESYSTEM */
sPymbed 16:048e5e270a58 11319
sPymbed 16:048e5e270a58 11320 /* Set AKID from certificate contains in buffer (DER encoded) */
sPymbed 16:048e5e270a58 11321 int wc_SetAuthKeyIdFromCert(Cert *cert, const byte *der, int derSz)
sPymbed 16:048e5e270a58 11322 {
sPymbed 16:048e5e270a58 11323 int ret;
sPymbed 16:048e5e270a58 11324
sPymbed 16:048e5e270a58 11325 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 11326 DecodedCert* decoded;
sPymbed 16:048e5e270a58 11327 #else
sPymbed 16:048e5e270a58 11328 DecodedCert decoded[1];
sPymbed 16:048e5e270a58 11329 #endif
sPymbed 16:048e5e270a58 11330
sPymbed 16:048e5e270a58 11331 if (cert == NULL || der == NULL || derSz <= 0)
sPymbed 16:048e5e270a58 11332 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 11333
sPymbed 16:048e5e270a58 11334 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 11335 decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert),
sPymbed 16:048e5e270a58 11336 cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 11337 if (decoded == NULL)
sPymbed 16:048e5e270a58 11338 return MEMORY_E;
sPymbed 16:048e5e270a58 11339 #endif
sPymbed 16:048e5e270a58 11340
sPymbed 16:048e5e270a58 11341 /* decode certificate and get SKID that will be AKID of current cert */
sPymbed 16:048e5e270a58 11342 InitDecodedCert(decoded, (byte*)der, derSz, NULL);
sPymbed 16:048e5e270a58 11343 ret = ParseCert(decoded, CERT_TYPE, NO_VERIFY, 0);
sPymbed 16:048e5e270a58 11344 if (ret != 0) {
sPymbed 16:048e5e270a58 11345 FreeDecodedCert(decoded);
sPymbed 16:048e5e270a58 11346 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 11347 XFREE(decoded, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 11348 #endif
sPymbed 16:048e5e270a58 11349 return ret;
sPymbed 16:048e5e270a58 11350 }
sPymbed 16:048e5e270a58 11351
sPymbed 16:048e5e270a58 11352 /* Subject Key Id not found !! */
sPymbed 16:048e5e270a58 11353 if (decoded->extSubjKeyIdSet == 0) {
sPymbed 16:048e5e270a58 11354 FreeDecodedCert(decoded);
sPymbed 16:048e5e270a58 11355 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 11356 XFREE(decoded, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 11357 #endif
sPymbed 16:048e5e270a58 11358 return ASN_NO_SKID;
sPymbed 16:048e5e270a58 11359 }
sPymbed 16:048e5e270a58 11360
sPymbed 16:048e5e270a58 11361 /* SKID invalid size */
sPymbed 16:048e5e270a58 11362 if (sizeof(cert->akid) < sizeof(decoded->extSubjKeyId)) {
sPymbed 16:048e5e270a58 11363 FreeDecodedCert(decoded);
sPymbed 16:048e5e270a58 11364 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 11365 XFREE(decoded, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 11366 #endif
sPymbed 16:048e5e270a58 11367 return MEMORY_E;
sPymbed 16:048e5e270a58 11368 }
sPymbed 16:048e5e270a58 11369
sPymbed 16:048e5e270a58 11370 /* Put the SKID of CA to AKID of certificate */
sPymbed 16:048e5e270a58 11371 XMEMCPY(cert->akid, decoded->extSubjKeyId, KEYID_SIZE);
sPymbed 16:048e5e270a58 11372 cert->akidSz = KEYID_SIZE;
sPymbed 16:048e5e270a58 11373
sPymbed 16:048e5e270a58 11374 FreeDecodedCert(decoded);
sPymbed 16:048e5e270a58 11375 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 11376 XFREE(decoded, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 11377 #endif
sPymbed 16:048e5e270a58 11378
sPymbed 16:048e5e270a58 11379 return 0;
sPymbed 16:048e5e270a58 11380 }
sPymbed 16:048e5e270a58 11381
sPymbed 16:048e5e270a58 11382
sPymbed 16:048e5e270a58 11383 #ifndef NO_FILESYSTEM
sPymbed 16:048e5e270a58 11384
sPymbed 16:048e5e270a58 11385 /* Set AKID from certificate file in PEM */
sPymbed 16:048e5e270a58 11386 int wc_SetAuthKeyId(Cert *cert, const char* file)
sPymbed 16:048e5e270a58 11387 {
sPymbed 16:048e5e270a58 11388 int ret;
sPymbed 16:048e5e270a58 11389 int derSz;
sPymbed 16:048e5e270a58 11390 byte* der;
sPymbed 16:048e5e270a58 11391
sPymbed 16:048e5e270a58 11392 if (cert == NULL || file == NULL)
sPymbed 16:048e5e270a58 11393 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 11394
sPymbed 16:048e5e270a58 11395 der = (byte*)XMALLOC(EIGHTK_BUF, cert->heap, DYNAMIC_TYPE_CERT);
sPymbed 16:048e5e270a58 11396 if (der == NULL) {
sPymbed 16:048e5e270a58 11397 WOLFSSL_MSG("wc_SetAuthKeyId OOF Problem");
sPymbed 16:048e5e270a58 11398 return MEMORY_E;
sPymbed 16:048e5e270a58 11399 }
sPymbed 16:048e5e270a58 11400
sPymbed 16:048e5e270a58 11401 derSz = wc_PemCertToDer(file, der, EIGHTK_BUF);
sPymbed 16:048e5e270a58 11402 if (derSz <= 0)
sPymbed 16:048e5e270a58 11403 {
sPymbed 16:048e5e270a58 11404 XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
sPymbed 16:048e5e270a58 11405 return derSz;
sPymbed 16:048e5e270a58 11406 }
sPymbed 16:048e5e270a58 11407
sPymbed 16:048e5e270a58 11408 ret = wc_SetAuthKeyIdFromCert(cert, der, derSz);
sPymbed 16:048e5e270a58 11409 XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
sPymbed 16:048e5e270a58 11410
sPymbed 16:048e5e270a58 11411 return ret;
sPymbed 16:048e5e270a58 11412 }
sPymbed 16:048e5e270a58 11413
sPymbed 16:048e5e270a58 11414 #endif /* NO_FILESYSTEM */
sPymbed 16:048e5e270a58 11415
sPymbed 16:048e5e270a58 11416 /* Set KeyUsage from human readable string */
sPymbed 16:048e5e270a58 11417 int wc_SetKeyUsage(Cert *cert, const char *value)
sPymbed 16:048e5e270a58 11418 {
sPymbed 16:048e5e270a58 11419 int ret = 0;
sPymbed 16:048e5e270a58 11420 char *token, *str, *ptr;
sPymbed 16:048e5e270a58 11421 word32 len;
sPymbed 16:048e5e270a58 11422
sPymbed 16:048e5e270a58 11423 if (cert == NULL || value == NULL)
sPymbed 16:048e5e270a58 11424 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 11425
sPymbed 16:048e5e270a58 11426 cert->keyUsage = 0;
sPymbed 16:048e5e270a58 11427
sPymbed 16:048e5e270a58 11428 len = (word32)XSTRLEN(value);
sPymbed 16:048e5e270a58 11429 str = (char*)XMALLOC(len+1, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 11430 if (str == NULL)
sPymbed 16:048e5e270a58 11431 return MEMORY_E;
sPymbed 16:048e5e270a58 11432
sPymbed 16:048e5e270a58 11433 XSTRNCPY(str, value, len);
sPymbed 16:048e5e270a58 11434 str[len] = '\0';
sPymbed 16:048e5e270a58 11435
sPymbed 16:048e5e270a58 11436 /* parse value, and set corresponding Key Usage value */
sPymbed 16:048e5e270a58 11437 if ((token = XSTRTOK(str, ",", &ptr)) == NULL) {
sPymbed 16:048e5e270a58 11438 XFREE(str, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 11439 return KEYUSAGE_E;
sPymbed 16:048e5e270a58 11440 }
sPymbed 16:048e5e270a58 11441 while (token != NULL)
sPymbed 16:048e5e270a58 11442 {
sPymbed 16:048e5e270a58 11443 len = (word32)XSTRLEN(token);
sPymbed 16:048e5e270a58 11444
sPymbed 16:048e5e270a58 11445 if (!XSTRNCASECMP(token, "digitalSignature", len))
sPymbed 16:048e5e270a58 11446 cert->keyUsage |= KEYUSE_DIGITAL_SIG;
sPymbed 16:048e5e270a58 11447 else if (!XSTRNCASECMP(token, "nonRepudiation", len) ||
sPymbed 16:048e5e270a58 11448 !XSTRNCASECMP(token, "contentCommitment", len))
sPymbed 16:048e5e270a58 11449 cert->keyUsage |= KEYUSE_CONTENT_COMMIT;
sPymbed 16:048e5e270a58 11450 else if (!XSTRNCASECMP(token, "keyEncipherment", len))
sPymbed 16:048e5e270a58 11451 cert->keyUsage |= KEYUSE_KEY_ENCIPHER;
sPymbed 16:048e5e270a58 11452 else if (!XSTRNCASECMP(token, "dataEncipherment", len))
sPymbed 16:048e5e270a58 11453 cert->keyUsage |= KEYUSE_DATA_ENCIPHER;
sPymbed 16:048e5e270a58 11454 else if (!XSTRNCASECMP(token, "keyAgreement", len))
sPymbed 16:048e5e270a58 11455 cert->keyUsage |= KEYUSE_KEY_AGREE;
sPymbed 16:048e5e270a58 11456 else if (!XSTRNCASECMP(token, "keyCertSign", len))
sPymbed 16:048e5e270a58 11457 cert->keyUsage |= KEYUSE_KEY_CERT_SIGN;
sPymbed 16:048e5e270a58 11458 else if (!XSTRNCASECMP(token, "cRLSign", len))
sPymbed 16:048e5e270a58 11459 cert->keyUsage |= KEYUSE_CRL_SIGN;
sPymbed 16:048e5e270a58 11460 else if (!XSTRNCASECMP(token, "encipherOnly", len))
sPymbed 16:048e5e270a58 11461 cert->keyUsage |= KEYUSE_ENCIPHER_ONLY;
sPymbed 16:048e5e270a58 11462 else if (!XSTRNCASECMP(token, "decipherOnly", len))
sPymbed 16:048e5e270a58 11463 cert->keyUsage |= KEYUSE_DECIPHER_ONLY;
sPymbed 16:048e5e270a58 11464 else {
sPymbed 16:048e5e270a58 11465 ret = KEYUSAGE_E;
sPymbed 16:048e5e270a58 11466 break;
sPymbed 16:048e5e270a58 11467 }
sPymbed 16:048e5e270a58 11468
sPymbed 16:048e5e270a58 11469 token = XSTRTOK(NULL, ",", &ptr);
sPymbed 16:048e5e270a58 11470 }
sPymbed 16:048e5e270a58 11471
sPymbed 16:048e5e270a58 11472 XFREE(str, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 11473 return ret;
sPymbed 16:048e5e270a58 11474 }
sPymbed 16:048e5e270a58 11475
sPymbed 16:048e5e270a58 11476 /* Set ExtendedKeyUsage from human readable string */
sPymbed 16:048e5e270a58 11477 int wc_SetExtKeyUsage(Cert *cert, const char *value)
sPymbed 16:048e5e270a58 11478 {
sPymbed 16:048e5e270a58 11479 int ret = 0;
sPymbed 16:048e5e270a58 11480 char *token, *str, *ptr;
sPymbed 16:048e5e270a58 11481 word32 len;
sPymbed 16:048e5e270a58 11482
sPymbed 16:048e5e270a58 11483 if (cert == NULL || value == NULL)
sPymbed 16:048e5e270a58 11484 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 11485
sPymbed 16:048e5e270a58 11486 cert->extKeyUsage = 0;
sPymbed 16:048e5e270a58 11487
sPymbed 16:048e5e270a58 11488 len = (word32)XSTRLEN(value);
sPymbed 16:048e5e270a58 11489 str = (char*)XMALLOC(len+1, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 11490 if (str == NULL)
sPymbed 16:048e5e270a58 11491 return MEMORY_E;
sPymbed 16:048e5e270a58 11492
sPymbed 16:048e5e270a58 11493 XSTRNCPY(str, value, len);
sPymbed 16:048e5e270a58 11494 str[len] = '\0';
sPymbed 16:048e5e270a58 11495
sPymbed 16:048e5e270a58 11496 /* parse value, and set corresponding Key Usage value */
sPymbed 16:048e5e270a58 11497 if ((token = XSTRTOK(str, ",", &ptr)) == NULL) {
sPymbed 16:048e5e270a58 11498 XFREE(str, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 11499 return EXTKEYUSAGE_E;
sPymbed 16:048e5e270a58 11500 }
sPymbed 16:048e5e270a58 11501
sPymbed 16:048e5e270a58 11502 while (token != NULL)
sPymbed 16:048e5e270a58 11503 {
sPymbed 16:048e5e270a58 11504 len = (word32)XSTRLEN(token);
sPymbed 16:048e5e270a58 11505
sPymbed 16:048e5e270a58 11506 if (!XSTRNCASECMP(token, "any", len))
sPymbed 16:048e5e270a58 11507 cert->extKeyUsage |= EXTKEYUSE_ANY;
sPymbed 16:048e5e270a58 11508 else if (!XSTRNCASECMP(token, "serverAuth", len))
sPymbed 16:048e5e270a58 11509 cert->extKeyUsage |= EXTKEYUSE_SERVER_AUTH;
sPymbed 16:048e5e270a58 11510 else if (!XSTRNCASECMP(token, "clientAuth", len))
sPymbed 16:048e5e270a58 11511 cert->extKeyUsage |= EXTKEYUSE_CLIENT_AUTH;
sPymbed 16:048e5e270a58 11512 else if (!XSTRNCASECMP(token, "codeSigning", len))
sPymbed 16:048e5e270a58 11513 cert->extKeyUsage |= EXTKEYUSE_CODESIGN;
sPymbed 16:048e5e270a58 11514 else if (!XSTRNCASECMP(token, "emailProtection", len))
sPymbed 16:048e5e270a58 11515 cert->extKeyUsage |= EXTKEYUSE_EMAILPROT;
sPymbed 16:048e5e270a58 11516 else if (!XSTRNCASECMP(token, "timeStamping", len))
sPymbed 16:048e5e270a58 11517 cert->extKeyUsage |= EXTKEYUSE_TIMESTAMP;
sPymbed 16:048e5e270a58 11518 else if (!XSTRNCASECMP(token, "OCSPSigning", len))
sPymbed 16:048e5e270a58 11519 cert->extKeyUsage |= EXTKEYUSE_OCSP_SIGN;
sPymbed 16:048e5e270a58 11520 else {
sPymbed 16:048e5e270a58 11521 ret = EXTKEYUSAGE_E;
sPymbed 16:048e5e270a58 11522 break;
sPymbed 16:048e5e270a58 11523 }
sPymbed 16:048e5e270a58 11524
sPymbed 16:048e5e270a58 11525 token = XSTRTOK(NULL, ",", &ptr);
sPymbed 16:048e5e270a58 11526 }
sPymbed 16:048e5e270a58 11527
sPymbed 16:048e5e270a58 11528 XFREE(str, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 11529 return ret;
sPymbed 16:048e5e270a58 11530 }
sPymbed 16:048e5e270a58 11531
sPymbed 16:048e5e270a58 11532 #ifdef WOLFSSL_EKU_OID
sPymbed 16:048e5e270a58 11533 /*
sPymbed 16:048e5e270a58 11534 * cert structure to set EKU oid in
sPymbed 16:048e5e270a58 11535 * oid the oid in byte representation
sPymbed 16:048e5e270a58 11536 * sz size of oid buffer
sPymbed 16:048e5e270a58 11537 * idx index of array to place oid
sPymbed 16:048e5e270a58 11538 *
sPymbed 16:048e5e270a58 11539 * returns 0 on success
sPymbed 16:048e5e270a58 11540 */
sPymbed 16:048e5e270a58 11541 int wc_SetExtKeyUsageOID(Cert *cert, const char *in, word32 sz, byte idx,
sPymbed 16:048e5e270a58 11542 void* heap)
sPymbed 16:048e5e270a58 11543 {
sPymbed 16:048e5e270a58 11544 byte oid[MAX_OID_SZ];
sPymbed 16:048e5e270a58 11545 word32 oidSz = MAX_OID_SZ;
sPymbed 16:048e5e270a58 11546
sPymbed 16:048e5e270a58 11547 if (idx >= CTC_MAX_EKU_NB || sz >= CTC_MAX_EKU_OID_SZ) {
sPymbed 16:048e5e270a58 11548 WOLFSSL_MSG("Either idx or sz was too large");
sPymbed 16:048e5e270a58 11549 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 11550 }
sPymbed 16:048e5e270a58 11551
sPymbed 16:048e5e270a58 11552 if (EncodePolicyOID(oid, &oidSz, in, heap) != 0) {
sPymbed 16:048e5e270a58 11553 return BUFFER_E;
sPymbed 16:048e5e270a58 11554 }
sPymbed 16:048e5e270a58 11555
sPymbed 16:048e5e270a58 11556 XMEMCPY(cert->extKeyUsageOID[idx], oid, oidSz);
sPymbed 16:048e5e270a58 11557 cert->extKeyUsageOIDSz[idx] = oidSz;
sPymbed 16:048e5e270a58 11558 cert->extKeyUsage |= EXTKEYUSE_USER;
sPymbed 16:048e5e270a58 11559
sPymbed 16:048e5e270a58 11560 return 0;
sPymbed 16:048e5e270a58 11561 }
sPymbed 16:048e5e270a58 11562 #endif /* WOLFSSL_EKU_OID */
sPymbed 16:048e5e270a58 11563 #endif /* WOLFSSL_CERT_EXT */
sPymbed 16:048e5e270a58 11564
sPymbed 16:048e5e270a58 11565
sPymbed 16:048e5e270a58 11566 #ifdef WOLFSSL_ALT_NAMES
sPymbed 16:048e5e270a58 11567
sPymbed 16:048e5e270a58 11568 /* Set Alt Names from der cert, return 0 on success */
sPymbed 16:048e5e270a58 11569 static int SetAltNamesFromCert(Cert* cert, const byte* der, int derSz)
sPymbed 16:048e5e270a58 11570 {
sPymbed 16:048e5e270a58 11571 int ret;
sPymbed 16:048e5e270a58 11572 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 11573 DecodedCert* decoded;
sPymbed 16:048e5e270a58 11574 #else
sPymbed 16:048e5e270a58 11575 DecodedCert decoded[1];
sPymbed 16:048e5e270a58 11576 #endif
sPymbed 16:048e5e270a58 11577
sPymbed 16:048e5e270a58 11578 if (derSz < 0)
sPymbed 16:048e5e270a58 11579 return derSz;
sPymbed 16:048e5e270a58 11580
sPymbed 16:048e5e270a58 11581 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 11582 decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), cert->heap,
sPymbed 16:048e5e270a58 11583 DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 11584 if (decoded == NULL)
sPymbed 16:048e5e270a58 11585 return MEMORY_E;
sPymbed 16:048e5e270a58 11586 #endif
sPymbed 16:048e5e270a58 11587
sPymbed 16:048e5e270a58 11588 InitDecodedCert(decoded, (byte*)der, derSz, NULL);
sPymbed 16:048e5e270a58 11589 ret = ParseCertRelative(decoded, CA_TYPE, NO_VERIFY, 0);
sPymbed 16:048e5e270a58 11590
sPymbed 16:048e5e270a58 11591 if (ret < 0) {
sPymbed 16:048e5e270a58 11592 WOLFSSL_MSG("ParseCertRelative error");
sPymbed 16:048e5e270a58 11593 }
sPymbed 16:048e5e270a58 11594 else if (decoded->extensions) {
sPymbed 16:048e5e270a58 11595 byte b;
sPymbed 16:048e5e270a58 11596 int length;
sPymbed 16:048e5e270a58 11597 word32 maxExtensionsIdx;
sPymbed 16:048e5e270a58 11598
sPymbed 16:048e5e270a58 11599 decoded->srcIdx = decoded->extensionsIdx;
sPymbed 16:048e5e270a58 11600 b = decoded->source[decoded->srcIdx++];
sPymbed 16:048e5e270a58 11601
sPymbed 16:048e5e270a58 11602 if (b != ASN_EXTENSIONS) {
sPymbed 16:048e5e270a58 11603 ret = ASN_PARSE_E;
sPymbed 16:048e5e270a58 11604 }
sPymbed 16:048e5e270a58 11605 else if (GetLength(decoded->source, &decoded->srcIdx, &length,
sPymbed 16:048e5e270a58 11606 decoded->maxIdx) < 0) {
sPymbed 16:048e5e270a58 11607 ret = ASN_PARSE_E;
sPymbed 16:048e5e270a58 11608 }
sPymbed 16:048e5e270a58 11609 else if (GetSequence(decoded->source, &decoded->srcIdx, &length,
sPymbed 16:048e5e270a58 11610 decoded->maxIdx) < 0) {
sPymbed 16:048e5e270a58 11611 ret = ASN_PARSE_E;
sPymbed 16:048e5e270a58 11612 }
sPymbed 16:048e5e270a58 11613 else {
sPymbed 16:048e5e270a58 11614 maxExtensionsIdx = decoded->srcIdx + length;
sPymbed 16:048e5e270a58 11615
sPymbed 16:048e5e270a58 11616 while (decoded->srcIdx < maxExtensionsIdx) {
sPymbed 16:048e5e270a58 11617 word32 oid;
sPymbed 16:048e5e270a58 11618 word32 startIdx = decoded->srcIdx;
sPymbed 16:048e5e270a58 11619 word32 tmpIdx;
sPymbed 16:048e5e270a58 11620
sPymbed 16:048e5e270a58 11621 if (GetSequence(decoded->source, &decoded->srcIdx, &length,
sPymbed 16:048e5e270a58 11622 decoded->maxIdx) < 0) {
sPymbed 16:048e5e270a58 11623 ret = ASN_PARSE_E;
sPymbed 16:048e5e270a58 11624 break;
sPymbed 16:048e5e270a58 11625 }
sPymbed 16:048e5e270a58 11626
sPymbed 16:048e5e270a58 11627 tmpIdx = decoded->srcIdx;
sPymbed 16:048e5e270a58 11628 decoded->srcIdx = startIdx;
sPymbed 16:048e5e270a58 11629
sPymbed 16:048e5e270a58 11630 if (GetAlgoId(decoded->source, &decoded->srcIdx, &oid,
sPymbed 16:048e5e270a58 11631 oidCertExtType, decoded->maxIdx) < 0) {
sPymbed 16:048e5e270a58 11632 ret = ASN_PARSE_E;
sPymbed 16:048e5e270a58 11633 break;
sPymbed 16:048e5e270a58 11634 }
sPymbed 16:048e5e270a58 11635
sPymbed 16:048e5e270a58 11636 if (oid == ALT_NAMES_OID) {
sPymbed 16:048e5e270a58 11637 cert->altNamesSz = length + (tmpIdx - startIdx);
sPymbed 16:048e5e270a58 11638
sPymbed 16:048e5e270a58 11639 if (cert->altNamesSz < (int)sizeof(cert->altNames))
sPymbed 16:048e5e270a58 11640 XMEMCPY(cert->altNames, &decoded->source[startIdx],
sPymbed 16:048e5e270a58 11641 cert->altNamesSz);
sPymbed 16:048e5e270a58 11642 else {
sPymbed 16:048e5e270a58 11643 cert->altNamesSz = 0;
sPymbed 16:048e5e270a58 11644 WOLFSSL_MSG("AltNames extensions too big");
sPymbed 16:048e5e270a58 11645 ret = ALT_NAME_E;
sPymbed 16:048e5e270a58 11646 break;
sPymbed 16:048e5e270a58 11647 }
sPymbed 16:048e5e270a58 11648 }
sPymbed 16:048e5e270a58 11649 decoded->srcIdx = tmpIdx + length;
sPymbed 16:048e5e270a58 11650 }
sPymbed 16:048e5e270a58 11651 }
sPymbed 16:048e5e270a58 11652 }
sPymbed 16:048e5e270a58 11653
sPymbed 16:048e5e270a58 11654 FreeDecodedCert(decoded);
sPymbed 16:048e5e270a58 11655 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 11656 XFREE(decoded, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 11657 #endif
sPymbed 16:048e5e270a58 11658
sPymbed 16:048e5e270a58 11659 return ret < 0 ? ret : 0;
sPymbed 16:048e5e270a58 11660 }
sPymbed 16:048e5e270a58 11661
sPymbed 16:048e5e270a58 11662
sPymbed 16:048e5e270a58 11663 /* Set Dates from der cert, return 0 on success */
sPymbed 16:048e5e270a58 11664 static int SetDatesFromCert(Cert* cert, const byte* der, int derSz)
sPymbed 16:048e5e270a58 11665 {
sPymbed 16:048e5e270a58 11666 int ret;
sPymbed 16:048e5e270a58 11667 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 11668 DecodedCert* decoded;
sPymbed 16:048e5e270a58 11669 #else
sPymbed 16:048e5e270a58 11670 DecodedCert decoded[1];
sPymbed 16:048e5e270a58 11671 #endif
sPymbed 16:048e5e270a58 11672
sPymbed 16:048e5e270a58 11673 WOLFSSL_ENTER("SetDatesFromCert");
sPymbed 16:048e5e270a58 11674 if (derSz < 0)
sPymbed 16:048e5e270a58 11675 return derSz;
sPymbed 16:048e5e270a58 11676
sPymbed 16:048e5e270a58 11677 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 11678 decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), cert->heap,
sPymbed 16:048e5e270a58 11679 DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 11680 if (decoded == NULL)
sPymbed 16:048e5e270a58 11681 return MEMORY_E;
sPymbed 16:048e5e270a58 11682 #endif
sPymbed 16:048e5e270a58 11683
sPymbed 16:048e5e270a58 11684 InitDecodedCert(decoded, (byte*)der, derSz, NULL);
sPymbed 16:048e5e270a58 11685 ret = ParseCertRelative(decoded, CA_TYPE, NO_VERIFY, 0);
sPymbed 16:048e5e270a58 11686
sPymbed 16:048e5e270a58 11687 if (ret < 0) {
sPymbed 16:048e5e270a58 11688 WOLFSSL_MSG("ParseCertRelative error");
sPymbed 16:048e5e270a58 11689 }
sPymbed 16:048e5e270a58 11690 else if (decoded->beforeDate == NULL || decoded->afterDate == NULL) {
sPymbed 16:048e5e270a58 11691 WOLFSSL_MSG("Couldn't extract dates");
sPymbed 16:048e5e270a58 11692 ret = -1;
sPymbed 16:048e5e270a58 11693 }
sPymbed 16:048e5e270a58 11694 else if (decoded->beforeDateLen > MAX_DATE_SIZE ||
sPymbed 16:048e5e270a58 11695 decoded->afterDateLen > MAX_DATE_SIZE) {
sPymbed 16:048e5e270a58 11696 WOLFSSL_MSG("Bad date size");
sPymbed 16:048e5e270a58 11697 ret = -1;
sPymbed 16:048e5e270a58 11698 }
sPymbed 16:048e5e270a58 11699 else {
sPymbed 16:048e5e270a58 11700 XMEMCPY(cert->beforeDate, decoded->beforeDate, decoded->beforeDateLen);
sPymbed 16:048e5e270a58 11701 XMEMCPY(cert->afterDate, decoded->afterDate, decoded->afterDateLen);
sPymbed 16:048e5e270a58 11702
sPymbed 16:048e5e270a58 11703 cert->beforeDateSz = decoded->beforeDateLen;
sPymbed 16:048e5e270a58 11704 cert->afterDateSz = decoded->afterDateLen;
sPymbed 16:048e5e270a58 11705 }
sPymbed 16:048e5e270a58 11706
sPymbed 16:048e5e270a58 11707 FreeDecodedCert(decoded);
sPymbed 16:048e5e270a58 11708
sPymbed 16:048e5e270a58 11709 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 11710 XFREE(decoded, cert->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 11711 #endif
sPymbed 16:048e5e270a58 11712
sPymbed 16:048e5e270a58 11713 return ret < 0 ? ret : 0;
sPymbed 16:048e5e270a58 11714 }
sPymbed 16:048e5e270a58 11715
sPymbed 16:048e5e270a58 11716 #endif /* WOLFSSL_ALT_NAMES */
sPymbed 16:048e5e270a58 11717
sPymbed 16:048e5e270a58 11718 /* Set cn name from der buffer, return 0 on success */
sPymbed 16:048e5e270a58 11719 static int SetNameFromCert(CertName* cn, const byte* der, int derSz)
sPymbed 16:048e5e270a58 11720 {
sPymbed 16:048e5e270a58 11721 int ret, sz;
sPymbed 16:048e5e270a58 11722 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 11723 DecodedCert* decoded;
sPymbed 16:048e5e270a58 11724 #else
sPymbed 16:048e5e270a58 11725 DecodedCert decoded[1];
sPymbed 16:048e5e270a58 11726 #endif
sPymbed 16:048e5e270a58 11727
sPymbed 16:048e5e270a58 11728 if (derSz < 0)
sPymbed 16:048e5e270a58 11729 return derSz;
sPymbed 16:048e5e270a58 11730
sPymbed 16:048e5e270a58 11731 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 11732 decoded = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
sPymbed 16:048e5e270a58 11733 DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 11734 if (decoded == NULL)
sPymbed 16:048e5e270a58 11735 return MEMORY_E;
sPymbed 16:048e5e270a58 11736 #endif
sPymbed 16:048e5e270a58 11737
sPymbed 16:048e5e270a58 11738 InitDecodedCert(decoded, (byte*)der, derSz, NULL);
sPymbed 16:048e5e270a58 11739 ret = ParseCertRelative(decoded, CA_TYPE, NO_VERIFY, 0);
sPymbed 16:048e5e270a58 11740
sPymbed 16:048e5e270a58 11741 if (ret < 0) {
sPymbed 16:048e5e270a58 11742 WOLFSSL_MSG("ParseCertRelative error");
sPymbed 16:048e5e270a58 11743 }
sPymbed 16:048e5e270a58 11744 else {
sPymbed 16:048e5e270a58 11745 if (decoded->subjectCN) {
sPymbed 16:048e5e270a58 11746 sz = (decoded->subjectCNLen < CTC_NAME_SIZE) ? decoded->subjectCNLen
sPymbed 16:048e5e270a58 11747 : CTC_NAME_SIZE - 1;
sPymbed 16:048e5e270a58 11748 XSTRNCPY(cn->commonName, decoded->subjectCN, CTC_NAME_SIZE);
sPymbed 16:048e5e270a58 11749 cn->commonName[sz] = '\0';
sPymbed 16:048e5e270a58 11750 cn->commonNameEnc = decoded->subjectCNEnc;
sPymbed 16:048e5e270a58 11751 }
sPymbed 16:048e5e270a58 11752 if (decoded->subjectC) {
sPymbed 16:048e5e270a58 11753 sz = (decoded->subjectCLen < CTC_NAME_SIZE) ? decoded->subjectCLen
sPymbed 16:048e5e270a58 11754 : CTC_NAME_SIZE - 1;
sPymbed 16:048e5e270a58 11755 XSTRNCPY(cn->country, decoded->subjectC, CTC_NAME_SIZE);
sPymbed 16:048e5e270a58 11756 cn->country[sz] = '\0';
sPymbed 16:048e5e270a58 11757 cn->countryEnc = decoded->subjectCEnc;
sPymbed 16:048e5e270a58 11758 }
sPymbed 16:048e5e270a58 11759 if (decoded->subjectST) {
sPymbed 16:048e5e270a58 11760 sz = (decoded->subjectSTLen < CTC_NAME_SIZE) ? decoded->subjectSTLen
sPymbed 16:048e5e270a58 11761 : CTC_NAME_SIZE - 1;
sPymbed 16:048e5e270a58 11762 XSTRNCPY(cn->state, decoded->subjectST, CTC_NAME_SIZE);
sPymbed 16:048e5e270a58 11763 cn->state[sz] = '\0';
sPymbed 16:048e5e270a58 11764 cn->stateEnc = decoded->subjectSTEnc;
sPymbed 16:048e5e270a58 11765 }
sPymbed 16:048e5e270a58 11766 if (decoded->subjectL) {
sPymbed 16:048e5e270a58 11767 sz = (decoded->subjectLLen < CTC_NAME_SIZE) ? decoded->subjectLLen
sPymbed 16:048e5e270a58 11768 : CTC_NAME_SIZE - 1;
sPymbed 16:048e5e270a58 11769 XSTRNCPY(cn->locality, decoded->subjectL, CTC_NAME_SIZE);
sPymbed 16:048e5e270a58 11770 cn->locality[sz] = '\0';
sPymbed 16:048e5e270a58 11771 cn->localityEnc = decoded->subjectLEnc;
sPymbed 16:048e5e270a58 11772 }
sPymbed 16:048e5e270a58 11773 if (decoded->subjectO) {
sPymbed 16:048e5e270a58 11774 sz = (decoded->subjectOLen < CTC_NAME_SIZE) ? decoded->subjectOLen
sPymbed 16:048e5e270a58 11775 : CTC_NAME_SIZE - 1;
sPymbed 16:048e5e270a58 11776 XSTRNCPY(cn->org, decoded->subjectO, CTC_NAME_SIZE);
sPymbed 16:048e5e270a58 11777 cn->org[sz] = '\0';
sPymbed 16:048e5e270a58 11778 cn->orgEnc = decoded->subjectOEnc;
sPymbed 16:048e5e270a58 11779 }
sPymbed 16:048e5e270a58 11780 if (decoded->subjectOU) {
sPymbed 16:048e5e270a58 11781 sz = (decoded->subjectOULen < CTC_NAME_SIZE) ? decoded->subjectOULen
sPymbed 16:048e5e270a58 11782 : CTC_NAME_SIZE - 1;
sPymbed 16:048e5e270a58 11783 XSTRNCPY(cn->unit, decoded->subjectOU, CTC_NAME_SIZE);
sPymbed 16:048e5e270a58 11784 cn->unit[sz] = '\0';
sPymbed 16:048e5e270a58 11785 cn->unitEnc = decoded->subjectOUEnc;
sPymbed 16:048e5e270a58 11786 }
sPymbed 16:048e5e270a58 11787 if (decoded->subjectSN) {
sPymbed 16:048e5e270a58 11788 sz = (decoded->subjectSNLen < CTC_NAME_SIZE) ? decoded->subjectSNLen
sPymbed 16:048e5e270a58 11789 : CTC_NAME_SIZE - 1;
sPymbed 16:048e5e270a58 11790 XSTRNCPY(cn->sur, decoded->subjectSN, CTC_NAME_SIZE);
sPymbed 16:048e5e270a58 11791 cn->sur[sz] = '\0';
sPymbed 16:048e5e270a58 11792 cn->surEnc = decoded->subjectSNEnc;
sPymbed 16:048e5e270a58 11793 }
sPymbed 16:048e5e270a58 11794 if (decoded->subjectEmail) {
sPymbed 16:048e5e270a58 11795 sz = (decoded->subjectEmailLen < CTC_NAME_SIZE)
sPymbed 16:048e5e270a58 11796 ? decoded->subjectEmailLen : CTC_NAME_SIZE - 1;
sPymbed 16:048e5e270a58 11797 XSTRNCPY(cn->email, decoded->subjectEmail, CTC_NAME_SIZE);
sPymbed 16:048e5e270a58 11798 cn->email[sz] = '\0';
sPymbed 16:048e5e270a58 11799 }
sPymbed 16:048e5e270a58 11800 }
sPymbed 16:048e5e270a58 11801
sPymbed 16:048e5e270a58 11802 FreeDecodedCert(decoded);
sPymbed 16:048e5e270a58 11803
sPymbed 16:048e5e270a58 11804 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 11805 XFREE(decoded, NULL, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 11806 #endif
sPymbed 16:048e5e270a58 11807
sPymbed 16:048e5e270a58 11808 return ret < 0 ? ret : 0;
sPymbed 16:048e5e270a58 11809 }
sPymbed 16:048e5e270a58 11810
sPymbed 16:048e5e270a58 11811
sPymbed 16:048e5e270a58 11812 #ifndef NO_FILESYSTEM
sPymbed 16:048e5e270a58 11813
sPymbed 16:048e5e270a58 11814 /* Set cert issuer from issuerFile in PEM */
sPymbed 16:048e5e270a58 11815 int wc_SetIssuer(Cert* cert, const char* issuerFile)
sPymbed 16:048e5e270a58 11816 {
sPymbed 16:048e5e270a58 11817 int ret;
sPymbed 16:048e5e270a58 11818 int derSz;
sPymbed 16:048e5e270a58 11819 byte* der = (byte*)XMALLOC(EIGHTK_BUF, cert->heap, DYNAMIC_TYPE_CERT);
sPymbed 16:048e5e270a58 11820
sPymbed 16:048e5e270a58 11821 if (der == NULL) {
sPymbed 16:048e5e270a58 11822 WOLFSSL_MSG("wc_SetIssuer OOF Problem");
sPymbed 16:048e5e270a58 11823 return MEMORY_E;
sPymbed 16:048e5e270a58 11824 }
sPymbed 16:048e5e270a58 11825 derSz = wc_PemCertToDer(issuerFile, der, EIGHTK_BUF);
sPymbed 16:048e5e270a58 11826 cert->selfSigned = 0;
sPymbed 16:048e5e270a58 11827 ret = SetNameFromCert(&cert->issuer, der, derSz);
sPymbed 16:048e5e270a58 11828 XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
sPymbed 16:048e5e270a58 11829
sPymbed 16:048e5e270a58 11830 return ret;
sPymbed 16:048e5e270a58 11831 }
sPymbed 16:048e5e270a58 11832
sPymbed 16:048e5e270a58 11833
sPymbed 16:048e5e270a58 11834 /* Set cert subject from subjectFile in PEM */
sPymbed 16:048e5e270a58 11835 int wc_SetSubject(Cert* cert, const char* subjectFile)
sPymbed 16:048e5e270a58 11836 {
sPymbed 16:048e5e270a58 11837 int ret;
sPymbed 16:048e5e270a58 11838 int derSz;
sPymbed 16:048e5e270a58 11839 byte* der = (byte*)XMALLOC(EIGHTK_BUF, cert->heap, DYNAMIC_TYPE_CERT);
sPymbed 16:048e5e270a58 11840
sPymbed 16:048e5e270a58 11841 if (der == NULL) {
sPymbed 16:048e5e270a58 11842 WOLFSSL_MSG("wc_SetSubject OOF Problem");
sPymbed 16:048e5e270a58 11843 return MEMORY_E;
sPymbed 16:048e5e270a58 11844 }
sPymbed 16:048e5e270a58 11845 derSz = wc_PemCertToDer(subjectFile, der, EIGHTK_BUF);
sPymbed 16:048e5e270a58 11846 ret = SetNameFromCert(&cert->subject, der, derSz);
sPymbed 16:048e5e270a58 11847 XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
sPymbed 16:048e5e270a58 11848
sPymbed 16:048e5e270a58 11849 return ret;
sPymbed 16:048e5e270a58 11850 }
sPymbed 16:048e5e270a58 11851
sPymbed 16:048e5e270a58 11852
sPymbed 16:048e5e270a58 11853 #ifdef WOLFSSL_ALT_NAMES
sPymbed 16:048e5e270a58 11854
sPymbed 16:048e5e270a58 11855 /* Set alt names from file in PEM */
sPymbed 16:048e5e270a58 11856 int wc_SetAltNames(Cert* cert, const char* file)
sPymbed 16:048e5e270a58 11857 {
sPymbed 16:048e5e270a58 11858 int ret;
sPymbed 16:048e5e270a58 11859 int derSz;
sPymbed 16:048e5e270a58 11860 byte* der = (byte*)XMALLOC(EIGHTK_BUF, cert->heap, DYNAMIC_TYPE_CERT);
sPymbed 16:048e5e270a58 11861
sPymbed 16:048e5e270a58 11862 if (der == NULL) {
sPymbed 16:048e5e270a58 11863 WOLFSSL_MSG("wc_SetAltNames OOF Problem");
sPymbed 16:048e5e270a58 11864 return MEMORY_E;
sPymbed 16:048e5e270a58 11865 }
sPymbed 16:048e5e270a58 11866 derSz = wc_PemCertToDer(file, der, EIGHTK_BUF);
sPymbed 16:048e5e270a58 11867 ret = SetAltNamesFromCert(cert, der, derSz);
sPymbed 16:048e5e270a58 11868 XFREE(der, cert->heap, DYNAMIC_TYPE_CERT);
sPymbed 16:048e5e270a58 11869
sPymbed 16:048e5e270a58 11870 return ret;
sPymbed 16:048e5e270a58 11871 }
sPymbed 16:048e5e270a58 11872
sPymbed 16:048e5e270a58 11873 #endif /* WOLFSSL_ALT_NAMES */
sPymbed 16:048e5e270a58 11874
sPymbed 16:048e5e270a58 11875 #endif /* NO_FILESYSTEM */
sPymbed 16:048e5e270a58 11876
sPymbed 16:048e5e270a58 11877 /* Set cert issuer from DER buffer */
sPymbed 16:048e5e270a58 11878 int wc_SetIssuerBuffer(Cert* cert, const byte* der, int derSz)
sPymbed 16:048e5e270a58 11879 {
sPymbed 16:048e5e270a58 11880 cert->selfSigned = 0;
sPymbed 16:048e5e270a58 11881 return SetNameFromCert(&cert->issuer, der, derSz);
sPymbed 16:048e5e270a58 11882 }
sPymbed 16:048e5e270a58 11883
sPymbed 16:048e5e270a58 11884
sPymbed 16:048e5e270a58 11885 /* Set cert subject from DER buffer */
sPymbed 16:048e5e270a58 11886 int wc_SetSubjectBuffer(Cert* cert, const byte* der, int derSz)
sPymbed 16:048e5e270a58 11887 {
sPymbed 16:048e5e270a58 11888 return SetNameFromCert(&cert->subject, der, derSz);
sPymbed 16:048e5e270a58 11889 }
sPymbed 16:048e5e270a58 11890
sPymbed 16:048e5e270a58 11891
sPymbed 16:048e5e270a58 11892 #ifdef WOLFSSL_ALT_NAMES
sPymbed 16:048e5e270a58 11893
sPymbed 16:048e5e270a58 11894 /* Set cert alt names from DER buffer */
sPymbed 16:048e5e270a58 11895 int wc_SetAltNamesBuffer(Cert* cert, const byte* der, int derSz)
sPymbed 16:048e5e270a58 11896 {
sPymbed 16:048e5e270a58 11897 return SetAltNamesFromCert(cert, der, derSz);
sPymbed 16:048e5e270a58 11898 }
sPymbed 16:048e5e270a58 11899
sPymbed 16:048e5e270a58 11900 /* Set cert dates from DER buffer */
sPymbed 16:048e5e270a58 11901 int wc_SetDatesBuffer(Cert* cert, const byte* der, int derSz)
sPymbed 16:048e5e270a58 11902 {
sPymbed 16:048e5e270a58 11903 return SetDatesFromCert(cert, der, derSz);
sPymbed 16:048e5e270a58 11904 }
sPymbed 16:048e5e270a58 11905
sPymbed 16:048e5e270a58 11906 #endif /* WOLFSSL_ALT_NAMES */
sPymbed 16:048e5e270a58 11907
sPymbed 16:048e5e270a58 11908 #endif /* WOLFSSL_CERT_GEN */
sPymbed 16:048e5e270a58 11909
sPymbed 16:048e5e270a58 11910
sPymbed 16:048e5e270a58 11911 #ifdef HAVE_ECC
sPymbed 16:048e5e270a58 11912
sPymbed 16:048e5e270a58 11913 /* Der Encode r & s ints into out, outLen is (in/out) size */
sPymbed 16:048e5e270a58 11914 int StoreECC_DSA_Sig(byte* out, word32* outLen, mp_int* r, mp_int* s)
sPymbed 16:048e5e270a58 11915 {
sPymbed 16:048e5e270a58 11916 word32 idx = 0;
sPymbed 16:048e5e270a58 11917 int rSz; /* encoding size */
sPymbed 16:048e5e270a58 11918 int sSz;
sPymbed 16:048e5e270a58 11919 word32 headerSz = 4; /* 2*ASN_TAG + 2*LEN(ENUM) */
sPymbed 16:048e5e270a58 11920
sPymbed 16:048e5e270a58 11921 /* If the leading bit on the INTEGER is a 1, add a leading zero */
sPymbed 16:048e5e270a58 11922 int rLeadingZero = mp_leading_bit(r);
sPymbed 16:048e5e270a58 11923 int sLeadingZero = mp_leading_bit(s);
sPymbed 16:048e5e270a58 11924 int rLen = mp_unsigned_bin_size(r); /* big int size */
sPymbed 16:048e5e270a58 11925 int sLen = mp_unsigned_bin_size(s);
sPymbed 16:048e5e270a58 11926
sPymbed 16:048e5e270a58 11927 if (*outLen < (rLen + rLeadingZero + sLen + sLeadingZero +
sPymbed 16:048e5e270a58 11928 headerSz + 2)) /* SEQ_TAG + LEN(ENUM) */
sPymbed 16:048e5e270a58 11929 return BUFFER_E;
sPymbed 16:048e5e270a58 11930
sPymbed 16:048e5e270a58 11931 idx = SetSequence(rLen + rLeadingZero + sLen+sLeadingZero + headerSz, out);
sPymbed 16:048e5e270a58 11932
sPymbed 16:048e5e270a58 11933 /* store r */
sPymbed 16:048e5e270a58 11934 rSz = SetASNIntMP(r, -1, &out[idx]);
sPymbed 16:048e5e270a58 11935 if (rSz < 0)
sPymbed 16:048e5e270a58 11936 return rSz;
sPymbed 16:048e5e270a58 11937 idx += rSz;
sPymbed 16:048e5e270a58 11938
sPymbed 16:048e5e270a58 11939 /* store s */
sPymbed 16:048e5e270a58 11940 sSz = SetASNIntMP(s, -1, &out[idx]);
sPymbed 16:048e5e270a58 11941 if (sSz < 0)
sPymbed 16:048e5e270a58 11942 return sSz;
sPymbed 16:048e5e270a58 11943 idx += sSz;
sPymbed 16:048e5e270a58 11944
sPymbed 16:048e5e270a58 11945 *outLen = idx;
sPymbed 16:048e5e270a58 11946
sPymbed 16:048e5e270a58 11947 return 0;
sPymbed 16:048e5e270a58 11948 }
sPymbed 16:048e5e270a58 11949
sPymbed 16:048e5e270a58 11950
sPymbed 16:048e5e270a58 11951 /* Der Decode ECC-DSA Signature, r & s stored as big ints */
sPymbed 16:048e5e270a58 11952 int DecodeECC_DSA_Sig(const byte* sig, word32 sigLen, mp_int* r, mp_int* s)
sPymbed 16:048e5e270a58 11953 {
sPymbed 16:048e5e270a58 11954 word32 idx = 0;
sPymbed 16:048e5e270a58 11955 int len = 0;
sPymbed 16:048e5e270a58 11956
sPymbed 16:048e5e270a58 11957 if (GetSequence(sig, &idx, &len, sigLen) < 0) {
sPymbed 16:048e5e270a58 11958 return ASN_ECC_KEY_E;
sPymbed 16:048e5e270a58 11959 }
sPymbed 16:048e5e270a58 11960
sPymbed 16:048e5e270a58 11961 if ((word32)len > (sigLen - idx)) {
sPymbed 16:048e5e270a58 11962 return ASN_ECC_KEY_E;
sPymbed 16:048e5e270a58 11963 }
sPymbed 16:048e5e270a58 11964
sPymbed 16:048e5e270a58 11965 if (GetInt(r, sig, &idx, sigLen) < 0) {
sPymbed 16:048e5e270a58 11966 return ASN_ECC_KEY_E;
sPymbed 16:048e5e270a58 11967 }
sPymbed 16:048e5e270a58 11968
sPymbed 16:048e5e270a58 11969 if (GetInt(s, sig, &idx, sigLen) < 0) {
sPymbed 16:048e5e270a58 11970 return ASN_ECC_KEY_E;
sPymbed 16:048e5e270a58 11971 }
sPymbed 16:048e5e270a58 11972
sPymbed 16:048e5e270a58 11973 return 0;
sPymbed 16:048e5e270a58 11974 }
sPymbed 16:048e5e270a58 11975
sPymbed 16:048e5e270a58 11976
sPymbed 16:048e5e270a58 11977 int wc_EccPrivateKeyDecode(const byte* input, word32* inOutIdx, ecc_key* key,
sPymbed 16:048e5e270a58 11978 word32 inSz)
sPymbed 16:048e5e270a58 11979 {
sPymbed 16:048e5e270a58 11980 word32 oidSum;
sPymbed 16:048e5e270a58 11981 int version, length;
sPymbed 16:048e5e270a58 11982 int privSz, pubSz = 0;
sPymbed 16:048e5e270a58 11983 byte b;
sPymbed 16:048e5e270a58 11984 int ret = 0;
sPymbed 16:048e5e270a58 11985 int curve_id = ECC_CURVE_DEF;
sPymbed 16:048e5e270a58 11986 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 11987 byte* priv;
sPymbed 16:048e5e270a58 11988 byte* pub;
sPymbed 16:048e5e270a58 11989 #else
sPymbed 16:048e5e270a58 11990 byte priv[ECC_MAXSIZE+1];
sPymbed 16:048e5e270a58 11991 byte pub[2*(ECC_MAXSIZE+1)]; /* public key has two parts plus header */
sPymbed 16:048e5e270a58 11992 #endif
sPymbed 16:048e5e270a58 11993 byte* pubData = NULL;
sPymbed 16:048e5e270a58 11994
sPymbed 16:048e5e270a58 11995 if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0)
sPymbed 16:048e5e270a58 11996 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 11997
sPymbed 16:048e5e270a58 11998 if (GetSequence(input, inOutIdx, &length, inSz) < 0)
sPymbed 16:048e5e270a58 11999 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 12000
sPymbed 16:048e5e270a58 12001 if (GetMyVersion(input, inOutIdx, &version, inSz) < 0)
sPymbed 16:048e5e270a58 12002 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 12003
sPymbed 16:048e5e270a58 12004 if (*inOutIdx >= inSz)
sPymbed 16:048e5e270a58 12005 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 12006
sPymbed 16:048e5e270a58 12007 b = input[*inOutIdx];
sPymbed 16:048e5e270a58 12008 *inOutIdx += 1;
sPymbed 16:048e5e270a58 12009
sPymbed 16:048e5e270a58 12010 /* priv type */
sPymbed 16:048e5e270a58 12011 if (b != 4 && b != 6 && b != 7)
sPymbed 16:048e5e270a58 12012 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 12013
sPymbed 16:048e5e270a58 12014 if (GetLength(input, inOutIdx, &length, inSz) < 0)
sPymbed 16:048e5e270a58 12015 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 12016
sPymbed 16:048e5e270a58 12017 if (length > ECC_MAXSIZE)
sPymbed 16:048e5e270a58 12018 return BUFFER_E;
sPymbed 16:048e5e270a58 12019
sPymbed 16:048e5e270a58 12020 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 12021 priv = (byte*)XMALLOC(ECC_MAXSIZE+1, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 12022 if (priv == NULL)
sPymbed 16:048e5e270a58 12023 return MEMORY_E;
sPymbed 16:048e5e270a58 12024
sPymbed 16:048e5e270a58 12025 pub = (byte*)XMALLOC(2*(ECC_MAXSIZE+1), key->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 12026 if (pub == NULL) {
sPymbed 16:048e5e270a58 12027 XFREE(priv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 12028 return MEMORY_E;
sPymbed 16:048e5e270a58 12029 }
sPymbed 16:048e5e270a58 12030 #endif
sPymbed 16:048e5e270a58 12031
sPymbed 16:048e5e270a58 12032 /* priv key */
sPymbed 16:048e5e270a58 12033 privSz = length;
sPymbed 16:048e5e270a58 12034 XMEMCPY(priv, &input[*inOutIdx], privSz);
sPymbed 16:048e5e270a58 12035 *inOutIdx += length;
sPymbed 16:048e5e270a58 12036
sPymbed 16:048e5e270a58 12037 if (ret == 0 && (*inOutIdx + 1) < inSz) {
sPymbed 16:048e5e270a58 12038 /* prefix 0, may have */
sPymbed 16:048e5e270a58 12039 b = input[*inOutIdx];
sPymbed 16:048e5e270a58 12040 if (b == ECC_PREFIX_0) {
sPymbed 16:048e5e270a58 12041 *inOutIdx += 1;
sPymbed 16:048e5e270a58 12042
sPymbed 16:048e5e270a58 12043 if (GetLength(input, inOutIdx, &length, inSz) <= 0)
sPymbed 16:048e5e270a58 12044 ret = ASN_PARSE_E;
sPymbed 16:048e5e270a58 12045 else {
sPymbed 16:048e5e270a58 12046 ret = GetObjectId(input, inOutIdx, &oidSum, oidIgnoreType,
sPymbed 16:048e5e270a58 12047 inSz);
sPymbed 16:048e5e270a58 12048 if (ret == 0) {
sPymbed 16:048e5e270a58 12049 if ((ret = CheckCurve(oidSum)) < 0)
sPymbed 16:048e5e270a58 12050 ret = ECC_CURVE_OID_E;
sPymbed 16:048e5e270a58 12051 else {
sPymbed 16:048e5e270a58 12052 curve_id = ret;
sPymbed 16:048e5e270a58 12053 ret = 0;
sPymbed 16:048e5e270a58 12054 }
sPymbed 16:048e5e270a58 12055 }
sPymbed 16:048e5e270a58 12056 }
sPymbed 16:048e5e270a58 12057 }
sPymbed 16:048e5e270a58 12058 }
sPymbed 16:048e5e270a58 12059
sPymbed 16:048e5e270a58 12060 if (ret == 0 && (*inOutIdx + 1) < inSz) {
sPymbed 16:048e5e270a58 12061 /* prefix 1 */
sPymbed 16:048e5e270a58 12062 b = input[*inOutIdx];
sPymbed 16:048e5e270a58 12063 *inOutIdx += 1;
sPymbed 16:048e5e270a58 12064
sPymbed 16:048e5e270a58 12065 if (b != ECC_PREFIX_1) {
sPymbed 16:048e5e270a58 12066 ret = ASN_ECC_KEY_E;
sPymbed 16:048e5e270a58 12067 }
sPymbed 16:048e5e270a58 12068 else if (GetLength(input, inOutIdx, &length, inSz) <= 0) {
sPymbed 16:048e5e270a58 12069 ret = ASN_PARSE_E;
sPymbed 16:048e5e270a58 12070 }
sPymbed 16:048e5e270a58 12071 else {
sPymbed 16:048e5e270a58 12072 /* key header */
sPymbed 16:048e5e270a58 12073 ret = CheckBitString(input, inOutIdx, &length, inSz, 0, NULL);
sPymbed 16:048e5e270a58 12074 if (ret == 0) {
sPymbed 16:048e5e270a58 12075 /* pub key */
sPymbed 16:048e5e270a58 12076 pubSz = length;
sPymbed 16:048e5e270a58 12077 if (pubSz < 2*(ECC_MAXSIZE+1)) {
sPymbed 16:048e5e270a58 12078 XMEMCPY(pub, &input[*inOutIdx], pubSz);
sPymbed 16:048e5e270a58 12079 *inOutIdx += length;
sPymbed 16:048e5e270a58 12080 pubData = pub;
sPymbed 16:048e5e270a58 12081 }
sPymbed 16:048e5e270a58 12082 else
sPymbed 16:048e5e270a58 12083 ret = BUFFER_E;
sPymbed 16:048e5e270a58 12084 }
sPymbed 16:048e5e270a58 12085 }
sPymbed 16:048e5e270a58 12086 }
sPymbed 16:048e5e270a58 12087
sPymbed 16:048e5e270a58 12088 if (ret == 0) {
sPymbed 16:048e5e270a58 12089 ret = wc_ecc_import_private_key_ex(priv, privSz, pubData, pubSz, key,
sPymbed 16:048e5e270a58 12090 curve_id);
sPymbed 16:048e5e270a58 12091 }
sPymbed 16:048e5e270a58 12092
sPymbed 16:048e5e270a58 12093 #ifdef WOLFSSL_SMALL_STACK
sPymbed 16:048e5e270a58 12094 XFREE(priv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 12095 XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 12096 #endif
sPymbed 16:048e5e270a58 12097
sPymbed 16:048e5e270a58 12098 return ret;
sPymbed 16:048e5e270a58 12099 }
sPymbed 16:048e5e270a58 12100
sPymbed 16:048e5e270a58 12101
sPymbed 16:048e5e270a58 12102 #ifdef WOLFSSL_CUSTOM_CURVES
sPymbed 16:048e5e270a58 12103 static void ByteToHex(byte n, char* str)
sPymbed 16:048e5e270a58 12104 {
sPymbed 16:048e5e270a58 12105 static const char hexChar[] = { '0', '1', '2', '3', '4', '5', '6', '7',
sPymbed 16:048e5e270a58 12106 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
sPymbed 16:048e5e270a58 12107
sPymbed 16:048e5e270a58 12108 str[0] = hexChar[n >> 4];
sPymbed 16:048e5e270a58 12109 str[1] = hexChar[n & 0xf];
sPymbed 16:048e5e270a58 12110 }
sPymbed 16:048e5e270a58 12111
sPymbed 16:048e5e270a58 12112 /* returns 0 on success */
sPymbed 16:048e5e270a58 12113 static int ASNToHexString(const byte* input, word32* inOutIdx, char** out,
sPymbed 16:048e5e270a58 12114 word32 inSz, void* heap, int heapType)
sPymbed 16:048e5e270a58 12115 {
sPymbed 16:048e5e270a58 12116 int len;
sPymbed 16:048e5e270a58 12117 int i;
sPymbed 16:048e5e270a58 12118 char* str;
sPymbed 16:048e5e270a58 12119
sPymbed 16:048e5e270a58 12120 if (*inOutIdx >= inSz) {
sPymbed 16:048e5e270a58 12121 return BUFFER_E;
sPymbed 16:048e5e270a58 12122 }
sPymbed 16:048e5e270a58 12123
sPymbed 16:048e5e270a58 12124 if (input[*inOutIdx] == ASN_INTEGER) {
sPymbed 16:048e5e270a58 12125 if (GetASNInt(input, inOutIdx, &len, inSz) < 0)
sPymbed 16:048e5e270a58 12126 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 12127 }
sPymbed 16:048e5e270a58 12128 else {
sPymbed 16:048e5e270a58 12129 if (GetOctetString(input, inOutIdx, &len, inSz) < 0)
sPymbed 16:048e5e270a58 12130 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 12131 }
sPymbed 16:048e5e270a58 12132
sPymbed 16:048e5e270a58 12133 str = (char*)XMALLOC(len * 2 + 1, heap, heapType);
sPymbed 16:048e5e270a58 12134 for (i=0; i<len; i++)
sPymbed 16:048e5e270a58 12135 ByteToHex(input[*inOutIdx + i], str + i*2);
sPymbed 16:048e5e270a58 12136 str[len*2] = '\0';
sPymbed 16:048e5e270a58 12137
sPymbed 16:048e5e270a58 12138 *inOutIdx += len;
sPymbed 16:048e5e270a58 12139 *out = str;
sPymbed 16:048e5e270a58 12140
sPymbed 16:048e5e270a58 12141 return 0;
sPymbed 16:048e5e270a58 12142 }
sPymbed 16:048e5e270a58 12143 #endif
sPymbed 16:048e5e270a58 12144
sPymbed 16:048e5e270a58 12145 int wc_EccPublicKeyDecode(const byte* input, word32* inOutIdx,
sPymbed 16:048e5e270a58 12146 ecc_key* key, word32 inSz)
sPymbed 16:048e5e270a58 12147 {
sPymbed 16:048e5e270a58 12148 int length;
sPymbed 16:048e5e270a58 12149 int ret;
sPymbed 16:048e5e270a58 12150 int curve_id = ECC_CURVE_DEF;
sPymbed 16:048e5e270a58 12151 word32 oidSum;
sPymbed 16:048e5e270a58 12152
sPymbed 16:048e5e270a58 12153 if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0)
sPymbed 16:048e5e270a58 12154 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 12155
sPymbed 16:048e5e270a58 12156 if (GetSequence(input, inOutIdx, &length, inSz) < 0)
sPymbed 16:048e5e270a58 12157 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 12158
sPymbed 16:048e5e270a58 12159 if (GetSequence(input, inOutIdx, &length, inSz) < 0)
sPymbed 16:048e5e270a58 12160 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 12161
sPymbed 16:048e5e270a58 12162 ret = SkipObjectId(input, inOutIdx, inSz);
sPymbed 16:048e5e270a58 12163 if (ret != 0)
sPymbed 16:048e5e270a58 12164 return ret;
sPymbed 16:048e5e270a58 12165
sPymbed 16:048e5e270a58 12166 if (*inOutIdx >= inSz) {
sPymbed 16:048e5e270a58 12167 return BUFFER_E;
sPymbed 16:048e5e270a58 12168 }
sPymbed 16:048e5e270a58 12169
sPymbed 16:048e5e270a58 12170 if (input[*inOutIdx] == (ASN_SEQUENCE | ASN_CONSTRUCTED)) {
sPymbed 16:048e5e270a58 12171 #ifdef WOLFSSL_CUSTOM_CURVES
sPymbed 16:048e5e270a58 12172 ecc_set_type* curve;
sPymbed 16:048e5e270a58 12173 int len;
sPymbed 16:048e5e270a58 12174 char* point;
sPymbed 16:048e5e270a58 12175
sPymbed 16:048e5e270a58 12176 ret = 0;
sPymbed 16:048e5e270a58 12177
sPymbed 16:048e5e270a58 12178 curve = (ecc_set_type*)XMALLOC(sizeof(*curve), key->heap,
sPymbed 16:048e5e270a58 12179 DYNAMIC_TYPE_ECC_BUFFER);
sPymbed 16:048e5e270a58 12180 if (curve == NULL)
sPymbed 16:048e5e270a58 12181 ret = MEMORY_E;
sPymbed 16:048e5e270a58 12182
sPymbed 16:048e5e270a58 12183 if (ret == 0) {
sPymbed 16:048e5e270a58 12184 XMEMSET(curve, 0, sizeof(*curve));
sPymbed 16:048e5e270a58 12185 curve->name = "Custom";
sPymbed 16:048e5e270a58 12186 curve->id = ECC_CURVE_CUSTOM;
sPymbed 16:048e5e270a58 12187
sPymbed 16:048e5e270a58 12188 if (GetSequence(input, inOutIdx, &length, inSz) < 0)
sPymbed 16:048e5e270a58 12189 ret = ASN_PARSE_E;
sPymbed 16:048e5e270a58 12190 }
sPymbed 16:048e5e270a58 12191
sPymbed 16:048e5e270a58 12192 if (ret == 0) {
sPymbed 16:048e5e270a58 12193 GetInteger7Bit(input, inOutIdx, inSz);
sPymbed 16:048e5e270a58 12194 if (GetSequence(input, inOutIdx, &length, inSz) < 0)
sPymbed 16:048e5e270a58 12195 ret = ASN_PARSE_E;
sPymbed 16:048e5e270a58 12196 }
sPymbed 16:048e5e270a58 12197 if (ret == 0) {
sPymbed 16:048e5e270a58 12198 SkipObjectId(input, inOutIdx, inSz);
sPymbed 16:048e5e270a58 12199 ret = ASNToHexString(input, inOutIdx, (char**)&curve->prime, inSz,
sPymbed 16:048e5e270a58 12200 key->heap, DYNAMIC_TYPE_ECC_BUFFER);
sPymbed 16:048e5e270a58 12201 }
sPymbed 16:048e5e270a58 12202 if (ret == 0) {
sPymbed 16:048e5e270a58 12203 curve->size = (int)XSTRLEN(curve->prime) / 2;
sPymbed 16:048e5e270a58 12204
sPymbed 16:048e5e270a58 12205 if (GetSequence(input, inOutIdx, &length, inSz) < 0)
sPymbed 16:048e5e270a58 12206 ret = ASN_PARSE_E;
sPymbed 16:048e5e270a58 12207 }
sPymbed 16:048e5e270a58 12208 if (ret == 0) {
sPymbed 16:048e5e270a58 12209 ret = ASNToHexString(input, inOutIdx, (char**)&curve->Af, inSz,
sPymbed 16:048e5e270a58 12210 key->heap, DYNAMIC_TYPE_ECC_BUFFER);
sPymbed 16:048e5e270a58 12211 }
sPymbed 16:048e5e270a58 12212 if (ret == 0) {
sPymbed 16:048e5e270a58 12213 ret = ASNToHexString(input, inOutIdx, (char**)&curve->Bf, inSz,
sPymbed 16:048e5e270a58 12214 key->heap, DYNAMIC_TYPE_ECC_BUFFER);
sPymbed 16:048e5e270a58 12215 }
sPymbed 16:048e5e270a58 12216 if (ret == 0) {
sPymbed 16:048e5e270a58 12217 if (*inOutIdx < inSz && input[*inOutIdx] == ASN_BIT_STRING) {
sPymbed 16:048e5e270a58 12218 len = 0;
sPymbed 16:048e5e270a58 12219 ret = GetASNHeader(input, ASN_BIT_STRING, inOutIdx, &len, inSz);
sPymbed 16:048e5e270a58 12220 *inOutIdx += len;
sPymbed 16:048e5e270a58 12221 }
sPymbed 16:048e5e270a58 12222 }
sPymbed 16:048e5e270a58 12223 if (ret == 0) {
sPymbed 16:048e5e270a58 12224 ret = ASNToHexString(input, inOutIdx, (char**)&point, inSz,
sPymbed 16:048e5e270a58 12225 key->heap, DYNAMIC_TYPE_ECC_BUFFER);
sPymbed 16:048e5e270a58 12226
sPymbed 16:048e5e270a58 12227 /* sanity check that point buffer is not smaller than the expected
sPymbed 16:048e5e270a58 12228 * size to hold ( 0 4 || Gx || Gy )
sPymbed 16:048e5e270a58 12229 * where Gx and Gy are each the size of curve->size * 2 */
sPymbed 16:048e5e270a58 12230 if (ret == 0 && (int)XSTRLEN(point) < (curve->size * 4) + 2) {
sPymbed 16:048e5e270a58 12231 XFREE(point, key->heap, DYNAMIC_TYPE_ECC_BUFFER);
sPymbed 16:048e5e270a58 12232 ret = BUFFER_E;
sPymbed 16:048e5e270a58 12233 }
sPymbed 16:048e5e270a58 12234 }
sPymbed 16:048e5e270a58 12235 if (ret == 0) {
sPymbed 16:048e5e270a58 12236 curve->Gx = (const char*)XMALLOC(curve->size * 2 + 2, key->heap,
sPymbed 16:048e5e270a58 12237 DYNAMIC_TYPE_ECC_BUFFER);
sPymbed 16:048e5e270a58 12238 curve->Gy = (const char*)XMALLOC(curve->size * 2 + 2, key->heap,
sPymbed 16:048e5e270a58 12239 DYNAMIC_TYPE_ECC_BUFFER);
sPymbed 16:048e5e270a58 12240 if (curve->Gx == NULL || curve->Gy == NULL) {
sPymbed 16:048e5e270a58 12241 XFREE(point, key->heap, DYNAMIC_TYPE_ECC_BUFFER);
sPymbed 16:048e5e270a58 12242 ret = MEMORY_E;
sPymbed 16:048e5e270a58 12243 }
sPymbed 16:048e5e270a58 12244 }
sPymbed 16:048e5e270a58 12245 if (ret == 0) {
sPymbed 16:048e5e270a58 12246 XMEMCPY((char*)curve->Gx, point + 2, curve->size * 2);
sPymbed 16:048e5e270a58 12247 XMEMCPY((char*)curve->Gy, point + curve->size * 2 + 2,
sPymbed 16:048e5e270a58 12248 curve->size * 2);
sPymbed 16:048e5e270a58 12249 ((char*)curve->Gx)[curve->size * 2] = '\0';
sPymbed 16:048e5e270a58 12250 ((char*)curve->Gy)[curve->size * 2] = '\0';
sPymbed 16:048e5e270a58 12251 XFREE(point, key->heap, DYNAMIC_TYPE_ECC_BUFFER);
sPymbed 16:048e5e270a58 12252 ret = ASNToHexString(input, inOutIdx, (char**)&curve->order, inSz,
sPymbed 16:048e5e270a58 12253 key->heap, DYNAMIC_TYPE_ECC_BUFFER);
sPymbed 16:048e5e270a58 12254 }
sPymbed 16:048e5e270a58 12255 if (ret == 0) {
sPymbed 16:048e5e270a58 12256 curve->cofactor = GetInteger7Bit(input, inOutIdx, inSz);
sPymbed 16:048e5e270a58 12257
sPymbed 16:048e5e270a58 12258 curve->oid = NULL;
sPymbed 16:048e5e270a58 12259 curve->oidSz = 0;
sPymbed 16:048e5e270a58 12260 curve->oidSum = 0;
sPymbed 16:048e5e270a58 12261
sPymbed 16:048e5e270a58 12262 if (wc_ecc_set_custom_curve(key, curve) < 0) {
sPymbed 16:048e5e270a58 12263 ret = ASN_PARSE_E;
sPymbed 16:048e5e270a58 12264 }
sPymbed 16:048e5e270a58 12265 key->deallocSet = 1;
sPymbed 16:048e5e270a58 12266 curve = NULL;
sPymbed 16:048e5e270a58 12267 }
sPymbed 16:048e5e270a58 12268 if (curve != NULL)
sPymbed 16:048e5e270a58 12269 wc_ecc_free_curve(curve, key->heap);
sPymbed 16:048e5e270a58 12270
sPymbed 16:048e5e270a58 12271 if (ret < 0)
sPymbed 16:048e5e270a58 12272 return ret;
sPymbed 16:048e5e270a58 12273 #else
sPymbed 16:048e5e270a58 12274 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 12275 #endif
sPymbed 16:048e5e270a58 12276 }
sPymbed 16:048e5e270a58 12277 else {
sPymbed 16:048e5e270a58 12278 /* ecc params information */
sPymbed 16:048e5e270a58 12279 ret = GetObjectId(input, inOutIdx, &oidSum, oidIgnoreType, inSz);
sPymbed 16:048e5e270a58 12280 if (ret != 0)
sPymbed 16:048e5e270a58 12281 return ret;
sPymbed 16:048e5e270a58 12282
sPymbed 16:048e5e270a58 12283 /* get curve id */
sPymbed 16:048e5e270a58 12284 curve_id = wc_ecc_get_oid(oidSum, NULL, 0);
sPymbed 16:048e5e270a58 12285 if (curve_id < 0)
sPymbed 16:048e5e270a58 12286 return ECC_CURVE_OID_E;
sPymbed 16:048e5e270a58 12287 }
sPymbed 16:048e5e270a58 12288
sPymbed 16:048e5e270a58 12289 /* key header */
sPymbed 16:048e5e270a58 12290 ret = CheckBitString(input, inOutIdx, NULL, inSz, 1, NULL);
sPymbed 16:048e5e270a58 12291 if (ret != 0)
sPymbed 16:048e5e270a58 12292 return ret;
sPymbed 16:048e5e270a58 12293
sPymbed 16:048e5e270a58 12294 /* This is the raw point data compressed or uncompressed. */
sPymbed 16:048e5e270a58 12295 if (wc_ecc_import_x963_ex(input + *inOutIdx, inSz - *inOutIdx, key,
sPymbed 16:048e5e270a58 12296 curve_id) != 0) {
sPymbed 16:048e5e270a58 12297 return ASN_ECC_KEY_E;
sPymbed 16:048e5e270a58 12298 }
sPymbed 16:048e5e270a58 12299
sPymbed 16:048e5e270a58 12300 return 0;
sPymbed 16:048e5e270a58 12301 }
sPymbed 16:048e5e270a58 12302
sPymbed 16:048e5e270a58 12303
sPymbed 16:048e5e270a58 12304 /* build DER formatted ECC key, include optional public key if requested,
sPymbed 16:048e5e270a58 12305 * return length on success, negative on error */
sPymbed 16:048e5e270a58 12306 static int wc_BuildEccKeyDer(ecc_key* key, byte* output, word32 inLen,
sPymbed 16:048e5e270a58 12307 int pubIn)
sPymbed 16:048e5e270a58 12308 {
sPymbed 16:048e5e270a58 12309 byte curve[MAX_ALGO_SZ+2];
sPymbed 16:048e5e270a58 12310 byte ver[MAX_VERSION_SZ];
sPymbed 16:048e5e270a58 12311 byte seq[MAX_SEQ_SZ];
sPymbed 16:048e5e270a58 12312 byte *prv = NULL, *pub = NULL;
sPymbed 16:048e5e270a58 12313 int ret, totalSz, curveSz, verSz;
sPymbed 16:048e5e270a58 12314 int privHdrSz = ASN_ECC_HEADER_SZ;
sPymbed 16:048e5e270a58 12315 int pubHdrSz = ASN_ECC_CONTEXT_SZ + ASN_ECC_HEADER_SZ;
sPymbed 16:048e5e270a58 12316
sPymbed 16:048e5e270a58 12317 word32 idx = 0, prvidx = 0, pubidx = 0, curveidx = 0;
sPymbed 16:048e5e270a58 12318 word32 seqSz, privSz, pubSz = ECC_BUFSIZE;
sPymbed 16:048e5e270a58 12319
sPymbed 16:048e5e270a58 12320 if (key == NULL || output == NULL || inLen == 0)
sPymbed 16:048e5e270a58 12321 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 12322
sPymbed 16:048e5e270a58 12323 /* curve */
sPymbed 16:048e5e270a58 12324 curve[curveidx++] = ECC_PREFIX_0;
sPymbed 16:048e5e270a58 12325 curveidx++ /* to put the size after computation */;
sPymbed 16:048e5e270a58 12326 curveSz = SetCurve(key, curve+curveidx);
sPymbed 16:048e5e270a58 12327 if (curveSz < 0)
sPymbed 16:048e5e270a58 12328 return curveSz;
sPymbed 16:048e5e270a58 12329 /* set computed size */
sPymbed 16:048e5e270a58 12330 curve[1] = (byte)curveSz;
sPymbed 16:048e5e270a58 12331 curveidx += curveSz;
sPymbed 16:048e5e270a58 12332
sPymbed 16:048e5e270a58 12333 /* private */
sPymbed 16:048e5e270a58 12334 privSz = key->dp->size;
sPymbed 16:048e5e270a58 12335 prv = (byte*)XMALLOC(privSz + privHdrSz + MAX_SEQ_SZ,
sPymbed 16:048e5e270a58 12336 key->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 12337 if (prv == NULL) {
sPymbed 16:048e5e270a58 12338 return MEMORY_E;
sPymbed 16:048e5e270a58 12339 }
sPymbed 16:048e5e270a58 12340 prvidx += SetOctetString8Bit(key->dp->size, &prv[prvidx]);
sPymbed 16:048e5e270a58 12341 ret = wc_ecc_export_private_only(key, prv + prvidx, &privSz);
sPymbed 16:048e5e270a58 12342 if (ret < 0) {
sPymbed 16:048e5e270a58 12343 XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 12344 return ret;
sPymbed 16:048e5e270a58 12345 }
sPymbed 16:048e5e270a58 12346 prvidx += privSz;
sPymbed 16:048e5e270a58 12347
sPymbed 16:048e5e270a58 12348 /* pubIn */
sPymbed 16:048e5e270a58 12349 if (pubIn) {
sPymbed 16:048e5e270a58 12350 ret = wc_ecc_export_x963(key, NULL, &pubSz);
sPymbed 16:048e5e270a58 12351 if (ret != LENGTH_ONLY_E) {
sPymbed 16:048e5e270a58 12352 XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 12353 return ret;
sPymbed 16:048e5e270a58 12354 }
sPymbed 16:048e5e270a58 12355
sPymbed 16:048e5e270a58 12356 pub = (byte*)XMALLOC(pubSz + pubHdrSz + MAX_SEQ_SZ,
sPymbed 16:048e5e270a58 12357 key->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 12358 if (pub == NULL) {
sPymbed 16:048e5e270a58 12359 XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 12360 return MEMORY_E;
sPymbed 16:048e5e270a58 12361 }
sPymbed 16:048e5e270a58 12362
sPymbed 16:048e5e270a58 12363 pub[pubidx++] = ECC_PREFIX_1;
sPymbed 16:048e5e270a58 12364 if (pubSz > 128) /* leading zero + extra size byte */
sPymbed 16:048e5e270a58 12365 pubidx += SetLength(pubSz + ASN_ECC_CONTEXT_SZ + 2, pub+pubidx);
sPymbed 16:048e5e270a58 12366 else /* leading zero */
sPymbed 16:048e5e270a58 12367 pubidx += SetLength(pubSz + ASN_ECC_CONTEXT_SZ + 1, pub+pubidx);
sPymbed 16:048e5e270a58 12368
sPymbed 16:048e5e270a58 12369 /* SetBitString adds leading zero */
sPymbed 16:048e5e270a58 12370 pubidx += SetBitString(pubSz, 0, pub + pubidx);
sPymbed 16:048e5e270a58 12371 ret = wc_ecc_export_x963(key, pub + pubidx, &pubSz);
sPymbed 16:048e5e270a58 12372 if (ret != 0) {
sPymbed 16:048e5e270a58 12373 XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 12374 XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 12375 return ret;
sPymbed 16:048e5e270a58 12376 }
sPymbed 16:048e5e270a58 12377 pubidx += pubSz;
sPymbed 16:048e5e270a58 12378 }
sPymbed 16:048e5e270a58 12379
sPymbed 16:048e5e270a58 12380 /* make headers */
sPymbed 16:048e5e270a58 12381 verSz = SetMyVersion(1, ver, FALSE);
sPymbed 16:048e5e270a58 12382 seqSz = SetSequence(verSz + prvidx + pubidx + curveidx, seq);
sPymbed 16:048e5e270a58 12383
sPymbed 16:048e5e270a58 12384 totalSz = prvidx + pubidx + curveidx + verSz + seqSz;
sPymbed 16:048e5e270a58 12385 if (totalSz > (int)inLen) {
sPymbed 16:048e5e270a58 12386 XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 12387 if (pubIn) {
sPymbed 16:048e5e270a58 12388 XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 12389 }
sPymbed 16:048e5e270a58 12390 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 12391 }
sPymbed 16:048e5e270a58 12392
sPymbed 16:048e5e270a58 12393 /* write out */
sPymbed 16:048e5e270a58 12394 /* seq */
sPymbed 16:048e5e270a58 12395 XMEMCPY(output + idx, seq, seqSz);
sPymbed 16:048e5e270a58 12396 idx = seqSz;
sPymbed 16:048e5e270a58 12397
sPymbed 16:048e5e270a58 12398 /* ver */
sPymbed 16:048e5e270a58 12399 XMEMCPY(output + idx, ver, verSz);
sPymbed 16:048e5e270a58 12400 idx += verSz;
sPymbed 16:048e5e270a58 12401
sPymbed 16:048e5e270a58 12402 /* private */
sPymbed 16:048e5e270a58 12403 XMEMCPY(output + idx, prv, prvidx);
sPymbed 16:048e5e270a58 12404 idx += prvidx;
sPymbed 16:048e5e270a58 12405 XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 12406
sPymbed 16:048e5e270a58 12407 /* curve */
sPymbed 16:048e5e270a58 12408 XMEMCPY(output + idx, curve, curveidx);
sPymbed 16:048e5e270a58 12409 idx += curveidx;
sPymbed 16:048e5e270a58 12410
sPymbed 16:048e5e270a58 12411 /* pubIn */
sPymbed 16:048e5e270a58 12412 if (pubIn) {
sPymbed 16:048e5e270a58 12413 XMEMCPY(output + idx, pub, pubidx);
sPymbed 16:048e5e270a58 12414 /* idx += pubidx; not used after write, if more data remove comment */
sPymbed 16:048e5e270a58 12415 XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 12416 }
sPymbed 16:048e5e270a58 12417
sPymbed 16:048e5e270a58 12418 return totalSz;
sPymbed 16:048e5e270a58 12419 }
sPymbed 16:048e5e270a58 12420
sPymbed 16:048e5e270a58 12421
sPymbed 16:048e5e270a58 12422 /* Write a Private ecc key, including public to DER format,
sPymbed 16:048e5e270a58 12423 * length on success else < 0 */
sPymbed 16:048e5e270a58 12424 int wc_EccKeyToDer(ecc_key* key, byte* output, word32 inLen)
sPymbed 16:048e5e270a58 12425 {
sPymbed 16:048e5e270a58 12426 return wc_BuildEccKeyDer(key, output, inLen, 1);
sPymbed 16:048e5e270a58 12427 }
sPymbed 16:048e5e270a58 12428
sPymbed 16:048e5e270a58 12429
sPymbed 16:048e5e270a58 12430 /* Write only private ecc key to DER format,
sPymbed 16:048e5e270a58 12431 * length on success else < 0 */
sPymbed 16:048e5e270a58 12432 int wc_EccPrivateKeyToDer(ecc_key* key, byte* output, word32 inLen)
sPymbed 16:048e5e270a58 12433 {
sPymbed 16:048e5e270a58 12434 return wc_BuildEccKeyDer(key, output, inLen, 0);
sPymbed 16:048e5e270a58 12435 }
sPymbed 16:048e5e270a58 12436
sPymbed 16:048e5e270a58 12437 /* Write only private ecc key to unencrypted PKCS#8 format.
sPymbed 16:048e5e270a58 12438 *
sPymbed 16:048e5e270a58 12439 * If output is NULL, places required PKCS#8 buffer size in outLen and
sPymbed 16:048e5e270a58 12440 * returns LENGTH_ONLY_E.
sPymbed 16:048e5e270a58 12441 *
sPymbed 16:048e5e270a58 12442 * return length on success else < 0 */
sPymbed 16:048e5e270a58 12443 int wc_EccPrivateKeyToPKCS8(ecc_key* key, byte* output, word32* outLen)
sPymbed 16:048e5e270a58 12444 {
sPymbed 16:048e5e270a58 12445 int ret, tmpDerSz;
sPymbed 16:048e5e270a58 12446 int algoID = 0;
sPymbed 16:048e5e270a58 12447 word32 oidSz = 0;
sPymbed 16:048e5e270a58 12448 word32 pkcs8Sz = 0;
sPymbed 16:048e5e270a58 12449 const byte* curveOID = NULL;
sPymbed 16:048e5e270a58 12450 byte* tmpDer = NULL;
sPymbed 16:048e5e270a58 12451
sPymbed 16:048e5e270a58 12452 if (key == NULL || outLen == NULL)
sPymbed 16:048e5e270a58 12453 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 12454
sPymbed 16:048e5e270a58 12455 /* set algoID, get curve OID */
sPymbed 16:048e5e270a58 12456 algoID = ECDSAk;
sPymbed 16:048e5e270a58 12457 ret = wc_ecc_get_oid(key->dp->oidSum, &curveOID, &oidSz);
sPymbed 16:048e5e270a58 12458 if (ret < 0)
sPymbed 16:048e5e270a58 12459 return ret;
sPymbed 16:048e5e270a58 12460
sPymbed 16:048e5e270a58 12461 /* temp buffer for plain DER key */
sPymbed 16:048e5e270a58 12462 tmpDer = (byte*)XMALLOC(ECC_BUFSIZE, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 12463 if (tmpDer == NULL)
sPymbed 16:048e5e270a58 12464 return MEMORY_E;
sPymbed 16:048e5e270a58 12465
sPymbed 16:048e5e270a58 12466 XMEMSET(tmpDer, 0, ECC_BUFSIZE);
sPymbed 16:048e5e270a58 12467
sPymbed 16:048e5e270a58 12468 tmpDerSz = wc_BuildEccKeyDer(key, tmpDer, ECC_BUFSIZE, 0);
sPymbed 16:048e5e270a58 12469 if (tmpDerSz < 0) {
sPymbed 16:048e5e270a58 12470 XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 12471 return tmpDerSz;
sPymbed 16:048e5e270a58 12472 }
sPymbed 16:048e5e270a58 12473
sPymbed 16:048e5e270a58 12474 /* get pkcs8 expected output size */
sPymbed 16:048e5e270a58 12475 ret = wc_CreatePKCS8Key(NULL, &pkcs8Sz, tmpDer, tmpDerSz, algoID,
sPymbed 16:048e5e270a58 12476 curveOID, oidSz);
sPymbed 16:048e5e270a58 12477 if (ret != LENGTH_ONLY_E) {
sPymbed 16:048e5e270a58 12478 XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 12479 return ret;
sPymbed 16:048e5e270a58 12480 }
sPymbed 16:048e5e270a58 12481
sPymbed 16:048e5e270a58 12482 if (output == NULL) {
sPymbed 16:048e5e270a58 12483 XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 12484 *outLen = pkcs8Sz;
sPymbed 16:048e5e270a58 12485 return LENGTH_ONLY_E;
sPymbed 16:048e5e270a58 12486
sPymbed 16:048e5e270a58 12487 } else if (*outLen < pkcs8Sz) {
sPymbed 16:048e5e270a58 12488 XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 12489 WOLFSSL_MSG("Input buffer too small for ECC PKCS#8 key");
sPymbed 16:048e5e270a58 12490 return BUFFER_E;
sPymbed 16:048e5e270a58 12491 }
sPymbed 16:048e5e270a58 12492
sPymbed 16:048e5e270a58 12493 ret = wc_CreatePKCS8Key(output, &pkcs8Sz, tmpDer, tmpDerSz,
sPymbed 16:048e5e270a58 12494 algoID, curveOID, oidSz);
sPymbed 16:048e5e270a58 12495 if (ret < 0) {
sPymbed 16:048e5e270a58 12496 XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 12497 return ret;
sPymbed 16:048e5e270a58 12498 }
sPymbed 16:048e5e270a58 12499
sPymbed 16:048e5e270a58 12500 XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
sPymbed 16:048e5e270a58 12501
sPymbed 16:048e5e270a58 12502 *outLen = ret;
sPymbed 16:048e5e270a58 12503 return ret;
sPymbed 16:048e5e270a58 12504 }
sPymbed 16:048e5e270a58 12505
sPymbed 16:048e5e270a58 12506 #endif /* HAVE_ECC */
sPymbed 16:048e5e270a58 12507
sPymbed 16:048e5e270a58 12508
sPymbed 16:048e5e270a58 12509 #ifdef HAVE_ED25519
sPymbed 16:048e5e270a58 12510
sPymbed 16:048e5e270a58 12511 int wc_Ed25519PrivateKeyDecode(const byte* input, word32* inOutIdx,
sPymbed 16:048e5e270a58 12512 ed25519_key* key, word32 inSz)
sPymbed 16:048e5e270a58 12513 {
sPymbed 16:048e5e270a58 12514 word32 oid;
sPymbed 16:048e5e270a58 12515 int ret, version, length, endKeyIdx, privSz, pubSz;
sPymbed 16:048e5e270a58 12516 const byte* priv;
sPymbed 16:048e5e270a58 12517 const byte* pub;
sPymbed 16:048e5e270a58 12518
sPymbed 16:048e5e270a58 12519 if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0)
sPymbed 16:048e5e270a58 12520 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 12521
sPymbed 16:048e5e270a58 12522 if (GetSequence(input, inOutIdx, &length, inSz) >= 0) {
sPymbed 16:048e5e270a58 12523 endKeyIdx = *inOutIdx + length;
sPymbed 16:048e5e270a58 12524
sPymbed 16:048e5e270a58 12525 if (GetMyVersion(input, inOutIdx, &version, inSz) < 0)
sPymbed 16:048e5e270a58 12526 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 12527 if (version != 0) {
sPymbed 16:048e5e270a58 12528 WOLFSSL_MSG("Unrecognized version of ED25519 private key");
sPymbed 16:048e5e270a58 12529 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 12530 }
sPymbed 16:048e5e270a58 12531
sPymbed 16:048e5e270a58 12532 if (GetAlgoId(input, inOutIdx, &oid, oidKeyType, inSz) < 0)
sPymbed 16:048e5e270a58 12533 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 12534 if (oid != ED25519k)
sPymbed 16:048e5e270a58 12535 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 12536
sPymbed 16:048e5e270a58 12537 if (GetOctetString(input, inOutIdx, &length, inSz) < 0)
sPymbed 16:048e5e270a58 12538 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 12539
sPymbed 16:048e5e270a58 12540 if (GetOctetString(input, inOutIdx, &privSz, inSz) < 0)
sPymbed 16:048e5e270a58 12541 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 12542
sPymbed 16:048e5e270a58 12543 priv = input + *inOutIdx;
sPymbed 16:048e5e270a58 12544 *inOutIdx += privSz;
sPymbed 16:048e5e270a58 12545 }
sPymbed 16:048e5e270a58 12546 else {
sPymbed 16:048e5e270a58 12547 if (GetOctetString(input, inOutIdx, &privSz, inSz) < 0)
sPymbed 16:048e5e270a58 12548 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 12549
sPymbed 16:048e5e270a58 12550 priv = input + *inOutIdx;
sPymbed 16:048e5e270a58 12551 *inOutIdx += privSz;
sPymbed 16:048e5e270a58 12552 endKeyIdx = *inOutIdx;
sPymbed 16:048e5e270a58 12553 }
sPymbed 16:048e5e270a58 12554
sPymbed 16:048e5e270a58 12555 if (endKeyIdx == (int)*inOutIdx) {
sPymbed 16:048e5e270a58 12556 ret = wc_ed25519_import_private_only(priv, privSz, key);
sPymbed 16:048e5e270a58 12557 }
sPymbed 16:048e5e270a58 12558 else {
sPymbed 16:048e5e270a58 12559 if (GetASNHeader(input, ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1,
sPymbed 16:048e5e270a58 12560 inOutIdx, &length, inSz) < 0) {
sPymbed 16:048e5e270a58 12561 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 12562 }
sPymbed 16:048e5e270a58 12563 if (GetOctetString(input, inOutIdx, &pubSz, inSz) < 0)
sPymbed 16:048e5e270a58 12564 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 12565 pub = input + *inOutIdx;
sPymbed 16:048e5e270a58 12566 *inOutIdx += pubSz;
sPymbed 16:048e5e270a58 12567
sPymbed 16:048e5e270a58 12568 ret = wc_ed25519_import_private_key(priv, privSz, pub, pubSz, key);
sPymbed 16:048e5e270a58 12569 }
sPymbed 16:048e5e270a58 12570 if (ret == 0 && endKeyIdx != (int)*inOutIdx)
sPymbed 16:048e5e270a58 12571 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 12572
sPymbed 16:048e5e270a58 12573 return ret;
sPymbed 16:048e5e270a58 12574 }
sPymbed 16:048e5e270a58 12575
sPymbed 16:048e5e270a58 12576
sPymbed 16:048e5e270a58 12577 int wc_Ed25519PublicKeyDecode(const byte* input, word32* inOutIdx,
sPymbed 16:048e5e270a58 12578 ed25519_key* key, word32 inSz)
sPymbed 16:048e5e270a58 12579 {
sPymbed 16:048e5e270a58 12580 int length;
sPymbed 16:048e5e270a58 12581 int ret;
sPymbed 16:048e5e270a58 12582
sPymbed 16:048e5e270a58 12583 if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0)
sPymbed 16:048e5e270a58 12584 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 12585
sPymbed 16:048e5e270a58 12586 if (GetSequence(input, inOutIdx, &length, inSz) < 0)
sPymbed 16:048e5e270a58 12587 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 12588
sPymbed 16:048e5e270a58 12589 if (GetSequence(input, inOutIdx, &length, inSz) < 0)
sPymbed 16:048e5e270a58 12590 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 12591
sPymbed 16:048e5e270a58 12592 ret = SkipObjectId(input, inOutIdx, inSz);
sPymbed 16:048e5e270a58 12593 if (ret != 0)
sPymbed 16:048e5e270a58 12594 return ret;
sPymbed 16:048e5e270a58 12595
sPymbed 16:048e5e270a58 12596 /* key header */
sPymbed 16:048e5e270a58 12597 ret = CheckBitString(input, inOutIdx, NULL, inSz, 1, NULL);
sPymbed 16:048e5e270a58 12598 if (ret != 0)
sPymbed 16:048e5e270a58 12599 return ret;
sPymbed 16:048e5e270a58 12600
sPymbed 16:048e5e270a58 12601 /* This is the raw point data compressed or uncompressed. */
sPymbed 16:048e5e270a58 12602 if (wc_ed25519_import_public(input + *inOutIdx, inSz - *inOutIdx, key) != 0)
sPymbed 16:048e5e270a58 12603 return ASN_ECC_KEY_E;
sPymbed 16:048e5e270a58 12604
sPymbed 16:048e5e270a58 12605 return 0;
sPymbed 16:048e5e270a58 12606 }
sPymbed 16:048e5e270a58 12607
sPymbed 16:048e5e270a58 12608
sPymbed 16:048e5e270a58 12609 #ifdef WOLFSSL_KEY_GEN
sPymbed 16:048e5e270a58 12610
sPymbed 16:048e5e270a58 12611 /* build DER formatted ED25519 key,
sPymbed 16:048e5e270a58 12612 * return length on success, negative on error */
sPymbed 16:048e5e270a58 12613 static int wc_BuildEd25519KeyDer(ed25519_key* key, byte* output, word32 inLen,
sPymbed 16:048e5e270a58 12614 int pubOut)
sPymbed 16:048e5e270a58 12615 {
sPymbed 16:048e5e270a58 12616 byte algoArray[MAX_ALGO_SZ];
sPymbed 16:048e5e270a58 12617 byte ver[MAX_VERSION_SZ];
sPymbed 16:048e5e270a58 12618 byte seq[MAX_SEQ_SZ];
sPymbed 16:048e5e270a58 12619 int ret;
sPymbed 16:048e5e270a58 12620 word32 idx = 0, seqSz, verSz, algoSz, privSz, pubSz = 0;
sPymbed 16:048e5e270a58 12621
sPymbed 16:048e5e270a58 12622 if (key == NULL || output == NULL || inLen == 0)
sPymbed 16:048e5e270a58 12623 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 12624
sPymbed 16:048e5e270a58 12625 if (pubOut)
sPymbed 16:048e5e270a58 12626 pubSz = 2 + 2 + ED25519_PUB_KEY_SIZE;
sPymbed 16:048e5e270a58 12627 privSz = 2 + 2 + ED25519_KEY_SIZE;
sPymbed 16:048e5e270a58 12628 algoSz = SetAlgoID(ED25519k, algoArray, oidKeyType, 0);
sPymbed 16:048e5e270a58 12629 verSz = SetMyVersion(0, ver, FALSE);
sPymbed 16:048e5e270a58 12630 seqSz = SetSequence(verSz + algoSz + privSz + pubSz, seq);
sPymbed 16:048e5e270a58 12631
sPymbed 16:048e5e270a58 12632 if (seqSz + verSz + algoSz + privSz + pubSz > inLen)
sPymbed 16:048e5e270a58 12633 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 12634
sPymbed 16:048e5e270a58 12635 /* write out */
sPymbed 16:048e5e270a58 12636 /* seq */
sPymbed 16:048e5e270a58 12637 XMEMCPY(output + idx, seq, seqSz);
sPymbed 16:048e5e270a58 12638 idx = seqSz;
sPymbed 16:048e5e270a58 12639 /* ver */
sPymbed 16:048e5e270a58 12640 XMEMCPY(output + idx, ver, verSz);
sPymbed 16:048e5e270a58 12641 idx += verSz;
sPymbed 16:048e5e270a58 12642 /* algo */
sPymbed 16:048e5e270a58 12643 XMEMCPY(output + idx, algoArray, algoSz);
sPymbed 16:048e5e270a58 12644 idx += algoSz;
sPymbed 16:048e5e270a58 12645 /* privKey */
sPymbed 16:048e5e270a58 12646 idx += SetOctetString(2 + ED25519_KEY_SIZE, output + idx);
sPymbed 16:048e5e270a58 12647 idx += SetOctetString(ED25519_KEY_SIZE, output + idx);
sPymbed 16:048e5e270a58 12648 ret = wc_ed25519_export_private_only(key, output + idx, &privSz);
sPymbed 16:048e5e270a58 12649 if (ret != 0)
sPymbed 16:048e5e270a58 12650 return ret;
sPymbed 16:048e5e270a58 12651 idx += privSz;
sPymbed 16:048e5e270a58 12652 /* pubKey */
sPymbed 16:048e5e270a58 12653 if (pubOut) {
sPymbed 16:048e5e270a58 12654 idx += SetExplicit(1, 2 + ED25519_PUB_KEY_SIZE, output + idx);
sPymbed 16:048e5e270a58 12655 idx += SetOctetString(ED25519_KEY_SIZE, output + idx);
sPymbed 16:048e5e270a58 12656 ret = wc_ed25519_export_public(key, output + idx, &pubSz);
sPymbed 16:048e5e270a58 12657 if (ret != 0)
sPymbed 16:048e5e270a58 12658 return ret;
sPymbed 16:048e5e270a58 12659 idx += pubSz;
sPymbed 16:048e5e270a58 12660 }
sPymbed 16:048e5e270a58 12661
sPymbed 16:048e5e270a58 12662 return idx;
sPymbed 16:048e5e270a58 12663 }
sPymbed 16:048e5e270a58 12664
sPymbed 16:048e5e270a58 12665 /* Write a Private ecc key, including public to DER format,
sPymbed 16:048e5e270a58 12666 * length on success else < 0 */
sPymbed 16:048e5e270a58 12667 int wc_Ed25519KeyToDer(ed25519_key* key, byte* output, word32 inLen)
sPymbed 16:048e5e270a58 12668 {
sPymbed 16:048e5e270a58 12669 return wc_BuildEd25519KeyDer(key, output, inLen, 1);
sPymbed 16:048e5e270a58 12670 }
sPymbed 16:048e5e270a58 12671
sPymbed 16:048e5e270a58 12672
sPymbed 16:048e5e270a58 12673
sPymbed 16:048e5e270a58 12674 /* Write only private ecc key to DER format,
sPymbed 16:048e5e270a58 12675 * length on success else < 0 */
sPymbed 16:048e5e270a58 12676 int wc_Ed25519PrivateKeyToDer(ed25519_key* key, byte* output, word32 inLen)
sPymbed 16:048e5e270a58 12677 {
sPymbed 16:048e5e270a58 12678 return wc_BuildEd25519KeyDer(key, output, inLen, 0);
sPymbed 16:048e5e270a58 12679 }
sPymbed 16:048e5e270a58 12680
sPymbed 16:048e5e270a58 12681 #endif /* WOLFSSL_KEY_GEN */
sPymbed 16:048e5e270a58 12682
sPymbed 16:048e5e270a58 12683 #endif /* HAVE_ED25519 */
sPymbed 16:048e5e270a58 12684
sPymbed 16:048e5e270a58 12685
sPymbed 16:048e5e270a58 12686 #if defined(HAVE_OCSP) || defined(HAVE_CRL)
sPymbed 16:048e5e270a58 12687
sPymbed 16:048e5e270a58 12688 /* Get raw Date only, no processing, 0 on success */
sPymbed 16:048e5e270a58 12689 static int GetBasicDate(const byte* source, word32* idx, byte* date,
sPymbed 16:048e5e270a58 12690 byte* format, int maxIdx)
sPymbed 16:048e5e270a58 12691 {
sPymbed 16:048e5e270a58 12692 int ret, length;
sPymbed 16:048e5e270a58 12693 const byte *datePtr = NULL;
sPymbed 16:048e5e270a58 12694
sPymbed 16:048e5e270a58 12695 WOLFSSL_ENTER("GetBasicDate");
sPymbed 16:048e5e270a58 12696
sPymbed 16:048e5e270a58 12697 ret = GetDateInfo(source, idx, &datePtr, format, &length, maxIdx);
sPymbed 16:048e5e270a58 12698 if (ret < 0)
sPymbed 16:048e5e270a58 12699 return ret;
sPymbed 16:048e5e270a58 12700
sPymbed 16:048e5e270a58 12701 XMEMCPY(date, datePtr, length);
sPymbed 16:048e5e270a58 12702
sPymbed 16:048e5e270a58 12703 return 0;
sPymbed 16:048e5e270a58 12704 }
sPymbed 16:048e5e270a58 12705
sPymbed 16:048e5e270a58 12706 #endif
sPymbed 16:048e5e270a58 12707
sPymbed 16:048e5e270a58 12708
sPymbed 16:048e5e270a58 12709 #ifdef HAVE_OCSP
sPymbed 16:048e5e270a58 12710
sPymbed 16:048e5e270a58 12711 static int GetEnumerated(const byte* input, word32* inOutIdx, int *value)
sPymbed 16:048e5e270a58 12712 {
sPymbed 16:048e5e270a58 12713 word32 idx = *inOutIdx;
sPymbed 16:048e5e270a58 12714 word32 len;
sPymbed 16:048e5e270a58 12715
sPymbed 16:048e5e270a58 12716 WOLFSSL_ENTER("GetEnumerated");
sPymbed 16:048e5e270a58 12717
sPymbed 16:048e5e270a58 12718 *value = 0;
sPymbed 16:048e5e270a58 12719
sPymbed 16:048e5e270a58 12720 if (input[idx++] != ASN_ENUMERATED)
sPymbed 16:048e5e270a58 12721 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 12722
sPymbed 16:048e5e270a58 12723 len = input[idx++];
sPymbed 16:048e5e270a58 12724 if (len > 4)
sPymbed 16:048e5e270a58 12725 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 12726
sPymbed 16:048e5e270a58 12727 while (len--) {
sPymbed 16:048e5e270a58 12728 *value = *value << 8 | input[idx++];
sPymbed 16:048e5e270a58 12729 }
sPymbed 16:048e5e270a58 12730
sPymbed 16:048e5e270a58 12731 *inOutIdx = idx;
sPymbed 16:048e5e270a58 12732
sPymbed 16:048e5e270a58 12733 return *value;
sPymbed 16:048e5e270a58 12734 }
sPymbed 16:048e5e270a58 12735
sPymbed 16:048e5e270a58 12736
sPymbed 16:048e5e270a58 12737 static int DecodeSingleResponse(byte* source,
sPymbed 16:048e5e270a58 12738 word32* ioIndex, OcspResponse* resp, word32 size)
sPymbed 16:048e5e270a58 12739 {
sPymbed 16:048e5e270a58 12740 word32 idx = *ioIndex, prevIndex, oid;
sPymbed 16:048e5e270a58 12741 int length, wrapperSz;
sPymbed 16:048e5e270a58 12742 CertStatus* cs = resp->status;
sPymbed 16:048e5e270a58 12743 int ret;
sPymbed 16:048e5e270a58 12744
sPymbed 16:048e5e270a58 12745 WOLFSSL_ENTER("DecodeSingleResponse");
sPymbed 16:048e5e270a58 12746
sPymbed 16:048e5e270a58 12747 /* Outer wrapper of the SEQUENCE OF Single Responses. */
sPymbed 16:048e5e270a58 12748 if (GetSequence(source, &idx, &wrapperSz, size) < 0)
sPymbed 16:048e5e270a58 12749 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 12750
sPymbed 16:048e5e270a58 12751 prevIndex = idx;
sPymbed 16:048e5e270a58 12752
sPymbed 16:048e5e270a58 12753 /* When making a request, we only request one status on one certificate
sPymbed 16:048e5e270a58 12754 * at a time. There should only be one SingleResponse */
sPymbed 16:048e5e270a58 12755
sPymbed 16:048e5e270a58 12756 /* Wrapper around the Single Response */
sPymbed 16:048e5e270a58 12757 if (GetSequence(source, &idx, &length, size) < 0)
sPymbed 16:048e5e270a58 12758 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 12759
sPymbed 16:048e5e270a58 12760 /* Wrapper around the CertID */
sPymbed 16:048e5e270a58 12761 if (GetSequence(source, &idx, &length, size) < 0)
sPymbed 16:048e5e270a58 12762 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 12763 /* Skip the hash algorithm */
sPymbed 16:048e5e270a58 12764 if (GetAlgoId(source, &idx, &oid, oidIgnoreType, size) < 0)
sPymbed 16:048e5e270a58 12765 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 12766 /* Save reference to the hash of CN */
sPymbed 16:048e5e270a58 12767 ret = GetOctetString(source, &idx, &length, size);
sPymbed 16:048e5e270a58 12768 if (ret < 0)
sPymbed 16:048e5e270a58 12769 return ret;
sPymbed 16:048e5e270a58 12770 resp->issuerHash = source + idx;
sPymbed 16:048e5e270a58 12771 idx += length;
sPymbed 16:048e5e270a58 12772 /* Save reference to the hash of the issuer public key */
sPymbed 16:048e5e270a58 12773 ret = GetOctetString(source, &idx, &length, size);
sPymbed 16:048e5e270a58 12774 if (ret < 0)
sPymbed 16:048e5e270a58 12775 return ret;
sPymbed 16:048e5e270a58 12776 resp->issuerKeyHash = source + idx;
sPymbed 16:048e5e270a58 12777 idx += length;
sPymbed 16:048e5e270a58 12778
sPymbed 16:048e5e270a58 12779 /* Get serial number */
sPymbed 16:048e5e270a58 12780 if (GetSerialNumber(source, &idx, cs->serial, &cs->serialSz, size) < 0)
sPymbed 16:048e5e270a58 12781 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 12782
sPymbed 16:048e5e270a58 12783 /* CertStatus */
sPymbed 16:048e5e270a58 12784 switch (source[idx++])
sPymbed 16:048e5e270a58 12785 {
sPymbed 16:048e5e270a58 12786 case (ASN_CONTEXT_SPECIFIC | CERT_GOOD):
sPymbed 16:048e5e270a58 12787 cs->status = CERT_GOOD;
sPymbed 16:048e5e270a58 12788 idx++;
sPymbed 16:048e5e270a58 12789 break;
sPymbed 16:048e5e270a58 12790 case (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | CERT_REVOKED):
sPymbed 16:048e5e270a58 12791 cs->status = CERT_REVOKED;
sPymbed 16:048e5e270a58 12792 if (GetLength(source, &idx, &length, size) < 0)
sPymbed 16:048e5e270a58 12793 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 12794 idx += length;
sPymbed 16:048e5e270a58 12795 break;
sPymbed 16:048e5e270a58 12796 case (ASN_CONTEXT_SPECIFIC | CERT_UNKNOWN):
sPymbed 16:048e5e270a58 12797 cs->status = CERT_UNKNOWN;
sPymbed 16:048e5e270a58 12798 idx++;
sPymbed 16:048e5e270a58 12799 break;
sPymbed 16:048e5e270a58 12800 default:
sPymbed 16:048e5e270a58 12801 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 12802 }
sPymbed 16:048e5e270a58 12803
sPymbed 16:048e5e270a58 12804 #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
sPymbed 16:048e5e270a58 12805 cs->thisDateAsn = source + idx;
sPymbed 16:048e5e270a58 12806 #endif
sPymbed 16:048e5e270a58 12807 if (GetBasicDate(source, &idx, cs->thisDate,
sPymbed 16:048e5e270a58 12808 &cs->thisDateFormat, size) < 0)
sPymbed 16:048e5e270a58 12809 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 12810
sPymbed 16:048e5e270a58 12811 #ifndef NO_ASN_TIME
sPymbed 16:048e5e270a58 12812 if (!XVALIDATE_DATE(cs->thisDate, cs->thisDateFormat, BEFORE))
sPymbed 16:048e5e270a58 12813 return ASN_BEFORE_DATE_E;
sPymbed 16:048e5e270a58 12814 #endif
sPymbed 16:048e5e270a58 12815
sPymbed 16:048e5e270a58 12816 /* The following items are optional. Only check for them if there is more
sPymbed 16:048e5e270a58 12817 * unprocessed data in the singleResponse wrapper. */
sPymbed 16:048e5e270a58 12818
sPymbed 16:048e5e270a58 12819 if (((int)(idx - prevIndex) < wrapperSz) &&
sPymbed 16:048e5e270a58 12820 (source[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)))
sPymbed 16:048e5e270a58 12821 {
sPymbed 16:048e5e270a58 12822 idx++;
sPymbed 16:048e5e270a58 12823 if (GetLength(source, &idx, &length, size) < 0)
sPymbed 16:048e5e270a58 12824 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 12825 #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
sPymbed 16:048e5e270a58 12826 cs->nextDateAsn = source + idx;
sPymbed 16:048e5e270a58 12827 #endif
sPymbed 16:048e5e270a58 12828 if (GetBasicDate(source, &idx, cs->nextDate,
sPymbed 16:048e5e270a58 12829 &cs->nextDateFormat, size) < 0)
sPymbed 16:048e5e270a58 12830 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 12831
sPymbed 16:048e5e270a58 12832 #ifndef NO_ASN_TIME
sPymbed 16:048e5e270a58 12833 if (!XVALIDATE_DATE(cs->nextDate, cs->nextDateFormat, AFTER))
sPymbed 16:048e5e270a58 12834 return ASN_AFTER_DATE_E;
sPymbed 16:048e5e270a58 12835 #endif
sPymbed 16:048e5e270a58 12836 }
sPymbed 16:048e5e270a58 12837 if (((int)(idx - prevIndex) < wrapperSz) &&
sPymbed 16:048e5e270a58 12838 (source[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)))
sPymbed 16:048e5e270a58 12839 {
sPymbed 16:048e5e270a58 12840 idx++;
sPymbed 16:048e5e270a58 12841 if (GetLength(source, &idx, &length, size) < 0)
sPymbed 16:048e5e270a58 12842 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 12843 idx += length;
sPymbed 16:048e5e270a58 12844 }
sPymbed 16:048e5e270a58 12845
sPymbed 16:048e5e270a58 12846 *ioIndex = idx;
sPymbed 16:048e5e270a58 12847
sPymbed 16:048e5e270a58 12848 return 0;
sPymbed 16:048e5e270a58 12849 }
sPymbed 16:048e5e270a58 12850
sPymbed 16:048e5e270a58 12851 static int DecodeOcspRespExtensions(byte* source,
sPymbed 16:048e5e270a58 12852 word32* ioIndex, OcspResponse* resp, word32 sz)
sPymbed 16:048e5e270a58 12853 {
sPymbed 16:048e5e270a58 12854 word32 idx = *ioIndex;
sPymbed 16:048e5e270a58 12855 int length;
sPymbed 16:048e5e270a58 12856 int ext_bound; /* boundary index for the sequence of extensions */
sPymbed 16:048e5e270a58 12857 word32 oid;
sPymbed 16:048e5e270a58 12858 int ret;
sPymbed 16:048e5e270a58 12859
sPymbed 16:048e5e270a58 12860 WOLFSSL_ENTER("DecodeOcspRespExtensions");
sPymbed 16:048e5e270a58 12861
sPymbed 16:048e5e270a58 12862 if ((idx + 1) > sz)
sPymbed 16:048e5e270a58 12863 return BUFFER_E;
sPymbed 16:048e5e270a58 12864
sPymbed 16:048e5e270a58 12865 if (source[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1))
sPymbed 16:048e5e270a58 12866 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 12867
sPymbed 16:048e5e270a58 12868 if (GetLength(source, &idx, &length, sz) < 0)
sPymbed 16:048e5e270a58 12869 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 12870
sPymbed 16:048e5e270a58 12871 if (GetSequence(source, &idx, &length, sz) < 0)
sPymbed 16:048e5e270a58 12872 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 12873
sPymbed 16:048e5e270a58 12874 ext_bound = idx + length;
sPymbed 16:048e5e270a58 12875
sPymbed 16:048e5e270a58 12876 while (idx < (word32)ext_bound) {
sPymbed 16:048e5e270a58 12877 if (GetSequence(source, &idx, &length, sz) < 0) {
sPymbed 16:048e5e270a58 12878 WOLFSSL_MSG("\tfail: should be a SEQUENCE");
sPymbed 16:048e5e270a58 12879 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 12880 }
sPymbed 16:048e5e270a58 12881
sPymbed 16:048e5e270a58 12882 oid = 0;
sPymbed 16:048e5e270a58 12883 if (GetObjectId(source, &idx, &oid, oidOcspType, sz) < 0) {
sPymbed 16:048e5e270a58 12884 WOLFSSL_MSG("\tfail: OBJECT ID");
sPymbed 16:048e5e270a58 12885 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 12886 }
sPymbed 16:048e5e270a58 12887
sPymbed 16:048e5e270a58 12888 /* check for critical flag */
sPymbed 16:048e5e270a58 12889 if (source[idx] == ASN_BOOLEAN) {
sPymbed 16:048e5e270a58 12890 WOLFSSL_MSG("\tfound optional critical flag, moving past");
sPymbed 16:048e5e270a58 12891 ret = GetBoolean(source, &idx, sz);
sPymbed 16:048e5e270a58 12892 if (ret < 0)
sPymbed 16:048e5e270a58 12893 return ret;
sPymbed 16:048e5e270a58 12894 }
sPymbed 16:048e5e270a58 12895
sPymbed 16:048e5e270a58 12896 ret = GetOctetString(source, &idx, &length, sz);
sPymbed 16:048e5e270a58 12897 if (ret < 0)
sPymbed 16:048e5e270a58 12898 return ret;
sPymbed 16:048e5e270a58 12899
sPymbed 16:048e5e270a58 12900 if (oid == OCSP_NONCE_OID) {
sPymbed 16:048e5e270a58 12901 /* get data inside extra OCTET_STRING */
sPymbed 16:048e5e270a58 12902 ret = GetOctetString(source, &idx, &length, sz);
sPymbed 16:048e5e270a58 12903 if (ret < 0)
sPymbed 16:048e5e270a58 12904 return ret;
sPymbed 16:048e5e270a58 12905
sPymbed 16:048e5e270a58 12906 resp->nonce = source + idx;
sPymbed 16:048e5e270a58 12907 resp->nonceSz = length;
sPymbed 16:048e5e270a58 12908 }
sPymbed 16:048e5e270a58 12909
sPymbed 16:048e5e270a58 12910 idx += length;
sPymbed 16:048e5e270a58 12911 }
sPymbed 16:048e5e270a58 12912
sPymbed 16:048e5e270a58 12913 *ioIndex = idx;
sPymbed 16:048e5e270a58 12914 return 0;
sPymbed 16:048e5e270a58 12915 }
sPymbed 16:048e5e270a58 12916
sPymbed 16:048e5e270a58 12917
sPymbed 16:048e5e270a58 12918 static int DecodeResponseData(byte* source,
sPymbed 16:048e5e270a58 12919 word32* ioIndex, OcspResponse* resp, word32 size)
sPymbed 16:048e5e270a58 12920 {
sPymbed 16:048e5e270a58 12921 word32 idx = *ioIndex, prev_idx;
sPymbed 16:048e5e270a58 12922 int length;
sPymbed 16:048e5e270a58 12923 int version;
sPymbed 16:048e5e270a58 12924 word32 responderId = 0;
sPymbed 16:048e5e270a58 12925
sPymbed 16:048e5e270a58 12926 WOLFSSL_ENTER("DecodeResponseData");
sPymbed 16:048e5e270a58 12927
sPymbed 16:048e5e270a58 12928 resp->response = source + idx;
sPymbed 16:048e5e270a58 12929 prev_idx = idx;
sPymbed 16:048e5e270a58 12930 if (GetSequence(source, &idx, &length, size) < 0)
sPymbed 16:048e5e270a58 12931 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 12932 resp->responseSz = length + idx - prev_idx;
sPymbed 16:048e5e270a58 12933
sPymbed 16:048e5e270a58 12934 /* Get version. It is an EXPLICIT[0] DEFAULT(0) value. If this
sPymbed 16:048e5e270a58 12935 * item isn't an EXPLICIT[0], then set version to zero and move
sPymbed 16:048e5e270a58 12936 * onto the next item.
sPymbed 16:048e5e270a58 12937 */
sPymbed 16:048e5e270a58 12938 if (source[idx] == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED))
sPymbed 16:048e5e270a58 12939 {
sPymbed 16:048e5e270a58 12940 idx += 2; /* Eat the value and length */
sPymbed 16:048e5e270a58 12941 if (GetMyVersion(source, &idx, &version, size) < 0)
sPymbed 16:048e5e270a58 12942 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 12943 } else
sPymbed 16:048e5e270a58 12944 version = 0;
sPymbed 16:048e5e270a58 12945
sPymbed 16:048e5e270a58 12946 responderId = source[idx++];
sPymbed 16:048e5e270a58 12947 if ((responderId == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1)) ||
sPymbed 16:048e5e270a58 12948 (responderId == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 2)))
sPymbed 16:048e5e270a58 12949 {
sPymbed 16:048e5e270a58 12950 if (GetLength(source, &idx, &length, size) < 0)
sPymbed 16:048e5e270a58 12951 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 12952 idx += length;
sPymbed 16:048e5e270a58 12953 }
sPymbed 16:048e5e270a58 12954 else
sPymbed 16:048e5e270a58 12955 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 12956
sPymbed 16:048e5e270a58 12957 /* save pointer to the producedAt time */
sPymbed 16:048e5e270a58 12958 if (GetBasicDate(source, &idx, resp->producedDate,
sPymbed 16:048e5e270a58 12959 &resp->producedDateFormat, size) < 0)
sPymbed 16:048e5e270a58 12960 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 12961
sPymbed 16:048e5e270a58 12962 if (DecodeSingleResponse(source, &idx, resp, size) < 0)
sPymbed 16:048e5e270a58 12963 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 12964
sPymbed 16:048e5e270a58 12965 /*
sPymbed 16:048e5e270a58 12966 * Check the length of the ResponseData against the current index to
sPymbed 16:048e5e270a58 12967 * see if there are extensions, they are optional.
sPymbed 16:048e5e270a58 12968 */
sPymbed 16:048e5e270a58 12969 if (idx - prev_idx < resp->responseSz)
sPymbed 16:048e5e270a58 12970 if (DecodeOcspRespExtensions(source, &idx, resp, size) < 0)
sPymbed 16:048e5e270a58 12971 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 12972
sPymbed 16:048e5e270a58 12973 *ioIndex = idx;
sPymbed 16:048e5e270a58 12974 return 0;
sPymbed 16:048e5e270a58 12975 }
sPymbed 16:048e5e270a58 12976
sPymbed 16:048e5e270a58 12977
sPymbed 16:048e5e270a58 12978 #ifndef WOLFSSL_NO_OCSP_OPTIONAL_CERTS
sPymbed 16:048e5e270a58 12979
sPymbed 16:048e5e270a58 12980 static int DecodeCerts(byte* source,
sPymbed 16:048e5e270a58 12981 word32* ioIndex, OcspResponse* resp, word32 size)
sPymbed 16:048e5e270a58 12982 {
sPymbed 16:048e5e270a58 12983 word32 idx = *ioIndex;
sPymbed 16:048e5e270a58 12984
sPymbed 16:048e5e270a58 12985 WOLFSSL_ENTER("DecodeCerts");
sPymbed 16:048e5e270a58 12986
sPymbed 16:048e5e270a58 12987 if (source[idx++] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC))
sPymbed 16:048e5e270a58 12988 {
sPymbed 16:048e5e270a58 12989 int length;
sPymbed 16:048e5e270a58 12990
sPymbed 16:048e5e270a58 12991 if (GetLength(source, &idx, &length, size) < 0)
sPymbed 16:048e5e270a58 12992 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 12993
sPymbed 16:048e5e270a58 12994 if (GetSequence(source, &idx, &length, size) < 0)
sPymbed 16:048e5e270a58 12995 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 12996
sPymbed 16:048e5e270a58 12997 resp->cert = source + idx;
sPymbed 16:048e5e270a58 12998 resp->certSz = length;
sPymbed 16:048e5e270a58 12999
sPymbed 16:048e5e270a58 13000 idx += length;
sPymbed 16:048e5e270a58 13001 }
sPymbed 16:048e5e270a58 13002 *ioIndex = idx;
sPymbed 16:048e5e270a58 13003 return 0;
sPymbed 16:048e5e270a58 13004 }
sPymbed 16:048e5e270a58 13005
sPymbed 16:048e5e270a58 13006 #endif /* WOLFSSL_NO_OCSP_OPTIONAL_CERTS */
sPymbed 16:048e5e270a58 13007
sPymbed 16:048e5e270a58 13008
sPymbed 16:048e5e270a58 13009 static int DecodeBasicOcspResponse(byte* source, word32* ioIndex,
sPymbed 16:048e5e270a58 13010 OcspResponse* resp, word32 size, void* cm, void* heap, int noVerify)
sPymbed 16:048e5e270a58 13011 {
sPymbed 16:048e5e270a58 13012 int length;
sPymbed 16:048e5e270a58 13013 word32 idx = *ioIndex;
sPymbed 16:048e5e270a58 13014 word32 end_index;
sPymbed 16:048e5e270a58 13015 int ret;
sPymbed 16:048e5e270a58 13016 int sigLength;
sPymbed 16:048e5e270a58 13017
sPymbed 16:048e5e270a58 13018 WOLFSSL_ENTER("DecodeBasicOcspResponse");
sPymbed 16:048e5e270a58 13019 (void)heap;
sPymbed 16:048e5e270a58 13020
sPymbed 16:048e5e270a58 13021 if (GetSequence(source, &idx, &length, size) < 0)
sPymbed 16:048e5e270a58 13022 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 13023
sPymbed 16:048e5e270a58 13024 if (idx + length > size)
sPymbed 16:048e5e270a58 13025 return ASN_INPUT_E;
sPymbed 16:048e5e270a58 13026 end_index = idx + length;
sPymbed 16:048e5e270a58 13027
sPymbed 16:048e5e270a58 13028 if (DecodeResponseData(source, &idx, resp, size) < 0)
sPymbed 16:048e5e270a58 13029 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 13030
sPymbed 16:048e5e270a58 13031 /* Get the signature algorithm */
sPymbed 16:048e5e270a58 13032 if (GetAlgoId(source, &idx, &resp->sigOID, oidSigType, size) < 0)
sPymbed 16:048e5e270a58 13033 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 13034
sPymbed 16:048e5e270a58 13035 ret = CheckBitString(source, &idx, &sigLength, size, 1, NULL);
sPymbed 16:048e5e270a58 13036 if (ret != 0)
sPymbed 16:048e5e270a58 13037 return ret;
sPymbed 16:048e5e270a58 13038
sPymbed 16:048e5e270a58 13039 resp->sigSz = sigLength;
sPymbed 16:048e5e270a58 13040 resp->sig = source + idx;
sPymbed 16:048e5e270a58 13041 idx += sigLength;
sPymbed 16:048e5e270a58 13042
sPymbed 16:048e5e270a58 13043 /*
sPymbed 16:048e5e270a58 13044 * Check the length of the BasicOcspResponse against the current index to
sPymbed 16:048e5e270a58 13045 * see if there are certificates, they are optional.
sPymbed 16:048e5e270a58 13046 */
sPymbed 16:048e5e270a58 13047 #ifndef WOLFSSL_NO_OCSP_OPTIONAL_CERTS
sPymbed 16:048e5e270a58 13048 if (idx < end_index)
sPymbed 16:048e5e270a58 13049 {
sPymbed 16:048e5e270a58 13050 DecodedCert cert;
sPymbed 16:048e5e270a58 13051
sPymbed 16:048e5e270a58 13052 if (DecodeCerts(source, &idx, resp, size) < 0)
sPymbed 16:048e5e270a58 13053 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 13054
sPymbed 16:048e5e270a58 13055 InitDecodedCert(&cert, resp->cert, resp->certSz, heap);
sPymbed 16:048e5e270a58 13056
sPymbed 16:048e5e270a58 13057 /* Don't verify if we don't have access to Cert Manager. */
sPymbed 16:048e5e270a58 13058 ret = ParseCertRelative(&cert, CERT_TYPE,
sPymbed 16:048e5e270a58 13059 noVerify ? NO_VERIFY : VERIFY_OCSP, cm);
sPymbed 16:048e5e270a58 13060 if (ret < 0) {
sPymbed 16:048e5e270a58 13061 WOLFSSL_MSG("\tOCSP Responder certificate parsing failed");
sPymbed 16:048e5e270a58 13062 FreeDecodedCert(&cert);
sPymbed 16:048e5e270a58 13063 return ret;
sPymbed 16:048e5e270a58 13064 }
sPymbed 16:048e5e270a58 13065
sPymbed 16:048e5e270a58 13066 #ifndef WOLFSSL_NO_OCSP_ISSUER_CHECK
sPymbed 16:048e5e270a58 13067 if ((cert.extExtKeyUsage & EXTKEYUSE_OCSP_SIGN) == 0) {
sPymbed 16:048e5e270a58 13068 if (XMEMCMP(cert.subjectHash,
sPymbed 16:048e5e270a58 13069 resp->issuerHash, KEYID_SIZE) == 0) {
sPymbed 16:048e5e270a58 13070 WOLFSSL_MSG("\tOCSP Response signed by issuer");
sPymbed 16:048e5e270a58 13071 }
sPymbed 16:048e5e270a58 13072 else {
sPymbed 16:048e5e270a58 13073 WOLFSSL_MSG("\tOCSP Responder key usage check failed");
sPymbed 16:048e5e270a58 13074 #ifdef OPENSSL_EXTRA
sPymbed 16:048e5e270a58 13075 resp->verifyError = OCSP_BAD_ISSUER;
sPymbed 16:048e5e270a58 13076 #else
sPymbed 16:048e5e270a58 13077 FreeDecodedCert(&cert);
sPymbed 16:048e5e270a58 13078 return BAD_OCSP_RESPONDER;
sPymbed 16:048e5e270a58 13079 #endif
sPymbed 16:048e5e270a58 13080 }
sPymbed 16:048e5e270a58 13081 }
sPymbed 16:048e5e270a58 13082 #endif
sPymbed 16:048e5e270a58 13083
sPymbed 16:048e5e270a58 13084 /* ConfirmSignature is blocking here */
sPymbed 16:048e5e270a58 13085 ret = ConfirmSignature(&cert.sigCtx,
sPymbed 16:048e5e270a58 13086 resp->response, resp->responseSz,
sPymbed 16:048e5e270a58 13087 cert.publicKey, cert.pubKeySize, cert.keyOID,
sPymbed 16:048e5e270a58 13088 resp->sig, resp->sigSz, resp->sigOID);
sPymbed 16:048e5e270a58 13089 FreeDecodedCert(&cert);
sPymbed 16:048e5e270a58 13090
sPymbed 16:048e5e270a58 13091 if (ret != 0) {
sPymbed 16:048e5e270a58 13092 WOLFSSL_MSG("\tOCSP Confirm signature failed");
sPymbed 16:048e5e270a58 13093 return ASN_OCSP_CONFIRM_E;
sPymbed 16:048e5e270a58 13094 }
sPymbed 16:048e5e270a58 13095 }
sPymbed 16:048e5e270a58 13096 else
sPymbed 16:048e5e270a58 13097 #endif /* WOLFSSL_NO_OCSP_OPTIONAL_CERTS */
sPymbed 16:048e5e270a58 13098 {
sPymbed 16:048e5e270a58 13099 Signer* ca = NULL;
sPymbed 16:048e5e270a58 13100 int sigValid = -1;
sPymbed 16:048e5e270a58 13101
sPymbed 16:048e5e270a58 13102 #ifndef NO_SKID
sPymbed 16:048e5e270a58 13103 ca = GetCA(cm, resp->issuerKeyHash);
sPymbed 16:048e5e270a58 13104 #else
sPymbed 16:048e5e270a58 13105 ca = GetCA(cm, resp->issuerHash);
sPymbed 16:048e5e270a58 13106 #endif
sPymbed 16:048e5e270a58 13107
sPymbed 16:048e5e270a58 13108 if (ca) {
sPymbed 16:048e5e270a58 13109 SignatureCtx sigCtx;
sPymbed 16:048e5e270a58 13110 InitSignatureCtx(&sigCtx, heap, INVALID_DEVID);
sPymbed 16:048e5e270a58 13111
sPymbed 16:048e5e270a58 13112 /* ConfirmSignature is blocking here */
sPymbed 16:048e5e270a58 13113 sigValid = ConfirmSignature(&sigCtx, resp->response,
sPymbed 16:048e5e270a58 13114 resp->responseSz, ca->publicKey, ca->pubKeySize, ca->keyOID,
sPymbed 16:048e5e270a58 13115 resp->sig, resp->sigSz, resp->sigOID);
sPymbed 16:048e5e270a58 13116 }
sPymbed 16:048e5e270a58 13117 if (ca == NULL || sigValid != 0) {
sPymbed 16:048e5e270a58 13118 WOLFSSL_MSG("\tOCSP Confirm signature failed");
sPymbed 16:048e5e270a58 13119 return ASN_OCSP_CONFIRM_E;
sPymbed 16:048e5e270a58 13120 }
sPymbed 16:048e5e270a58 13121
sPymbed 16:048e5e270a58 13122 (void)noVerify;
sPymbed 16:048e5e270a58 13123 }
sPymbed 16:048e5e270a58 13124
sPymbed 16:048e5e270a58 13125 *ioIndex = idx;
sPymbed 16:048e5e270a58 13126 return 0;
sPymbed 16:048e5e270a58 13127 }
sPymbed 16:048e5e270a58 13128
sPymbed 16:048e5e270a58 13129
sPymbed 16:048e5e270a58 13130 void InitOcspResponse(OcspResponse* resp, CertStatus* status,
sPymbed 16:048e5e270a58 13131 byte* source, word32 inSz)
sPymbed 16:048e5e270a58 13132 {
sPymbed 16:048e5e270a58 13133 WOLFSSL_ENTER("InitOcspResponse");
sPymbed 16:048e5e270a58 13134
sPymbed 16:048e5e270a58 13135 XMEMSET(status, 0, sizeof(CertStatus));
sPymbed 16:048e5e270a58 13136 XMEMSET(resp, 0, sizeof(OcspResponse));
sPymbed 16:048e5e270a58 13137
sPymbed 16:048e5e270a58 13138 resp->responseStatus = -1;
sPymbed 16:048e5e270a58 13139 resp->status = status;
sPymbed 16:048e5e270a58 13140 resp->source = source;
sPymbed 16:048e5e270a58 13141 resp->maxIdx = inSz;
sPymbed 16:048e5e270a58 13142 }
sPymbed 16:048e5e270a58 13143
sPymbed 16:048e5e270a58 13144
sPymbed 16:048e5e270a58 13145 int OcspResponseDecode(OcspResponse* resp, void* cm, void* heap, int noVerify)
sPymbed 16:048e5e270a58 13146 {
sPymbed 16:048e5e270a58 13147 int ret;
sPymbed 16:048e5e270a58 13148 int length = 0;
sPymbed 16:048e5e270a58 13149 word32 idx = 0;
sPymbed 16:048e5e270a58 13150 byte* source = resp->source;
sPymbed 16:048e5e270a58 13151 word32 size = resp->maxIdx;
sPymbed 16:048e5e270a58 13152 word32 oid;
sPymbed 16:048e5e270a58 13153
sPymbed 16:048e5e270a58 13154 WOLFSSL_ENTER("OcspResponseDecode");
sPymbed 16:048e5e270a58 13155
sPymbed 16:048e5e270a58 13156 /* peel the outer SEQUENCE wrapper */
sPymbed 16:048e5e270a58 13157 if (GetSequence(source, &idx, &length, size) < 0)
sPymbed 16:048e5e270a58 13158 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 13159
sPymbed 16:048e5e270a58 13160 /* First get the responseStatus, an ENUMERATED */
sPymbed 16:048e5e270a58 13161 if (GetEnumerated(source, &idx, &resp->responseStatus) < 0)
sPymbed 16:048e5e270a58 13162 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 13163
sPymbed 16:048e5e270a58 13164 if (resp->responseStatus != OCSP_SUCCESSFUL)
sPymbed 16:048e5e270a58 13165 return 0;
sPymbed 16:048e5e270a58 13166
sPymbed 16:048e5e270a58 13167 /* Next is an EXPLICIT record called ResponseBytes, OPTIONAL */
sPymbed 16:048e5e270a58 13168 if (idx >= size)
sPymbed 16:048e5e270a58 13169 return ASN_INPUT_E;
sPymbed 16:048e5e270a58 13170 if (source[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC))
sPymbed 16:048e5e270a58 13171 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 13172 if (GetLength(source, &idx, &length, size) < 0)
sPymbed 16:048e5e270a58 13173 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 13174
sPymbed 16:048e5e270a58 13175 /* Get the responseBytes SEQUENCE */
sPymbed 16:048e5e270a58 13176 if (GetSequence(source, &idx, &length, size) < 0)
sPymbed 16:048e5e270a58 13177 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 13178
sPymbed 16:048e5e270a58 13179 /* Check ObjectID for the resposeBytes */
sPymbed 16:048e5e270a58 13180 if (GetObjectId(source, &idx, &oid, oidOcspType, size) < 0)
sPymbed 16:048e5e270a58 13181 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 13182 if (oid != OCSP_BASIC_OID)
sPymbed 16:048e5e270a58 13183 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 13184 ret = GetOctetString(source, &idx, &length, size);
sPymbed 16:048e5e270a58 13185 if (ret < 0)
sPymbed 16:048e5e270a58 13186 return ret;
sPymbed 16:048e5e270a58 13187
sPymbed 16:048e5e270a58 13188 ret = DecodeBasicOcspResponse(source, &idx, resp, size, cm, heap, noVerify);
sPymbed 16:048e5e270a58 13189 if (ret < 0)
sPymbed 16:048e5e270a58 13190 return ret;
sPymbed 16:048e5e270a58 13191
sPymbed 16:048e5e270a58 13192 return 0;
sPymbed 16:048e5e270a58 13193 }
sPymbed 16:048e5e270a58 13194
sPymbed 16:048e5e270a58 13195
sPymbed 16:048e5e270a58 13196 word32 EncodeOcspRequestExtensions(OcspRequest* req, byte* output, word32 size)
sPymbed 16:048e5e270a58 13197 {
sPymbed 16:048e5e270a58 13198 static const byte NonceObjId[] = { 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
sPymbed 16:048e5e270a58 13199 0x30, 0x01, 0x02 };
sPymbed 16:048e5e270a58 13200 byte seqArray[5][MAX_SEQ_SZ];
sPymbed 16:048e5e270a58 13201 word32 seqSz[5], totalSz = (word32)sizeof(NonceObjId);
sPymbed 16:048e5e270a58 13202
sPymbed 16:048e5e270a58 13203 WOLFSSL_ENTER("SetOcspReqExtensions");
sPymbed 16:048e5e270a58 13204
sPymbed 16:048e5e270a58 13205 if (!req || !output || !req->nonceSz)
sPymbed 16:048e5e270a58 13206 return 0;
sPymbed 16:048e5e270a58 13207
sPymbed 16:048e5e270a58 13208 totalSz += req->nonceSz;
sPymbed 16:048e5e270a58 13209 totalSz += seqSz[0] = SetOctetString(req->nonceSz, seqArray[0]);
sPymbed 16:048e5e270a58 13210 totalSz += seqSz[1] = SetOctetString(req->nonceSz + seqSz[0], seqArray[1]);
sPymbed 16:048e5e270a58 13211 totalSz += seqSz[2] = SetObjectId(sizeof(NonceObjId), seqArray[2]);
sPymbed 16:048e5e270a58 13212 totalSz += seqSz[3] = SetSequence(totalSz, seqArray[3]);
sPymbed 16:048e5e270a58 13213 totalSz += seqSz[4] = SetSequence(totalSz, seqArray[4]);
sPymbed 16:048e5e270a58 13214
sPymbed 16:048e5e270a58 13215 if (totalSz > size)
sPymbed 16:048e5e270a58 13216 return 0;
sPymbed 16:048e5e270a58 13217
sPymbed 16:048e5e270a58 13218 totalSz = 0;
sPymbed 16:048e5e270a58 13219
sPymbed 16:048e5e270a58 13220 XMEMCPY(output + totalSz, seqArray[4], seqSz[4]);
sPymbed 16:048e5e270a58 13221 totalSz += seqSz[4];
sPymbed 16:048e5e270a58 13222
sPymbed 16:048e5e270a58 13223 XMEMCPY(output + totalSz, seqArray[3], seqSz[3]);
sPymbed 16:048e5e270a58 13224 totalSz += seqSz[3];
sPymbed 16:048e5e270a58 13225
sPymbed 16:048e5e270a58 13226 XMEMCPY(output + totalSz, seqArray[2], seqSz[2]);
sPymbed 16:048e5e270a58 13227 totalSz += seqSz[2];
sPymbed 16:048e5e270a58 13228
sPymbed 16:048e5e270a58 13229 XMEMCPY(output + totalSz, NonceObjId, sizeof(NonceObjId));
sPymbed 16:048e5e270a58 13230 totalSz += (word32)sizeof(NonceObjId);
sPymbed 16:048e5e270a58 13231
sPymbed 16:048e5e270a58 13232 XMEMCPY(output + totalSz, seqArray[1], seqSz[1]);
sPymbed 16:048e5e270a58 13233 totalSz += seqSz[1];
sPymbed 16:048e5e270a58 13234
sPymbed 16:048e5e270a58 13235 XMEMCPY(output + totalSz, seqArray[0], seqSz[0]);
sPymbed 16:048e5e270a58 13236 totalSz += seqSz[0];
sPymbed 16:048e5e270a58 13237
sPymbed 16:048e5e270a58 13238 XMEMCPY(output + totalSz, req->nonce, req->nonceSz);
sPymbed 16:048e5e270a58 13239 totalSz += req->nonceSz;
sPymbed 16:048e5e270a58 13240
sPymbed 16:048e5e270a58 13241 return totalSz;
sPymbed 16:048e5e270a58 13242 }
sPymbed 16:048e5e270a58 13243
sPymbed 16:048e5e270a58 13244
sPymbed 16:048e5e270a58 13245 int EncodeOcspRequest(OcspRequest* req, byte* output, word32 size)
sPymbed 16:048e5e270a58 13246 {
sPymbed 16:048e5e270a58 13247 byte seqArray[5][MAX_SEQ_SZ];
sPymbed 16:048e5e270a58 13248 /* The ASN.1 of the OCSP Request is an onion of sequences */
sPymbed 16:048e5e270a58 13249 byte algoArray[MAX_ALGO_SZ];
sPymbed 16:048e5e270a58 13250 byte issuerArray[MAX_ENCODED_DIG_SZ];
sPymbed 16:048e5e270a58 13251 byte issuerKeyArray[MAX_ENCODED_DIG_SZ];
sPymbed 16:048e5e270a58 13252 byte snArray[MAX_SN_SZ];
sPymbed 16:048e5e270a58 13253 byte extArray[MAX_OCSP_EXT_SZ];
sPymbed 16:048e5e270a58 13254 word32 seqSz[5], algoSz, issuerSz, issuerKeySz, extSz, totalSz;
sPymbed 16:048e5e270a58 13255 int i, snSz;
sPymbed 16:048e5e270a58 13256
sPymbed 16:048e5e270a58 13257 WOLFSSL_ENTER("EncodeOcspRequest");
sPymbed 16:048e5e270a58 13258
sPymbed 16:048e5e270a58 13259 #ifdef NO_SHA
sPymbed 16:048e5e270a58 13260 algoSz = SetAlgoID(SHA256h, algoArray, oidHashType, 0);
sPymbed 16:048e5e270a58 13261 #else
sPymbed 16:048e5e270a58 13262 algoSz = SetAlgoID(SHAh, algoArray, oidHashType, 0);
sPymbed 16:048e5e270a58 13263 #endif
sPymbed 16:048e5e270a58 13264
sPymbed 16:048e5e270a58 13265 issuerSz = SetDigest(req->issuerHash, KEYID_SIZE, issuerArray);
sPymbed 16:048e5e270a58 13266 issuerKeySz = SetDigest(req->issuerKeyHash, KEYID_SIZE, issuerKeyArray);
sPymbed 16:048e5e270a58 13267 snSz = SetSerialNumber(req->serial, req->serialSz, snArray, MAX_SN_SZ);
sPymbed 16:048e5e270a58 13268 extSz = 0;
sPymbed 16:048e5e270a58 13269
sPymbed 16:048e5e270a58 13270 if (snSz < 0)
sPymbed 16:048e5e270a58 13271 return snSz;
sPymbed 16:048e5e270a58 13272
sPymbed 16:048e5e270a58 13273 if (req->nonceSz) {
sPymbed 16:048e5e270a58 13274 /* TLS Extensions use this function too - put extensions after
sPymbed 16:048e5e270a58 13275 * ASN.1: Context Specific [2].
sPymbed 16:048e5e270a58 13276 */
sPymbed 16:048e5e270a58 13277 extSz = EncodeOcspRequestExtensions(req, extArray + 2,
sPymbed 16:048e5e270a58 13278 OCSP_NONCE_EXT_SZ);
sPymbed 16:048e5e270a58 13279 extSz += SetExplicit(2, extSz, extArray);
sPymbed 16:048e5e270a58 13280 }
sPymbed 16:048e5e270a58 13281
sPymbed 16:048e5e270a58 13282 totalSz = algoSz + issuerSz + issuerKeySz + snSz;
sPymbed 16:048e5e270a58 13283 for (i = 4; i >= 0; i--) {
sPymbed 16:048e5e270a58 13284 seqSz[i] = SetSequence(totalSz, seqArray[i]);
sPymbed 16:048e5e270a58 13285 totalSz += seqSz[i];
sPymbed 16:048e5e270a58 13286 if (i == 2) totalSz += extSz;
sPymbed 16:048e5e270a58 13287 }
sPymbed 16:048e5e270a58 13288
sPymbed 16:048e5e270a58 13289 if (output == NULL)
sPymbed 16:048e5e270a58 13290 return totalSz;
sPymbed 16:048e5e270a58 13291 if (totalSz > size)
sPymbed 16:048e5e270a58 13292 return BUFFER_E;
sPymbed 16:048e5e270a58 13293
sPymbed 16:048e5e270a58 13294 totalSz = 0;
sPymbed 16:048e5e270a58 13295 for (i = 0; i < 5; i++) {
sPymbed 16:048e5e270a58 13296 XMEMCPY(output + totalSz, seqArray[i], seqSz[i]);
sPymbed 16:048e5e270a58 13297 totalSz += seqSz[i];
sPymbed 16:048e5e270a58 13298 }
sPymbed 16:048e5e270a58 13299
sPymbed 16:048e5e270a58 13300 XMEMCPY(output + totalSz, algoArray, algoSz);
sPymbed 16:048e5e270a58 13301 totalSz += algoSz;
sPymbed 16:048e5e270a58 13302
sPymbed 16:048e5e270a58 13303 XMEMCPY(output + totalSz, issuerArray, issuerSz);
sPymbed 16:048e5e270a58 13304 totalSz += issuerSz;
sPymbed 16:048e5e270a58 13305
sPymbed 16:048e5e270a58 13306 XMEMCPY(output + totalSz, issuerKeyArray, issuerKeySz);
sPymbed 16:048e5e270a58 13307 totalSz += issuerKeySz;
sPymbed 16:048e5e270a58 13308
sPymbed 16:048e5e270a58 13309 XMEMCPY(output + totalSz, snArray, snSz);
sPymbed 16:048e5e270a58 13310 totalSz += snSz;
sPymbed 16:048e5e270a58 13311
sPymbed 16:048e5e270a58 13312 if (extSz != 0) {
sPymbed 16:048e5e270a58 13313 XMEMCPY(output + totalSz, extArray, extSz);
sPymbed 16:048e5e270a58 13314 totalSz += extSz;
sPymbed 16:048e5e270a58 13315 }
sPymbed 16:048e5e270a58 13316
sPymbed 16:048e5e270a58 13317 return totalSz;
sPymbed 16:048e5e270a58 13318 }
sPymbed 16:048e5e270a58 13319
sPymbed 16:048e5e270a58 13320
sPymbed 16:048e5e270a58 13321 int InitOcspRequest(OcspRequest* req, DecodedCert* cert, byte useNonce,
sPymbed 16:048e5e270a58 13322 void* heap)
sPymbed 16:048e5e270a58 13323 {
sPymbed 16:048e5e270a58 13324 int ret;
sPymbed 16:048e5e270a58 13325
sPymbed 16:048e5e270a58 13326 WOLFSSL_ENTER("InitOcspRequest");
sPymbed 16:048e5e270a58 13327
sPymbed 16:048e5e270a58 13328 if (req == NULL)
sPymbed 16:048e5e270a58 13329 return BAD_FUNC_ARG;
sPymbed 16:048e5e270a58 13330
sPymbed 16:048e5e270a58 13331 ForceZero(req, sizeof(OcspRequest));
sPymbed 16:048e5e270a58 13332 req->heap = heap;
sPymbed 16:048e5e270a58 13333
sPymbed 16:048e5e270a58 13334 if (cert) {
sPymbed 16:048e5e270a58 13335 XMEMCPY(req->issuerHash, cert->issuerHash, KEYID_SIZE);
sPymbed 16:048e5e270a58 13336 XMEMCPY(req->issuerKeyHash, cert->issuerKeyHash, KEYID_SIZE);
sPymbed 16:048e5e270a58 13337
sPymbed 16:048e5e270a58 13338 req->serial = (byte*)XMALLOC(cert->serialSz, req->heap,
sPymbed 16:048e5e270a58 13339 DYNAMIC_TYPE_OCSP_REQUEST);
sPymbed 16:048e5e270a58 13340 if (req->serial == NULL)
sPymbed 16:048e5e270a58 13341 return MEMORY_E;
sPymbed 16:048e5e270a58 13342
sPymbed 16:048e5e270a58 13343 XMEMCPY(req->serial, cert->serial, cert->serialSz);
sPymbed 16:048e5e270a58 13344 req->serialSz = cert->serialSz;
sPymbed 16:048e5e270a58 13345
sPymbed 16:048e5e270a58 13346 if (cert->extAuthInfoSz != 0 && cert->extAuthInfo != NULL) {
sPymbed 16:048e5e270a58 13347 req->url = (byte*)XMALLOC(cert->extAuthInfoSz, req->heap,
sPymbed 16:048e5e270a58 13348 DYNAMIC_TYPE_OCSP_REQUEST);
sPymbed 16:048e5e270a58 13349 if (req->url == NULL) {
sPymbed 16:048e5e270a58 13350 XFREE(req->serial, req->heap, DYNAMIC_TYPE_OCSP);
sPymbed 16:048e5e270a58 13351 return MEMORY_E;
sPymbed 16:048e5e270a58 13352 }
sPymbed 16:048e5e270a58 13353
sPymbed 16:048e5e270a58 13354 XMEMCPY(req->url, cert->extAuthInfo, cert->extAuthInfoSz);
sPymbed 16:048e5e270a58 13355 req->urlSz = cert->extAuthInfoSz;
sPymbed 16:048e5e270a58 13356 }
sPymbed 16:048e5e270a58 13357 }
sPymbed 16:048e5e270a58 13358
sPymbed 16:048e5e270a58 13359 if (useNonce) {
sPymbed 16:048e5e270a58 13360 WC_RNG rng;
sPymbed 16:048e5e270a58 13361
sPymbed 16:048e5e270a58 13362 #ifndef HAVE_FIPS
sPymbed 16:048e5e270a58 13363 ret = wc_InitRng_ex(&rng, req->heap, INVALID_DEVID);
sPymbed 16:048e5e270a58 13364 #else
sPymbed 16:048e5e270a58 13365 ret = wc_InitRng(&rng);
sPymbed 16:048e5e270a58 13366 #endif
sPymbed 16:048e5e270a58 13367 if (ret != 0) {
sPymbed 16:048e5e270a58 13368 WOLFSSL_MSG("\tCannot initialize RNG. Skipping the OSCP Nonce.");
sPymbed 16:048e5e270a58 13369 } else {
sPymbed 16:048e5e270a58 13370 if (wc_RNG_GenerateBlock(&rng, req->nonce, MAX_OCSP_NONCE_SZ) != 0)
sPymbed 16:048e5e270a58 13371 WOLFSSL_MSG("\tCannot run RNG. Skipping the OSCP Nonce.");
sPymbed 16:048e5e270a58 13372 else
sPymbed 16:048e5e270a58 13373 req->nonceSz = MAX_OCSP_NONCE_SZ;
sPymbed 16:048e5e270a58 13374
sPymbed 16:048e5e270a58 13375 wc_FreeRng(&rng);
sPymbed 16:048e5e270a58 13376 }
sPymbed 16:048e5e270a58 13377 }
sPymbed 16:048e5e270a58 13378
sPymbed 16:048e5e270a58 13379 return 0;
sPymbed 16:048e5e270a58 13380 }
sPymbed 16:048e5e270a58 13381
sPymbed 16:048e5e270a58 13382 void FreeOcspRequest(OcspRequest* req)
sPymbed 16:048e5e270a58 13383 {
sPymbed 16:048e5e270a58 13384 WOLFSSL_ENTER("FreeOcspRequest");
sPymbed 16:048e5e270a58 13385
sPymbed 16:048e5e270a58 13386 if (req) {
sPymbed 16:048e5e270a58 13387 if (req->serial)
sPymbed 16:048e5e270a58 13388 XFREE(req->serial, req->heap, DYNAMIC_TYPE_OCSP_REQUEST);
sPymbed 16:048e5e270a58 13389
sPymbed 16:048e5e270a58 13390 if (req->url)
sPymbed 16:048e5e270a58 13391 XFREE(req->url, req->heap, DYNAMIC_TYPE_OCSP_REQUEST);
sPymbed 16:048e5e270a58 13392 }
sPymbed 16:048e5e270a58 13393 }
sPymbed 16:048e5e270a58 13394
sPymbed 16:048e5e270a58 13395
sPymbed 16:048e5e270a58 13396 int CompareOcspReqResp(OcspRequest* req, OcspResponse* resp)
sPymbed 16:048e5e270a58 13397 {
sPymbed 16:048e5e270a58 13398 int cmp;
sPymbed 16:048e5e270a58 13399
sPymbed 16:048e5e270a58 13400 WOLFSSL_ENTER("CompareOcspReqResp");
sPymbed 16:048e5e270a58 13401
sPymbed 16:048e5e270a58 13402 if (req == NULL)
sPymbed 16:048e5e270a58 13403 {
sPymbed 16:048e5e270a58 13404 WOLFSSL_MSG("\tReq missing");
sPymbed 16:048e5e270a58 13405 return -1;
sPymbed 16:048e5e270a58 13406 }
sPymbed 16:048e5e270a58 13407
sPymbed 16:048e5e270a58 13408 if (resp == NULL)
sPymbed 16:048e5e270a58 13409 {
sPymbed 16:048e5e270a58 13410 WOLFSSL_MSG("\tResp missing");
sPymbed 16:048e5e270a58 13411 return 1;
sPymbed 16:048e5e270a58 13412 }
sPymbed 16:048e5e270a58 13413
sPymbed 16:048e5e270a58 13414 /* Nonces are not critical. The responder may not necessarily add
sPymbed 16:048e5e270a58 13415 * the nonce to the response. */
sPymbed 16:048e5e270a58 13416 if (resp->nonceSz != 0) {
sPymbed 16:048e5e270a58 13417 cmp = req->nonceSz - resp->nonceSz;
sPymbed 16:048e5e270a58 13418 if (cmp != 0)
sPymbed 16:048e5e270a58 13419 {
sPymbed 16:048e5e270a58 13420 WOLFSSL_MSG("\tnonceSz mismatch");
sPymbed 16:048e5e270a58 13421 return cmp;
sPymbed 16:048e5e270a58 13422 }
sPymbed 16:048e5e270a58 13423
sPymbed 16:048e5e270a58 13424 cmp = XMEMCMP(req->nonce, resp->nonce, req->nonceSz);
sPymbed 16:048e5e270a58 13425 if (cmp != 0)
sPymbed 16:048e5e270a58 13426 {
sPymbed 16:048e5e270a58 13427 WOLFSSL_MSG("\tnonce mismatch");
sPymbed 16:048e5e270a58 13428 return cmp;
sPymbed 16:048e5e270a58 13429 }
sPymbed 16:048e5e270a58 13430 }
sPymbed 16:048e5e270a58 13431
sPymbed 16:048e5e270a58 13432 cmp = XMEMCMP(req->issuerHash, resp->issuerHash, KEYID_SIZE);
sPymbed 16:048e5e270a58 13433 if (cmp != 0)
sPymbed 16:048e5e270a58 13434 {
sPymbed 16:048e5e270a58 13435 WOLFSSL_MSG("\tissuerHash mismatch");
sPymbed 16:048e5e270a58 13436 return cmp;
sPymbed 16:048e5e270a58 13437 }
sPymbed 16:048e5e270a58 13438
sPymbed 16:048e5e270a58 13439 cmp = XMEMCMP(req->issuerKeyHash, resp->issuerKeyHash, KEYID_SIZE);
sPymbed 16:048e5e270a58 13440 if (cmp != 0)
sPymbed 16:048e5e270a58 13441 {
sPymbed 16:048e5e270a58 13442 WOLFSSL_MSG("\tissuerKeyHash mismatch");
sPymbed 16:048e5e270a58 13443 return cmp;
sPymbed 16:048e5e270a58 13444 }
sPymbed 16:048e5e270a58 13445
sPymbed 16:048e5e270a58 13446 cmp = req->serialSz - resp->status->serialSz;
sPymbed 16:048e5e270a58 13447 if (cmp != 0)
sPymbed 16:048e5e270a58 13448 {
sPymbed 16:048e5e270a58 13449 WOLFSSL_MSG("\tserialSz mismatch");
sPymbed 16:048e5e270a58 13450 return cmp;
sPymbed 16:048e5e270a58 13451 }
sPymbed 16:048e5e270a58 13452
sPymbed 16:048e5e270a58 13453 cmp = XMEMCMP(req->serial, resp->status->serial, req->serialSz);
sPymbed 16:048e5e270a58 13454 if (cmp != 0)
sPymbed 16:048e5e270a58 13455 {
sPymbed 16:048e5e270a58 13456 WOLFSSL_MSG("\tserial mismatch");
sPymbed 16:048e5e270a58 13457 return cmp;
sPymbed 16:048e5e270a58 13458 }
sPymbed 16:048e5e270a58 13459
sPymbed 16:048e5e270a58 13460 return 0;
sPymbed 16:048e5e270a58 13461 }
sPymbed 16:048e5e270a58 13462
sPymbed 16:048e5e270a58 13463 #endif
sPymbed 16:048e5e270a58 13464
sPymbed 16:048e5e270a58 13465
sPymbed 16:048e5e270a58 13466 /* store WC_SHA hash of NAME */
sPymbed 16:048e5e270a58 13467 WOLFSSL_LOCAL int GetNameHash(const byte* source, word32* idx, byte* hash,
sPymbed 16:048e5e270a58 13468 int maxIdx)
sPymbed 16:048e5e270a58 13469 {
sPymbed 16:048e5e270a58 13470 int length; /* length of all distinguished names */
sPymbed 16:048e5e270a58 13471 int ret;
sPymbed 16:048e5e270a58 13472 word32 dummy;
sPymbed 16:048e5e270a58 13473
sPymbed 16:048e5e270a58 13474 WOLFSSL_ENTER("GetNameHash");
sPymbed 16:048e5e270a58 13475
sPymbed 16:048e5e270a58 13476 if (source[*idx] == ASN_OBJECT_ID) {
sPymbed 16:048e5e270a58 13477 WOLFSSL_MSG("Trying optional prefix...");
sPymbed 16:048e5e270a58 13478
sPymbed 16:048e5e270a58 13479 if (GetLength(source, idx, &length, maxIdx) < 0)
sPymbed 16:048e5e270a58 13480 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 13481
sPymbed 16:048e5e270a58 13482 *idx += length;
sPymbed 16:048e5e270a58 13483 WOLFSSL_MSG("Got optional prefix");
sPymbed 16:048e5e270a58 13484 }
sPymbed 16:048e5e270a58 13485
sPymbed 16:048e5e270a58 13486 /* For OCSP, RFC2560 section 4.1.1 states the issuer hash should be
sPymbed 16:048e5e270a58 13487 * calculated over the entire DER encoding of the Name field, including
sPymbed 16:048e5e270a58 13488 * the tag and length. */
sPymbed 16:048e5e270a58 13489 dummy = *idx;
sPymbed 16:048e5e270a58 13490 if (GetSequence(source, idx, &length, maxIdx) < 0)
sPymbed 16:048e5e270a58 13491 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 13492
sPymbed 16:048e5e270a58 13493 #ifdef NO_SHA
sPymbed 16:048e5e270a58 13494 ret = wc_Sha256Hash(source + dummy, length + *idx - dummy, hash);
sPymbed 16:048e5e270a58 13495 #else
sPymbed 16:048e5e270a58 13496 ret = wc_ShaHash(source + dummy, length + *idx - dummy, hash);
sPymbed 16:048e5e270a58 13497 #endif
sPymbed 16:048e5e270a58 13498
sPymbed 16:048e5e270a58 13499 *idx += length;
sPymbed 16:048e5e270a58 13500
sPymbed 16:048e5e270a58 13501 return ret;
sPymbed 16:048e5e270a58 13502 }
sPymbed 16:048e5e270a58 13503
sPymbed 16:048e5e270a58 13504
sPymbed 16:048e5e270a58 13505 #ifdef HAVE_CRL
sPymbed 16:048e5e270a58 13506
sPymbed 16:048e5e270a58 13507 /* initialize decoded CRL */
sPymbed 16:048e5e270a58 13508 void InitDecodedCRL(DecodedCRL* dcrl, void* heap)
sPymbed 16:048e5e270a58 13509 {
sPymbed 16:048e5e270a58 13510 WOLFSSL_MSG("InitDecodedCRL");
sPymbed 16:048e5e270a58 13511
sPymbed 16:048e5e270a58 13512 dcrl->certBegin = 0;
sPymbed 16:048e5e270a58 13513 dcrl->sigIndex = 0;
sPymbed 16:048e5e270a58 13514 dcrl->sigLength = 0;
sPymbed 16:048e5e270a58 13515 dcrl->signatureOID = 0;
sPymbed 16:048e5e270a58 13516 dcrl->certs = NULL;
sPymbed 16:048e5e270a58 13517 dcrl->totalCerts = 0;
sPymbed 16:048e5e270a58 13518 dcrl->heap = heap;
sPymbed 16:048e5e270a58 13519 #ifdef WOLFSSL_HEAP_TEST
sPymbed 16:048e5e270a58 13520 dcrl->heap = (void*)WOLFSSL_HEAP_TEST;
sPymbed 16:048e5e270a58 13521 #endif
sPymbed 16:048e5e270a58 13522 }
sPymbed 16:048e5e270a58 13523
sPymbed 16:048e5e270a58 13524
sPymbed 16:048e5e270a58 13525 /* free decoded CRL resources */
sPymbed 16:048e5e270a58 13526 void FreeDecodedCRL(DecodedCRL* dcrl)
sPymbed 16:048e5e270a58 13527 {
sPymbed 16:048e5e270a58 13528 RevokedCert* tmp = dcrl->certs;
sPymbed 16:048e5e270a58 13529
sPymbed 16:048e5e270a58 13530 WOLFSSL_MSG("FreeDecodedCRL");
sPymbed 16:048e5e270a58 13531
sPymbed 16:048e5e270a58 13532 while(tmp) {
sPymbed 16:048e5e270a58 13533 RevokedCert* next = tmp->next;
sPymbed 16:048e5e270a58 13534 XFREE(tmp, dcrl->heap, DYNAMIC_TYPE_REVOKED);
sPymbed 16:048e5e270a58 13535 tmp = next;
sPymbed 16:048e5e270a58 13536 }
sPymbed 16:048e5e270a58 13537 }
sPymbed 16:048e5e270a58 13538
sPymbed 16:048e5e270a58 13539
sPymbed 16:048e5e270a58 13540 /* Get Revoked Cert list, 0 on success */
sPymbed 16:048e5e270a58 13541 static int GetRevoked(const byte* buff, word32* idx, DecodedCRL* dcrl,
sPymbed 16:048e5e270a58 13542 int maxIdx)
sPymbed 16:048e5e270a58 13543 {
sPymbed 16:048e5e270a58 13544 int ret, len;
sPymbed 16:048e5e270a58 13545 word32 end;
sPymbed 16:048e5e270a58 13546 byte b;
sPymbed 16:048e5e270a58 13547 RevokedCert* rc;
sPymbed 16:048e5e270a58 13548
sPymbed 16:048e5e270a58 13549 WOLFSSL_ENTER("GetRevoked");
sPymbed 16:048e5e270a58 13550
sPymbed 16:048e5e270a58 13551 if (GetSequence(buff, idx, &len, maxIdx) < 0)
sPymbed 16:048e5e270a58 13552 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 13553
sPymbed 16:048e5e270a58 13554 end = *idx + len;
sPymbed 16:048e5e270a58 13555
sPymbed 16:048e5e270a58 13556 rc = (RevokedCert*)XMALLOC(sizeof(RevokedCert), dcrl->heap,
sPymbed 16:048e5e270a58 13557 DYNAMIC_TYPE_REVOKED);
sPymbed 16:048e5e270a58 13558 if (rc == NULL) {
sPymbed 16:048e5e270a58 13559 WOLFSSL_MSG("Alloc Revoked Cert failed");
sPymbed 16:048e5e270a58 13560 return MEMORY_E;
sPymbed 16:048e5e270a58 13561 }
sPymbed 16:048e5e270a58 13562
sPymbed 16:048e5e270a58 13563 if (GetSerialNumber(buff, idx, rc->serialNumber, &rc->serialSz,
sPymbed 16:048e5e270a58 13564 maxIdx) < 0) {
sPymbed 16:048e5e270a58 13565 XFREE(rc, dcrl->heap, DYNAMIC_TYPE_REVOKED);
sPymbed 16:048e5e270a58 13566 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 13567 }
sPymbed 16:048e5e270a58 13568
sPymbed 16:048e5e270a58 13569 /* add to list */
sPymbed 16:048e5e270a58 13570 rc->next = dcrl->certs;
sPymbed 16:048e5e270a58 13571 dcrl->certs = rc;
sPymbed 16:048e5e270a58 13572 dcrl->totalCerts++;
sPymbed 16:048e5e270a58 13573
sPymbed 16:048e5e270a58 13574 /* get date */
sPymbed 16:048e5e270a58 13575 ret = GetDateInfo(buff, idx, NULL, &b, NULL, maxIdx);
sPymbed 16:048e5e270a58 13576 if (ret < 0) {
sPymbed 16:048e5e270a58 13577 WOLFSSL_MSG("Expecting Date");
sPymbed 16:048e5e270a58 13578 return ret;
sPymbed 16:048e5e270a58 13579 }
sPymbed 16:048e5e270a58 13580
sPymbed 16:048e5e270a58 13581 if (*idx != end) /* skip extensions */
sPymbed 16:048e5e270a58 13582 *idx = end;
sPymbed 16:048e5e270a58 13583
sPymbed 16:048e5e270a58 13584 return 0;
sPymbed 16:048e5e270a58 13585 }
sPymbed 16:048e5e270a58 13586
sPymbed 16:048e5e270a58 13587
sPymbed 16:048e5e270a58 13588 /* Get CRL Signature, 0 on success */
sPymbed 16:048e5e270a58 13589 static int GetCRL_Signature(const byte* source, word32* idx, DecodedCRL* dcrl,
sPymbed 16:048e5e270a58 13590 int maxIdx)
sPymbed 16:048e5e270a58 13591 {
sPymbed 16:048e5e270a58 13592 int length;
sPymbed 16:048e5e270a58 13593 int ret;
sPymbed 16:048e5e270a58 13594
sPymbed 16:048e5e270a58 13595 WOLFSSL_ENTER("GetCRL_Signature");
sPymbed 16:048e5e270a58 13596
sPymbed 16:048e5e270a58 13597 ret = CheckBitString(source, idx, &length, maxIdx, 1, NULL);
sPymbed 16:048e5e270a58 13598 if (ret != 0)
sPymbed 16:048e5e270a58 13599 return ret;
sPymbed 16:048e5e270a58 13600 dcrl->sigLength = length;
sPymbed 16:048e5e270a58 13601
sPymbed 16:048e5e270a58 13602 dcrl->signature = (byte*)&source[*idx];
sPymbed 16:048e5e270a58 13603 *idx += dcrl->sigLength;
sPymbed 16:048e5e270a58 13604
sPymbed 16:048e5e270a58 13605 return 0;
sPymbed 16:048e5e270a58 13606 }
sPymbed 16:048e5e270a58 13607
sPymbed 16:048e5e270a58 13608 int VerifyCRL_Signature(SignatureCtx* sigCtx, const byte* toBeSigned,
sPymbed 16:048e5e270a58 13609 word32 tbsSz, const byte* signature, word32 sigSz,
sPymbed 16:048e5e270a58 13610 word32 signatureOID, Signer *ca, void* heap)
sPymbed 16:048e5e270a58 13611 {
sPymbed 16:048e5e270a58 13612 /* try to confirm/verify signature */
sPymbed 16:048e5e270a58 13613 #ifndef IGNORE_KEY_EXTENSIONS
sPymbed 16:048e5e270a58 13614 if ((ca->keyUsage & KEYUSE_CRL_SIGN) == 0) {
sPymbed 16:048e5e270a58 13615 WOLFSSL_MSG("CA cannot sign CRLs");
sPymbed 16:048e5e270a58 13616 return ASN_CRL_NO_SIGNER_E;
sPymbed 16:048e5e270a58 13617 }
sPymbed 16:048e5e270a58 13618 #endif /* IGNORE_KEY_EXTENSIONS */
sPymbed 16:048e5e270a58 13619
sPymbed 16:048e5e270a58 13620 InitSignatureCtx(sigCtx, heap, INVALID_DEVID);
sPymbed 16:048e5e270a58 13621 if (ConfirmSignature(sigCtx, toBeSigned, tbsSz, ca->publicKey,
sPymbed 16:048e5e270a58 13622 ca->pubKeySize, ca->keyOID, signature, sigSz,
sPymbed 16:048e5e270a58 13623 signatureOID) != 0) {
sPymbed 16:048e5e270a58 13624 WOLFSSL_MSG("CRL Confirm signature failed");
sPymbed 16:048e5e270a58 13625 return ASN_CRL_CONFIRM_E;
sPymbed 16:048e5e270a58 13626 }
sPymbed 16:048e5e270a58 13627
sPymbed 16:048e5e270a58 13628 return 0;
sPymbed 16:048e5e270a58 13629 }
sPymbed 16:048e5e270a58 13630
sPymbed 16:048e5e270a58 13631 /* prase crl buffer into decoded state, 0 on success */
sPymbed 16:048e5e270a58 13632 int ParseCRL(DecodedCRL* dcrl, const byte* buff, word32 sz, void* cm)
sPymbed 16:048e5e270a58 13633 {
sPymbed 16:048e5e270a58 13634 int version, len, doNextDate = 1;
sPymbed 16:048e5e270a58 13635 word32 oid, idx = 0, dateIdx;
sPymbed 16:048e5e270a58 13636 Signer* ca = NULL;
sPymbed 16:048e5e270a58 13637 SignatureCtx sigCtx;
sPymbed 16:048e5e270a58 13638
sPymbed 16:048e5e270a58 13639 WOLFSSL_MSG("ParseCRL");
sPymbed 16:048e5e270a58 13640
sPymbed 16:048e5e270a58 13641 /* raw crl hash */
sPymbed 16:048e5e270a58 13642 /* hash here if needed for optimized comparisons
sPymbed 16:048e5e270a58 13643 * wc_Sha sha;
sPymbed 16:048e5e270a58 13644 * wc_InitSha(&sha);
sPymbed 16:048e5e270a58 13645 * wc_ShaUpdate(&sha, buff, sz);
sPymbed 16:048e5e270a58 13646 * wc_ShaFinal(&sha, dcrl->crlHash); */
sPymbed 16:048e5e270a58 13647
sPymbed 16:048e5e270a58 13648 if (GetSequence(buff, &idx, &len, sz) < 0)
sPymbed 16:048e5e270a58 13649 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 13650
sPymbed 16:048e5e270a58 13651 dcrl->certBegin = idx;
sPymbed 16:048e5e270a58 13652
sPymbed 16:048e5e270a58 13653 if (GetSequence(buff, &idx, &len, sz) < 0)
sPymbed 16:048e5e270a58 13654 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 13655 dcrl->sigIndex = len + idx;
sPymbed 16:048e5e270a58 13656
sPymbed 16:048e5e270a58 13657 /* may have version */
sPymbed 16:048e5e270a58 13658 if (buff[idx] == ASN_INTEGER) {
sPymbed 16:048e5e270a58 13659 if (GetMyVersion(buff, &idx, &version, sz) < 0)
sPymbed 16:048e5e270a58 13660 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 13661 }
sPymbed 16:048e5e270a58 13662
sPymbed 16:048e5e270a58 13663 if (GetAlgoId(buff, &idx, &oid, oidIgnoreType, sz) < 0)
sPymbed 16:048e5e270a58 13664 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 13665
sPymbed 16:048e5e270a58 13666 if (GetNameHash(buff, &idx, dcrl->issuerHash, sz) < 0)
sPymbed 16:048e5e270a58 13667 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 13668
sPymbed 16:048e5e270a58 13669 if (GetBasicDate(buff, &idx, dcrl->lastDate, &dcrl->lastDateFormat, sz) < 0)
sPymbed 16:048e5e270a58 13670 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 13671
sPymbed 16:048e5e270a58 13672 dateIdx = idx;
sPymbed 16:048e5e270a58 13673
sPymbed 16:048e5e270a58 13674 if (GetBasicDate(buff, &idx, dcrl->nextDate, &dcrl->nextDateFormat, sz) < 0)
sPymbed 16:048e5e270a58 13675 {
sPymbed 16:048e5e270a58 13676 #ifndef WOLFSSL_NO_CRL_NEXT_DATE
sPymbed 16:048e5e270a58 13677 (void)dateIdx;
sPymbed 16:048e5e270a58 13678 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 13679 #else
sPymbed 16:048e5e270a58 13680 dcrl->nextDateFormat = ASN_OTHER_TYPE; /* skip flag */
sPymbed 16:048e5e270a58 13681 doNextDate = 0;
sPymbed 16:048e5e270a58 13682 idx = dateIdx;
sPymbed 16:048e5e270a58 13683 #endif
sPymbed 16:048e5e270a58 13684 }
sPymbed 16:048e5e270a58 13685
sPymbed 16:048e5e270a58 13686 if (doNextDate) {
sPymbed 16:048e5e270a58 13687 #ifndef NO_ASN_TIME
sPymbed 16:048e5e270a58 13688 if (!XVALIDATE_DATE(dcrl->nextDate, dcrl->nextDateFormat, AFTER)) {
sPymbed 16:048e5e270a58 13689 WOLFSSL_MSG("CRL after date is no longer valid");
sPymbed 16:048e5e270a58 13690 return ASN_AFTER_DATE_E;
sPymbed 16:048e5e270a58 13691 }
sPymbed 16:048e5e270a58 13692 #endif
sPymbed 16:048e5e270a58 13693 }
sPymbed 16:048e5e270a58 13694
sPymbed 16:048e5e270a58 13695 if (idx != dcrl->sigIndex && buff[idx] != CRL_EXTENSIONS) {
sPymbed 16:048e5e270a58 13696 if (GetSequence(buff, &idx, &len, sz) < 0)
sPymbed 16:048e5e270a58 13697 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 13698
sPymbed 16:048e5e270a58 13699 len += idx;
sPymbed 16:048e5e270a58 13700
sPymbed 16:048e5e270a58 13701 while (idx < (word32)len) {
sPymbed 16:048e5e270a58 13702 if (GetRevoked(buff, &idx, dcrl, sz) < 0)
sPymbed 16:048e5e270a58 13703 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 13704 }
sPymbed 16:048e5e270a58 13705 }
sPymbed 16:048e5e270a58 13706
sPymbed 16:048e5e270a58 13707 if (idx != dcrl->sigIndex)
sPymbed 16:048e5e270a58 13708 idx = dcrl->sigIndex; /* skip extensions */
sPymbed 16:048e5e270a58 13709
sPymbed 16:048e5e270a58 13710 if (GetAlgoId(buff, &idx, &dcrl->signatureOID, oidSigType, sz) < 0)
sPymbed 16:048e5e270a58 13711 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 13712
sPymbed 16:048e5e270a58 13713 if (GetCRL_Signature(buff, &idx, dcrl, sz) < 0)
sPymbed 16:048e5e270a58 13714 return ASN_PARSE_E;
sPymbed 16:048e5e270a58 13715
sPymbed 16:048e5e270a58 13716 /* openssl doesn't add skid by default for CRLs cause firefox chokes
sPymbed 16:048e5e270a58 13717 we're not assuming it's available yet */
sPymbed 16:048e5e270a58 13718 #if !defined(NO_SKID) && defined(CRL_SKID_READY)
sPymbed 16:048e5e270a58 13719 if (dcrl->extAuthKeyIdSet)
sPymbed 16:048e5e270a58 13720 ca = GetCA(cm, dcrl->extAuthKeyId);
sPymbed 16:048e5e270a58 13721 if (ca == NULL)
sPymbed 16:048e5e270a58 13722 ca = GetCAByName(cm, dcrl->issuerHash);
sPymbed 16:048e5e270a58 13723 #else
sPymbed 16:048e5e270a58 13724 ca = GetCA(cm, dcrl->issuerHash);
sPymbed 16:048e5e270a58 13725 #endif /* !NO_SKID && CRL_SKID_READY */
sPymbed 16:048e5e270a58 13726 WOLFSSL_MSG("About to verify CRL signature");
sPymbed 16:048e5e270a58 13727
sPymbed 16:048e5e270a58 13728 if (ca == NULL) {
sPymbed 16:048e5e270a58 13729 WOLFSSL_MSG("Did NOT find CRL issuer CA");
sPymbed 16:048e5e270a58 13730 return ASN_CRL_NO_SIGNER_E;
sPymbed 16:048e5e270a58 13731 }
sPymbed 16:048e5e270a58 13732
sPymbed 16:048e5e270a58 13733 WOLFSSL_MSG("Found CRL issuer CA");
sPymbed 16:048e5e270a58 13734 return VerifyCRL_Signature(&sigCtx, buff + dcrl->certBegin,
sPymbed 16:048e5e270a58 13735 dcrl->sigIndex - dcrl->certBegin, dcrl->signature, dcrl->sigLength,
sPymbed 16:048e5e270a58 13736 dcrl->signatureOID, ca, dcrl->heap);
sPymbed 16:048e5e270a58 13737 }
sPymbed 16:048e5e270a58 13738
sPymbed 16:048e5e270a58 13739 #endif /* HAVE_CRL */
sPymbed 16:048e5e270a58 13740
sPymbed 16:048e5e270a58 13741 #undef ERROR_OUT
sPymbed 16:048e5e270a58 13742
sPymbed 16:048e5e270a58 13743 #endif /* !NO_ASN */
sPymbed 16:048e5e270a58 13744
sPymbed 16:048e5e270a58 13745 #ifdef WOLFSSL_SEP
sPymbed 16:048e5e270a58 13746
sPymbed 16:048e5e270a58 13747
sPymbed 16:048e5e270a58 13748 #endif /* WOLFSSL_SEP */
sPymbed 16:048e5e270a58 13749