evp_pkey.c 7.0 KB

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