evp_pkey.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. /* evp_pkey.c */
  2. /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  3. * project 1999.
  4. */
  5. /* ====================================================================
  6. * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions
  10. * are met:
  11. *
  12. * 1. Redistributions of source code must retain the above copyright
  13. * notice, this list of conditions and the following disclaimer.
  14. *
  15. * 2. Redistributions in binary form must reproduce the above copyright
  16. * notice, this list of conditions and the following disclaimer in
  17. * the documentation and/or other materials provided with the
  18. * distribution.
  19. *
  20. * 3. All advertising materials mentioning features or use of this
  21. * software must display the following acknowledgment:
  22. * "This product includes software developed by the OpenSSL Project
  23. * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
  24. *
  25. * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
  26. * endorse or promote products derived from this software without
  27. * prior written permission. For written permission, please contact
  28. * licensing@OpenSSL.org.
  29. *
  30. * 5. Products derived from this software may not be called "OpenSSL"
  31. * nor may "OpenSSL" appear in their names without prior written
  32. * permission of the OpenSSL Project.
  33. *
  34. * 6. Redistributions of any form whatsoever must retain the following
  35. * acknowledgment:
  36. * "This product includes software developed by the OpenSSL Project
  37. * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
  38. *
  39. * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
  40. * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  41. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  42. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
  43. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  44. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  45. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  46. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  47. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  48. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  49. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  50. * OF THE POSSIBILITY OF SUCH DAMAGE.
  51. * ====================================================================
  52. *
  53. * This product includes cryptographic software written by Eric Young
  54. * (eay@cryptsoft.com). This product includes software written by Tim
  55. * Hudson (tjh@cryptsoft.com).
  56. *
  57. */
  58. #include <stdio.h>
  59. #include <stdlib.h>
  60. #include "cryptlib.h"
  61. #include <openssl/x509.h>
  62. #include <openssl/rand.h>
  63. #include "asn1_locl.h"
  64. /* Extract a private key from a PKCS8 structure */
  65. EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8)
  66. {
  67. EVP_PKEY *pkey = NULL;
  68. ASN1_OBJECT *algoid;
  69. char obj_tmp[80];
  70. if (!PKCS8_pkey_get0(&algoid, NULL, NULL, NULL, p8))
  71. return NULL;
  72. if (!(pkey = EVP_PKEY_new())) {
  73. EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE);
  74. return NULL;
  75. }
  76. if (!EVP_PKEY_set_type(pkey, OBJ_obj2nid(algoid)))
  77. {
  78. EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
  79. i2t_ASN1_OBJECT(obj_tmp, 80, algoid);
  80. ERR_add_error_data(2, "TYPE=", obj_tmp);
  81. goto error;
  82. }
  83. if (pkey->ameth->priv_decode)
  84. {
  85. if (!pkey->ameth->priv_decode(pkey, p8))
  86. {
  87. EVPerr(EVP_F_EVP_PKCS82PKEY,
  88. EVP_R_PRIVATE_KEY_DECODE_ERROR);
  89. goto error;
  90. }
  91. }
  92. else
  93. {
  94. EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_METHOD_NOT_SUPPORTED);
  95. goto error;
  96. }
  97. return pkey;
  98. error:
  99. EVP_PKEY_free (pkey);
  100. return NULL;
  101. }
  102. PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey)
  103. {
  104. return EVP_PKEY2PKCS8_broken(pkey, PKCS8_OK);
  105. }
  106. /* Turn a private key into a PKCS8 structure */
  107. PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken)
  108. {
  109. PKCS8_PRIV_KEY_INFO *p8;
  110. if (!(p8 = PKCS8_PRIV_KEY_INFO_new())) {
  111. EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,ERR_R_MALLOC_FAILURE);
  112. return NULL;
  113. }
  114. p8->broken = broken;
  115. if (pkey->ameth)
  116. {
  117. if (pkey->ameth->priv_encode)
  118. {
  119. if (!pkey->ameth->priv_encode(p8, pkey))
  120. {
  121. EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,
  122. EVP_R_PRIVATE_KEY_ENCODE_ERROR);
  123. goto error;
  124. }
  125. }
  126. else
  127. {
  128. EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,
  129. EVP_R_METHOD_NOT_SUPPORTED);
  130. goto error;
  131. }
  132. }
  133. else
  134. {
  135. EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,
  136. EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
  137. goto error;
  138. }
  139. RAND_add(p8->pkey->value.octet_string->data,
  140. p8->pkey->value.octet_string->length, 0.0);
  141. return p8;
  142. error:
  143. PKCS8_PRIV_KEY_INFO_free(p8);
  144. return NULL;
  145. }
  146. PKCS8_PRIV_KEY_INFO *PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken)
  147. {
  148. switch (broken) {
  149. case PKCS8_OK:
  150. p8->broken = PKCS8_OK;
  151. return p8;
  152. break;
  153. case PKCS8_NO_OCTET:
  154. p8->broken = PKCS8_NO_OCTET;
  155. p8->pkey->type = V_ASN1_SEQUENCE;
  156. return p8;
  157. break;
  158. default:
  159. EVPerr(EVP_F_PKCS8_SET_BROKEN,EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE);
  160. return NULL;
  161. }
  162. }
  163. /* EVP_PKEY attribute functions */
  164. int EVP_PKEY_get_attr_count(const EVP_PKEY *key)
  165. {
  166. return X509at_get_attr_count(key->attributes);
  167. }
  168. int EVP_PKEY_get_attr_by_NID(const EVP_PKEY *key, int nid,
  169. int lastpos)
  170. {
  171. return X509at_get_attr_by_NID(key->attributes, nid, lastpos);
  172. }
  173. int EVP_PKEY_get_attr_by_OBJ(const EVP_PKEY *key, ASN1_OBJECT *obj,
  174. int lastpos)
  175. {
  176. return X509at_get_attr_by_OBJ(key->attributes, obj, lastpos);
  177. }
  178. X509_ATTRIBUTE *EVP_PKEY_get_attr(const EVP_PKEY *key, int loc)
  179. {
  180. return X509at_get_attr(key->attributes, loc);
  181. }
  182. X509_ATTRIBUTE *EVP_PKEY_delete_attr(EVP_PKEY *key, int loc)
  183. {
  184. return X509at_delete_attr(key->attributes, loc);
  185. }
  186. int EVP_PKEY_add1_attr(EVP_PKEY *key, X509_ATTRIBUTE *attr)
  187. {
  188. if(X509at_add1_attr(&key->attributes, attr)) return 1;
  189. return 0;
  190. }
  191. int EVP_PKEY_add1_attr_by_OBJ(EVP_PKEY *key,
  192. const ASN1_OBJECT *obj, int type,
  193. const unsigned char *bytes, int len)
  194. {
  195. if(X509at_add1_attr_by_OBJ(&key->attributes, obj,
  196. type, bytes, len)) return 1;
  197. return 0;
  198. }
  199. int EVP_PKEY_add1_attr_by_NID(EVP_PKEY *key,
  200. int nid, int type,
  201. const unsigned char *bytes, int len)
  202. {
  203. if(X509at_add1_attr_by_NID(&key->attributes, nid,
  204. type, bytes, len)) return 1;
  205. return 0;
  206. }
  207. int EVP_PKEY_add1_attr_by_txt(EVP_PKEY *key,
  208. const char *attrname, int type,
  209. const unsigned char *bytes, int len)
  210. {
  211. if(X509at_add1_attr_by_txt(&key->attributes, attrname,
  212. type, bytes, len)) return 1;
  213. return 0;
  214. }