Tizen 2.0 Release
[external/libgnutls26.git] / lib / x509 / mpi.c
1 /*
2  * Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009, 2010 Free Software
3  * Foundation, Inc.
4  *
5  * Author: Nikos Mavrogiannopoulos
6  *
7  * This file is part of GnuTLS.
8  *
9  * The GnuTLS is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public License
11  * as published by the Free Software Foundation; either version 2.1 of
12  * the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
22  * USA
23  *
24  */
25
26 #include <gnutls_int.h>
27 #include <gnutls_errors.h>
28 #include <gnutls_global.h>
29 #include <libtasn1.h>
30 #include <gnutls_datum.h>
31 #include "common.h"
32 #include "x509_int.h"
33 #include <gnutls_num.h>
34
35 /*
36  * some x509 certificate parsing functions that relate to MPI parameter
37  * extraction. This reads the BIT STRING subjectPublicKey.
38  * Returns 2 parameters (m,e).
39  */
40 int
41 _gnutls_x509_read_rsa_params (opaque * der, int dersize, bigint_t * params)
42 {
43   int result;
44   ASN1_TYPE spk = ASN1_TYPE_EMPTY;
45
46   if ((result = asn1_create_element
47        (_gnutls_get_gnutls_asn (), "GNUTLS.RSAPublicKey", &spk))
48       != ASN1_SUCCESS)
49     {
50       gnutls_assert ();
51       return _gnutls_asn2err (result);
52     }
53
54   result = asn1_der_decoding (&spk, der, dersize, NULL);
55
56   if (result != ASN1_SUCCESS)
57     {
58       gnutls_assert ();
59       asn1_delete_structure (&spk);
60       return _gnutls_asn2err (result);
61     }
62
63
64   if ((result = _gnutls_x509_read_int (spk, "modulus", &params[0])) < 0)
65     {
66       gnutls_assert ();
67       asn1_delete_structure (&spk);
68       return GNUTLS_E_ASN1_GENERIC_ERROR;
69     }
70
71   if ((result = _gnutls_x509_read_int (spk, "publicExponent",
72                                        &params[1])) < 0)
73     {
74       gnutls_assert ();
75       _gnutls_mpi_release (&params[0]);
76       asn1_delete_structure (&spk);
77       return GNUTLS_E_ASN1_GENERIC_ERROR;
78     }
79
80   asn1_delete_structure (&spk);
81
82   return 0;
83
84 }
85
86
87 /* reads p,q and g 
88  * from the certificate (subjectPublicKey BIT STRING).
89  * params[0-2]
90  */
91 int
92 _gnutls_x509_read_dsa_params (opaque * der, int dersize, bigint_t * params)
93 {
94   int result;
95   ASN1_TYPE spk = ASN1_TYPE_EMPTY;
96
97   if ((result = asn1_create_element
98        (_gnutls_get_pkix (), "PKIX1.Dss-Parms", &spk)) != ASN1_SUCCESS)
99     {
100       gnutls_assert ();
101       return _gnutls_asn2err (result);
102     }
103
104   result = asn1_der_decoding (&spk, der, dersize, NULL);
105
106   if (result != ASN1_SUCCESS)
107     {
108       gnutls_assert ();
109       asn1_delete_structure (&spk);
110       return _gnutls_asn2err (result);
111     }
112
113   /* FIXME: If the parameters are not included in the certificate
114    * then the issuer's parameters should be used. This is not
115    * done yet.
116    */
117
118   /* Read p */
119
120   if ((result = _gnutls_x509_read_int (spk, "p", &params[0])) < 0)
121     {
122       gnutls_assert ();
123       asn1_delete_structure (&spk);
124       return GNUTLS_E_ASN1_GENERIC_ERROR;
125     }
126
127   /* Read q */
128
129   if ((result = _gnutls_x509_read_int (spk, "q", &params[1])) < 0)
130     {
131       gnutls_assert ();
132       asn1_delete_structure (&spk);
133       _gnutls_mpi_release (&params[0]);
134       return GNUTLS_E_ASN1_GENERIC_ERROR;
135     }
136
137   /* Read g */
138
139   if ((result = _gnutls_x509_read_int (spk, "g", &params[2])) < 0)
140     {
141       gnutls_assert ();
142       asn1_delete_structure (&spk);
143       _gnutls_mpi_release (&params[0]);
144       _gnutls_mpi_release (&params[1]);
145       return GNUTLS_E_ASN1_GENERIC_ERROR;
146     }
147
148   asn1_delete_structure (&spk);
149
150   return 0;
151
152 }
153
154 /* Reads an Integer from the DER encoded data
155  */
156
157 int
158 _gnutls_x509_read_der_int (opaque * der, int dersize, bigint_t * out)
159 {
160   int result;
161   ASN1_TYPE spk = ASN1_TYPE_EMPTY;
162
163   /* == INTEGER */
164   if ((result = asn1_create_element
165        (_gnutls_get_gnutls_asn (), "GNUTLS.DSAPublicKey",
166         &spk)) != ASN1_SUCCESS)
167     {
168       gnutls_assert ();
169       return _gnutls_asn2err (result);
170     }
171
172   result = asn1_der_decoding (&spk, der, dersize, NULL);
173
174   if (result != ASN1_SUCCESS)
175     {
176       gnutls_assert ();
177       asn1_delete_structure (&spk);
178       return _gnutls_asn2err (result);
179     }
180
181   /* Read Y */
182
183   if ((result = _gnutls_x509_read_int (spk, "", out)) < 0)
184     {
185       gnutls_assert ();
186       asn1_delete_structure (&spk);
187       return _gnutls_asn2err (result);
188     }
189
190   asn1_delete_structure (&spk);
191
192   return 0;
193
194 }
195
196 /* reads DSA's Y
197  * from the certificate 
198  * only sets params[3]
199  */
200 int
201 _gnutls_x509_read_dsa_pubkey (opaque * der, int dersize, bigint_t * params)
202 {
203   return _gnutls_x509_read_der_int (der, dersize, &params[3]);
204 }
205
206
207 /* Extracts DSA and RSA parameters from a certificate.
208  */
209 int
210 _gnutls_get_asn_mpis (ASN1_TYPE asn, const char *root,
211                       bigint_t * params, int *params_size)
212 {
213   int result;
214   char name[256];
215   gnutls_datum_t tmp = { NULL, 0 };
216   gnutls_pk_algorithm pk_algorithm;
217
218   result = _gnutls_x509_get_pk_algorithm (asn, root, NULL);
219   if (result < 0)
220     {
221       gnutls_assert ();
222       return result;
223     }
224
225   pk_algorithm = result;
226
227   /* Read the algorithm's parameters
228    */
229   _asnstr_append_name (name, sizeof (name), root, ".subjectPublicKey");
230   result = _gnutls_x509_read_value (asn, name, &tmp, 2);
231
232   if (result < 0)
233     {
234       gnutls_assert ();
235       return result;
236     }
237
238   switch (pk_algorithm)
239     {
240     case GNUTLS_PK_RSA:
241       /* params[0] is the modulus,
242        * params[1] is the exponent
243        */
244       if (*params_size < RSA_PUBLIC_PARAMS)
245         {
246           gnutls_assert ();
247           /* internal error. Increase the bigint_ts in params */
248           result = GNUTLS_E_INTERNAL_ERROR;
249           goto error;
250         }
251
252       if ((result =
253            _gnutls_x509_read_rsa_params (tmp.data, tmp.size, params)) < 0)
254         {
255           gnutls_assert ();
256           goto error;
257         }
258       *params_size = RSA_PUBLIC_PARAMS;
259
260       break;
261     case GNUTLS_PK_DSA:
262       /* params[0] is p,
263        * params[1] is q,
264        * params[2] is q,
265        * params[3] is pub.
266        */
267
268       if (*params_size < DSA_PUBLIC_PARAMS)
269         {
270           gnutls_assert ();
271           /* internal error. Increase the bigint_ts in params */
272           result = GNUTLS_E_INTERNAL_ERROR;
273           goto error;
274         }
275
276       if ((result =
277            _gnutls_x509_read_dsa_pubkey (tmp.data, tmp.size, params)) < 0)
278         {
279           gnutls_assert ();
280           goto error;
281         }
282
283       /* Now read the parameters
284        */
285       _gnutls_free_datum (&tmp);
286
287       _asnstr_append_name (name, sizeof (name), root,
288                            ".algorithm.parameters");
289       result = _gnutls_x509_read_value (asn, name, &tmp, 0);
290
291       /* FIXME: If the parameters are not included in the certificate
292        * then the issuer's parameters should be used. This is not
293        * done yet.
294        */
295
296       if (result < 0)
297         {
298           gnutls_assert ();
299           goto error;
300         }
301
302       if ((result =
303            _gnutls_x509_read_dsa_params (tmp.data, tmp.size, params)) < 0)
304         {
305           gnutls_assert ();
306           goto error;
307         }
308       *params_size = DSA_PUBLIC_PARAMS;
309
310       break;
311
312     default:
313       /* other types like DH
314        * currently not supported
315        */
316       gnutls_assert ();
317       result = GNUTLS_E_X509_CERTIFICATE_ERROR;
318       goto error;
319     }
320
321   result = 0;
322
323 error:
324   _gnutls_free_datum (&tmp);
325   return result;
326 }
327
328 /* Extracts DSA and RSA parameters from a certificate.
329  */
330 int
331 _gnutls_x509_crt_get_mpis (gnutls_x509_crt_t cert,
332                            bigint_t * params, int *params_size)
333 {
334   /* Read the algorithm's OID
335    */
336   return _gnutls_get_asn_mpis (cert->cert,
337                                "tbsCertificate.subjectPublicKeyInfo", params,
338                                params_size);
339 }
340
341 #ifdef ENABLE_PKI
342
343 /* Extracts DSA and RSA parameters from a certificate.
344  */
345 int
346 _gnutls_x509_crq_get_mpis (gnutls_x509_crq_t cert,
347                            bigint_t * params, int *params_size)
348 {
349   /* Read the algorithm's OID
350    */
351   return _gnutls_get_asn_mpis (cert->crq,
352                                "certificationRequestInfo.subjectPKInfo",
353                                params, params_size);
354 }
355
356 #endif
357
358 /*
359  * some x509 certificate functions that relate to MPI parameter
360  * setting. This writes the BIT STRING subjectPublicKey.
361  * Needs 2 parameters (m,e).
362  *
363  * Allocates the space used to store the DER data.
364  */
365 int
366 _gnutls_x509_write_rsa_params (bigint_t * params, int params_size,
367                                gnutls_datum_t * der)
368 {
369   int result;
370   ASN1_TYPE spk = ASN1_TYPE_EMPTY;
371
372   der->data = NULL;
373   der->size = 0;
374
375   if (params_size < 2)
376     {
377       gnutls_assert ();
378       result = GNUTLS_E_INVALID_REQUEST;
379       goto cleanup;
380     }
381
382   if ((result = asn1_create_element
383        (_gnutls_get_gnutls_asn (), "GNUTLS.RSAPublicKey", &spk))
384       != ASN1_SUCCESS)
385     {
386       gnutls_assert ();
387       return _gnutls_asn2err (result);
388     }
389
390   result = _gnutls_x509_write_int (spk, "modulus", params[0], 1);
391   if (result < 0)
392     {
393       gnutls_assert ();
394       goto cleanup;
395     }
396
397   result = _gnutls_x509_write_int (spk, "publicExponent", params[1], 1);
398   if (result < 0)
399     {
400       gnutls_assert ();
401       goto cleanup;
402     }
403
404   result = _gnutls_x509_der_encode (spk, "", der, 0);
405   if (result < 0)
406     {
407       gnutls_assert ();
408       goto cleanup;
409     }
410
411   asn1_delete_structure (&spk);
412   return 0;
413
414 cleanup:
415   asn1_delete_structure (&spk);
416
417   return result;
418 }
419
420 /*
421  * This function writes and encodes the parameters for DSS or RSA keys.
422  * This is the "signatureAlgorithm" fields.
423  */
424 int
425 _gnutls_x509_write_sig_params (ASN1_TYPE dst, const char *dst_name,
426                                gnutls_pk_algorithm_t pk_algorithm,
427                                gnutls_digest_algorithm_t dig)
428 {
429   int result;
430   char name[128];
431   const char *pk;
432
433   _gnutls_str_cpy (name, sizeof (name), dst_name);
434   _gnutls_str_cat (name, sizeof (name), ".algorithm");
435
436   pk = _gnutls_x509_sign_to_oid (pk_algorithm, HASH2MAC (dig));
437   if (pk == NULL)
438     {
439       gnutls_assert ();
440       _gnutls_debug_log
441         ("Cannot find OID for sign algorithm pk: %d dig: %d\n",
442          (int) pk_algorithm, (int) dig);
443       return GNUTLS_E_INVALID_REQUEST;
444     }
445
446   /* write the OID.
447    */
448   result = asn1_write_value (dst, name, pk, 1);
449   if (result != ASN1_SUCCESS)
450     {
451       gnutls_assert ();
452       return _gnutls_asn2err (result);
453     }
454
455
456   _gnutls_str_cpy (name, sizeof (name), dst_name);
457   _gnutls_str_cat (name, sizeof (name), ".parameters");
458
459   if (pk_algorithm == GNUTLS_PK_RSA)
460     result = asn1_write_value (dst, name, ASN1_NULL, ASN1_NULL_SIZE);
461   else
462     result = asn1_write_value (dst, name, NULL, 0);
463
464   if (result != ASN1_SUCCESS && result != ASN1_ELEMENT_NOT_FOUND)
465     {
466       /* Here we ignore the element not found error, since this
467        * may have been disabled before.
468        */
469       gnutls_assert ();
470       return _gnutls_asn2err (result);
471     }
472
473   return 0;
474 }
475
476 /*
477  * This function writes the parameters for DSS keys.
478  * Needs 3 parameters (p,q,g).
479  *
480  * Allocates the space used to store the DER data.
481  */
482 int
483 _gnutls_x509_write_dsa_params (bigint_t * params, int params_size,
484                                gnutls_datum_t * der)
485 {
486   int result;
487   ASN1_TYPE spk = ASN1_TYPE_EMPTY;
488
489   der->data = NULL;
490   der->size = 0;
491
492   if (params_size < 3)
493     {
494       gnutls_assert ();
495       result = GNUTLS_E_INVALID_REQUEST;
496       goto cleanup;
497     }
498
499   if ((result = asn1_create_element
500        (_gnutls_get_gnutls_asn (), "GNUTLS.DSAParameters", &spk))
501       != ASN1_SUCCESS)
502     {
503       gnutls_assert ();
504       return _gnutls_asn2err (result);
505     }
506
507   result = _gnutls_x509_write_int (spk, "p", params[0], 1);
508   if (result < 0)
509     {
510       gnutls_assert ();
511       goto cleanup;
512     }
513
514   result = _gnutls_x509_write_int (spk, "q", params[1], 1);
515   if (result < 0)
516     {
517       gnutls_assert ();
518       goto cleanup;
519     }
520
521   result = _gnutls_x509_write_int (spk, "g", params[2], 1);
522   if (result < 0)
523     {
524       gnutls_assert ();
525       goto cleanup;
526     }
527
528   result = _gnutls_x509_der_encode (spk, "", der, 0);
529   if (result < 0)
530     {
531       gnutls_assert ();
532       goto cleanup;
533     }
534
535   result = 0;
536
537 cleanup:
538   asn1_delete_structure (&spk);
539   return result;
540 }
541
542 /*
543  * This function writes the public parameters for DSS keys.
544  * Needs 1 parameter (y).
545  *
546  * Allocates the space used to store the DER data.
547  */
548 int
549 _gnutls_x509_write_dsa_public_key (bigint_t * params, int params_size,
550                                    gnutls_datum_t * der)
551 {
552   int result;
553   ASN1_TYPE spk = ASN1_TYPE_EMPTY;
554
555   der->data = NULL;
556   der->size = 0;
557
558   if (params_size < 3)
559     {
560       gnutls_assert ();
561       result = GNUTLS_E_INVALID_REQUEST;
562       goto cleanup;
563     }
564
565   if ((result = asn1_create_element
566        (_gnutls_get_gnutls_asn (), "GNUTLS.DSAPublicKey", &spk))
567       != ASN1_SUCCESS)
568     {
569       gnutls_assert ();
570       return _gnutls_asn2err (result);
571     }
572
573   result = _gnutls_x509_write_int (spk, "", params[3], 1);
574   if (result < 0)
575     {
576       gnutls_assert ();
577       goto cleanup;
578     }
579
580   result = _gnutls_x509_der_encode (spk, "", der, 0);
581   if (result < 0)
582     {
583       gnutls_assert ();
584       goto cleanup;
585     }
586
587   result = 0;
588
589 cleanup:
590   asn1_delete_structure (&spk);
591   return result;
592 }
593
594
595 /* this function reads a (small) unsigned integer
596  * from asn1 structs. Combines the read and the convertion
597  * steps.
598  */
599 int
600 _gnutls_x509_read_uint (ASN1_TYPE node, const char *value, unsigned int *ret)
601 {
602   int len, result;
603   opaque *tmpstr;
604
605   len = 0;
606   result = asn1_read_value (node, value, NULL, &len);
607   if (result != ASN1_MEM_ERROR)
608     {
609       gnutls_assert ();
610       return _gnutls_asn2err (result);
611     }
612
613   tmpstr = gnutls_malloc (len);
614   if (tmpstr == NULL)
615     {
616       gnutls_assert ();
617       return GNUTLS_E_MEMORY_ERROR;
618     }
619
620   result = asn1_read_value (node, value, tmpstr, &len);
621
622   if (result != ASN1_SUCCESS)
623     {
624       gnutls_assert ();
625       gnutls_free (tmpstr);
626       return _gnutls_asn2err (result);
627     }
628
629   if (len == 1)
630     *ret = tmpstr[0];
631   else if (len == 2)
632     *ret = _gnutls_read_uint16 (tmpstr);
633   else if (len == 3)
634     *ret = _gnutls_read_uint24 (tmpstr);
635   else if (len == 4)
636     *ret = _gnutls_read_uint32 (tmpstr);
637   else
638     {
639       gnutls_assert ();
640       gnutls_free (tmpstr);
641       return GNUTLS_E_INTERNAL_ERROR;
642     }
643
644   gnutls_free (tmpstr);
645
646   return 0;
647 }
648
649 /* Writes the specified integer into the specified node.
650  */
651 int
652 _gnutls_x509_write_uint32 (ASN1_TYPE node, const char *value, uint32_t num)
653 {
654   opaque tmpstr[4];
655   int result;
656
657   _gnutls_write_uint32 (num, tmpstr);
658
659   result = asn1_write_value (node, value, tmpstr, 4);
660
661   if (result != ASN1_SUCCESS)
662     {
663       gnutls_assert ();
664       return _gnutls_asn2err (result);
665     }
666
667   return 0;
668 }