• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
2  * All rights reserved.
3  *
4  * This package is an SSL implementation written
5  * by Eric Young (eay@cryptsoft.com).
6  * The implementation was written so as to conform with Netscapes SSL.
7  *
8  * This library is free for commercial and non-commercial use as long as
9  * the following conditions are aheared to.  The following conditions
10  * apply to all code found in this distribution, be it the RC4, RSA,
11  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
12  * included with this distribution is covered by the same copyright terms
13  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
14  *
15  * Copyright remains Eric Young's, and as such any Copyright notices in
16  * the code are not to be removed.
17  * If this package is used in a product, Eric Young should be given attribution
18  * as the author of the parts of the library used.
19  * This can be in the form of a textual message at program startup or
20  * in documentation (online or textual) provided with the package.
21  *
22  * Redistribution and use in source and binary forms, with or without
23  * modification, are permitted provided that the following conditions
24  * are met:
25  * 1. Redistributions of source code must retain the copyright
26  *    notice, this list of conditions and the following disclaimer.
27  * 2. Redistributions in binary form must reproduce the above copyright
28  *    notice, this list of conditions and the following disclaimer in the
29  *    documentation and/or other materials provided with the distribution.
30  * 3. All advertising materials mentioning features or use of this software
31  *    must display the following acknowledgement:
32  *    "This product includes cryptographic software written by
33  *     Eric Young (eay@cryptsoft.com)"
34  *    The word 'cryptographic' can be left out if the rouines from the library
35  *    being used are not cryptographic related :-).
36  * 4. If you include any Windows specific code (or a derivative thereof) from
37  *    the apps directory (application code) you must include an acknowledgement:
38  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
39  *
40  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50  * SUCH DAMAGE.
51  *
52  * The licence and distribution terms for any publically available version or
53  * derivative of this code cannot be changed.  i.e. this code cannot simply be
54  * copied and put under another distribution licence
55  * [including the GNU Public Licence.] */
56 
57 #include <openssl/evp.h>
58 
59 #include <assert.h>
60 #include <string.h>
61 
62 #include <openssl/bio.h>
63 #include <openssl/dh.h>
64 #include <openssl/dsa.h>
65 #include <openssl/ec.h>
66 #include <openssl/err.h>
67 #include <openssl/mem.h>
68 #include <openssl/obj.h>
69 #include <openssl/rsa.h>
70 #include <openssl/thread.h>
71 
72 #include "internal.h"
73 #include "../internal.h"
74 
75 
76 extern const EVP_PKEY_ASN1_METHOD dsa_asn1_meth;
77 extern const EVP_PKEY_ASN1_METHOD ec_asn1_meth;
78 extern const EVP_PKEY_ASN1_METHOD hmac_asn1_meth;
79 extern const EVP_PKEY_ASN1_METHOD rsa_asn1_meth;
80 
EVP_PKEY_new(void)81 EVP_PKEY *EVP_PKEY_new(void) {
82   EVP_PKEY *ret;
83 
84   ret = OPENSSL_malloc(sizeof(EVP_PKEY));
85   if (ret == NULL) {
86     OPENSSL_PUT_ERROR(EVP, EVP_PKEY_new, ERR_R_MALLOC_FAILURE);
87     return NULL;
88   }
89 
90   memset(ret, 0, sizeof(EVP_PKEY));
91   ret->type = EVP_PKEY_NONE;
92   ret->references = 1;
93 
94   return ret;
95 }
96 
free_it(EVP_PKEY * pkey)97 static void free_it(EVP_PKEY *pkey) {
98   if (pkey->ameth && pkey->ameth->pkey_free) {
99     pkey->ameth->pkey_free(pkey);
100     pkey->pkey.ptr = NULL;
101     pkey->type = EVP_PKEY_NONE;
102   }
103 }
104 
EVP_PKEY_free(EVP_PKEY * pkey)105 void EVP_PKEY_free(EVP_PKEY *pkey) {
106   if (pkey == NULL) {
107     return;
108   }
109 
110   if (!CRYPTO_refcount_dec_and_test_zero(&pkey->references)) {
111     return;
112   }
113 
114   free_it(pkey);
115   OPENSSL_free(pkey);
116 }
117 
EVP_PKEY_up_ref(EVP_PKEY * pkey)118 EVP_PKEY *EVP_PKEY_up_ref(EVP_PKEY *pkey) {
119   CRYPTO_refcount_inc(&pkey->references);
120   return pkey;
121 }
122 
EVP_PKEY_is_opaque(const EVP_PKEY * pkey)123 int EVP_PKEY_is_opaque(const EVP_PKEY *pkey) {
124   if (pkey->ameth && pkey->ameth->pkey_opaque) {
125     return pkey->ameth->pkey_opaque(pkey);
126   }
127   return 0;
128 }
129 
EVP_PKEY_supports_digest(const EVP_PKEY * pkey,const EVP_MD * md)130 int EVP_PKEY_supports_digest(const EVP_PKEY *pkey, const EVP_MD *md) {
131   if (pkey->ameth && pkey->ameth->pkey_supports_digest) {
132     return pkey->ameth->pkey_supports_digest(pkey, md);
133   }
134   return 1;
135 }
136 
EVP_PKEY_cmp(const EVP_PKEY * a,const EVP_PKEY * b)137 int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b) {
138   if (a->type != b->type) {
139     return -1;
140   }
141 
142   if (a->ameth) {
143     int ret;
144     /* Compare parameters if the algorithm has them */
145     if (a->ameth->param_cmp) {
146       ret = a->ameth->param_cmp(a, b);
147       if (ret <= 0) {
148         return ret;
149       }
150     }
151 
152     if (a->ameth->pub_cmp) {
153       return a->ameth->pub_cmp(a, b);
154     }
155   }
156 
157   return -2;
158 }
159 
EVP_PKEY_copy_parameters(EVP_PKEY * to,const EVP_PKEY * from)160 int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) {
161   if (to->type != from->type) {
162     OPENSSL_PUT_ERROR(EVP, EVP_PKEY_copy_parameters, EVP_R_DIFFERENT_KEY_TYPES);
163     goto err;
164   }
165 
166   if (EVP_PKEY_missing_parameters(from)) {
167     OPENSSL_PUT_ERROR(EVP, EVP_PKEY_copy_parameters, EVP_R_MISSING_PARAMETERS);
168     goto err;
169   }
170 
171   if (from->ameth && from->ameth->param_copy) {
172     return from->ameth->param_copy(to, from);
173   }
174 
175 err:
176   return 0;
177 }
178 
EVP_PKEY_missing_parameters(const EVP_PKEY * pkey)179 int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey) {
180   if (pkey->ameth && pkey->ameth->param_missing) {
181     return pkey->ameth->param_missing(pkey);
182   }
183   return 0;
184 }
185 
EVP_PKEY_size(const EVP_PKEY * pkey)186 int EVP_PKEY_size(const EVP_PKEY *pkey) {
187   if (pkey && pkey->ameth && pkey->ameth->pkey_size) {
188     return pkey->ameth->pkey_size(pkey);
189   }
190   return 0;
191 }
192 
EVP_PKEY_bits(EVP_PKEY * pkey)193 int EVP_PKEY_bits(EVP_PKEY *pkey) {
194   if (pkey && pkey->ameth && pkey->ameth->pkey_bits) {
195     return pkey->ameth->pkey_bits(pkey);
196   }
197   return 0;
198 }
199 
EVP_PKEY_id(const EVP_PKEY * pkey)200 int EVP_PKEY_id(const EVP_PKEY *pkey) {
201   return pkey->type;
202 }
203 
204 /* TODO(fork): remove the first argument. */
EVP_PKEY_asn1_find(ENGINE ** pengine,int nid)205 const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pengine, int nid) {
206   switch (nid) {
207     case EVP_PKEY_RSA:
208     case EVP_PKEY_RSA2:
209       return &rsa_asn1_meth;
210     case EVP_PKEY_HMAC:
211       return &hmac_asn1_meth;
212     case EVP_PKEY_EC:
213       return &ec_asn1_meth;
214     case EVP_PKEY_DSA:
215       return &dsa_asn1_meth;
216     default:
217       return NULL;
218   }
219 }
220 
EVP_PKEY_type(int nid)221 int EVP_PKEY_type(int nid) {
222   const EVP_PKEY_ASN1_METHOD *meth = EVP_PKEY_asn1_find(NULL, nid);
223   if (meth == NULL) {
224     return NID_undef;
225   }
226   return meth->pkey_id;
227 }
228 
EVP_PKEY_new_mac_key(int type,ENGINE * e,const uint8_t * mac_key,size_t mac_key_len)229 EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e, const uint8_t *mac_key,
230                                size_t mac_key_len) {
231   EVP_PKEY_CTX *mac_ctx = NULL;
232   EVP_PKEY *ret = NULL;
233 
234   mac_ctx = EVP_PKEY_CTX_new_id(type, e);
235   if (!mac_ctx) {
236     return NULL;
237   }
238 
239   if (!EVP_PKEY_keygen_init(mac_ctx) ||
240       !EVP_PKEY_CTX_ctrl(mac_ctx, -1, EVP_PKEY_OP_KEYGEN,
241                          EVP_PKEY_CTRL_SET_MAC_KEY, mac_key_len,
242                          (uint8_t *)mac_key) ||
243       !EVP_PKEY_keygen(mac_ctx, &ret)) {
244     ret = NULL;
245     goto merr;
246   }
247 
248 merr:
249   if (mac_ctx) {
250     EVP_PKEY_CTX_free(mac_ctx);
251   }
252   return ret;
253 }
254 
EVP_PKEY_set1_RSA(EVP_PKEY * pkey,RSA * key)255 int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key) {
256   if (EVP_PKEY_assign_RSA(pkey, key)) {
257     RSA_up_ref(key);
258     return 1;
259   }
260   return 0;
261 }
262 
EVP_PKEY_assign_RSA(EVP_PKEY * pkey,RSA * key)263 int EVP_PKEY_assign_RSA(EVP_PKEY *pkey, RSA *key) {
264   return EVP_PKEY_assign(pkey, EVP_PKEY_RSA, key);
265 }
266 
EVP_PKEY_get1_RSA(EVP_PKEY * pkey)267 RSA *EVP_PKEY_get1_RSA(EVP_PKEY *pkey) {
268   if (pkey->type != EVP_PKEY_RSA) {
269     OPENSSL_PUT_ERROR(EVP, EVP_PKEY_get1_RSA, EVP_R_EXPECTING_AN_RSA_KEY);
270     return NULL;
271   }
272   RSA_up_ref(pkey->pkey.rsa);
273   return pkey->pkey.rsa;
274 }
275 
EVP_PKEY_set1_DSA(EVP_PKEY * pkey,DSA * key)276 int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key) {
277   if (EVP_PKEY_assign_DSA(pkey, key)) {
278     DSA_up_ref(key);
279     return 1;
280   }
281   return 0;
282 }
283 
EVP_PKEY_assign_DSA(EVP_PKEY * pkey,DSA * key)284 int EVP_PKEY_assign_DSA(EVP_PKEY *pkey, DSA *key) {
285   return EVP_PKEY_assign(pkey, EVP_PKEY_DSA, key);
286 }
287 
EVP_PKEY_get1_DSA(EVP_PKEY * pkey)288 DSA *EVP_PKEY_get1_DSA(EVP_PKEY *pkey) {
289   if (pkey->type != EVP_PKEY_DSA) {
290     OPENSSL_PUT_ERROR(EVP, EVP_PKEY_get1_DSA, EVP_R_EXPECTING_A_DSA_KEY);
291     return NULL;
292   }
293   DSA_up_ref(pkey->pkey.dsa);
294   return pkey->pkey.dsa;
295 }
296 
EVP_PKEY_set1_EC_KEY(EVP_PKEY * pkey,EC_KEY * key)297 int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key) {
298   if (EVP_PKEY_assign_EC_KEY(pkey, key)) {
299     EC_KEY_up_ref(key);
300     return 1;
301   }
302   return 0;
303 }
304 
EVP_PKEY_assign_EC_KEY(EVP_PKEY * pkey,EC_KEY * key)305 int EVP_PKEY_assign_EC_KEY(EVP_PKEY *pkey, EC_KEY *key) {
306   return EVP_PKEY_assign(pkey, EVP_PKEY_EC, key);
307 }
308 
EVP_PKEY_get1_EC_KEY(EVP_PKEY * pkey)309 EC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey) {
310   if (pkey->type != EVP_PKEY_EC) {
311     OPENSSL_PUT_ERROR(EVP, EVP_PKEY_get1_EC_KEY, EVP_R_EXPECTING_AN_EC_KEY_KEY);
312     return NULL;
313   }
314   EC_KEY_up_ref(pkey->pkey.ec);
315   return pkey->pkey.ec;
316 }
317 
EVP_PKEY_set1_DH(EVP_PKEY * pkey,DH * key)318 int EVP_PKEY_set1_DH(EVP_PKEY *pkey, DH *key) {
319   if (EVP_PKEY_assign_DH(pkey, key)) {
320     DH_up_ref(key);
321     return 1;
322   }
323   return 0;
324 }
325 
EVP_PKEY_assign_DH(EVP_PKEY * pkey,DH * key)326 int EVP_PKEY_assign_DH(EVP_PKEY *pkey, DH *key) {
327   return EVP_PKEY_assign(pkey, EVP_PKEY_DH, key);
328 }
329 
EVP_PKEY_get1_DH(EVP_PKEY * pkey)330 DH *EVP_PKEY_get1_DH(EVP_PKEY *pkey) {
331   if (pkey->type != EVP_PKEY_DH) {
332     OPENSSL_PUT_ERROR(EVP, EVP_PKEY_get1_DH, EVP_R_EXPECTING_A_DH_KEY);
333     return NULL;
334   }
335   DH_up_ref(pkey->pkey.dh);
336   return pkey->pkey.dh;
337 }
338 
EVP_PKEY_assign(EVP_PKEY * pkey,int type,void * key)339 int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key) {
340   if (!EVP_PKEY_set_type(pkey, type)) {
341     return 0;
342   }
343   pkey->pkey.ptr = key;
344   return key != NULL;
345 }
346 
EVP_PKEY_asn1_find_str(ENGINE ** pengine,const char * name,size_t len)347 const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pengine,
348                                                    const char *name,
349                                                    size_t len) {
350   if (len == 3 && memcmp(name, "RSA", 3) == 0) {
351     return &rsa_asn1_meth;
352   } else if (len == 4 && memcmp(name, "HMAC", 4) == 0) {
353     return &hmac_asn1_meth;
354   } if (len == 2 && memcmp(name, "EC", 2) == 0) {
355     return &ec_asn1_meth;
356   }
357   return NULL;
358 }
359 
EVP_PKEY_set_type(EVP_PKEY * pkey,int type)360 int EVP_PKEY_set_type(EVP_PKEY *pkey, int type) {
361   const EVP_PKEY_ASN1_METHOD *ameth;
362 
363   if (pkey && pkey->pkey.ptr) {
364     free_it(pkey);
365   }
366 
367   ameth = EVP_PKEY_asn1_find(NULL, type);
368   if (ameth == NULL) {
369     OPENSSL_PUT_ERROR(EVP, EVP_PKEY_set_type, EVP_R_UNSUPPORTED_ALGORITHM);
370     ERR_add_error_dataf("algorithm %d (%s)", type, OBJ_nid2sn(type));
371     return 0;
372   }
373 
374   if (pkey) {
375     pkey->ameth = ameth;
376     pkey->type = pkey->ameth->pkey_id;
377   }
378 
379   return 1;
380 }
381 
382 
383 
EVP_PKEY_cmp_parameters(const EVP_PKEY * a,const EVP_PKEY * b)384 int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) {
385   if (a->type != b->type) {
386     return -1;
387   }
388   if (a->ameth && a->ameth->param_cmp) {
389     return a->ameth->param_cmp(a, b);
390   }
391   return -2;
392 }
393 
print_unsupported(BIO * out,const EVP_PKEY * pkey,int indent,const char * kstr)394 static int print_unsupported(BIO *out, const EVP_PKEY *pkey, int indent,
395                              const char *kstr) {
396   BIO_indent(out, indent, 128);
397   BIO_printf(out, "%s algorithm \"%s\" unsupported\n", kstr,
398              OBJ_nid2ln(pkey->type));
399   return 1;
400 }
401 
EVP_PKEY_print_public(BIO * out,const EVP_PKEY * pkey,int indent,ASN1_PCTX * pctx)402 int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey, int indent,
403                           ASN1_PCTX *pctx) {
404   if (pkey->ameth && pkey->ameth->pub_print) {
405     return pkey->ameth->pub_print(out, pkey, indent, pctx);
406   }
407 
408   return print_unsupported(out, pkey, indent, "Public Key");
409 }
410 
EVP_PKEY_print_private(BIO * out,const EVP_PKEY * pkey,int indent,ASN1_PCTX * pctx)411 int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey, int indent,
412                            ASN1_PCTX *pctx) {
413   if (pkey->ameth && pkey->ameth->priv_print) {
414     return pkey->ameth->priv_print(out, pkey, indent, pctx);
415   }
416 
417   return print_unsupported(out, pkey, indent, "Private Key");
418 }
419 
EVP_PKEY_print_params(BIO * out,const EVP_PKEY * pkey,int indent,ASN1_PCTX * pctx)420 int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey, int indent,
421                           ASN1_PCTX *pctx) {
422   if (pkey->ameth && pkey->ameth->param_print) {
423     return pkey->ameth->param_print(out, pkey, indent, pctx);
424   }
425 
426   return print_unsupported(out, pkey, indent, "Parameters");
427 }
428 
EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX * ctx,const EVP_MD * md)429 int EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) {
430   return EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG, EVP_PKEY_CTRL_MD, 0,
431                            (void *)md);
432 }
433 
EVP_PKEY_CTX_get_signature_md(EVP_PKEY_CTX * ctx,const EVP_MD ** out_md)434 int EVP_PKEY_CTX_get_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD **out_md) {
435   return EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG, EVP_PKEY_CTRL_GET_MD,
436                            0, (void *)out_md);
437 }
438 
EVP_PKEY_dup(EVP_PKEY * pkey)439 EVP_PKEY *EVP_PKEY_dup(EVP_PKEY *pkey) {
440   return EVP_PKEY_up_ref(pkey);
441 }
442 
OpenSSL_add_all_algorithms(void)443 void OpenSSL_add_all_algorithms(void) {}
444 
OpenSSL_add_all_ciphers(void)445 void OpenSSL_add_all_ciphers(void) {}
446 
OpenSSL_add_all_digests(void)447 void OpenSSL_add_all_digests(void) {}
448 
EVP_cleanup(void)449 void EVP_cleanup(void) {}
450