1 /* Copyright (C) 1995-1998 Eric Young (eay (at) cryptsoft.com) 2 * All rights reserved. 3 * 4 * This package is an SSL implementation written 5 * by Eric Young (eay (at) cryptsoft.com). 6 * The implementation was written so as to conform with Netscapes SSL. 7 * 8 * This library is free for commercial and non-commercial use as long as 9 * the following conditions are aheared to. The following conditions 10 * apply to all code found in this distribution, be it the RC4, RSA, 11 * lhash, DES, etc., code; not just the SSL code. The SSL documentation 12 * included with this distribution is covered by the same copyright terms 13 * except that the holder is Tim Hudson (tjh (at) cryptsoft.com). 14 * 15 * Copyright remains Eric Young's, and as such any Copyright notices in 16 * the code are not to be removed. 17 * If this package is used in a product, Eric Young should be given attribution 18 * as the author of the parts of the library used. 19 * This can be in the form of a textual message at program startup or 20 * in documentation (online or textual) provided with the package. 21 * 22 * Redistribution and use in source and binary forms, with or without 23 * modification, are permitted provided that the following conditions 24 * are met: 25 * 1. Redistributions of source code must retain the copyright 26 * notice, this list of conditions and the following disclaimer. 27 * 2. Redistributions in binary form must reproduce the above copyright 28 * notice, this list of conditions and the following disclaimer in the 29 * documentation and/or other materials provided with the distribution. 30 * 3. All advertising materials mentioning features or use of this software 31 * must display the following acknowledgement: 32 * "This product includes cryptographic software written by 33 * Eric Young (eay (at) cryptsoft.com)" 34 * The word 'cryptographic' can be left out if the rouines from the library 35 * being used are not cryptographic related :-). 36 * 4. If you include any Windows specific code (or a derivative thereof) from 37 * the apps directory (application code) you must include an acknowledgement: 38 * "This product includes software written by Tim Hudson (tjh (at) cryptsoft.com)" 39 * 40 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 41 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 43 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 44 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 45 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 46 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 48 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 49 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 50 * SUCH DAMAGE. 51 * 52 * The licence and distribution terms for any publically available version or 53 * derivative of this code cannot be changed. i.e. this code cannot simply be 54 * copied and put under another distribution licence 55 * [including the GNU Public Licence.] */ 56 57 #include <openssl/evp.h> 58 59 #include <string.h> 60 61 #include <openssl/bytestring.h> 62 #include <openssl/dsa.h> 63 #include <openssl/ec_key.h> 64 #include <openssl/err.h> 65 #include <openssl/rsa.h> 66 67 #include "internal.h" 68 #include "../internal.h" 69 70 71 static const EVP_PKEY_ASN1_METHOD *const kASN1Methods[] = { 72 &rsa_asn1_meth, 73 &ec_asn1_meth, 74 &dsa_asn1_meth, 75 &ed25519_asn1_meth, 76 }; 77 78 static int parse_key_type(CBS *cbs, int *out_type) { 79 CBS oid; 80 if (!CBS_get_asn1(cbs, &oid, CBS_ASN1_OBJECT)) { 81 return 0; 82 } 83 84 for (unsigned i = 0; i < OPENSSL_ARRAY_SIZE(kASN1Methods); i++) { 85 const EVP_PKEY_ASN1_METHOD *method = kASN1Methods[i]; 86 if (CBS_len(&oid) == method->oid_len && 87 OPENSSL_memcmp(CBS_data(&oid), method->oid, method->oid_len) == 0) { 88 *out_type = method->pkey_id; 89 return 1; 90 } 91 } 92 93 return 0; 94 } 95 96 EVP_PKEY *EVP_parse_public_key(CBS *cbs) { 97 // Parse the SubjectPublicKeyInfo. 98 CBS spki, algorithm, key; 99 int type; 100 uint8_t padding; 101 if (!CBS_get_asn1(cbs, &spki, CBS_ASN1_SEQUENCE) || 102 !CBS_get_asn1(&spki, &algorithm, CBS_ASN1_SEQUENCE) || 103 !CBS_get_asn1(&spki, &key, CBS_ASN1_BITSTRING) || 104 CBS_len(&spki) != 0) { 105 OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); 106 return NULL; 107 } 108 if (!parse_key_type(&algorithm, &type)) { 109 OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); 110 return NULL; 111 } 112 if (// Every key type defined encodes the key as a byte string with the same 113 // conversion to BIT STRING. 114 !CBS_get_u8(&key, &padding) || 115 padding != 0) { 116 OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); 117 return NULL; 118 } 119 120 // Set up an |EVP_PKEY| of the appropriate type. 121 EVP_PKEY *ret = EVP_PKEY_new(); 122 if (ret == NULL || 123 !EVP_PKEY_set_type(ret, type)) { 124 goto err; 125 } 126 127 // Call into the type-specific SPKI decoding function. 128 if (ret->ameth->pub_decode == NULL) { 129 OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); 130 goto err; 131 } 132 if (!ret->ameth->pub_decode(ret, &algorithm, &key)) { 133 goto err; 134 } 135 136 return ret; 137 138 err: 139 EVP_PKEY_free(ret); 140 return NULL; 141 } 142 143 int EVP_marshal_public_key(CBB *cbb, const EVP_PKEY *key) { 144 if (key->ameth == NULL || key->ameth->pub_encode == NULL) { 145 OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); 146 return 0; 147 } 148 149 return key->ameth->pub_encode(cbb, key); 150 } 151 152 EVP_PKEY *EVP_parse_private_key(CBS *cbs) { 153 // Parse the PrivateKeyInfo. 154 CBS pkcs8, algorithm, key; 155 uint64_t version; 156 int type; 157 if (!CBS_get_asn1(cbs, &pkcs8, CBS_ASN1_SEQUENCE) || 158 !CBS_get_asn1_uint64(&pkcs8, &version) || 159 version != 0 || 160 !CBS_get_asn1(&pkcs8, &algorithm, CBS_ASN1_SEQUENCE) || 161 !CBS_get_asn1(&pkcs8, &key, CBS_ASN1_OCTETSTRING)) { 162 OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); 163 return NULL; 164 } 165 if (!parse_key_type(&algorithm, &type)) { 166 OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); 167 return NULL; 168 } 169 170 // A PrivateKeyInfo ends with a SET of Attributes which we ignore. 171 172 // Set up an |EVP_PKEY| of the appropriate type. 173 EVP_PKEY *ret = EVP_PKEY_new(); 174 if (ret == NULL || 175 !EVP_PKEY_set_type(ret, type)) { 176 goto err; 177 } 178 179 // Call into the type-specific PrivateKeyInfo decoding function. 180 if (ret->ameth->priv_decode == NULL) { 181 OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); 182 goto err; 183 } 184 if (!ret->ameth->priv_decode(ret, &algorithm, &key)) { 185 goto err; 186 } 187 188 return ret; 189 190 err: 191 EVP_PKEY_free(ret); 192 return NULL; 193 } 194 195 int EVP_marshal_private_key(CBB *cbb, const EVP_PKEY *key) { 196 if (key->ameth == NULL || key->ameth->priv_encode == NULL) { 197 OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); 198 return 0; 199 } 200 201 return key->ameth->priv_encode(cbb, key); 202 } 203 204 static EVP_PKEY *old_priv_decode(CBS *cbs, int type) { 205 EVP_PKEY *ret = EVP_PKEY_new(); 206 if (ret == NULL) { 207 return NULL; 208 } 209 210 switch (type) { 211 case EVP_PKEY_EC: { 212 EC_KEY *ec_key = EC_KEY_parse_private_key(cbs, NULL); 213 if (ec_key == NULL || !EVP_PKEY_assign_EC_KEY(ret, ec_key)) { 214 EC_KEY_free(ec_key); 215 goto err; 216 } 217 return ret; 218 } 219 case EVP_PKEY_DSA: { 220 DSA *dsa = DSA_parse_private_key(cbs); 221 if (dsa == NULL || !EVP_PKEY_assign_DSA(ret, dsa)) { 222 DSA_free(dsa); 223 goto err; 224 } 225 return ret; 226 } 227 case EVP_PKEY_RSA: { 228 RSA *rsa = RSA_parse_private_key(cbs); 229 if (rsa == NULL || !EVP_PKEY_assign_RSA(ret, rsa)) { 230 RSA_free(rsa); 231 goto err; 232 } 233 return ret; 234 } 235 default: 236 OPENSSL_PUT_ERROR(EVP, EVP_R_UNKNOWN_PUBLIC_KEY_TYPE); 237 goto err; 238 } 239 240 err: 241 EVP_PKEY_free(ret); 242 return NULL; 243 } 244 245 EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **out, const uint8_t **inp, 246 long len) { 247 if (len < 0) { 248 OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); 249 return NULL; 250 } 251 252 // Parse with the legacy format. 253 CBS cbs; 254 CBS_init(&cbs, *inp, (size_t)len); 255 EVP_PKEY *ret = old_priv_decode(&cbs, type); 256 if (ret == NULL) { 257 // Try again with PKCS#8. 258 ERR_clear_error(); 259 CBS_init(&cbs, *inp, (size_t)len); 260 ret = EVP_parse_private_key(&cbs); 261 if (ret == NULL) { 262 return NULL; 263 } 264 if (ret->type != type) { 265 OPENSSL_PUT_ERROR(EVP, EVP_R_DIFFERENT_KEY_TYPES); 266 EVP_PKEY_free(ret); 267 return NULL; 268 } 269 } 270 271 if (out != NULL) { 272 EVP_PKEY_free(*out); 273 *out = ret; 274 } 275 *inp = CBS_data(&cbs); 276 return ret; 277 } 278 279 // num_elements parses one SEQUENCE from |in| and returns the number of elements 280 // in it. On parse error, it returns zero. 281 static size_t num_elements(const uint8_t *in, size_t in_len) { 282 CBS cbs, sequence; 283 CBS_init(&cbs, in, (size_t)in_len); 284 285 if (!CBS_get_asn1(&cbs, &sequence, CBS_ASN1_SEQUENCE)) { 286 return 0; 287 } 288 289 size_t count = 0; 290 while (CBS_len(&sequence) > 0) { 291 if (!CBS_get_any_asn1_element(&sequence, NULL, NULL, NULL)) { 292 return 0; 293 } 294 295 count++; 296 } 297 298 return count; 299 } 300 301 EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **out, const uint8_t **inp, long len) { 302 if (len < 0) { 303 OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); 304 return NULL; 305 } 306 307 // Parse the input as a PKCS#8 PrivateKeyInfo. 308 CBS cbs; 309 CBS_init(&cbs, *inp, (size_t)len); 310 EVP_PKEY *ret = EVP_parse_private_key(&cbs); 311 if (ret != NULL) { 312 if (out != NULL) { 313 EVP_PKEY_free(*out); 314 *out = ret; 315 } 316 *inp = CBS_data(&cbs); 317 return ret; 318 } 319 ERR_clear_error(); 320 321 // Count the elements to determine the legacy key format. 322 switch (num_elements(*inp, (size_t)len)) { 323 case 4: 324 return d2i_PrivateKey(EVP_PKEY_EC, out, inp, len); 325 326 case 6: 327 return d2i_PrivateKey(EVP_PKEY_DSA, out, inp, len); 328 329 default: 330 return d2i_PrivateKey(EVP_PKEY_RSA, out, inp, len); 331 } 332 } 333 334 int i2d_PublicKey(const EVP_PKEY *key, uint8_t **outp) { 335 switch (key->type) { 336 case EVP_PKEY_RSA: 337 return i2d_RSAPublicKey(key->pkey.rsa, outp); 338 case EVP_PKEY_DSA: 339 return i2d_DSAPublicKey(key->pkey.dsa, outp); 340 case EVP_PKEY_EC: 341 return i2o_ECPublicKey(key->pkey.ec, outp); 342 default: 343 OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_PUBLIC_KEY_TYPE); 344 return -1; 345 } 346 } 347 348 EVP_PKEY *d2i_PublicKey(int type, EVP_PKEY **out, const uint8_t **inp, 349 long len) { 350 EVP_PKEY *ret = EVP_PKEY_new(); 351 if (ret == NULL) { 352 return NULL; 353 } 354 355 CBS cbs; 356 CBS_init(&cbs, *inp, len < 0 ? 0 : (size_t)len); 357 switch (type) { 358 case EVP_PKEY_RSA: { 359 RSA *rsa = RSA_parse_public_key(&cbs); 360 if (rsa == NULL || !EVP_PKEY_assign_RSA(ret, rsa)) { 361 RSA_free(rsa); 362 goto err; 363 } 364 break; 365 } 366 367 // Unlike OpenSSL, we do not support EC keys with this API. The raw EC 368 // public key serialization requires knowing the group. In OpenSSL, calling 369 // this function with |EVP_PKEY_EC| and setting |out| to NULL does not work. 370 // It requires |*out| to include a partially-initiazed |EVP_PKEY| to extract 371 // the group. 372 default: 373 OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_PUBLIC_KEY_TYPE); 374 goto err; 375 } 376 377 *inp = CBS_data(&cbs); 378 if (out != NULL) { 379 EVP_PKEY_free(*out); 380 *out = ret; 381 } 382 return ret; 383 384 err: 385 EVP_PKEY_free(ret); 386 return NULL; 387 } 388