8bea61ebbd2e409139ac24d0e7acdffe0e8b30ea
[openssl.git] / crypto / evp / evp_pkey.c
1 /* evp_pkey.c */
2 /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
3  * project 1999.
4  */
5 /* ====================================================================
6  * Copyright (c) 1999 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
59 #include <stdio.h>
60 #include <stdlib.h>
61 #include "cryptlib.h"
62 #include <openssl/x509.h>
63 #include <openssl/rand.h>
64
65 /* Extract a private key from a PKCS8 structure */
66
67 EVP_PKEY *EVP_PKCS82PKEY (PKCS8_PRIV_KEY_INFO *p8)
68 {
69         EVP_PKEY *pkey;
70         RSA *rsa;
71         DSA *dsa;
72         ASN1_INTEGER *dsapriv;
73         X509_ALGOR *a;
74         STACK *ndsa;
75         BN_CTX *ctx;
76         unsigned char *p;
77         int plen, pkeylen;
78         char obj_tmp[80];
79
80         switch (p8->broken) {
81                 case PKCS8_OK:
82                 p = p8->pkey->value.octet_string->data;
83                 pkeylen = p8->pkey->value.octet_string->length;
84                 break;
85
86                 case PKCS8_NO_OCTET:
87                 p = p8->pkey->value.sequence->data;
88                 pkeylen = p8->pkey->value.sequence->length;
89                 break;
90
91                 default:
92                 EVPerr(EVP_F_EVP_PKCS82PKEY,EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE);
93                 return NULL;
94                 break;
95         }
96         if (!(pkey = EVP_PKEY_new())) {
97                 EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE);
98                 return NULL;
99         }
100         a = p8->pkeyalg;
101         switch (OBJ_obj2nid(a->algorithm))
102         {
103                 case NID_rsaEncryption:
104                 if (!(rsa = d2i_RSAPrivateKey (NULL, &p, pkeylen))) {
105                         EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
106                         return NULL;
107                 }
108                 EVP_PKEY_assign_RSA (pkey, rsa);
109                 break;
110                 
111                 case NID_dsa:
112                 /* PKCS#8 DSA is weird: you just get a private key integer
113                  * and parameters in the AlgorithmIdentifier the pubkey must
114                  * be recalculated.
115                  */
116         
117                 /* Check for broken Netscape Database DSA PKCS#8, UGH! */
118                 if(*p == (V_ASN1_SEQUENCE|V_ASN1_CONSTRUCTED)) {
119                     if(!(ndsa = ASN1_seq_unpack(p, pkeylen, 
120                                         (char *(*)())d2i_ASN1_INTEGER,
121                                                          ASN1_STRING_free))) {
122                         EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
123                         return NULL;
124                     }
125                     if(sk_num(ndsa) != 2 ) {
126                         EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
127                         sk_pop_free(ndsa, ASN1_STRING_free);
128                         return NULL;
129                     }
130                     dsapriv = (ASN1_INTEGER *) sk_pop(ndsa);
131                     sk_pop_free(ndsa, ASN1_STRING_free);
132                 } else if (!(dsapriv=d2i_ASN1_INTEGER (NULL, &p, pkeylen))) {
133                         EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
134                         return NULL;
135                 }
136                 /* Retrieve parameters */
137                 if (a->parameter->type != V_ASN1_SEQUENCE) {
138                         EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_NO_DSA_PARAMETERS);
139                         return NULL;
140                 }
141                 p = a->parameter->value.sequence->data;
142                 plen = a->parameter->value.sequence->length;
143                 if (!(dsa = d2i_DSAparams (NULL, &p, plen))) {
144                         EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR);
145                         return NULL;
146                 }
147                 /* We have parameters now set private key */
148                 if (!(dsa->priv_key = ASN1_INTEGER_to_BN(dsapriv, NULL))) {
149                         EVPerr(EVP_F_EVP_PKCS82PKEY,EVP_R_BN_DECODE_ERROR);
150                         DSA_free (dsa);
151                         return NULL;
152                 }
153                 /* Calculate public key (ouch!) */
154                 if (!(dsa->pub_key = BN_new())) {
155                         EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE);
156                         DSA_free (dsa);
157                         return NULL;
158                 }
159                 if (!(ctx = BN_CTX_new())) {
160                         EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE);
161                         DSA_free (dsa);
162                         return NULL;
163                 }
164                         
165                 if (!BN_mod_exp(dsa->pub_key, dsa->g,
166                                                  dsa->priv_key, dsa->p, ctx)) {
167                         
168                         EVPerr(EVP_F_EVP_PKCS82PKEY,EVP_R_BN_PUBKEY_ERROR);
169                         BN_CTX_free (ctx);
170                         DSA_free (dsa);
171                         return NULL;
172                 }
173
174                 EVP_PKEY_assign_DSA (pkey, dsa);
175                 BN_CTX_free (ctx);
176                 break;
177
178                 default:
179                 EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
180                 if (!a->algorithm) strcpy (obj_tmp, "NULL");
181                 else i2t_ASN1_OBJECT(obj_tmp, 80, a->algorithm);
182                 ERR_add_error_data(2, "TYPE=", obj_tmp);
183                 EVP_PKEY_free (pkey);
184                 return NULL;
185         }
186         return pkey;
187 }
188
189 /* Turn a private key into a PKCS8 structure */
190
191 PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey)
192 {
193         PKCS8_PRIV_KEY_INFO *p8;
194         ASN1_INTEGER *dpkey;
195         unsigned char *p, *q;
196         int len;
197         if (!(p8 = PKCS8_PRIV_KEY_INFO_new())) {        
198                 EVPerr(EVP_F_EVP_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
199                 return NULL;
200         }
201         ASN1_INTEGER_set (p8->version, 0);
202         if (!(p8->pkeyalg->parameter = ASN1_TYPE_new ())) {
203                 EVPerr(EVP_F_EVP_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
204                 PKCS8_PRIV_KEY_INFO_free (p8);
205                 return NULL;
206         }
207         switch (EVP_PKEY_type(pkey->type)) {
208                 case EVP_PKEY_RSA:
209
210                 p8->pkeyalg->algorithm = OBJ_nid2obj(NID_rsaEncryption);
211                 p8->pkeyalg->parameter->type = V_ASN1_NULL;
212                 if (!ASN1_pack_string ((char *)pkey, i2d_PrivateKey,
213                                          &p8->pkey->value.octet_string)) {
214                         EVPerr(EVP_F_EVP_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
215                         PKCS8_PRIV_KEY_INFO_free (p8);
216                         return NULL;
217                 }
218                 break;
219
220                 case EVP_PKEY_DSA:
221                 p8->pkeyalg->algorithm = OBJ_nid2obj(NID_dsa);
222
223                 /* get paramaters and place in AlgorithmIdentifier */
224                 len = i2d_DSAparams (pkey->pkey.dsa, NULL);
225                 if (!(p = Malloc(len))) {
226                         EVPerr(EVP_F_EVP_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
227                         PKCS8_PRIV_KEY_INFO_free (p8);
228                         return NULL;
229                 }
230                 q = p;
231                 i2d_DSAparams (pkey->pkey.dsa, &q);
232                 p8->pkeyalg->parameter->type = V_ASN1_SEQUENCE;
233                 p8->pkeyalg->parameter->value.sequence = ASN1_STRING_new();
234                 ASN1_STRING_set(p8->pkeyalg->parameter->value.sequence, p, len);
235                 Free(p);
236                 /* Get private key into an integer and pack */
237                 if (!(dpkey = BN_to_ASN1_INTEGER (pkey->pkey.dsa->priv_key, NULL))) {
238                         EVPerr(EVP_F_EVP_PKEY2PKCS8,EVP_R_ENCODE_ERROR);
239                         PKCS8_PRIV_KEY_INFO_free (p8);
240                         return NULL;
241                 }
242                 
243                 if (!ASN1_pack_string((char *)dpkey, i2d_ASN1_INTEGER,
244                                          &p8->pkey->value.octet_string)) {
245                         EVPerr(EVP_F_EVP_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
246                         ASN1_INTEGER_free (dpkey);
247                         PKCS8_PRIV_KEY_INFO_free (p8);
248                         return NULL;
249                 }
250                 ASN1_INTEGER_free (dpkey);
251                 break;
252
253                 default:
254                 EVPerr(EVP_F_EVP_PKEY2PKCS8, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
255                 PKCS8_PRIV_KEY_INFO_free (p8);
256                 return NULL;
257         }
258         p8->pkey->type = V_ASN1_OCTET_STRING;
259         RAND_seed (p8->pkey->value.octet_string->data,
260                                          p8->pkey->value.octet_string->length);
261         return p8;
262 }
263
264 PKCS8_PRIV_KEY_INFO *PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken)
265 {
266         switch (broken) {
267
268                 case PKCS8_OK:
269                 p8->broken = PKCS8_OK;
270                 return p8;
271                 break;
272
273                 case PKCS8_NO_OCTET:
274                 p8->broken = PKCS8_NO_OCTET;
275                 p8->pkey->type = V_ASN1_SEQUENCE;
276                 return p8;
277                 break;
278
279                 default:
280                 EVPerr(EVP_F_EVP_PKCS8_SET_BROKEN,EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE);
281                 return NULL;
282                 break;
283                 
284         }
285 }
286
287