x_pubkey.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495
  1. /* crypto/asn1/x_pubkey.c */
  2. /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  3. * All rights reserved.
  4. *
  5. * This package is an SSL implementation written
  6. * by Eric Young (eay@cryptsoft.com).
  7. * The implementation was written so as to conform with Netscapes SSL.
  8. *
  9. * This library is free for commercial and non-commercial use as long as
  10. * the following conditions are aheared to. The following conditions
  11. * apply to all code found in this distribution, be it the RC4, RSA,
  12. * lhash, DES, etc., code; not just the SSL code. The SSL documentation
  13. * included with this distribution is covered by the same copyright terms
  14. * except that the holder is Tim Hudson (tjh@cryptsoft.com).
  15. *
  16. * Copyright remains Eric Young's, and as such any Copyright notices in
  17. * the code are not to be removed.
  18. * If this package is used in a product, Eric Young should be given attribution
  19. * as the author of the parts of the library used.
  20. * This can be in the form of a textual message at program startup or
  21. * in documentation (online or textual) provided with the package.
  22. *
  23. * Redistribution and use in source and binary forms, with or without
  24. * modification, are permitted provided that the following conditions
  25. * are met:
  26. * 1. Redistributions of source code must retain the copyright
  27. * notice, this list of conditions and the following disclaimer.
  28. * 2. Redistributions in binary form must reproduce the above copyright
  29. * notice, this list of conditions and the following disclaimer in the
  30. * documentation and/or other materials provided with the distribution.
  31. * 3. All advertising materials mentioning features or use of this software
  32. * must display the following acknowledgement:
  33. * "This product includes cryptographic software written by
  34. * Eric Young (eay@cryptsoft.com)"
  35. * The word 'cryptographic' can be left out if the rouines from the library
  36. * being used are not cryptographic related :-).
  37. * 4. If you include any Windows specific code (or a derivative thereof) from
  38. * the apps directory (application code) you must include an acknowledgement:
  39. * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
  40. *
  41. * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
  42. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  43. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  44. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  45. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  46. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  47. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  48. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  49. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  50. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  51. * SUCH DAMAGE.
  52. *
  53. * The licence and distribution terms for any publically available version or
  54. * derivative of this code cannot be changed. i.e. this code cannot simply be
  55. * copied and put under another distribution licence
  56. * [including the GNU Public Licence.]
  57. */
  58. #include <stdio.h>
  59. #include "cryptlib.h"
  60. #include <openssl/asn1t.h>
  61. #include <openssl/x509.h>
  62. #include <openssl/rsa.h>
  63. #include <openssl/dsa.h>
  64. /* Minor tweak to operation: free up EVP_PKEY */
  65. static int pubkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it)
  66. {
  67. if (operation == ASN1_OP_FREE_POST)
  68. {
  69. X509_PUBKEY *pubkey = (X509_PUBKEY *)*pval;
  70. EVP_PKEY_free(pubkey->pkey);
  71. }
  72. return 1;
  73. }
  74. ASN1_SEQUENCE_cb(X509_PUBKEY, pubkey_cb) = {
  75. ASN1_SIMPLE(X509_PUBKEY, algor, X509_ALGOR),
  76. ASN1_SIMPLE(X509_PUBKEY, public_key, ASN1_BIT_STRING)
  77. } ASN1_SEQUENCE_END_cb(X509_PUBKEY, X509_PUBKEY)
  78. IMPLEMENT_ASN1_FUNCTIONS(X509_PUBKEY)
  79. int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey)
  80. {
  81. int ok=0;
  82. X509_PUBKEY *pk;
  83. X509_ALGOR *a;
  84. ASN1_OBJECT *o;
  85. unsigned char *s,*p = NULL;
  86. int i;
  87. if (x == NULL) return(0);
  88. if ((pk=X509_PUBKEY_new()) == NULL) goto err;
  89. a=pk->algor;
  90. /* set the algorithm id */
  91. if ((o=OBJ_nid2obj(pkey->type)) == NULL) goto err;
  92. ASN1_OBJECT_free(a->algorithm);
  93. a->algorithm=o;
  94. /* Set the parameter list */
  95. if (!pkey->save_parameters || (pkey->type == EVP_PKEY_RSA))
  96. {
  97. if ((a->parameter == NULL) ||
  98. (a->parameter->type != V_ASN1_NULL))
  99. {
  100. ASN1_TYPE_free(a->parameter);
  101. a->parameter=ASN1_TYPE_new();
  102. a->parameter->type=V_ASN1_NULL;
  103. }
  104. }
  105. #ifndef OPENSSL_NO_DSA
  106. else if (pkey->type == EVP_PKEY_DSA)
  107. {
  108. unsigned char *pp;
  109. DSA *dsa;
  110. dsa=pkey->pkey.dsa;
  111. dsa->write_params=0;
  112. ASN1_TYPE_free(a->parameter);
  113. i=i2d_DSAparams(dsa,NULL);
  114. if ((p=(unsigned char *)OPENSSL_malloc(i)) == NULL) goto err;
  115. pp=p;
  116. i2d_DSAparams(dsa,&pp);
  117. a->parameter=ASN1_TYPE_new();
  118. a->parameter->type=V_ASN1_SEQUENCE;
  119. a->parameter->value.sequence=ASN1_STRING_new();
  120. ASN1_STRING_set(a->parameter->value.sequence,p,i);
  121. OPENSSL_free(p);
  122. }
  123. #endif
  124. #ifndef OPENSSL_NO_EC
  125. else if (pkey->type == EVP_PKEY_EC)
  126. {
  127. int nid=0;
  128. unsigned char *pp;
  129. EC_KEY *eckey;
  130. eckey = pkey->pkey.eckey;
  131. ASN1_TYPE_free(a->parameter);
  132. if ((a->parameter = ASN1_TYPE_new()) == NULL)
  133. {
  134. X509err(X509_F_X509_PUBKEY_SET, ERR_R_ASN1_LIB);
  135. goto err;
  136. }
  137. if (EC_GROUP_get_asn1_flag(eckey->group)
  138. && (nid = EC_GROUP_get_nid(eckey->group)))
  139. {
  140. /* just set the OID */
  141. a->parameter->type = V_ASN1_OBJECT;
  142. a->parameter->value.object = OBJ_nid2obj(nid);
  143. }
  144. else /* explicit parameters */
  145. {
  146. if ((i = i2d_ECParameters(eckey, NULL)) == 0)
  147. {
  148. X509err(X509_F_X509_PUBKEY_SET, ERR_R_EC_LIB);
  149. goto err;
  150. }
  151. if ((p = (unsigned char *) OPENSSL_malloc(i)) == NULL)
  152. {
  153. X509err(X509_F_X509_PUBKEY_SET, ERR_R_MALLOC_FAILURE);
  154. goto err;
  155. }
  156. pp = p;
  157. if (!i2d_ECParameters(eckey, &pp))
  158. {
  159. X509err(X509_F_X509_PUBKEY_SET, ERR_R_EC_LIB);
  160. OPENSSL_free(p);
  161. goto err;
  162. }
  163. a->parameter->type = V_ASN1_SEQUENCE;
  164. if ((a->parameter->value.sequence = ASN1_STRING_new()) == NULL)
  165. {
  166. X509err(X509_F_X509_PUBKEY_SET, ERR_R_ASN1_LIB);
  167. OPENSSL_free(p);
  168. goto err;
  169. }
  170. ASN1_STRING_set(a->parameter->value.sequence, p, i);
  171. OPENSSL_free(p);
  172. }
  173. }
  174. #endif
  175. else if (1)
  176. {
  177. X509err(X509_F_X509_PUBKEY_SET,X509_R_UNSUPPORTED_ALGORITHM);
  178. goto err;
  179. }
  180. if ((i=i2d_PublicKey(pkey,NULL)) <= 0) goto err;
  181. if ((s=(unsigned char *)OPENSSL_malloc(i+1)) == NULL)
  182. {
  183. X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE);
  184. goto err;
  185. }
  186. p=s;
  187. i2d_PublicKey(pkey,&p);
  188. if (!M_ASN1_BIT_STRING_set(pk->public_key,s,i)) goto err;
  189. /* Set number of unused bits to zero */
  190. pk->public_key->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
  191. pk->public_key->flags|=ASN1_STRING_FLAG_BITS_LEFT;
  192. OPENSSL_free(s);
  193. #if 0
  194. CRYPTO_add(&pkey->references,1,CRYPTO_LOCK_EVP_PKEY);
  195. pk->pkey=pkey;
  196. #endif
  197. if (*x != NULL)
  198. X509_PUBKEY_free(*x);
  199. *x=pk;
  200. pk=NULL;
  201. ok=1;
  202. err:
  203. if (pk != NULL) X509_PUBKEY_free(pk);
  204. return(ok);
  205. }
  206. EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key)
  207. {
  208. EVP_PKEY *ret=NULL;
  209. long j;
  210. int type;
  211. const unsigned char *p;
  212. #if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_ECDSA)
  213. const unsigned char *cp;
  214. X509_ALGOR *a;
  215. #endif
  216. if (key == NULL) goto err;
  217. if (key->pkey != NULL)
  218. {
  219. CRYPTO_add(&key->pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
  220. return(key->pkey);
  221. }
  222. if (key->public_key == NULL) goto err;
  223. type=OBJ_obj2nid(key->algor->algorithm);
  224. if ((ret = EVP_PKEY_new()) == NULL)
  225. {
  226. X509err(X509_F_X509_PUBKEY_GET, ERR_R_MALLOC_FAILURE);
  227. goto err;
  228. }
  229. ret->type = EVP_PKEY_type(type);
  230. /* the parameters must be extracted before the public key (ECDSA!) */
  231. #if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_ECDSA)
  232. a=key->algor;
  233. #endif
  234. if (0)
  235. ;
  236. #ifndef OPENSSL_NO_DSA
  237. else if (ret->type == EVP_PKEY_DSA)
  238. {
  239. if (a->parameter && (a->parameter->type == V_ASN1_SEQUENCE))
  240. {
  241. if ((ret->pkey.dsa = DSA_new()) == NULL)
  242. {
  243. X509err(X509_F_X509_PUBKEY_GET, ERR_R_MALLOC_FAILURE);
  244. goto err;
  245. }
  246. ret->pkey.dsa->write_params=0;
  247. cp=p=a->parameter->value.sequence->data;
  248. j=a->parameter->value.sequence->length;
  249. if (!d2i_DSAparams(&ret->pkey.dsa, &cp, (long)j))
  250. goto err;
  251. }
  252. ret->save_parameters=1;
  253. }
  254. #endif
  255. #ifndef OPENSSL_NO_EC
  256. else if (ret->type == EVP_PKEY_EC)
  257. {
  258. if (a->parameter && (a->parameter->type == V_ASN1_SEQUENCE))
  259. {
  260. /* type == V_ASN1_SEQUENCE => we have explicit parameters
  261. * (e.g. parameters in the X9_62_EC_PARAMETERS-structure )
  262. */
  263. if ((ret->pkey.eckey= EC_KEY_new()) == NULL)
  264. {
  265. X509err(X509_F_X509_PUBKEY_GET,
  266. ERR_R_MALLOC_FAILURE);
  267. goto err;
  268. }
  269. cp = p = a->parameter->value.sequence->data;
  270. j = a->parameter->value.sequence->length;
  271. if (!d2i_ECParameters(&ret->pkey.eckey, &cp, (long)j))
  272. {
  273. X509err(X509_F_X509_PUBKEY_GET, ERR_R_EC_LIB);
  274. goto err;
  275. }
  276. }
  277. else if (a->parameter && (a->parameter->type == V_ASN1_OBJECT))
  278. {
  279. /* type == V_ASN1_OBJECT => the parameters are given
  280. * by an asn1 OID
  281. */
  282. EC_KEY *eckey;
  283. if (ret->pkey.eckey == NULL)
  284. ret->pkey.eckey = EC_KEY_new();
  285. eckey = ret->pkey.eckey;
  286. if (eckey->group)
  287. EC_GROUP_free(eckey->group);
  288. if ((eckey->group = EC_GROUP_new_by_nid(
  289. OBJ_obj2nid(a->parameter->value.object))) == NULL)
  290. goto err;
  291. EC_GROUP_set_asn1_flag(eckey->group,
  292. OPENSSL_EC_NAMED_CURVE);
  293. }
  294. /* the case implicitlyCA is currently not implemented */
  295. ret->save_parameters = 1;
  296. }
  297. #endif
  298. p=key->public_key->data;
  299. j=key->public_key->length;
  300. if (!d2i_PublicKey(type, &ret, &p, (long)j))
  301. {
  302. X509err(X509_F_X509_PUBKEY_GET, X509_R_ERR_ASN1_LIB);
  303. goto err;
  304. }
  305. key->pkey = ret;
  306. CRYPTO_add(&ret->references, 1, CRYPTO_LOCK_EVP_PKEY);
  307. return(ret);
  308. err:
  309. if (ret != NULL)
  310. EVP_PKEY_free(ret);
  311. return(NULL);
  312. }
  313. /* Now two pseudo ASN1 routines that take an EVP_PKEY structure
  314. * and encode or decode as X509_PUBKEY
  315. */
  316. EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp,
  317. long length)
  318. {
  319. X509_PUBKEY *xpk;
  320. EVP_PKEY *pktmp;
  321. xpk = d2i_X509_PUBKEY(NULL, pp, length);
  322. if(!xpk) return NULL;
  323. pktmp = X509_PUBKEY_get(xpk);
  324. X509_PUBKEY_free(xpk);
  325. if(!pktmp) return NULL;
  326. if(a)
  327. {
  328. EVP_PKEY_free(*a);
  329. *a = pktmp;
  330. }
  331. return pktmp;
  332. }
  333. int i2d_PUBKEY(EVP_PKEY *a, unsigned char **pp)
  334. {
  335. X509_PUBKEY *xpk=NULL;
  336. int ret;
  337. if(!a) return 0;
  338. if(!X509_PUBKEY_set(&xpk, a)) return 0;
  339. ret = i2d_X509_PUBKEY(xpk, pp);
  340. X509_PUBKEY_free(xpk);
  341. return ret;
  342. }
  343. /* The following are equivalents but which return RSA and DSA
  344. * keys
  345. */
  346. #ifndef OPENSSL_NO_RSA
  347. RSA *d2i_RSA_PUBKEY(RSA **a, const unsigned char **pp,
  348. long length)
  349. {
  350. EVP_PKEY *pkey;
  351. RSA *key;
  352. const unsigned char *q;
  353. q = *pp;
  354. pkey = d2i_PUBKEY(NULL, &q, length);
  355. if (!pkey) return NULL;
  356. key = EVP_PKEY_get1_RSA(pkey);
  357. EVP_PKEY_free(pkey);
  358. if (!key) return NULL;
  359. *pp = q;
  360. if (a)
  361. {
  362. RSA_free(*a);
  363. *a = key;
  364. }
  365. return key;
  366. }
  367. int i2d_RSA_PUBKEY(RSA *a, unsigned char **pp)
  368. {
  369. EVP_PKEY *pktmp;
  370. int ret;
  371. if (!a) return 0;
  372. pktmp = EVP_PKEY_new();
  373. if (!pktmp)
  374. {
  375. ASN1err(ASN1_F_I2D_RSA_PUBKEY, ERR_R_MALLOC_FAILURE);
  376. return 0;
  377. }
  378. EVP_PKEY_set1_RSA(pktmp, a);
  379. ret = i2d_PUBKEY(pktmp, pp);
  380. EVP_PKEY_free(pktmp);
  381. return ret;
  382. }
  383. #endif
  384. #ifndef OPENSSL_NO_DSA
  385. DSA *d2i_DSA_PUBKEY(DSA **a, const unsigned char **pp,
  386. long length)
  387. {
  388. EVP_PKEY *pkey;
  389. DSA *key;
  390. const unsigned char *q;
  391. q = *pp;
  392. pkey = d2i_PUBKEY(NULL, &q, length);
  393. if (!pkey) return NULL;
  394. key = EVP_PKEY_get1_DSA(pkey);
  395. EVP_PKEY_free(pkey);
  396. if (!key) return NULL;
  397. *pp = q;
  398. if (a)
  399. {
  400. DSA_free(*a);
  401. *a = key;
  402. }
  403. return key;
  404. }
  405. int i2d_DSA_PUBKEY(DSA *a, unsigned char **pp)
  406. {
  407. EVP_PKEY *pktmp;
  408. int ret;
  409. if(!a) return 0;
  410. pktmp = EVP_PKEY_new();
  411. if(!pktmp)
  412. {
  413. ASN1err(ASN1_F_I2D_DSA_PUBKEY, ERR_R_MALLOC_FAILURE);
  414. return 0;
  415. }
  416. EVP_PKEY_set1_DSA(pktmp, a);
  417. ret = i2d_PUBKEY(pktmp, pp);
  418. EVP_PKEY_free(pktmp);
  419. return ret;
  420. }
  421. #endif
  422. #ifndef OPENSSL_NO_EC
  423. EC_KEY *d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp, long length)
  424. {
  425. EVP_PKEY *pkey;
  426. EC_KEY *key;
  427. const unsigned char *q;
  428. q = *pp;
  429. pkey = d2i_PUBKEY(NULL, &q, length);
  430. if (!pkey) return(NULL);
  431. key = EVP_PKEY_get1_EC_KEY(pkey);
  432. EVP_PKEY_free(pkey);
  433. if (!key) return(NULL);
  434. *pp = q;
  435. if (a)
  436. {
  437. EC_KEY_free(*a);
  438. *a = key;
  439. }
  440. return(key);
  441. }
  442. int i2d_EC_PUBKEY(EC_KEY *a, unsigned char **pp)
  443. {
  444. EVP_PKEY *pktmp;
  445. int ret;
  446. if (!a) return(0);
  447. if ((pktmp = EVP_PKEY_new()) == NULL)
  448. {
  449. ASN1err(ASN1_F_I2D_EC_PUBKEY, ERR_R_MALLOC_FAILURE);
  450. return(0);
  451. }
  452. EVP_PKEY_set1_EC_KEY(pktmp, a);
  453. ret = i2d_PUBKEY(pktmp, pp);
  454. EVP_PKEY_free(pktmp);
  455. return(ret);
  456. }
  457. #endif