65ccd5bac4fd2cac3ab8223179e6e53b14033358
[openssl.git] / crypto / evp / evp_pkey.c
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
60 #include <stdio.h>
61 #include <stdlib.h>
62 #include "internal/cryptlib.h"
63 #include <openssl/x509.h>
64 #include <openssl/rand.h>
65 #include "internal/asn1_int.h"
66 #include "internal/evp_int.h"
67
68 /* Extract a private key from a PKCS8 structure */
69
70 EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8)
71 {
72     EVP_PKEY *pkey = NULL;
73     ASN1_OBJECT *algoid;
74     char obj_tmp[80];
75
76     if (!PKCS8_pkey_get0(&algoid, NULL, NULL, NULL, p8))
77         return NULL;
78
79     if ((pkey = EVP_PKEY_new()) == NULL) {
80         EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_MALLOC_FAILURE);
81         return NULL;
82     }
83
84     if (!EVP_PKEY_set_type(pkey, OBJ_obj2nid(algoid))) {
85         EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
86         i2t_ASN1_OBJECT(obj_tmp, 80, algoid);
87         ERR_add_error_data(2, "TYPE=", obj_tmp);
88         goto error;
89     }
90
91     if (pkey->ameth->priv_decode) {
92         if (!pkey->ameth->priv_decode(pkey, p8)) {
93             EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_PRIVATE_KEY_DECODE_ERROR);
94             goto error;
95         }
96     } else {
97         EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_METHOD_NOT_SUPPORTED);
98         goto error;
99     }
100
101     return pkey;
102
103  error:
104     EVP_PKEY_free(pkey);
105     return NULL;
106 }
107
108 PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey)
109 {
110     return EVP_PKEY2PKCS8_broken(pkey, PKCS8_OK);
111 }
112
113 /* Turn a private key into a PKCS8 structure */
114
115 PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken)
116 {
117     PKCS8_PRIV_KEY_INFO *p8;
118
119     if ((p8 = PKCS8_PRIV_KEY_INFO_new()) == NULL) {
120         EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN, ERR_R_MALLOC_FAILURE);
121         return NULL;
122     }
123     p8->broken = broken;
124
125     if (pkey->ameth) {
126         if (pkey->ameth->priv_encode) {
127             if (!pkey->ameth->priv_encode(p8, pkey)) {
128                 EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,
129                        EVP_R_PRIVATE_KEY_ENCODE_ERROR);
130                 goto error;
131             }
132         } else {
133             EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN, EVP_R_METHOD_NOT_SUPPORTED);
134             goto error;
135         }
136     } else {
137         EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,
138                EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
139         goto error;
140     }
141     RAND_add(p8->pkey->value.octet_string->data,
142              p8->pkey->value.octet_string->length, 0.0);
143     return p8;
144  error:
145     PKCS8_PRIV_KEY_INFO_free(p8);
146     return NULL;
147 }
148
149 PKCS8_PRIV_KEY_INFO *PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken)
150 {
151     switch (broken) {
152
153     case PKCS8_OK:
154         p8->broken = PKCS8_OK;
155         return p8;
156
157     case PKCS8_NO_OCTET:
158         p8->broken = PKCS8_NO_OCTET;
159         p8->pkey->type = V_ASN1_SEQUENCE;
160         return p8;
161
162     default:
163         EVPerr(EVP_F_PKCS8_SET_BROKEN, EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE);
164         return NULL;
165     }
166 }
167
168 /* EVP_PKEY attribute functions */
169
170 int EVP_PKEY_get_attr_count(const EVP_PKEY *key)
171 {
172     return X509at_get_attr_count(key->attributes);
173 }
174
175 int EVP_PKEY_get_attr_by_NID(const EVP_PKEY *key, int nid, int lastpos)
176 {
177     return X509at_get_attr_by_NID(key->attributes, nid, lastpos);
178 }
179
180 int EVP_PKEY_get_attr_by_OBJ(const EVP_PKEY *key, ASN1_OBJECT *obj,
181                              int lastpos)
182 {
183     return X509at_get_attr_by_OBJ(key->attributes, obj, lastpos);
184 }
185
186 X509_ATTRIBUTE *EVP_PKEY_get_attr(const EVP_PKEY *key, int loc)
187 {
188     return X509at_get_attr(key->attributes, loc);
189 }
190
191 X509_ATTRIBUTE *EVP_PKEY_delete_attr(EVP_PKEY *key, int loc)
192 {
193     return X509at_delete_attr(key->attributes, loc);
194 }
195
196 int EVP_PKEY_add1_attr(EVP_PKEY *key, X509_ATTRIBUTE *attr)
197 {
198     if (X509at_add1_attr(&key->attributes, attr))
199         return 1;
200     return 0;
201 }
202
203 int EVP_PKEY_add1_attr_by_OBJ(EVP_PKEY *key,
204                               const ASN1_OBJECT *obj, int type,
205                               const unsigned char *bytes, int len)
206 {
207     if (X509at_add1_attr_by_OBJ(&key->attributes, obj, type, bytes, len))
208         return 1;
209     return 0;
210 }
211
212 int EVP_PKEY_add1_attr_by_NID(EVP_PKEY *key,
213                               int nid, int type,
214                               const unsigned char *bytes, int len)
215 {
216     if (X509at_add1_attr_by_NID(&key->attributes, nid, type, bytes, len))
217         return 1;
218     return 0;
219 }
220
221 int EVP_PKEY_add1_attr_by_txt(EVP_PKEY *key,
222                               const char *attrname, int type,
223                               const unsigned char *bytes, int len)
224 {
225     if (X509at_add1_attr_by_txt(&key->attributes, attrname, type, bytes, len))
226         return 1;
227     return 0;
228 }