1 /* 2 * Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the OpenSSL license (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10 #include "e_os.h" /* for strncasecmp */ 11 #include "internal/cryptlib.h" 12 #include <stdio.h> 13 #include <openssl/asn1t.h> 14 #include <openssl/x509.h> 15 #include <openssl/engine.h> 16 #include "internal/asn1_int.h" 17 #include "internal/evp_int.h" 18 19 #include "standard_methods.h" 20 21 typedef int sk_cmp_fn_type(const char *const *a, const char *const *b); 22 static STACK_OF(EVP_PKEY_ASN1_METHOD) *app_methods = NULL; 23 24 DECLARE_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_ASN1_METHOD *, 25 const EVP_PKEY_ASN1_METHOD *, ameth); 26 27 static int ameth_cmp(const EVP_PKEY_ASN1_METHOD *const *a, 28 const EVP_PKEY_ASN1_METHOD *const *b) 29 { 30 return ((*a)->pkey_id - (*b)->pkey_id); 31 } 32 33 IMPLEMENT_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_ASN1_METHOD *, 34 const EVP_PKEY_ASN1_METHOD *, ameth); 35 36 int EVP_PKEY_asn1_get_count(void) 37 { 38 int num = OSSL_NELEM(standard_methods); 39 if (app_methods) 40 num += sk_EVP_PKEY_ASN1_METHOD_num(app_methods); 41 return num; 42 } 43 44 const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_get0(int idx) 45 { 46 int num = OSSL_NELEM(standard_methods); 47 if (idx < 0) 48 return NULL; 49 if (idx < num) 50 return standard_methods[idx]; 51 idx -= num; 52 return sk_EVP_PKEY_ASN1_METHOD_value(app_methods, idx); 53 } 54 55 static const EVP_PKEY_ASN1_METHOD *pkey_asn1_find(int type) 56 { 57 EVP_PKEY_ASN1_METHOD tmp; 58 const EVP_PKEY_ASN1_METHOD *t = &tmp, **ret; 59 tmp.pkey_id = type; 60 if (app_methods) { 61 int idx; 62 idx = sk_EVP_PKEY_ASN1_METHOD_find(app_methods, &tmp); 63 if (idx >= 0) 64 return sk_EVP_PKEY_ASN1_METHOD_value(app_methods, idx); 65 } 66 ret = OBJ_bsearch_ameth(&t, standard_methods, OSSL_NELEM(standard_methods)); 67 if (!ret || !*ret) 68 return NULL; 69 return *ret; 70 } 71 72 /* 73 * Find an implementation of an ASN1 algorithm. If 'pe' is not NULL also 74 * search through engines and set *pe to a functional reference to the engine 75 * implementing 'type' or NULL if no engine implements it. 76 */ 77 78 const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pe, int type) 79 { 80 const EVP_PKEY_ASN1_METHOD *t; 81 82 for (;;) { 83 t = pkey_asn1_find(type); 84 if (!t || !(t->pkey_flags & ASN1_PKEY_ALIAS)) 85 break; 86 type = t->pkey_base_id; 87 } 88 if (pe) { 89 #ifndef OPENSSL_NO_ENGINE 90 ENGINE *e; 91 /* type will contain the final unaliased type */ 92 e = ENGINE_get_pkey_asn1_meth_engine(type); 93 if (e) { 94 *pe = e; 95 return ENGINE_get_pkey_asn1_meth(e, type); 96 } 97 #endif 98 *pe = NULL; 99 } 100 return t; 101 } 102 103 const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pe, 104 const char *str, int len) 105 { 106 int i; 107 const EVP_PKEY_ASN1_METHOD *ameth = NULL; 108 109 if (len == -1) 110 len = strlen(str); 111 if (pe) { 112 #ifndef OPENSSL_NO_ENGINE 113 ENGINE *e; 114 ameth = ENGINE_pkey_asn1_find_str(&e, str, len); 115 if (ameth) { 116 /* 117 * Convert structural into functional reference 118 */ 119 if (!ENGINE_init(e)) 120 ameth = NULL; 121 ENGINE_free(e); 122 *pe = e; 123 return ameth; 124 } 125 #endif 126 *pe = NULL; 127 } 128 for (i = EVP_PKEY_asn1_get_count(); i-- > 0; ) { 129 ameth = EVP_PKEY_asn1_get0(i); 130 if (ameth->pkey_flags & ASN1_PKEY_ALIAS) 131 continue; 132 if ((int)strlen(ameth->pem_str) == len 133 && strncasecmp(ameth->pem_str, str, len) == 0) 134 return ameth; 135 } 136 return NULL; 137 } 138 139 int EVP_PKEY_asn1_add0(const EVP_PKEY_ASN1_METHOD *ameth) 140 { 141 EVP_PKEY_ASN1_METHOD tmp = { 0, }; 142 143 /* 144 * One of the following must be true: 145 * 146 * pem_str == NULL AND ASN1_PKEY_ALIAS is set 147 * pem_str != NULL AND ASN1_PKEY_ALIAS is clear 148 * 149 * Anything else is an error and may lead to a corrupt ASN1 method table 150 */ 151 if (!((ameth->pem_str == NULL 152 && (ameth->pkey_flags & ASN1_PKEY_ALIAS) != 0) 153 || (ameth->pem_str != NULL 154 && (ameth->pkey_flags & ASN1_PKEY_ALIAS) == 0))) { 155 EVPerr(EVP_F_EVP_PKEY_ASN1_ADD0, ERR_R_PASSED_INVALID_ARGUMENT); 156 return 0; 157 } 158 159 if (app_methods == NULL) { 160 app_methods = sk_EVP_PKEY_ASN1_METHOD_new(ameth_cmp); 161 if (app_methods == NULL) 162 return 0; 163 } 164 165 tmp.pkey_id = ameth->pkey_id; 166 if (sk_EVP_PKEY_ASN1_METHOD_find(app_methods, &tmp) >= 0) { 167 EVPerr(EVP_F_EVP_PKEY_ASN1_ADD0, 168 EVP_R_PKEY_APPLICATION_ASN1_METHOD_ALREADY_REGISTERED); 169 return 0; 170 } 171 172 if (!sk_EVP_PKEY_ASN1_METHOD_push(app_methods, ameth)) 173 return 0; 174 sk_EVP_PKEY_ASN1_METHOD_sort(app_methods); 175 return 1; 176 } 177 178 int EVP_PKEY_asn1_add_alias(int to, int from) 179 { 180 EVP_PKEY_ASN1_METHOD *ameth; 181 ameth = EVP_PKEY_asn1_new(from, ASN1_PKEY_ALIAS, NULL, NULL); 182 if (ameth == NULL) 183 return 0; 184 ameth->pkey_base_id = to; 185 if (!EVP_PKEY_asn1_add0(ameth)) { 186 EVP_PKEY_asn1_free(ameth); 187 return 0; 188 } 189 return 1; 190 } 191 192 int EVP_PKEY_asn1_get0_info(int *ppkey_id, int *ppkey_base_id, 193 int *ppkey_flags, const char **pinfo, 194 const char **ppem_str, 195 const EVP_PKEY_ASN1_METHOD *ameth) 196 { 197 if (!ameth) 198 return 0; 199 if (ppkey_id) 200 *ppkey_id = ameth->pkey_id; 201 if (ppkey_base_id) 202 *ppkey_base_id = ameth->pkey_base_id; 203 if (ppkey_flags) 204 *ppkey_flags = ameth->pkey_flags; 205 if (pinfo) 206 *pinfo = ameth->info; 207 if (ppem_str) 208 *ppem_str = ameth->pem_str; 209 return 1; 210 } 211 212 const EVP_PKEY_ASN1_METHOD *EVP_PKEY_get0_asn1(const EVP_PKEY *pkey) 213 { 214 return pkey->ameth; 215 } 216 217 EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_new(int id, int flags, 218 const char *pem_str, const char *info) 219 { 220 EVP_PKEY_ASN1_METHOD *ameth = OPENSSL_zalloc(sizeof(*ameth)); 221 222 if (ameth == NULL) 223 return NULL; 224 225 ameth->pkey_id = id; 226 ameth->pkey_base_id = id; 227 ameth->pkey_flags = flags | ASN1_PKEY_DYNAMIC; 228 229 if (info) { 230 ameth->info = OPENSSL_strdup(info); 231 if (!ameth->info) 232 goto err; 233 } 234 235 if (pem_str) { 236 ameth->pem_str = OPENSSL_strdup(pem_str); 237 if (!ameth->pem_str) 238 goto err; 239 } 240 241 return ameth; 242 243 err: 244 EVP_PKEY_asn1_free(ameth); 245 return NULL; 246 247 } 248 249 void EVP_PKEY_asn1_copy(EVP_PKEY_ASN1_METHOD *dst, 250 const EVP_PKEY_ASN1_METHOD *src) 251 { 252 253 dst->pub_decode = src->pub_decode; 254 dst->pub_encode = src->pub_encode; 255 dst->pub_cmp = src->pub_cmp; 256 dst->pub_print = src->pub_print; 257 258 dst->priv_decode = src->priv_decode; 259 dst->priv_encode = src->priv_encode; 260 dst->priv_print = src->priv_print; 261 262 dst->old_priv_encode = src->old_priv_encode; 263 dst->old_priv_decode = src->old_priv_decode; 264 265 dst->pkey_size = src->pkey_size; 266 dst->pkey_bits = src->pkey_bits; 267 268 dst->param_decode = src->param_decode; 269 dst->param_encode = src->param_encode; 270 dst->param_missing = src->param_missing; 271 dst->param_copy = src->param_copy; 272 dst->param_cmp = src->param_cmp; 273 dst->param_print = src->param_print; 274 275 dst->pkey_free = src->pkey_free; 276 dst->pkey_ctrl = src->pkey_ctrl; 277 278 dst->item_sign = src->item_sign; 279 dst->item_verify = src->item_verify; 280 281 dst->siginf_set = src->siginf_set; 282 283 dst->pkey_check = src->pkey_check; 284 285 } 286 287 void EVP_PKEY_asn1_free(EVP_PKEY_ASN1_METHOD *ameth) 288 { 289 if (ameth && (ameth->pkey_flags & ASN1_PKEY_DYNAMIC)) { 290 OPENSSL_free(ameth->pem_str); 291 OPENSSL_free(ameth->info); 292 OPENSSL_free(ameth); 293 } 294 } 295 296 void EVP_PKEY_asn1_set_public(EVP_PKEY_ASN1_METHOD *ameth, 297 int (*pub_decode) (EVP_PKEY *pk, 298 X509_PUBKEY *pub), 299 int (*pub_encode) (X509_PUBKEY *pub, 300 const EVP_PKEY *pk), 301 int (*pub_cmp) (const EVP_PKEY *a, 302 const EVP_PKEY *b), 303 int (*pub_print) (BIO *out, 304 const EVP_PKEY *pkey, 305 int indent, ASN1_PCTX *pctx), 306 int (*pkey_size) (const EVP_PKEY *pk), 307 int (*pkey_bits) (const EVP_PKEY *pk)) 308 { 309 ameth->pub_decode = pub_decode; 310 ameth->pub_encode = pub_encode; 311 ameth->pub_cmp = pub_cmp; 312 ameth->pub_print = pub_print; 313 ameth->pkey_size = pkey_size; 314 ameth->pkey_bits = pkey_bits; 315 } 316 317 void EVP_PKEY_asn1_set_private(EVP_PKEY_ASN1_METHOD *ameth, 318 int (*priv_decode) (EVP_PKEY *pk, 319 const PKCS8_PRIV_KEY_INFO 320 *p8inf), 321 int (*priv_encode) (PKCS8_PRIV_KEY_INFO *p8, 322 const EVP_PKEY *pk), 323 int (*priv_print) (BIO *out, 324 const EVP_PKEY *pkey, 325 int indent, 326 ASN1_PCTX *pctx)) 327 { 328 ameth->priv_decode = priv_decode; 329 ameth->priv_encode = priv_encode; 330 ameth->priv_print = priv_print; 331 } 332 333 void EVP_PKEY_asn1_set_param(EVP_PKEY_ASN1_METHOD *ameth, 334 int (*param_decode) (EVP_PKEY *pkey, 335 const unsigned char **pder, 336 int derlen), 337 int (*param_encode) (const EVP_PKEY *pkey, 338 unsigned char **pder), 339 int (*param_missing) (const EVP_PKEY *pk), 340 int (*param_copy) (EVP_PKEY *to, 341 const EVP_PKEY *from), 342 int (*param_cmp) (const EVP_PKEY *a, 343 const EVP_PKEY *b), 344 int (*param_print) (BIO *out, 345 const EVP_PKEY *pkey, 346 int indent, ASN1_PCTX *pctx)) 347 { 348 ameth->param_decode = param_decode; 349 ameth->param_encode = param_encode; 350 ameth->param_missing = param_missing; 351 ameth->param_copy = param_copy; 352 ameth->param_cmp = param_cmp; 353 ameth->param_print = param_print; 354 } 355 356 void EVP_PKEY_asn1_set_free(EVP_PKEY_ASN1_METHOD *ameth, 357 void (*pkey_free) (EVP_PKEY *pkey)) 358 { 359 ameth->pkey_free = pkey_free; 360 } 361 362 void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth, 363 int (*pkey_ctrl) (EVP_PKEY *pkey, int op, 364 long arg1, void *arg2)) 365 { 366 ameth->pkey_ctrl = pkey_ctrl; 367 } 368 369 void EVP_PKEY_asn1_set_security_bits(EVP_PKEY_ASN1_METHOD *ameth, 370 int (*pkey_security_bits) (const EVP_PKEY 371 *pk)) 372 { 373 ameth->pkey_security_bits = pkey_security_bits; 374 } 375 376 void EVP_PKEY_asn1_set_item(EVP_PKEY_ASN1_METHOD *ameth, 377 int (*item_verify) (EVP_MD_CTX *ctx, 378 const ASN1_ITEM *it, 379 void *asn, 380 X509_ALGOR *a, 381 ASN1_BIT_STRING *sig, 382 EVP_PKEY *pkey), 383 int (*item_sign) (EVP_MD_CTX *ctx, 384 const ASN1_ITEM *it, 385 void *asn, 386 X509_ALGOR *alg1, 387 X509_ALGOR *alg2, 388 ASN1_BIT_STRING *sig)) 389 { 390 ameth->item_sign = item_sign; 391 ameth->item_verify = item_verify; 392 } 393 394 void EVP_PKEY_asn1_set_siginf(EVP_PKEY_ASN1_METHOD *ameth, 395 int (*siginf_set) (X509_SIG_INFO *siginf, 396 const X509_ALGOR *alg, 397 const ASN1_STRING *sig)) 398 { 399 ameth->siginf_set = siginf_set; 400 } 401 402 void EVP_PKEY_asn1_set_check(EVP_PKEY_ASN1_METHOD *ameth, 403 int (*pkey_check) (const EVP_PKEY *pk)) 404 { 405 ameth->pkey_check = pkey_check; 406 } 407 408 void EVP_PKEY_asn1_set_public_check(EVP_PKEY_ASN1_METHOD *ameth, 409 int (*pkey_pub_check) (const EVP_PKEY *pk)) 410 { 411 ameth->pkey_public_check = pkey_pub_check; 412 } 413 414 void EVP_PKEY_asn1_set_param_check(EVP_PKEY_ASN1_METHOD *ameth, 415 int (*pkey_param_check) (const EVP_PKEY *pk)) 416 { 417 ameth->pkey_param_check = pkey_param_check; 418 } 419 420 void EVP_PKEY_asn1_set_set_priv_key(EVP_PKEY_ASN1_METHOD *ameth, 421 int (*set_priv_key) (EVP_PKEY *pk, 422 const unsigned char 423 *priv, 424 size_t len)) 425 { 426 ameth->set_priv_key = set_priv_key; 427 } 428 429 void EVP_PKEY_asn1_set_set_pub_key(EVP_PKEY_ASN1_METHOD *ameth, 430 int (*set_pub_key) (EVP_PKEY *pk, 431 const unsigned char *pub, 432 size_t len)) 433 { 434 ameth->set_pub_key = set_pub_key; 435 } 436 437 void EVP_PKEY_asn1_set_get_priv_key(EVP_PKEY_ASN1_METHOD *ameth, 438 int (*get_priv_key) (const EVP_PKEY *pk, 439 unsigned char *priv, 440 size_t *len)) 441 { 442 ameth->get_priv_key = get_priv_key; 443 } 444 445 void EVP_PKEY_asn1_set_get_pub_key(EVP_PKEY_ASN1_METHOD *ameth, 446 int (*get_pub_key) (const EVP_PKEY *pk, 447 unsigned char *pub, 448 size_t *len)) 449 { 450 ameth->get_pub_key = get_pub_key; 451 } 452