Tizen 2.0 Release
[external/libgnutls26.git] / lib / x509 / common.c
1 /*
2  * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free
3  * Software 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 <libtasn1.h>
28 #include <gnutls_datum.h>
29 #include <gnutls_global.h>
30 #include <gnutls_errors.h>
31 #include <gnutls_str.h>
32 #include <gnutls_x509.h>
33 #include <gnutls_num.h>
34 #include <x509_b64.h>
35 #include "x509_int.h"
36 #include <common.h>
37
38 struct oid2string
39 {
40   const char *oid;
41   const char *ldap_desc;
42   int choice;                   /* of type DirectoryString */
43   int printable;
44   const char *asn_desc;         /* description in the pkix file */
45 };
46
47 /* This list contains all the OIDs that may be
48  * contained in a rdnSequence and are printable.
49  */
50 static const struct oid2string _oid2str[] = {
51   /* PKIX
52    */
53   {"1.3.6.1.5.5.7.9.1", "dateOfBirth", 0, 1, "PKIX1.GeneralizedTime"},
54   {"1.3.6.1.5.5.7.9.2", "placeOfBirth", 0, 1, "PKIX1.DirectoryString"},
55   {"1.3.6.1.5.5.7.9.3", "gender", 0, 1, "PKIX1.PrintableString"},
56   {"1.3.6.1.5.5.7.9.4", "countryOfCitizenship", 0, 1,
57    "PKIX1.PrintableString"},
58   {"1.3.6.1.5.5.7.9.5", "countryOfResidence", 0, 1, "PKIX1.PrintableString"},
59
60   {"2.5.4.6", "C", 0, 1, "PKIX1.PrintableString"},
61   {"2.5.4.9", "STREET", 1, 1, "PKIX1.DirectoryString"},
62   {"2.5.4.12", "T", 1, 1, "PKIX1.DirectoryString"},
63   {"2.5.4.10", "O", 1, 1, "PKIX1.DirectoryString"},
64   {"2.5.4.11", "OU", 1, 1, "PKIX1.DirectoryString"},
65   {"2.5.4.3", "CN", 1, 1, "PKIX1.DirectoryString"},
66   {"2.5.4.7", "L", 1, 1, "PKIX1.DirectoryString"},
67   {"2.5.4.8", "ST", 1, 1, "PKIX1.DirectoryString"},
68
69   {"2.5.4.5", "serialNumber", 0, 1, "PKIX1.PrintableString"},
70   {"2.5.4.20", "telephoneNumber", 0, 1, "PKIX1.PrintableString"},
71   {"2.5.4.4", "surName", 1, 1, "PKIX1.DirectoryString"},
72   {"2.5.4.43", "initials", 1, 1, "PKIX1.DirectoryString"},
73   {"2.5.4.44", "generationQualifier", 1, 1, "PKIX1.DirectoryString"},
74   {"2.5.4.42", "givenName", 1, 1, "PKIX1.DirectoryString"},
75   {"2.5.4.65", "pseudonym", 1, 1, "PKIX1.DirectoryString"},
76   {"2.5.4.46", "dnQualifier", 0, 1, "PKIX1.PrintableString"},
77   {"2.5.4.17", "postalCode", 1, 1, "PKIX1.DirectoryString"},
78   {"2.5.4.41", "Name", 1, 1, "PKIX1.DirectoryString"},
79   {"2.5.4.15", "businessCategory", 1, 1, "PKIX1.DirectoryString"},
80
81   {"0.9.2342.19200300.100.1.25", "DC", 0, 1, "PKIX1.IA5String"},
82   {"0.9.2342.19200300.100.1.1", "UID", 1, 1, "PKIX1.DirectoryString"},
83
84   /* Extended validation
85    */
86   {"1.3.6.1.4.1.311.60.2.1.1", "jurisdictionOfIncorporationLocalityName", 1,
87    1, "PKIX1.DirectoryString"},
88   {"1.3.6.1.4.1.311.60.2.1.2",
89    "jurisdictionOfIncorporationStateOrProvinceName", 1, 1,
90    "PKIX1.DirectoryString"},
91   {"1.3.6.1.4.1.311.60.2.1.3", "jurisdictionOfIncorporationCountryName", 0, 1,
92    "PKIX1.PrintableString"},
93
94   /* PKCS #9
95    */
96   {"1.2.840.113549.1.9.1", "EMAIL", 0, 1, "PKIX1.IA5String"},
97   {"1.2.840.113549.1.9.7", NULL, 1, 1, "PKIX1.pkcs-9-challengePassword"},
98
99   /* friendly name */
100   {"1.2.840.113549.1.9.20", NULL, 0, 1, "PKIX1.BMPString"},
101   /* local key id */
102   {"1.2.840.113549.1.9.21", NULL, 0, 1, "PKIX1.pkcs-9-localKeyId"},
103
104   /* rfc3920 section 5.1.1 */
105   {"1.3.6.1.5.5.7.8.5", "XmppAddr", 0, 1, "PKIX1.UTF8String"},
106
107   {NULL, NULL, 0, 0, ""}
108 };
109
110 /* Returns 1 if the data defined by the OID are printable.
111  */
112 int
113 _gnutls_x509_oid_data_printable (const char *oid)
114 {
115   int i = 0;
116
117   do
118     {
119       if (strcmp (_oid2str[i].oid, oid) == 0)
120         return _oid2str[i].printable;
121       i++;
122     }
123   while (_oid2str[i].oid != NULL);
124
125   return 0;
126 }
127
128 /**
129  * gnutls_x509_dn_oid_known:
130  * @oid: holds an Object Identifier in a null terminated string
131  *
132  * This function will inform about known DN OIDs. This is useful since
133  * functions like gnutls_x509_crt_set_dn_by_oid() use the information
134  * on known OIDs to properly encode their input. Object Identifiers
135  * that are not known are not encoded by these functions, and their
136  * input is stored directly into the ASN.1 structure. In that case of
137  * unknown OIDs, you have the responsibility of DER encoding your
138  * data.
139  *
140  * Returns: 1 on known OIDs and 0 otherwise.
141  **/
142 int
143 gnutls_x509_dn_oid_known (const char *oid)
144 {
145   int i = 0;
146
147   do
148     {
149       if (strcmp (_oid2str[i].oid, oid) == 0)
150         return 1;
151       i++;
152     }
153   while (_oid2str[i].oid != NULL);
154
155   return 0;
156 }
157
158 /* Returns 1 if the data defined by the OID are of a choice
159  * type.
160  */
161 int
162 _gnutls_x509_oid_data_choice (const char *oid)
163 {
164   int i = 0;
165
166   do
167     {
168       if (strcmp (_oid2str[i].oid, oid) == 0)
169         return _oid2str[i].choice;
170       i++;
171     }
172   while (_oid2str[i].oid != NULL);
173
174   return 0;
175 }
176
177 const char *
178 _gnutls_x509_oid2ldap_string (const char *oid)
179 {
180   int i = 0;
181
182   do
183     {
184       if (strcmp (_oid2str[i].oid, oid) == 0)
185         return _oid2str[i].ldap_desc;
186       i++;
187     }
188   while (_oid2str[i].oid != NULL);
189
190   return NULL;
191 }
192
193 const char *
194 _gnutls_x509_oid2asn_string (const char *oid)
195 {
196   int i = 0;
197
198   do
199     {
200       if (strcmp (_oid2str[i].oid, oid) == 0)
201         return _oid2str[i].asn_desc;
202       i++;
203     }
204   while (_oid2str[i].oid != NULL);
205
206   return NULL;
207 }
208
209
210 /* This function will convert an attribute value, specified by the OID,
211  * to a string. The result will be a null terminated string.
212  *
213  * res may be null. This will just return the res_size, needed to
214  * hold the string.
215  */
216 int
217 _gnutls_x509_oid_data2string (const char *oid, void *value,
218                               int value_size, char *res, size_t * res_size)
219 {
220   char str[MAX_STRING_LEN], tmpname[128];
221   const char *ANAME = NULL;
222   int CHOICE = -1, len = -1, result;
223   ASN1_TYPE tmpasn = ASN1_TYPE_EMPTY;
224   char asn1_err[ASN1_MAX_ERROR_DESCRIPTION_SIZE] = "";
225
226   if (value == NULL || value_size <= 0 || res_size == NULL)
227     {
228       gnutls_assert ();
229       return GNUTLS_E_INVALID_REQUEST;
230     }
231
232   if (_gnutls_x509_oid_data_printable (oid) == 0)
233     {
234       gnutls_assert ();
235       return GNUTLS_E_INTERNAL_ERROR;
236     }
237
238   ANAME = _gnutls_x509_oid2asn_string (oid);
239   CHOICE = _gnutls_x509_oid_data_choice (oid);
240
241   if (ANAME == NULL)
242     {
243       gnutls_assert ();
244       return GNUTLS_E_INTERNAL_ERROR;
245     }
246
247   if ((result =
248        asn1_create_element (_gnutls_get_pkix (), ANAME,
249                             &tmpasn)) != ASN1_SUCCESS)
250     {
251       gnutls_assert ();
252       return _gnutls_asn2err (result);
253     }
254
255   if ((result =
256        asn1_der_decoding (&tmpasn, value, value_size,
257                           asn1_err)) != ASN1_SUCCESS)
258     {
259       gnutls_assert ();
260       _gnutls_x509_log ("asn1_der_decoding: %s:%s\n", str, asn1_err);
261       asn1_delete_structure (&tmpasn);
262       return _gnutls_asn2err (result);
263     }
264
265   /* If this is a choice then we read the choice. Otherwise it
266    * is the value;
267    */
268   len = sizeof (str) - 1;
269   if ((result = asn1_read_value (tmpasn, "", str, &len)) != ASN1_SUCCESS)
270     {                           /* CHOICE */
271       gnutls_assert ();
272       asn1_delete_structure (&tmpasn);
273       return _gnutls_asn2err (result);
274     }
275
276   if (CHOICE == 0)
277     {
278       str[len] = 0;
279
280       /* Refuse to deal with strings containing NULs. */
281       if (strlen (str) != len)
282         return GNUTLS_E_ASN1_DER_ERROR;
283
284       if (res)
285         _gnutls_str_cpy (res, *res_size, str);
286       *res_size = len;
287
288       asn1_delete_structure (&tmpasn);
289     }
290   else
291     {                           /* CHOICE */
292       int non_printable = 0, teletex = 0;
293       str[len] = 0;
294
295       /* Note that we do not support strings other than
296        * UTF-8 (thus ASCII as well).
297        */
298       if (strcmp (str, "printableString") != 0 &&
299           strcmp (str, "ia5String") != 0 && strcmp (str, "utf8String") != 0)
300         {
301           non_printable = 1;
302         }
303       if (strcmp (str, "teletexString") == 0)
304         teletex = 1;
305
306
307       _gnutls_str_cpy (tmpname, sizeof (tmpname), str);
308
309       len = sizeof (str) - 1;
310       if ((result =
311            asn1_read_value (tmpasn, tmpname, str, &len)) != ASN1_SUCCESS)
312         {
313           asn1_delete_structure (&tmpasn);
314           return _gnutls_asn2err (result);
315         }
316
317       asn1_delete_structure (&tmpasn);
318
319       if (teletex != 0)
320         {
321           int ascii = 0, i;
322           /* HACK: if the teletex string contains only ascii
323            * characters then treat it as printable.
324            */
325           for (i = 0; i < len; i++)
326             if (!isascii (str[i]))
327               ascii = 1;
328
329           if (ascii == 0)
330             non_printable = 0;
331         }
332
333       if (non_printable == 0)
334         {
335           str[len] = 0;
336
337           /* Refuse to deal with strings containing NULs. */
338           if (strlen (str) != len)
339             return GNUTLS_E_ASN1_DER_ERROR;
340
341           if (res)
342             _gnutls_str_cpy (res, *res_size, str);
343           *res_size = len;
344         }
345       else
346         {
347           result = _gnutls_x509_data2hex (str, len, res, res_size);
348           if (result < 0)
349             {
350               gnutls_assert ();
351               return result;
352             }
353         }
354     }
355
356   return 0;
357 }
358
359
360 /* Converts a data string to an LDAP rfc2253 hex string
361  * something like '#01020304'
362  */
363 int
364 _gnutls_x509_data2hex (const opaque * data, size_t data_size,
365                        opaque * out, size_t * sizeof_out)
366 {
367   char *res;
368   char escaped[MAX_STRING_LEN];
369   unsigned int size;
370
371   if (2 * data_size + 1 > MAX_STRING_LEN)
372     {
373       gnutls_assert ();
374       return GNUTLS_E_INTERNAL_ERROR;
375     }
376
377   res = _gnutls_bin2hex (data, data_size, escaped, sizeof (escaped), NULL);
378   if (!res)
379     {
380       gnutls_assert ();
381       return GNUTLS_E_INTERNAL_ERROR;
382     }
383
384   size = strlen (res) + 1;
385   if (size + 1 > *sizeof_out)
386     {
387       *sizeof_out = size;
388       return GNUTLS_E_SHORT_MEMORY_BUFFER;
389     }
390   *sizeof_out = size;           /* -1 for the null +1 for the '#' */
391
392   if (out)
393     {
394       strcpy (out, "#");
395       strcat (out, res);
396     }
397
398   return 0;
399 }
400
401
402 /* TIME functions 
403  * Convertions between generalized or UTC time to time_t
404  *
405  */
406
407 /* This is an emulations of the struct tm.
408  * Since we do not use libc's functions, we don't need to
409  * depend on the libc structure.
410  */
411 typedef struct fake_tm
412 {
413   int tm_mon;
414   int tm_year;                  /* FULL year - ie 1971 */
415   int tm_mday;
416   int tm_hour;
417   int tm_min;
418   int tm_sec;
419 } fake_tm;
420
421 /* The mktime_utc function is due to Russ Allbery (rra@stanford.edu),
422  * who placed it under public domain:
423  */
424
425 /* The number of days in each month. 
426  */
427 static const int MONTHDAYS[] = {
428   31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
429 };
430
431     /* Whether a given year is a leap year. */
432 #define ISLEAP(year) \
433         (((year) % 4) == 0 && (((year) % 100) != 0 || ((year) % 400) == 0))
434
435 /*
436  **  Given a struct tm representing a calendar time in UTC, convert it to
437  **  seconds since epoch.  Returns (time_t) -1 if the time is not
438  **  convertable.  Note that this function does not canonicalize the provided
439  **  struct tm, nor does it allow out of range values or years before 1970.
440  */
441 static time_t
442 mktime_utc (const struct fake_tm *tm)
443 {
444   time_t result = 0;
445   int i;
446
447 /* We do allow some ill-formed dates, but we don't do anything special
448  * with them and our callers really shouldn't pass them to us.  Do
449  * explicitly disallow the ones that would cause invalid array accesses
450  * or other algorithm problems. 
451  */
452   if (tm->tm_mon < 0 || tm->tm_mon > 11 || tm->tm_year < 1970)
453     return (time_t) - 1;
454
455 /* Convert to a time_t. 
456  */
457   for (i = 1970; i < tm->tm_year; i++)
458     result += 365 + ISLEAP (i);
459   for (i = 0; i < tm->tm_mon; i++)
460     result += MONTHDAYS[i];
461   if (tm->tm_mon > 1 && ISLEAP (tm->tm_year))
462     result++;
463   result = 24 * (result + tm->tm_mday - 1) + tm->tm_hour;
464   result = 60 * result + tm->tm_min;
465   result = 60 * result + tm->tm_sec;
466   return result;
467 }
468
469
470 /* this one will parse dates of the form:
471  * month|day|hour|minute|sec* (2 chars each)
472  * and year is given. Returns a time_t date.
473  */
474 static time_t
475 _gnutls_x509_time2gtime (const char *ttime, int year)
476 {
477   char xx[4];
478   struct fake_tm etime;
479   time_t ret;
480
481   if (strlen (ttime) < 8)
482     {
483       gnutls_assert ();
484       return (time_t) - 1;
485     }
486
487   etime.tm_year = year;
488
489   /* In order to work with 32 bit
490    * time_t.
491    */
492   if (sizeof (time_t) <= 4 && etime.tm_year >= 2038)
493     return (time_t) 2145914603; /* 2037-12-31 23:23:23 */
494
495   if (etime.tm_year < 1970)
496     return (time_t) 0;
497
498   xx[2] = 0;
499
500 /* get the month
501  */
502   memcpy (xx, ttime, 2);        /* month */
503   etime.tm_mon = atoi (xx) - 1;
504   ttime += 2;
505
506 /* get the day
507  */
508   memcpy (xx, ttime, 2);        /* day */
509   etime.tm_mday = atoi (xx);
510   ttime += 2;
511
512 /* get the hour
513  */
514   memcpy (xx, ttime, 2);        /* hour */
515   etime.tm_hour = atoi (xx);
516   ttime += 2;
517
518 /* get the minutes
519  */
520   memcpy (xx, ttime, 2);        /* minutes */
521   etime.tm_min = atoi (xx);
522   ttime += 2;
523
524   if (strlen (ttime) >= 2)
525     {
526       memcpy (xx, ttime, 2);
527       etime.tm_sec = atoi (xx);
528       ttime += 2;
529     }
530   else
531     etime.tm_sec = 0;
532
533   ret = mktime_utc (&etime);
534
535   return ret;
536 }
537
538
539 /* returns a time_t value that contains the given time.
540  * The given time is expressed as:
541  * YEAR(2)|MONTH(2)|DAY(2)|HOUR(2)|MIN(2)|SEC(2)*
542  *
543  * (seconds are optional)
544  */
545 static time_t
546 _gnutls_x509_utcTime2gtime (const char *ttime)
547 {
548   char xx[3];
549   int year;
550
551   if (strlen (ttime) < 10)
552     {
553       gnutls_assert ();
554       return (time_t) - 1;
555     }
556   xx[2] = 0;
557 /* get the year
558  */
559   memcpy (xx, ttime, 2);        /* year */
560   year = atoi (xx);
561   ttime += 2;
562
563   if (year > 49)
564     year += 1900;
565   else
566     year += 2000;
567
568   return _gnutls_x509_time2gtime (ttime, year);
569 }
570
571 /* returns a time value that contains the given time.
572  * The given time is expressed as:
573  * YEAR(2)|MONTH(2)|DAY(2)|HOUR(2)|MIN(2)|SEC(2)
574  */
575 static int
576 _gnutls_x509_gtime2utcTime (time_t gtime, char *str_time, int str_time_size)
577 {
578   size_t ret;
579   struct tm _tm;
580
581   if (!gmtime_r (&gtime, &_tm))
582     {
583       gnutls_assert ();
584       return GNUTLS_E_INTERNAL_ERROR;
585     }
586
587   ret = strftime (str_time, str_time_size, "%y%m%d%H%M%SZ", &_tm);
588   if (!ret)
589     {
590       gnutls_assert ();
591       return GNUTLS_E_SHORT_MEMORY_BUFFER;
592     }
593
594
595   return 0;
596
597 }
598
599 /* returns a time_t value that contains the given time.
600  * The given time is expressed as:
601  * YEAR(4)|MONTH(2)|DAY(2)|HOUR(2)|MIN(2)|SEC(2)*
602  */
603 static time_t
604 _gnutls_x509_generalTime2gtime (const char *ttime)
605 {
606   char xx[5];
607   int year;
608
609   if (strlen (ttime) < 12)
610     {
611       gnutls_assert ();
612       return (time_t) - 1;
613     }
614
615   if (strchr (ttime, 'Z') == 0)
616     {
617       gnutls_assert ();
618       /* sorry we don't support it yet
619        */
620       return (time_t) - 1;
621     }
622   xx[4] = 0;
623
624 /* get the year
625  */
626   memcpy (xx, ttime, 4);        /* year */
627   year = atoi (xx);
628   ttime += 4;
629
630   return _gnutls_x509_time2gtime (ttime, year);
631
632 }
633
634 /* Extracts the time in time_t from the ASN1_TYPE given. When should
635  * be something like "tbsCertList.thisUpdate".
636  */
637 #define MAX_TIME 64
638 time_t
639 _gnutls_x509_get_time (ASN1_TYPE c2, const char *when)
640 {
641   char ttime[MAX_TIME];
642   char name[128];
643   time_t c_time = (time_t) - 1;
644   int len, result;
645
646   _gnutls_str_cpy (name, sizeof (name), when);
647
648   len = sizeof (ttime) - 1;
649   if ((result = asn1_read_value (c2, name, ttime, &len)) < 0)
650     {
651       gnutls_assert ();
652       return (time_t) (-1);
653     }
654
655   /* CHOICE */
656   if (strcmp (ttime, "generalTime") == 0)
657     {
658
659       _gnutls_str_cat (name, sizeof (name), ".generalTime");
660       len = sizeof (ttime) - 1;
661       result = asn1_read_value (c2, name, ttime, &len);
662       if (result == ASN1_SUCCESS)
663         c_time = _gnutls_x509_generalTime2gtime (ttime);
664     }
665   else
666     {                           /* UTCTIME */
667
668       _gnutls_str_cat (name, sizeof (name), ".utcTime");
669       len = sizeof (ttime) - 1;
670       result = asn1_read_value (c2, name, ttime, &len);
671       if (result == ASN1_SUCCESS)
672         c_time = _gnutls_x509_utcTime2gtime (ttime);
673     }
674
675   /* We cannot handle dates after 2031 in 32 bit machines.
676    * a time_t of 64bits has to be used.
677    */
678
679   if (result != ASN1_SUCCESS)
680     {
681       gnutls_assert ();
682       return (time_t) (-1);
683     }
684   return c_time;
685 }
686
687 /* Sets the time in time_t in the ASN1_TYPE given. Where should
688  * be something like "tbsCertList.thisUpdate".
689  */
690 int
691 _gnutls_x509_set_time (ASN1_TYPE c2, const char *where, time_t tim)
692 {
693   char str_time[MAX_TIME];
694   char name[128];
695   int result, len;
696
697   _gnutls_str_cpy (name, sizeof (name), where);
698
699   if ((result = asn1_write_value (c2, name, "utcTime", 1)) < 0)
700     {
701       gnutls_assert ();
702       return _gnutls_asn2err (result);
703     }
704
705   result = _gnutls_x509_gtime2utcTime (tim, str_time, sizeof (str_time));
706   if (result < 0)
707     {
708       gnutls_assert ();
709       return result;
710     }
711
712   _gnutls_str_cat (name, sizeof (name), ".utcTime");
713
714   len = strlen (str_time);
715   result = asn1_write_value (c2, name, str_time, len);
716   if (result != ASN1_SUCCESS)
717     {
718       gnutls_assert ();
719       return _gnutls_asn2err (result);
720     }
721
722   return 0;
723 }
724
725
726 gnutls_x509_subject_alt_name_t
727 _gnutls_x509_san_find_type (char *str_type)
728 {
729   if (strcmp (str_type, "dNSName") == 0)
730     return GNUTLS_SAN_DNSNAME;
731   if (strcmp (str_type, "rfc822Name") == 0)
732     return GNUTLS_SAN_RFC822NAME;
733   if (strcmp (str_type, "uniformResourceIdentifier") == 0)
734     return GNUTLS_SAN_URI;
735   if (strcmp (str_type, "iPAddress") == 0)
736     return GNUTLS_SAN_IPADDRESS;
737   if (strcmp (str_type, "otherName") == 0)
738     return GNUTLS_SAN_OTHERNAME;
739   if (strcmp (str_type, "directoryName") == 0)
740     return GNUTLS_SAN_DN;
741   return (gnutls_x509_subject_alt_name_t) - 1;
742 }
743
744 /* A generic export function. Will export the given ASN.1 encoded data
745  * to PEM or DER raw data.
746  */
747 int
748 _gnutls_x509_export_int_named (ASN1_TYPE asn1_data, const char *name,
749                                gnutls_x509_crt_fmt_t format,
750                                const char *pem_header,
751                                unsigned char *output_data,
752                                size_t * output_data_size)
753 {
754   int result, len;
755
756   if (format == GNUTLS_X509_FMT_DER)
757     {
758
759       if (output_data == NULL)
760         *output_data_size = 0;
761
762       len = *output_data_size;
763
764       if ((result =
765            asn1_der_coding (asn1_data, name, output_data, &len,
766                             NULL)) != ASN1_SUCCESS)
767         {
768           *output_data_size = len;
769           if (result == ASN1_MEM_ERROR)
770             {
771               return GNUTLS_E_SHORT_MEMORY_BUFFER;
772             }
773           gnutls_assert ();
774           return _gnutls_asn2err (result);
775         }
776
777       *output_data_size = len;
778
779     }
780   else
781     {                           /* PEM */
782       opaque *out;
783       gnutls_datum_t tmp;
784
785       result = _gnutls_x509_der_encode (asn1_data, name, &tmp, 0);
786       if (result < 0)
787         {
788           gnutls_assert ();
789           return result;
790         }
791
792       result = _gnutls_fbase64_encode (pem_header, tmp.data, tmp.size, &out);
793
794       _gnutls_free_datum (&tmp);
795
796       if (result < 0)
797         {
798           gnutls_assert ();
799           return result;
800         }
801
802       if (result == 0)
803         {                       /* oooops */
804           gnutls_assert ();
805           return GNUTLS_E_INTERNAL_ERROR;
806         }
807
808       if ((unsigned) result > *output_data_size)
809         {
810           gnutls_assert ();
811           gnutls_free (out);
812           *output_data_size = result;
813           return GNUTLS_E_SHORT_MEMORY_BUFFER;
814         }
815
816       *output_data_size = result;
817
818       if (output_data)
819         {
820           memcpy (output_data, out, result);
821
822           /* do not include the null character into output size.
823            */
824           *output_data_size = result - 1;
825         }
826       gnutls_free (out);
827
828     }
829
830   return 0;
831 }
832
833 int
834 _gnutls_x509_export_int (ASN1_TYPE asn1_data,
835                          gnutls_x509_crt_fmt_t format,
836                          const char *pem_header,
837                          unsigned char *output_data,
838                          size_t * output_data_size)
839 {
840   return _gnutls_x509_export_int_named (asn1_data, "",
841                                         format, pem_header, output_data,
842                                         output_data_size);
843 }
844
845 /* Decodes an octet string. Leave string_type null for a normal
846  * octet string. Otherwise put something like BMPString, PrintableString
847  * etc.
848  */
849 int
850 _gnutls_x509_decode_octet_string (const char *string_type,
851                                   const opaque * der, size_t der_size,
852                                   opaque * output, size_t * output_size)
853 {
854   ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
855   int result, tmp_output_size;
856   char strname[64];
857
858   if (string_type == NULL)
859     _gnutls_str_cpy (strname, sizeof (strname), "PKIX1.pkcs-7-Data");
860   else
861     {
862       _gnutls_str_cpy (strname, sizeof (strname), "PKIX1.");
863       _gnutls_str_cat (strname, sizeof (strname), string_type);
864     }
865
866   if ((result = asn1_create_element
867        (_gnutls_get_pkix (), strname, &c2)) != ASN1_SUCCESS)
868     {
869       gnutls_assert ();
870       result = _gnutls_asn2err (result);
871       goto cleanup;
872     }
873
874   result = asn1_der_decoding (&c2, der, der_size, NULL);
875   if (result != ASN1_SUCCESS)
876     {
877       gnutls_assert ();
878       result = _gnutls_asn2err (result);
879       goto cleanup;
880     }
881
882   tmp_output_size = *output_size;
883   result = asn1_read_value (c2, "", output, &tmp_output_size);
884   *output_size = tmp_output_size;
885
886   if (result != ASN1_SUCCESS)
887     {
888       gnutls_assert ();
889       result = _gnutls_asn2err (result);
890       goto cleanup;
891     }
892
893   result = 0;
894
895 cleanup:
896   if (c2)
897     asn1_delete_structure (&c2);
898
899   return result;
900 }
901
902
903 /* Reads a value from an ASN1 tree, and puts the output
904  * in an allocated variable in the given datum.
905  * flags == 0 do nothing  with the DER output
906  * flags == 1 parse the DER output as OCTET STRING
907  * flags == 2 the value is a BIT STRING
908  */
909 int
910 _gnutls_x509_read_value (ASN1_TYPE c, const char *root,
911                          gnutls_datum_t * ret, int flags)
912 {
913   int len = 0, result;
914   size_t slen;
915   opaque *tmp = NULL;
916
917   result = asn1_read_value (c, root, NULL, &len);
918   if (result != ASN1_MEM_ERROR)
919     {
920       gnutls_assert ();
921       result = _gnutls_asn2err (result);
922       return result;
923     }
924
925   if (flags == 2)
926     len /= 8;
927
928   tmp = gnutls_malloc (len);
929   if (tmp == NULL)
930     {
931       gnutls_assert ();
932       result = GNUTLS_E_MEMORY_ERROR;
933       goto cleanup;
934     }
935
936   result = asn1_read_value (c, root, tmp, &len);
937   if (result != ASN1_SUCCESS)
938     {
939       gnutls_assert ();
940       result = _gnutls_asn2err (result);
941       goto cleanup;
942     }
943
944   if (flags == 2)
945     len /= 8;
946
947   /* Extract the OCTET STRING.
948    */
949
950   if (flags == 1)
951     {
952       slen = len;
953       result = _gnutls_x509_decode_octet_string (NULL, tmp, slen, tmp, &slen);
954       if (result < 0)
955         {
956           gnutls_assert ();
957           goto cleanup;
958         }
959       len = slen;
960     }
961
962   ret->data = tmp;
963   ret->size = len;
964
965   return 0;
966
967 cleanup:
968   gnutls_free (tmp);
969   return result;
970
971 }
972
973 /* DER Encodes the src ASN1_TYPE and stores it to
974  * the given datum. If str is non null then the data are encoded as
975  * an OCTET STRING.
976  */
977 int
978 _gnutls_x509_der_encode (ASN1_TYPE src, const char *src_name,
979                          gnutls_datum_t * res, int str)
980 {
981   int size, result;
982   int asize;
983   opaque *data = NULL;
984   ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
985
986   size = 0;
987   result = asn1_der_coding (src, src_name, NULL, &size, NULL);
988   if (result != ASN1_MEM_ERROR)
989     {
990       gnutls_assert ();
991       result = _gnutls_asn2err (result);
992       goto cleanup;
993     }
994
995   /* allocate data for the der
996    */
997
998   if (str)
999     size += 16;                 /* for later to include the octet tags */
1000   asize = size;
1001
1002   data = gnutls_malloc (size);
1003   if (data == NULL)
1004     {
1005       gnutls_assert ();
1006       result = GNUTLS_E_MEMORY_ERROR;
1007       goto cleanup;
1008     }
1009
1010   result = asn1_der_coding (src, src_name, data, &size, NULL);
1011   if (result != ASN1_SUCCESS)
1012     {
1013       gnutls_assert ();
1014       result = _gnutls_asn2err (result);
1015       goto cleanup;
1016     }
1017
1018   if (str)
1019     {
1020       if ((result = asn1_create_element
1021            (_gnutls_get_pkix (), "PKIX1.pkcs-7-Data", &c2)) != ASN1_SUCCESS)
1022         {
1023           gnutls_assert ();
1024           result = _gnutls_asn2err (result);
1025           goto cleanup;
1026         }
1027
1028       result = asn1_write_value (c2, "", data, size);
1029       if (result != ASN1_SUCCESS)
1030         {
1031           gnutls_assert ();
1032           result = _gnutls_asn2err (result);
1033           goto cleanup;
1034         }
1035
1036       result = asn1_der_coding (c2, "", data, &asize, NULL);
1037       if (result != ASN1_SUCCESS)
1038         {
1039           gnutls_assert ();
1040           result = _gnutls_asn2err (result);
1041           goto cleanup;
1042         }
1043
1044       size = asize;
1045
1046       asn1_delete_structure (&c2);
1047     }
1048
1049   res->data = data;
1050   res->size = size;
1051   return 0;
1052
1053 cleanup:
1054   gnutls_free (data);
1055   asn1_delete_structure (&c2);
1056   return result;
1057
1058 }
1059
1060 /* DER Encodes the src ASN1_TYPE and stores it to
1061  * dest in dest_name. Useful to encode something and store it
1062  * as OCTET. If str is non null then the data are encoded as
1063  * an OCTET STRING.
1064  */
1065 int
1066 _gnutls_x509_der_encode_and_copy (ASN1_TYPE src, const char *src_name,
1067                                   ASN1_TYPE dest, const char *dest_name,
1068                                   int str)
1069 {
1070   int result;
1071   gnutls_datum_t encoded;
1072
1073   result = _gnutls_x509_der_encode (src, src_name, &encoded, str);
1074
1075   if (result < 0)
1076     {
1077       gnutls_assert ();
1078       return result;
1079     }
1080
1081   /* Write the data.
1082    */
1083   result = asn1_write_value (dest, dest_name, encoded.data, encoded.size);
1084
1085   _gnutls_free_datum (&encoded);
1086
1087   if (result != ASN1_SUCCESS)
1088     {
1089       gnutls_assert ();
1090       return _gnutls_asn2err (result);
1091     }
1092
1093   return 0;
1094 }
1095
1096 /* Writes the value of the datum in the given ASN1_TYPE. If str is non
1097  * zero it encodes it as OCTET STRING.
1098  */
1099 int
1100 _gnutls_x509_write_value (ASN1_TYPE c, const char *root,
1101                           const gnutls_datum_t * data, int str)
1102 {
1103   int result;
1104   ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
1105   gnutls_datum_t val = { NULL, 0 };
1106
1107   if (str)
1108     {
1109       /* Convert it to OCTET STRING
1110        */
1111       if ((result = asn1_create_element
1112            (_gnutls_get_pkix (), "PKIX1.pkcs-7-Data", &c2)) != ASN1_SUCCESS)
1113         {
1114           gnutls_assert ();
1115           result = _gnutls_asn2err (result);
1116           goto cleanup;
1117         }
1118
1119       result = asn1_write_value (c2, "", data->data, data->size);
1120       if (result != ASN1_SUCCESS)
1121         {
1122           gnutls_assert ();
1123           result = _gnutls_asn2err (result);
1124           goto cleanup;
1125         }
1126
1127       result = _gnutls_x509_der_encode (c2, "", &val, 0);
1128       if (result < 0)
1129         {
1130           gnutls_assert ();
1131           goto cleanup;
1132         }
1133
1134     }
1135   else
1136     {
1137       val.data = data->data;
1138       val.size = data->size;
1139     }
1140
1141   /* Write the data.
1142    */
1143   result = asn1_write_value (c, root, val.data, val.size);
1144   if (result != ASN1_SUCCESS)
1145     {
1146       gnutls_assert ();
1147       result = _gnutls_asn2err (result);
1148       goto cleanup;
1149     }
1150
1151   result = 0;
1152
1153 cleanup:
1154   asn1_delete_structure (&c2);
1155   if (val.data != data->data)
1156     _gnutls_free_datum (&val);
1157   return result;
1158 }
1159
1160 void
1161 _asnstr_append_name (char *name, size_t name_size, const char *part1,
1162                      const char *part2)
1163 {
1164   if (part1[0] != 0)
1165     {
1166       _gnutls_str_cpy (name, name_size, part1);
1167       _gnutls_str_cat (name, name_size, part2);
1168     }
1169   else
1170     _gnutls_str_cpy (name, name_size, part2 + 1 /* remove initial dot */ );
1171 }
1172
1173
1174 /* Encodes and copies the private key parameters into a
1175  * subjectPublicKeyInfo structure.
1176  *
1177  */
1178 int
1179 _gnutls_x509_encode_and_copy_PKI_params (ASN1_TYPE dst,
1180                                          const char *dst_name,
1181                                          gnutls_pk_algorithm_t
1182                                          pk_algorithm, bigint_t * params,
1183                                          int params_size)
1184 {
1185   const char *pk;
1186   gnutls_datum_t der = { NULL, 0 };
1187   int result;
1188   char name[128];
1189
1190   pk = _gnutls_x509_pk_to_oid (pk_algorithm);
1191   if (pk == NULL)
1192     {
1193       gnutls_assert ();
1194       return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
1195     }
1196
1197   /* write the OID
1198    */
1199   _asnstr_append_name (name, sizeof (name), dst_name, ".algorithm.algorithm");
1200
1201   result = asn1_write_value (dst, name, pk, 1);
1202   if (result != ASN1_SUCCESS)
1203     {
1204       gnutls_assert ();
1205       return _gnutls_asn2err (result);
1206     }
1207
1208   if (pk_algorithm == GNUTLS_PK_RSA)
1209     {
1210       /* disable parameters, which are not used in RSA.
1211        */
1212       _asnstr_append_name (name, sizeof (name), dst_name,
1213                            ".algorithm.parameters");
1214
1215       result = asn1_write_value (dst, name, ASN1_NULL, ASN1_NULL_SIZE);
1216       if (result != ASN1_SUCCESS)
1217         {
1218           gnutls_assert ();
1219           return _gnutls_asn2err (result);
1220         }
1221
1222       result = _gnutls_x509_write_rsa_params (params, params_size, &der);
1223       if (result < 0)
1224         {
1225           gnutls_assert ();
1226           return result;
1227         }
1228
1229       /* Write the DER parameters. (in bits)
1230        */
1231       _asnstr_append_name (name, sizeof (name), dst_name,
1232                            ".subjectPublicKey");
1233       result = asn1_write_value (dst, name, der.data, der.size * 8);
1234
1235       _gnutls_free_datum (&der);
1236
1237       if (result != ASN1_SUCCESS)
1238         {
1239           gnutls_assert ();
1240           return _gnutls_asn2err (result);
1241         }
1242     }
1243   else if (pk_algorithm == GNUTLS_PK_DSA)
1244     {
1245
1246       result = _gnutls_x509_write_dsa_params (params, params_size, &der);
1247       if (result < 0)
1248         {
1249           gnutls_assert ();
1250           return result;
1251         }
1252
1253       /* Write the DER parameters.
1254        */
1255       _asnstr_append_name (name, sizeof (name), dst_name,
1256                            ".algorithm.parameters");
1257       result = asn1_write_value (dst, name, der.data, der.size);
1258
1259       _gnutls_free_datum (&der);
1260
1261       if (result != ASN1_SUCCESS)
1262         {
1263           gnutls_assert ();
1264           return _gnutls_asn2err (result);
1265         }
1266
1267       result = _gnutls_x509_write_dsa_public_key (params, params_size, &der);
1268       if (result < 0)
1269         {
1270           gnutls_assert ();
1271           return result;
1272         }
1273
1274       _asnstr_append_name (name, sizeof (name), dst_name,
1275                            ".subjectPublicKey");
1276       result = asn1_write_value (dst, name, der.data, der.size * 8);
1277
1278       _gnutls_free_datum (&der);
1279
1280       if (result != ASN1_SUCCESS)
1281         {
1282           gnutls_assert ();
1283           return _gnutls_asn2err (result);
1284         }
1285
1286     }
1287   else
1288     return GNUTLS_E_UNIMPLEMENTED_FEATURE;
1289
1290   return 0;
1291 }
1292
1293 /* Reads and returns the PK algorithm of the given certificate-like
1294  * ASN.1 structure. src_name should be something like "tbsCertificate.subjectPublicKeyInfo".
1295  */
1296 int
1297 _gnutls_x509_get_pk_algorithm (ASN1_TYPE src, const char *src_name,
1298                                unsigned int *bits)
1299 {
1300   int result;
1301   opaque *str = NULL;
1302   int algo;
1303   char oid[64];
1304   int len;
1305   bigint_t params[MAX_PUBLIC_PARAMS_SIZE];
1306   char name[128];
1307
1308
1309   _asnstr_append_name (name, sizeof (name), src_name, ".algorithm.algorithm");
1310   len = sizeof (oid);
1311   result = asn1_read_value (src, name, oid, &len);
1312
1313   if (result != ASN1_SUCCESS)
1314     {
1315       gnutls_assert ();
1316       return _gnutls_asn2err (result);
1317     }
1318
1319   algo = _gnutls_x509_oid2pk_algorithm (oid);
1320   if (algo == GNUTLS_PK_UNKNOWN)
1321     {
1322       _gnutls_x509_log
1323         ("%s: unknown public key algorithm: %s\n", __func__, oid);
1324     }
1325
1326   if (bits == NULL)
1327     {
1328       return algo;
1329     }
1330
1331   /* Now read the parameters' bits 
1332    */
1333   _asnstr_append_name (name, sizeof (name), src_name, ".subjectPublicKey");
1334
1335   len = 0;
1336   result = asn1_read_value (src, name, NULL, &len);
1337   if (result != ASN1_MEM_ERROR)
1338     {
1339       gnutls_assert ();
1340       return _gnutls_asn2err (result);
1341     }
1342
1343   if (len % 8 != 0)
1344     {
1345       gnutls_assert ();
1346       return GNUTLS_E_CERTIFICATE_ERROR;
1347     }
1348
1349   len /= 8;
1350
1351   str = gnutls_malloc (len);
1352   if (str == NULL)
1353     {
1354       gnutls_assert ();
1355       return GNUTLS_E_MEMORY_ERROR;
1356     }
1357
1358   _asnstr_append_name (name, sizeof (name), src_name, ".subjectPublicKey");
1359
1360   result = asn1_read_value (src, name, str, &len);
1361
1362   if (result != ASN1_SUCCESS)
1363     {
1364       gnutls_assert ();
1365       gnutls_free (str);
1366       return _gnutls_asn2err (result);
1367     }
1368
1369   len /= 8;
1370
1371   switch (algo)
1372     {
1373     case GNUTLS_PK_RSA:
1374       {
1375         if ((result = _gnutls_x509_read_rsa_params (str, len, params)) < 0)
1376           {
1377             gnutls_assert ();
1378             return result;
1379           }
1380
1381         bits[0] = _gnutls_mpi_get_nbits (params[0]);
1382
1383         _gnutls_mpi_release (&params[0]);
1384         _gnutls_mpi_release (&params[1]);
1385       }
1386       break;
1387     case GNUTLS_PK_DSA:
1388       {
1389
1390         if ((result = _gnutls_x509_read_dsa_pubkey (str, len, params)) < 0)
1391           {
1392             gnutls_assert ();
1393             return result;
1394           }
1395
1396         bits[0] = _gnutls_mpi_get_nbits (params[3]);
1397
1398         _gnutls_mpi_release (&params[3]);
1399       }
1400       break;
1401     }
1402
1403   gnutls_free (str);
1404   return algo;
1405 }
1406
1407 /* Reads the DER signed data from the certificate and allocates space and
1408  * returns them into signed_data.
1409  */
1410 int
1411 _gnutls_x509_get_signed_data (ASN1_TYPE src, const char *src_name,
1412                               gnutls_datum_t * signed_data)
1413 {
1414   gnutls_datum_t der;
1415   int start, end, result;
1416
1417   result = _gnutls_x509_der_encode (src, "", &der, 0);
1418   if (result < 0)
1419     {
1420       gnutls_assert ();
1421       return result;
1422     }
1423
1424   /* Get the signed data
1425    */
1426   result = asn1_der_decoding_startEnd (src, der.data, der.size,
1427                                        src_name, &start, &end);
1428   if (result != ASN1_SUCCESS)
1429     {
1430       result = _gnutls_asn2err (result);
1431       gnutls_assert ();
1432       goto cleanup;
1433     }
1434
1435   result = _gnutls_set_datum (signed_data, &der.data[start], end - start + 1);
1436
1437   if (result < 0)
1438     {
1439       gnutls_assert ();
1440       goto cleanup;
1441     }
1442
1443   result = 0;
1444
1445 cleanup:
1446   _gnutls_free_datum (&der);
1447
1448   return result;
1449 }
1450
1451 /* Reads the DER signature from the certificate and allocates space and
1452  * returns them into signed_data.
1453  */
1454 int
1455 _gnutls_x509_get_signature (ASN1_TYPE src, const char *src_name,
1456                             gnutls_datum_t * signature)
1457 {
1458   int bits, result, len;
1459
1460   signature->data = NULL;
1461   signature->size = 0;
1462
1463   /* Read the signature 
1464    */
1465   bits = 0;
1466   result = asn1_read_value (src, src_name, NULL, &bits);
1467
1468   if (result != ASN1_MEM_ERROR)
1469     {
1470       result = _gnutls_asn2err (result);
1471       gnutls_assert ();
1472       goto cleanup;
1473     }
1474
1475   if (bits % 8 != 0)
1476     {
1477       gnutls_assert ();
1478       result = GNUTLS_E_CERTIFICATE_ERROR;
1479       goto cleanup;
1480     }
1481
1482   len = bits / 8;
1483
1484   signature->data = gnutls_malloc (len);
1485   if (signature->data == NULL)
1486     {
1487       gnutls_assert ();
1488       result = GNUTLS_E_MEMORY_ERROR;
1489       return result;
1490     }
1491
1492   /* read the bit string of the signature
1493    */
1494   bits = len;
1495   result = asn1_read_value (src, src_name, signature->data, &bits);
1496
1497   if (result != ASN1_SUCCESS)
1498     {
1499       result = _gnutls_asn2err (result);
1500       gnutls_assert ();
1501       goto cleanup;
1502     }
1503
1504   signature->size = len;
1505
1506   return 0;
1507
1508 cleanup:
1509   return result;
1510 }