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 if (app_methods == NULL) { 144 app_methods = sk_EVP_PKEY_ASN1_METHOD_new(ameth_cmp); 145 if (app_methods == NULL) 146 return 0; 147 } 148 149 tmp.pkey_id = ameth->pkey_id; 150 if (sk_EVP_PKEY_ASN1_METHOD_find(app_methods, &tmp) >= 0) { 151 EVPerr(EVP_F_EVP_PKEY_ASN1_ADD0, 152 EVP_R_PKEY_APPLICATION_ASN1_METHOD_ALREADY_REGISTERED); 153 return 0; 154 } 155 156 if (!sk_EVP_PKEY_ASN1_METHOD_push(app_methods, ameth)) 157 return 0; 158 sk_EVP_PKEY_ASN1_METHOD_sort(app_methods); 159 return 1; 160 } 161 162 int EVP_PKEY_asn1_add_alias(int to, int from) 163 { 164 EVP_PKEY_ASN1_METHOD *ameth; 165 ameth = EVP_PKEY_asn1_new(from, ASN1_PKEY_ALIAS, NULL, NULL); 166 if (ameth == NULL) 167 return 0; 168 ameth->pkey_base_id = to; 169 if (!EVP_PKEY_asn1_add0(ameth)) { 170 EVP_PKEY_asn1_free(ameth); 171 return 0; 172 } 173 return 1; 174 } 175 176 int EVP_PKEY_asn1_get0_info(int *ppkey_id, int *ppkey_base_id, 177 int *ppkey_flags, const char **pinfo, 178 const char **ppem_str, 179 const EVP_PKEY_ASN1_METHOD *ameth) 180 { 181 if (!ameth) 182 return 0; 183 if (ppkey_id) 184 *ppkey_id = ameth->pkey_id; 185 if (ppkey_base_id) 186 *ppkey_base_id = ameth->pkey_base_id; 187 if (ppkey_flags) 188 *ppkey_flags = ameth->pkey_flags; 189 if (pinfo) 190 *pinfo = ameth->info; 191 if (ppem_str) 192 *ppem_str = ameth->pem_str; 193 return 1; 194 } 195 196 const EVP_PKEY_ASN1_METHOD *EVP_PKEY_get0_asn1(const EVP_PKEY *pkey) 197 { 198 return pkey->ameth; 199 } 200 201 EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_new(int id, int flags, 202 const char *pem_str, const char *info) 203 { 204 EVP_PKEY_ASN1_METHOD *ameth = OPENSSL_zalloc(sizeof(*ameth)); 205 206 if (ameth == NULL) 207 return NULL; 208 209 ameth->pkey_id = id; 210 ameth->pkey_base_id = id; 211 ameth->pkey_flags = flags | ASN1_PKEY_DYNAMIC; 212 213 if (info) { 214 ameth->info = OPENSSL_strdup(info); 215 if (!ameth->info) 216 goto err; 217 } 218 219 /* 220 * One of the following must be true: 221 * 222 * pem_str == NULL AND ASN1_PKEY_ALIAS is set 223 * pem_str != NULL AND ASN1_PKEY_ALIAS is clear 224 * 225 * Anything else is an error and may lead to a corrupt ASN1 method table 226 */ 227 if (!((pem_str == NULL && (flags & ASN1_PKEY_ALIAS) != 0) 228 || (pem_str != NULL && (flags & ASN1_PKEY_ALIAS) == 0))) 229 goto err; 230 231 if (pem_str) { 232 ameth->pem_str = OPENSSL_strdup(pem_str); 233 if (!ameth->pem_str) 234 goto err; 235 } 236 237 return ameth; 238 239 err: 240 EVP_PKEY_asn1_free(ameth); 241 return NULL; 242 243 } 244 245 void EVP_PKEY_asn1_copy(EVP_PKEY_ASN1_METHOD *dst, 246 const EVP_PKEY_ASN1_METHOD *src) 247 { 248 249 dst->pub_decode = src->pub_decode; 250 dst->pub_encode = src->pub_encode; 251 dst->pub_cmp = src->pub_cmp; 252 dst->pub_print = src->pub_print; 253 254 dst->priv_decode = src->priv_decode; 255 dst->priv_encode = src->priv_encode; 256 dst->priv_print = src->priv_print; 257 258 dst->old_priv_encode = src->old_priv_encode; 259 dst->old_priv_decode = src->old_priv_decode; 260 261 dst->pkey_size = src->pkey_size; 262 dst->pkey_bits = src->pkey_bits; 263 264 dst->param_decode = src->param_decode; 265 dst->param_encode = src->param_encode; 266 dst->param_missing = src->param_missing; 267 dst->param_copy = src->param_copy; 268 dst->param_cmp = src->param_cmp; 269 dst->param_print = src->param_print; 270 271 dst->pkey_free = src->pkey_free; 272 dst->pkey_ctrl = src->pkey_ctrl; 273 274 dst->item_sign = src->item_sign; 275 dst->item_verify = src->item_verify; 276 277 dst->siginf_set = src->siginf_set; 278 279 dst->pkey_check = src->pkey_check; 280 281 } 282 283 void EVP_PKEY_asn1_free(EVP_PKEY_ASN1_METHOD *ameth) 284 { 285 if (ameth && (ameth->pkey_flags & ASN1_PKEY_DYNAMIC)) { 286 OPENSSL_free(ameth->pem_str); 287 OPENSSL_free(ameth->info); 288 OPENSSL_free(ameth); 289 } 290 } 291 292 void EVP_PKEY_asn1_set_public(EVP_PKEY_ASN1_METHOD *ameth, 293 int (*pub_decode) (EVP_PKEY *pk, 294 X509_PUBKEY *pub), 295 int (*pub_encode) (X509_PUBKEY *pub, 296 const EVP_PKEY *pk), 297 int (*pub_cmp) (const EVP_PKEY *a, 298 const EVP_PKEY *b), 299 int (*pub_print) (BIO *out, 300 const EVP_PKEY *pkey, 301 int indent, ASN1_PCTX *pctx), 302 int (*pkey_size) (const EVP_PKEY *pk), 303 int (*pkey_bits) (const EVP_PKEY *pk)) 304 { 305 ameth->pub_decode = pub_decode; 306 ameth->pub_encode = pub_encode; 307 ameth->pub_cmp = pub_cmp; 308 ameth->pub_print = pub_print; 309 ameth->pkey_size = pkey_size; 310 ameth->pkey_bits = pkey_bits; 311 } 312 313 void EVP_PKEY_asn1_set_private(EVP_PKEY_ASN1_METHOD *ameth, 314 int (*priv_decode) (EVP_PKEY *pk, 315 const PKCS8_PRIV_KEY_INFO 316 *p8inf), 317 int (*priv_encode) (PKCS8_PRIV_KEY_INFO *p8, 318 const EVP_PKEY *pk), 319 int (*priv_print) (BIO *out, 320 const EVP_PKEY *pkey, 321 int indent, 322 ASN1_PCTX *pctx)) 323 { 324 ameth->priv_decode = priv_decode; 325 ameth->priv_encode = priv_encode; 326 ameth->priv_print = priv_print; 327 } 328 329 void EVP_PKEY_asn1_set_param(EVP_PKEY_ASN1_METHOD *ameth, 330 int (*param_decode) (EVP_PKEY *pkey, 331 const unsigned char **pder, 332 int derlen), 333 int (*param_encode) (const EVP_PKEY *pkey, 334 unsigned char **pder), 335 int (*param_missing) (const EVP_PKEY *pk), 336 int (*param_copy) (EVP_PKEY *to, 337 const EVP_PKEY *from), 338 int (*param_cmp) (const EVP_PKEY *a, 339 const EVP_PKEY *b), 340 int (*param_print) (BIO *out, 341 const EVP_PKEY *pkey, 342 int indent, ASN1_PCTX *pctx)) 343 { 344 ameth->param_decode = param_decode; 345 ameth->param_encode = param_encode; 346 ameth->param_missing = param_missing; 347 ameth->param_copy = param_copy; 348 ameth->param_cmp = param_cmp; 349 ameth->param_print = param_print; 350 } 351 352 void EVP_PKEY_asn1_set_free(EVP_PKEY_ASN1_METHOD *ameth, 353 void (*pkey_free) (EVP_PKEY *pkey)) 354 { 355 ameth->pkey_free = pkey_free; 356 } 357 358 void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth, 359 int (*pkey_ctrl) (EVP_PKEY *pkey, int op, 360 long arg1, void *arg2)) 361 { 362 ameth->pkey_ctrl = pkey_ctrl; 363 } 364 365 void EVP_PKEY_asn1_set_security_bits(EVP_PKEY_ASN1_METHOD *ameth, 366 int (*pkey_security_bits) (const EVP_PKEY 367 *pk)) 368 { 369 ameth->pkey_security_bits = pkey_security_bits; 370 } 371 372 void EVP_PKEY_asn1_set_item(EVP_PKEY_ASN1_METHOD *ameth, 373 int (*item_verify) (EVP_MD_CTX *ctx, 374 const ASN1_ITEM *it, 375 void *asn, 376 X509_ALGOR *a, 377 ASN1_BIT_STRING *sig, 378 EVP_PKEY *pkey), 379 int (*item_sign) (EVP_MD_CTX *ctx, 380 const ASN1_ITEM *it, 381 void *asn, 382 X509_ALGOR *alg1, 383 X509_ALGOR *alg2, 384 ASN1_BIT_STRING *sig)) 385 { 386 ameth->item_sign = item_sign; 387 ameth->item_verify = item_verify; 388 } 389 390 void EVP_PKEY_asn1_set_siginf(EVP_PKEY_ASN1_METHOD *ameth, 391 int (*siginf_set) (X509_SIG_INFO *siginf, 392 const X509_ALGOR *alg, 393 const ASN1_STRING *sig)) 394 { 395 ameth->siginf_set = siginf_set; 396 } 397 398 void EVP_PKEY_asn1_set_check(EVP_PKEY_ASN1_METHOD *ameth, 399 int (*pkey_check) (const EVP_PKEY *pk)) 400 { 401 ameth->pkey_check = pkey_check; 402 } 403 404 void EVP_PKEY_asn1_set_public_check(EVP_PKEY_ASN1_METHOD *ameth, 405 int (*pkey_pub_check) (const EVP_PKEY *pk)) 406 { 407 ameth->pkey_public_check = pkey_pub_check; 408 } 409 410 void EVP_PKEY_asn1_set_param_check(EVP_PKEY_ASN1_METHOD *ameth, 411 int (*pkey_param_check) (const EVP_PKEY *pk)) 412 { 413 ameth->pkey_param_check = pkey_param_check; 414 } 415 416 void EVP_PKEY_asn1_set_set_priv_key(EVP_PKEY_ASN1_METHOD *ameth, 417 int (*set_priv_key) (EVP_PKEY *pk, 418 const unsigned char 419 *priv, 420 size_t len)) 421 { 422 ameth->set_priv_key = set_priv_key; 423 } 424 425 void EVP_PKEY_asn1_set_set_pub_key(EVP_PKEY_ASN1_METHOD *ameth, 426 int (*set_pub_key) (EVP_PKEY *pk, 427 const unsigned char *pub, 428 size_t len)) 429 { 430 ameth->set_pub_key = set_pub_key; 431 } 432 433 void EVP_PKEY_asn1_set_get_priv_key(EVP_PKEY_ASN1_METHOD *ameth, 434 int (*get_priv_key) (const EVP_PKEY *pk, 435 unsigned char *priv, 436 size_t *len)) 437 { 438 ameth->get_priv_key = get_priv_key; 439 } 440 441 void EVP_PKEY_asn1_set_get_pub_key(EVP_PKEY_ASN1_METHOD *ameth, 442 int (*get_pub_key) (const EVP_PKEY *pk, 443 unsigned char *pub, 444 size_t *len)) 445 { 446 ameth->get_pub_key = get_pub_key; 447 } 448