A local copy of OpenSSL from GitHub
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

397 lines
12 KiB

  1. /*
  2. * Copyright 2006-2016 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. #include <stdio.h>
  10. #include "internal/cryptlib.h"
  11. #include <openssl/asn1t.h>
  12. #include <openssl/x509.h>
  13. #include <openssl/engine.h>
  14. #include "internal/asn1_int.h"
  15. #include "internal/evp_int.h"
  16. /* Keep this sorted in type order !! */
  17. static const EVP_PKEY_ASN1_METHOD *standard_methods[] = {
  18. #ifndef OPENSSL_NO_RSA
  19. &rsa_asn1_meths[0],
  20. &rsa_asn1_meths[1],
  21. #endif
  22. #ifndef OPENSSL_NO_DH
  23. &dh_asn1_meth,
  24. #endif
  25. #ifndef OPENSSL_NO_DSA
  26. &dsa_asn1_meths[0],
  27. &dsa_asn1_meths[1],
  28. &dsa_asn1_meths[2],
  29. &dsa_asn1_meths[3],
  30. &dsa_asn1_meths[4],
  31. #endif
  32. #ifndef OPENSSL_NO_EC
  33. &eckey_asn1_meth,
  34. #endif
  35. &hmac_asn1_meth,
  36. #ifndef OPENSSL_NO_CMAC
  37. &cmac_asn1_meth,
  38. #endif
  39. #ifndef OPENSSL_NO_DH
  40. &dhx_asn1_meth
  41. #endif
  42. };
  43. typedef int sk_cmp_fn_type(const char *const *a, const char *const *b);
  44. static STACK_OF(EVP_PKEY_ASN1_METHOD) *app_methods = NULL;
  45. #ifdef TEST
  46. void main()
  47. {
  48. int i;
  49. for (i = 0; i < OSSL_NELEM(standard_methods); i++)
  50. fprintf(stderr, "Number %d id=%d (%s)\n", i,
  51. standard_methods[i]->pkey_id,
  52. OBJ_nid2sn(standard_methods[i]->pkey_id));
  53. }
  54. #endif
  55. DECLARE_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_ASN1_METHOD *,
  56. const EVP_PKEY_ASN1_METHOD *, ameth);
  57. static int ameth_cmp(const EVP_PKEY_ASN1_METHOD *const *a,
  58. const EVP_PKEY_ASN1_METHOD *const *b)
  59. {
  60. return ((*a)->pkey_id - (*b)->pkey_id);
  61. }
  62. IMPLEMENT_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_ASN1_METHOD *,
  63. const EVP_PKEY_ASN1_METHOD *, ameth);
  64. int EVP_PKEY_asn1_get_count(void)
  65. {
  66. int num = OSSL_NELEM(standard_methods);
  67. if (app_methods)
  68. num += sk_EVP_PKEY_ASN1_METHOD_num(app_methods);
  69. return num;
  70. }
  71. const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_get0(int idx)
  72. {
  73. int num = OSSL_NELEM(standard_methods);
  74. if (idx < 0)
  75. return NULL;
  76. if (idx < num)
  77. return standard_methods[idx];
  78. idx -= num;
  79. return sk_EVP_PKEY_ASN1_METHOD_value(app_methods, idx);
  80. }
  81. static const EVP_PKEY_ASN1_METHOD *pkey_asn1_find(int type)
  82. {
  83. EVP_PKEY_ASN1_METHOD tmp;
  84. const EVP_PKEY_ASN1_METHOD *t = &tmp, **ret;
  85. tmp.pkey_id = type;
  86. if (app_methods) {
  87. int idx;
  88. idx = sk_EVP_PKEY_ASN1_METHOD_find(app_methods, &tmp);
  89. if (idx >= 0)
  90. return sk_EVP_PKEY_ASN1_METHOD_value(app_methods, idx);
  91. }
  92. ret = OBJ_bsearch_ameth(&t, standard_methods, OSSL_NELEM(standard_methods));
  93. if (!ret || !*ret)
  94. return NULL;
  95. return *ret;
  96. }
  97. /*
  98. * Find an implementation of an ASN1 algorithm. If 'pe' is not NULL also
  99. * search through engines and set *pe to a functional reference to the engine
  100. * implementing 'type' or NULL if no engine implements it.
  101. */
  102. const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pe, int type)
  103. {
  104. const EVP_PKEY_ASN1_METHOD *t;
  105. for (;;) {
  106. t = pkey_asn1_find(type);
  107. if (!t || !(t->pkey_flags & ASN1_PKEY_ALIAS))
  108. break;
  109. type = t->pkey_base_id;
  110. }
  111. if (pe) {
  112. #ifndef OPENSSL_NO_ENGINE
  113. ENGINE *e;
  114. /* type will contain the final unaliased type */
  115. e = ENGINE_get_pkey_asn1_meth_engine(type);
  116. if (e) {
  117. *pe = e;
  118. return ENGINE_get_pkey_asn1_meth(e, type);
  119. }
  120. #endif
  121. *pe = NULL;
  122. }
  123. return t;
  124. }
  125. const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pe,
  126. const char *str, int len)
  127. {
  128. int i;
  129. const EVP_PKEY_ASN1_METHOD *ameth;
  130. if (len == -1)
  131. len = strlen(str);
  132. if (pe) {
  133. #ifndef OPENSSL_NO_ENGINE
  134. ENGINE *e;
  135. ameth = ENGINE_pkey_asn1_find_str(&e, str, len);
  136. if (ameth) {
  137. /*
  138. * Convert structural into functional reference
  139. */
  140. if (!ENGINE_init(e))
  141. ameth = NULL;
  142. ENGINE_free(e);
  143. *pe = e;
  144. return ameth;
  145. }
  146. #endif
  147. *pe = NULL;
  148. }
  149. for (i = 0; i < EVP_PKEY_asn1_get_count(); i++) {
  150. ameth = EVP_PKEY_asn1_get0(i);
  151. if (ameth->pkey_flags & ASN1_PKEY_ALIAS)
  152. continue;
  153. if (((int)strlen(ameth->pem_str) == len)
  154. && (strncasecmp(ameth->pem_str, str, len) == 0))
  155. return ameth;
  156. }
  157. return NULL;
  158. }
  159. int EVP_PKEY_asn1_add0(const EVP_PKEY_ASN1_METHOD *ameth)
  160. {
  161. if (app_methods == NULL) {
  162. app_methods = sk_EVP_PKEY_ASN1_METHOD_new(ameth_cmp);
  163. if (app_methods == NULL)
  164. return 0;
  165. }
  166. if (!sk_EVP_PKEY_ASN1_METHOD_push(app_methods, ameth))
  167. return 0;
  168. sk_EVP_PKEY_ASN1_METHOD_sort(app_methods);
  169. return 1;
  170. }
  171. int EVP_PKEY_asn1_add_alias(int to, int from)
  172. {
  173. EVP_PKEY_ASN1_METHOD *ameth;
  174. ameth = EVP_PKEY_asn1_new(from, ASN1_PKEY_ALIAS, NULL, NULL);
  175. if (ameth == NULL)
  176. return 0;
  177. ameth->pkey_base_id = to;
  178. if (!EVP_PKEY_asn1_add0(ameth)) {
  179. EVP_PKEY_asn1_free(ameth);
  180. return 0;
  181. }
  182. return 1;
  183. }
  184. int EVP_PKEY_asn1_get0_info(int *ppkey_id, int *ppkey_base_id,
  185. int *ppkey_flags, const char **pinfo,
  186. const char **ppem_str,
  187. const EVP_PKEY_ASN1_METHOD *ameth)
  188. {
  189. if (!ameth)
  190. return 0;
  191. if (ppkey_id)
  192. *ppkey_id = ameth->pkey_id;
  193. if (ppkey_base_id)
  194. *ppkey_base_id = ameth->pkey_base_id;
  195. if (ppkey_flags)
  196. *ppkey_flags = ameth->pkey_flags;
  197. if (pinfo)
  198. *pinfo = ameth->info;
  199. if (ppem_str)
  200. *ppem_str = ameth->pem_str;
  201. return 1;
  202. }
  203. const EVP_PKEY_ASN1_METHOD *EVP_PKEY_get0_asn1(EVP_PKEY *pkey)
  204. {
  205. return pkey->ameth;
  206. }
  207. EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_new(int id, int flags,
  208. const char *pem_str, const char *info)
  209. {
  210. EVP_PKEY_ASN1_METHOD *ameth = OPENSSL_zalloc(sizeof(*ameth));
  211. if (ameth == NULL)
  212. return NULL;
  213. ameth->pkey_id = id;
  214. ameth->pkey_base_id = id;
  215. ameth->pkey_flags = flags | ASN1_PKEY_DYNAMIC;
  216. if (info) {
  217. ameth->info = OPENSSL_strdup(info);
  218. if (!ameth->info)
  219. goto err;
  220. }
  221. if (pem_str) {
  222. ameth->pem_str = OPENSSL_strdup(pem_str);
  223. if (!ameth->pem_str)
  224. goto err;
  225. }
  226. return ameth;
  227. err:
  228. EVP_PKEY_asn1_free(ameth);
  229. return NULL;
  230. }
  231. void EVP_PKEY_asn1_copy(EVP_PKEY_ASN1_METHOD *dst,
  232. const EVP_PKEY_ASN1_METHOD *src)
  233. {
  234. dst->pub_decode = src->pub_decode;
  235. dst->pub_encode = src->pub_encode;
  236. dst->pub_cmp = src->pub_cmp;
  237. dst->pub_print = src->pub_print;
  238. dst->priv_decode = src->priv_decode;
  239. dst->priv_encode = src->priv_encode;
  240. dst->priv_print = src->priv_print;
  241. dst->old_priv_encode = src->old_priv_encode;
  242. dst->old_priv_decode = src->old_priv_decode;
  243. dst->pkey_size = src->pkey_size;
  244. dst->pkey_bits = src->pkey_bits;
  245. dst->param_decode = src->param_decode;
  246. dst->param_encode = src->param_encode;
  247. dst->param_missing = src->param_missing;
  248. dst->param_copy = src->param_copy;
  249. dst->param_cmp = src->param_cmp;
  250. dst->param_print = src->param_print;
  251. dst->pkey_free = src->pkey_free;
  252. dst->pkey_ctrl = src->pkey_ctrl;
  253. dst->item_sign = src->item_sign;
  254. dst->item_verify = src->item_verify;
  255. }
  256. void EVP_PKEY_asn1_free(EVP_PKEY_ASN1_METHOD *ameth)
  257. {
  258. if (ameth && (ameth->pkey_flags & ASN1_PKEY_DYNAMIC)) {
  259. OPENSSL_free(ameth->pem_str);
  260. OPENSSL_free(ameth->info);
  261. OPENSSL_free(ameth);
  262. }
  263. }
  264. void EVP_PKEY_asn1_set_public(EVP_PKEY_ASN1_METHOD *ameth,
  265. int (*pub_decode) (EVP_PKEY *pk,
  266. X509_PUBKEY *pub),
  267. int (*pub_encode) (X509_PUBKEY *pub,
  268. const EVP_PKEY *pk),
  269. int (*pub_cmp) (const EVP_PKEY *a,
  270. const EVP_PKEY *b),
  271. int (*pub_print) (BIO *out,
  272. const EVP_PKEY *pkey,
  273. int indent, ASN1_PCTX *pctx),
  274. int (*pkey_size) (const EVP_PKEY *pk),
  275. int (*pkey_bits) (const EVP_PKEY *pk))
  276. {
  277. ameth->pub_decode = pub_decode;
  278. ameth->pub_encode = pub_encode;
  279. ameth->pub_cmp = pub_cmp;
  280. ameth->pub_print = pub_print;
  281. ameth->pkey_size = pkey_size;
  282. ameth->pkey_bits = pkey_bits;
  283. }
  284. void EVP_PKEY_asn1_set_private(EVP_PKEY_ASN1_METHOD *ameth,
  285. int (*priv_decode) (EVP_PKEY *pk,
  286. PKCS8_PRIV_KEY_INFO
  287. *p8inf),
  288. int (*priv_encode) (PKCS8_PRIV_KEY_INFO *p8,
  289. const EVP_PKEY *pk),
  290. int (*priv_print) (BIO *out,
  291. const EVP_PKEY *pkey,
  292. int indent,
  293. ASN1_PCTX *pctx))
  294. {
  295. ameth->priv_decode = priv_decode;
  296. ameth->priv_encode = priv_encode;
  297. ameth->priv_print = priv_print;
  298. }
  299. void EVP_PKEY_asn1_set_param(EVP_PKEY_ASN1_METHOD *ameth,
  300. int (*param_decode) (EVP_PKEY *pkey,
  301. const unsigned char **pder,
  302. int derlen),
  303. int (*param_encode) (const EVP_PKEY *pkey,
  304. unsigned char **pder),
  305. int (*param_missing) (const EVP_PKEY *pk),
  306. int (*param_copy) (EVP_PKEY *to,
  307. const EVP_PKEY *from),
  308. int (*param_cmp) (const EVP_PKEY *a,
  309. const EVP_PKEY *b),
  310. int (*param_print) (BIO *out,
  311. const EVP_PKEY *pkey,
  312. int indent, ASN1_PCTX *pctx))
  313. {
  314. ameth->param_decode = param_decode;
  315. ameth->param_encode = param_encode;
  316. ameth->param_missing = param_missing;
  317. ameth->param_copy = param_copy;
  318. ameth->param_cmp = param_cmp;
  319. ameth->param_print = param_print;
  320. }
  321. void EVP_PKEY_asn1_set_free(EVP_PKEY_ASN1_METHOD *ameth,
  322. void (*pkey_free) (EVP_PKEY *pkey))
  323. {
  324. ameth->pkey_free = pkey_free;
  325. }
  326. void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth,
  327. int (*pkey_ctrl) (EVP_PKEY *pkey, int op,
  328. long arg1, void *arg2))
  329. {
  330. ameth->pkey_ctrl = pkey_ctrl;
  331. }
  332. void EVP_PKEY_asn1_set_security_bits(EVP_PKEY_ASN1_METHOD *ameth,
  333. int (*pkey_security_bits) (const EVP_PKEY
  334. *pk))
  335. {
  336. ameth->pkey_security_bits = pkey_security_bits;
  337. }
  338. void EVP_PKEY_asn1_set_item(EVP_PKEY_ASN1_METHOD *ameth,
  339. int (*item_verify) (EVP_MD_CTX *ctx,
  340. const ASN1_ITEM *it,
  341. void *asn,
  342. X509_ALGOR *a,
  343. ASN1_BIT_STRING *sig,
  344. EVP_PKEY *pkey),
  345. int (*item_sign) (EVP_MD_CTX *ctx,
  346. const ASN1_ITEM *it,
  347. void *asn,
  348. X509_ALGOR *alg1,
  349. X509_ALGOR *alg2,
  350. ASN1_BIT_STRING *sig))
  351. {
  352. ameth->item_sign = item_sign;
  353. ameth->item_verify = item_verify;
  354. }