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 !parse_key_type(&algorithm, &type) || 104 !CBS_get_asn1(&spki, &key, CBS_ASN1_BITSTRING) || 105 CBS_len(&spki) != 0 || 106 // Every key type defined encodes the key as a byte string with the same 107 // conversion to BIT STRING. 108 !CBS_get_u8(&key, &padding) || 109 padding != 0) { 110 OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); 111 return NULL; 112 } 113 114 // Set up an |EVP_PKEY| of the appropriate type. 115 EVP_PKEY *ret = EVP_PKEY_new(); 116 if (ret == NULL || 117 !EVP_PKEY_set_type(ret, type)) { 118 goto err; 119 } 120 121 // Call into the type-specific SPKI decoding function. 122 if (ret->ameth->pub_decode == NULL) { 123 OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); 124 goto err; 125 } 126 if (!ret->ameth->pub_decode(ret, &algorithm, &key)) { 127 goto err; 128 } 129 130 return ret; 131 132 err: 133 EVP_PKEY_free(ret); 134 return NULL; 135 } 136 137 int EVP_marshal_public_key(CBB *cbb, const EVP_PKEY *key) { 138 if (key->ameth == NULL || key->ameth->pub_encode == NULL) { 139 OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); 140 return 0; 141 } 142 143 return key->ameth->pub_encode(cbb, key); 144 } 145 146 EVP_PKEY *EVP_parse_private_key(CBS *cbs) { 147 // Parse the PrivateKeyInfo. 148 CBS pkcs8, algorithm, key; 149 uint64_t version; 150 int type; 151 if (!CBS_get_asn1(cbs, &pkcs8, CBS_ASN1_SEQUENCE) || 152 !CBS_get_asn1_uint64(&pkcs8, &version) || 153 version != 0 || 154 !CBS_get_asn1(&pkcs8, &algorithm, CBS_ASN1_SEQUENCE) || 155 !parse_key_type(&algorithm, &type) || 156 !CBS_get_asn1(&pkcs8, &key, CBS_ASN1_OCTETSTRING)) { 157 OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); 158 return NULL; 159 } 160 161 // A PrivateKeyInfo ends with a SET of Attributes which we ignore. 162 163 // Set up an |EVP_PKEY| of the appropriate type. 164 EVP_PKEY *ret = EVP_PKEY_new(); 165 if (ret == NULL || 166 !EVP_PKEY_set_type(ret, type)) { 167 goto err; 168 } 169 170 // Call into the type-specific PrivateKeyInfo decoding function. 171 if (ret->ameth->priv_decode == NULL) { 172 OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); 173 goto err; 174 } 175 if (!ret->ameth->priv_decode(ret, &algorithm, &key)) { 176 goto err; 177 } 178 179 return ret; 180 181 err: 182 EVP_PKEY_free(ret); 183 return NULL; 184 } 185 186 int EVP_marshal_private_key(CBB *cbb, const EVP_PKEY *key) { 187 if (key->ameth == NULL || key->ameth->priv_encode == NULL) { 188 OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); 189 return 0; 190 } 191 192 return key->ameth->priv_encode(cbb, key); 193 } 194 195 static EVP_PKEY *old_priv_decode(CBS *cbs, int type) { 196 EVP_PKEY *ret = EVP_PKEY_new(); 197 if (ret == NULL) { 198 return NULL; 199 } 200 201 switch (type) { 202 case EVP_PKEY_EC: { 203 EC_KEY *ec_key = EC_KEY_parse_private_key(cbs, NULL); 204 if (ec_key == NULL || !EVP_PKEY_assign_EC_KEY(ret, ec_key)) { 205 EC_KEY_free(ec_key); 206 goto err; 207 } 208 return ret; 209 } 210 case EVP_PKEY_DSA: { 211 DSA *dsa = DSA_parse_private_key(cbs); 212 if (dsa == NULL || !EVP_PKEY_assign_DSA(ret, dsa)) { 213 DSA_free(dsa); 214 goto err; 215 } 216 return ret; 217 } 218 case EVP_PKEY_RSA: { 219 RSA *rsa = RSA_parse_private_key(cbs); 220 if (rsa == NULL || !EVP_PKEY_assign_RSA(ret, rsa)) { 221 RSA_free(rsa); 222 goto err; 223 } 224 return ret; 225 } 226 default: 227 OPENSSL_PUT_ERROR(EVP, EVP_R_UNKNOWN_PUBLIC_KEY_TYPE); 228 goto err; 229 } 230 231 err: 232 EVP_PKEY_free(ret); 233 return NULL; 234 } 235 236 EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **out, const uint8_t **inp, 237 long len) { 238 if (len < 0) { 239 OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); 240 return NULL; 241 } 242 243 // Parse with the legacy format. 244 CBS cbs; 245 CBS_init(&cbs, *inp, (size_t)len); 246 EVP_PKEY *ret = old_priv_decode(&cbs, type); 247 if (ret == NULL) { 248 // Try again with PKCS#8. 249 ERR_clear_error(); 250 CBS_init(&cbs, *inp, (size_t)len); 251 ret = EVP_parse_private_key(&cbs); 252 if (ret == NULL) { 253 return NULL; 254 } 255 if (ret->type != type) { 256 OPENSSL_PUT_ERROR(EVP, EVP_R_DIFFERENT_KEY_TYPES); 257 EVP_PKEY_free(ret); 258 return NULL; 259 } 260 } 261 262 if (out != NULL) { 263 EVP_PKEY_free(*out); 264 *out = ret; 265 } 266 *inp = CBS_data(&cbs); 267 return ret; 268 } 269 270 // num_elements parses one SEQUENCE from |in| and returns the number of elements 271 // in it. On parse error, it returns zero. 272 static size_t num_elements(const uint8_t *in, size_t in_len) { 273 CBS cbs, sequence; 274 CBS_init(&cbs, in, (size_t)in_len); 275 276 if (!CBS_get_asn1(&cbs, &sequence, CBS_ASN1_SEQUENCE)) { 277 return 0; 278 } 279 280 size_t count = 0; 281 while (CBS_len(&sequence) > 0) { 282 if (!CBS_get_any_asn1_element(&sequence, NULL, NULL, NULL)) { 283 return 0; 284 } 285 286 count++; 287 } 288 289 return count; 290 } 291 292 EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **out, const uint8_t **inp, long len) { 293 if (len < 0) { 294 OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); 295 return NULL; 296 } 297 298 // Parse the input as a PKCS#8 PrivateKeyInfo. 299 CBS cbs; 300 CBS_init(&cbs, *inp, (size_t)len); 301 EVP_PKEY *ret = EVP_parse_private_key(&cbs); 302 if (ret != NULL) { 303 if (out != NULL) { 304 EVP_PKEY_free(*out); 305 *out = ret; 306 } 307 *inp = CBS_data(&cbs); 308 return ret; 309 } 310 ERR_clear_error(); 311 312 // Count the elements to determine the legacy key format. 313 switch (num_elements(*inp, (size_t)len)) { 314 case 4: 315 return d2i_PrivateKey(EVP_PKEY_EC, out, inp, len); 316 317 case 6: 318 return d2i_PrivateKey(EVP_PKEY_DSA, out, inp, len); 319 320 default: 321 return d2i_PrivateKey(EVP_PKEY_RSA, out, inp, len); 322 } 323 } 324 325 int i2d_PublicKey(EVP_PKEY *key, uint8_t **outp) { 326 switch (key->type) { 327 case EVP_PKEY_RSA: 328 return i2d_RSAPublicKey(key->pkey.rsa, outp); 329 case EVP_PKEY_DSA: 330 return i2d_DSAPublicKey(key->pkey.dsa, outp); 331 case EVP_PKEY_EC: 332 return i2o_ECPublicKey(key->pkey.ec, outp); 333 default: 334 OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_PUBLIC_KEY_TYPE); 335 return -1; 336 } 337 } 338