Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / boringssl / src / crypto / evp / p_ec_asn1.c
1 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
2  * project 2006.
3  */
4 /* ====================================================================
5  * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer. 
13  *
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in
16  *    the documentation and/or other materials provided with the
17  *    distribution.
18  *
19  * 3. All advertising materials mentioning features or use of this
20  *    software must display the following acknowledgment:
21  *    "This product includes software developed by the OpenSSL Project
22  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
23  *
24  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
25  *    endorse or promote products derived from this software without
26  *    prior written permission. For written permission, please contact
27  *    licensing@OpenSSL.org.
28  *
29  * 5. Products derived from this software may not be called "OpenSSL"
30  *    nor may "OpenSSL" appear in their names without prior written
31  *    permission of the OpenSSL Project.
32  *
33  * 6. Redistributions of any form whatsoever must retain the following
34  *    acknowledgment:
35  *    "This product includes software developed by the OpenSSL Project
36  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
37  *
38  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
39  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
41  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
42  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
43  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
44  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
47  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
48  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
49  * OF THE POSSIBILITY OF SUCH DAMAGE.
50  * ====================================================================
51  *
52  * This product includes cryptographic software written by Eric Young
53  * (eay@cryptsoft.com).  This product includes software written by Tim
54  * Hudson (tjh@cryptsoft.com). */
55
56 #include <openssl/evp.h>
57
58 #include <openssl/asn1t.h>
59 #include <openssl/bn.h>
60 #include <openssl/ec.h>
61 #include <openssl/err.h>
62 #include <openssl/mem.h>
63 #include <openssl/obj.h>
64 #include <openssl/x509.h>
65
66 #include "internal.h"
67
68
69 static int eckey_param2type(int *pptype, void **ppval, EC_KEY *ec_key) {
70   const EC_GROUP *group;
71   int nid;
72
73   if (ec_key == NULL || (group = EC_KEY_get0_group(ec_key)) == NULL) {
74     OPENSSL_PUT_ERROR(EVP, eckey_param2type, EVP_R_MISSING_PARAMETERS);
75     return 0;
76   }
77
78   nid = EC_GROUP_get_curve_name(group);
79   if (nid == NID_undef) {
80     OPENSSL_PUT_ERROR(EVP, eckey_param2type, EVP_R_NO_NID_FOR_CURVE);
81     return 0;
82   }
83
84   *ppval = (void*) OBJ_nid2obj(nid);
85   *pptype = V_ASN1_OBJECT;
86   return 1;
87 }
88
89 static int eckey_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) {
90   EC_KEY *ec_key = pkey->pkey.ec;
91   void *pval = NULL;
92   int ptype;
93   uint8_t *penc = NULL, *p;
94   int penclen;
95
96   if (!eckey_param2type(&ptype, &pval, ec_key)) {
97     OPENSSL_PUT_ERROR(EVP, eckey_pub_encode, ERR_R_EC_LIB);
98     return 0;
99   }
100   penclen = i2o_ECPublicKey(ec_key, NULL);
101   if (penclen <= 0) {
102     goto err;
103   }
104   penc = OPENSSL_malloc(penclen);
105   if (!penc) {
106     goto err;
107   }
108   p = penc;
109   penclen = i2o_ECPublicKey(ec_key, &p);
110   if (penclen <= 0) {
111     goto err;
112   }
113   if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_EC), ptype, pval, penc,
114                              penclen)) {
115     return 1;
116   }
117
118 err:
119   if (ptype == V_ASN1_OBJECT) {
120     ASN1_OBJECT_free(pval);
121   } else {
122     ASN1_STRING_free(pval);
123   }
124   if (penc) {
125     OPENSSL_free(penc);
126   }
127   return 0;
128 }
129
130 static EC_KEY *eckey_type2param(int ptype, void *pval) {
131   EC_KEY *eckey = NULL;
132
133   if (ptype == V_ASN1_SEQUENCE) {
134     ASN1_STRING *pstr = pval;
135     const uint8_t *pm = pstr->data;
136     int pmlen = pstr->length;
137
138     eckey = d2i_ECParameters(NULL, &pm, pmlen);
139     if (eckey == NULL) {
140       OPENSSL_PUT_ERROR(EVP, eckey_type2param, EVP_R_DECODE_ERROR);
141       goto err;
142     }
143   } else if (ptype == V_ASN1_OBJECT) {
144     ASN1_OBJECT *poid = pval;
145     EC_GROUP *group;
146
147     /* type == V_ASN1_OBJECT => the parameters are given
148      * by an asn1 OID */
149     eckey = EC_KEY_new();
150     if (eckey == NULL) {
151       OPENSSL_PUT_ERROR(EVP, eckey_type2param, ERR_R_MALLOC_FAILURE);
152       goto err;
153     }
154     group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(poid));
155     if (group == NULL) {
156       goto err;
157     }
158     if (EC_KEY_set_group(eckey, group) == 0) {
159       goto err;
160     }
161     EC_GROUP_free(group);
162   } else {
163     OPENSSL_PUT_ERROR(EVP, eckey_type2param, EVP_R_DECODE_ERROR);
164     goto err;
165   }
166
167   return eckey;
168
169 err:
170   if (eckey) {
171     EC_KEY_free(eckey);
172   }
173   return NULL;
174 }
175
176 static int eckey_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) {
177   const uint8_t *p = NULL;
178   void *pval;
179   int ptype, pklen;
180   EC_KEY *eckey = NULL;
181   X509_ALGOR *palg;
182
183   if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey)) {
184     return 0;
185   }
186   X509_ALGOR_get0(NULL, &ptype, &pval, palg);
187
188   eckey = eckey_type2param(ptype, pval);
189   if (!eckey) {
190     OPENSSL_PUT_ERROR(EVP, eckey_pub_decode, ERR_R_EC_LIB);
191     return 0;
192   }
193
194   /* We have parameters now set public key */
195   if (!o2i_ECPublicKey(&eckey, &p, pklen)) {
196     OPENSSL_PUT_ERROR(EVP, eckey_pub_decode, EVP_R_DECODE_ERROR);
197     goto err;
198   }
199
200   EVP_PKEY_assign_EC_KEY(pkey, eckey);
201   return 1;
202
203 err:
204   if (eckey)
205     EC_KEY_free(eckey);
206   return 0;
207 }
208
209 static int eckey_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) {
210   int r;
211   const EC_GROUP *group = EC_KEY_get0_group(b->pkey.ec);
212   const EC_POINT *pa = EC_KEY_get0_public_key(a->pkey.ec),
213                  *pb = EC_KEY_get0_public_key(b->pkey.ec);
214   r = EC_POINT_cmp(group, pa, pb, NULL);
215   if (r == 0) {
216     return 1;
217   } else if (r == 1) {
218     return 0;
219   } else {
220     return -2;
221   }
222 }
223
224 static int eckey_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) {
225   const uint8_t *p = NULL;
226   void *pval;
227   int ptype, pklen;
228   EC_KEY *eckey = NULL;
229   X509_ALGOR *palg;
230
231   if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8)) {
232     return 0;
233   }
234   X509_ALGOR_get0(NULL, &ptype, &pval, palg);
235
236   eckey = eckey_type2param(ptype, pval);
237
238   if (!eckey)
239     goto ecliberr;
240
241   /* We have parameters now set private key */
242   if (!d2i_ECPrivateKey(&eckey, &p, pklen)) {
243     OPENSSL_PUT_ERROR(EVP, eckey_priv_decode, EVP_R_DECODE_ERROR);
244     goto ecerr;
245   }
246
247   /* calculate public key (if necessary) */
248   if (EC_KEY_get0_public_key(eckey) == NULL) {
249     const BIGNUM *priv_key;
250     const EC_GROUP *group;
251     EC_POINT *pub_key;
252     /* the public key was not included in the SEC1 private
253      * key => calculate the public key */
254     group = EC_KEY_get0_group(eckey);
255     pub_key = EC_POINT_new(group);
256     if (pub_key == NULL) {
257       OPENSSL_PUT_ERROR(EVP, eckey_priv_decode, ERR_R_EC_LIB);
258       goto ecliberr;
259     }
260     if (!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group))) {
261       EC_POINT_free(pub_key);
262       OPENSSL_PUT_ERROR(EVP, eckey_priv_decode, ERR_R_EC_LIB);
263       goto ecliberr;
264     }
265     priv_key = EC_KEY_get0_private_key(eckey);
266     if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, NULL)) {
267       EC_POINT_free(pub_key);
268       OPENSSL_PUT_ERROR(EVP, eckey_priv_decode, ERR_R_EC_LIB);
269       goto ecliberr;
270     }
271     if (EC_KEY_set_public_key(eckey, pub_key) == 0) {
272       EC_POINT_free(pub_key);
273       OPENSSL_PUT_ERROR(EVP, eckey_priv_decode, ERR_R_EC_LIB);
274       goto ecliberr;
275     }
276     EC_POINT_free(pub_key);
277   }
278
279   EVP_PKEY_assign_EC_KEY(pkey, eckey);
280   return 1;
281
282 ecliberr:
283   OPENSSL_PUT_ERROR(EVP, eckey_priv_decode, ERR_R_EC_LIB);
284 ecerr:
285   if (eckey)
286     EC_KEY_free(eckey);
287   return 0;
288 }
289
290 static int eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) {
291   EC_KEY *ec_key;
292   uint8_t *ep, *p;
293   int eplen, ptype;
294   void *pval;
295   unsigned int tmp_flags, old_flags;
296
297   ec_key = pkey->pkey.ec;
298
299   if (!eckey_param2type(&ptype, &pval, ec_key)) {
300     OPENSSL_PUT_ERROR(EVP, eckey_priv_encode, EVP_R_DECODE_ERROR);
301     return 0;
302   }
303
304   /* set the private key */
305
306   /* do not include the parameters in the SEC1 private key
307    * see PKCS#11 12.11 */
308   old_flags = EC_KEY_get_enc_flags(ec_key);
309   tmp_flags = old_flags | EC_PKEY_NO_PARAMETERS;
310   EC_KEY_set_enc_flags(ec_key, tmp_flags);
311   eplen = i2d_ECPrivateKey(ec_key, NULL);
312   if (!eplen) {
313     EC_KEY_set_enc_flags(ec_key, old_flags);
314     OPENSSL_PUT_ERROR(EVP, eckey_priv_encode, ERR_R_EC_LIB);
315     return 0;
316   }
317   ep = (uint8_t *)OPENSSL_malloc(eplen);
318   if (!ep) {
319     EC_KEY_set_enc_flags(ec_key, old_flags);
320     OPENSSL_PUT_ERROR(EVP, eckey_priv_encode, ERR_R_MALLOC_FAILURE);
321     return 0;
322   }
323   p = ep;
324   if (!i2d_ECPrivateKey(ec_key, &p)) {
325     EC_KEY_set_enc_flags(ec_key, old_flags);
326     OPENSSL_free(ep);
327     OPENSSL_PUT_ERROR(EVP, eckey_priv_encode, ERR_R_EC_LIB);
328     return 0;
329   }
330   /* restore old encoding flags */
331   EC_KEY_set_enc_flags(ec_key, old_flags);
332
333   if (!PKCS8_pkey_set0(p8, (ASN1_OBJECT *)OBJ_nid2obj(NID_X9_62_id_ecPublicKey),
334                        0, ptype, pval, ep, eplen)) {
335     return 0;
336   }
337
338   return 1;
339 }
340
341 static int int_ec_size(const EVP_PKEY *pkey) {
342   return ECDSA_size(pkey->pkey.ec);
343 }
344
345 static int ec_bits(const EVP_PKEY *pkey) {
346   BIGNUM *order = BN_new();
347   const EC_GROUP *group;
348   int ret;
349
350   if (!order) {
351     ERR_clear_error();
352     return 0;
353   }
354   group = EC_KEY_get0_group(pkey->pkey.ec);
355   if (!EC_GROUP_get_order(group, order, NULL)) {
356     ERR_clear_error();
357     return 0;
358   }
359
360   ret = BN_num_bits(order);
361   BN_free(order);
362   return ret;
363 }
364
365 static int ec_missing_parameters(const EVP_PKEY *pkey) {
366   return EC_KEY_get0_group(pkey->pkey.ec) == NULL;
367 }
368
369 static int ec_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) {
370   EC_GROUP *group = EC_GROUP_dup(EC_KEY_get0_group(from->pkey.ec));
371   if (group == NULL ||
372       EC_KEY_set_group(to->pkey.ec, group) == 0) {
373     return 0;
374   }
375   EC_GROUP_free(group);
376   return 1;
377 }
378
379 static int ec_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) {
380   const EC_GROUP *group_a = EC_KEY_get0_group(a->pkey.ec),
381                  *group_b = EC_KEY_get0_group(b->pkey.ec);
382   return EC_GROUP_cmp(group_a, group_b);
383 }
384
385 static void int_ec_free(EVP_PKEY *pkey) { EC_KEY_free(pkey->pkey.ec); }
386
387 static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype) {
388   uint8_t *buffer = NULL;
389   const char *ecstr;
390   size_t buf_len = 0, i;
391   int ret = 0, reason = ERR_R_BIO_LIB;
392   BIGNUM *order = NULL;
393   BN_CTX *ctx = NULL;
394   const EC_GROUP *group;
395   const EC_POINT *public_key;
396   const BIGNUM *priv_key;
397   uint8_t *pub_key_bytes = NULL;
398   size_t pub_key_bytes_len = 0;
399
400   if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) {
401     reason = ERR_R_PASSED_NULL_PARAMETER;
402     goto err;
403   }
404
405   ctx = BN_CTX_new();
406   if (ctx == NULL) {
407     reason = ERR_R_MALLOC_FAILURE;
408     goto err;
409   }
410
411   if (ktype > 0) {
412     public_key = EC_KEY_get0_public_key(x);
413     if (public_key != NULL) {
414       pub_key_bytes_len = EC_POINT_point2oct(
415           group, public_key, EC_KEY_get_conv_form(x), NULL, 0, ctx);
416       if (pub_key_bytes_len == 0) {
417         reason = ERR_R_MALLOC_FAILURE;
418         goto err;
419       }
420       pub_key_bytes = OPENSSL_malloc(pub_key_bytes_len);
421       if (pub_key_bytes == NULL) {
422         reason = ERR_R_MALLOC_FAILURE;
423         goto err;
424       }
425       pub_key_bytes_len =
426           EC_POINT_point2oct(group, public_key, EC_KEY_get_conv_form(x),
427                              pub_key_bytes, pub_key_bytes_len, ctx);
428       if (pub_key_bytes_len == 0) {
429         reason = ERR_R_MALLOC_FAILURE;
430         goto err;
431       }
432       buf_len = pub_key_bytes_len;
433     }
434   }
435
436   if (ktype == 2) {
437     priv_key = EC_KEY_get0_private_key(x);
438     if (priv_key && (i = (size_t)BN_num_bytes(priv_key)) > buf_len)
439       buf_len = i;
440   } else
441     priv_key = NULL;
442
443   if (ktype > 0) {
444     buf_len += 10;
445     if ((buffer = OPENSSL_malloc(buf_len)) == NULL) {
446       reason = ERR_R_MALLOC_FAILURE;
447       goto err;
448     }
449   }
450   if (ktype == 2)
451     ecstr = "Private-Key";
452   else if (ktype == 1)
453     ecstr = "Public-Key";
454   else
455     ecstr = "ECDSA-Parameters";
456
457   if (!BIO_indent(bp, off, 128))
458     goto err;
459   if ((order = BN_new()) == NULL)
460     goto err;
461   if (!EC_GROUP_get_order(group, order, NULL))
462     goto err;
463   if (BIO_printf(bp, "%s: (%d bit)\n", ecstr, BN_num_bits(order)) <= 0)
464     goto err;
465
466   if ((priv_key != NULL) && !ASN1_bn_print(bp, "priv:", priv_key, buffer, off))
467     goto err;
468   if (pub_key_bytes != NULL) {
469     BIO_hexdump(bp, pub_key_bytes, pub_key_bytes_len, off);
470   }
471   /* TODO(fork): implement */
472   /*
473   if (!ECPKParameters_print(bp, group, off))
474     goto err; */
475   ret = 1;
476
477 err:
478   if (!ret)
479     OPENSSL_PUT_ERROR(EVP, do_EC_KEY_print, reason);
480   if (pub_key_bytes)
481     OPENSSL_free(pub_key_bytes);
482   if (order)
483     BN_free(order);
484   if (ctx)
485     BN_CTX_free(ctx);
486   if (buffer != NULL)
487     OPENSSL_free(buffer);
488   return ret;
489 }
490
491 static int eckey_param_decode(EVP_PKEY *pkey, const uint8_t **pder,
492                               int derlen) {
493   EC_KEY *eckey;
494   if (!(eckey = d2i_ECParameters(NULL, pder, derlen))) {
495     OPENSSL_PUT_ERROR(EVP, eckey_param_decode, ERR_R_EC_LIB);
496     return 0;
497   }
498   EVP_PKEY_assign_EC_KEY(pkey, eckey);
499   return 1;
500 }
501
502 static int eckey_param_encode(const EVP_PKEY *pkey, uint8_t **pder) {
503   return i2d_ECParameters(pkey->pkey.ec, pder);
504 }
505
506 static int eckey_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
507                              ASN1_PCTX *ctx) {
508   return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 0);
509 }
510
511 static int eckey_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
512                            ASN1_PCTX *ctx) {
513   return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 1);
514 }
515
516
517 static int eckey_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
518                             ASN1_PCTX *ctx) {
519   return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 2);
520 }
521
522 static int eckey_opaque(const EVP_PKEY *pkey) {
523   return EC_KEY_is_opaque(pkey->pkey.ec);
524 }
525
526 static int old_ec_priv_decode(EVP_PKEY *pkey, const uint8_t **pder,
527                               int derlen) {
528   EC_KEY *ec;
529   if (!(ec = d2i_ECPrivateKey(NULL, pder, derlen))) {
530     OPENSSL_PUT_ERROR(EVP, old_ec_priv_decode, EVP_R_DECODE_ERROR);
531     return 0;
532   }
533   EVP_PKEY_assign_EC_KEY(pkey, ec);
534   return 1;
535 }
536
537 static int old_ec_priv_encode(const EVP_PKEY *pkey, uint8_t **pder) {
538   return i2d_ECPrivateKey(pkey->pkey.ec, pder);
539 }
540
541 static int ec_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) {
542   switch (op) {
543     case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
544       *(int *)arg2 = NID_sha1;
545       return 2;
546
547     default:
548       return -2;
549   }
550 }
551
552 const EVP_PKEY_ASN1_METHOD ec_asn1_meth = {
553   EVP_PKEY_EC,
554   EVP_PKEY_EC,
555   0,
556   "EC",
557   "OpenSSL EC algorithm",
558
559   eckey_pub_decode,
560   eckey_pub_encode,
561   eckey_pub_cmp,
562   eckey_pub_print,
563
564   eckey_priv_decode,
565   eckey_priv_encode,
566   eckey_priv_print,
567
568   eckey_opaque,
569
570   int_ec_size,
571   ec_bits,
572
573   eckey_param_decode,
574   eckey_param_encode,
575   ec_missing_parameters,
576   ec_copy_parameters,
577   ec_cmp_parameters,
578   eckey_param_print,
579   0,
580
581   int_ec_free,
582   ec_pkey_ctrl,
583   old_ec_priv_decode,
584   old_ec_priv_encode
585 };