check for either iconv or libiconv.
[gnutls.git] / lib / x509 / common.c
blob0eff7a8bc16984ab969b435c02c40183b26e4de8
1 /*
2 * Copyright (C) 2003-2012 Free Software Foundation, Inc.
4 * Author: Nikos Mavrogiannopoulos
6 * This file is part of GnuTLS.
8 * The GnuTLS is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 3 of
11 * the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>
23 #include <gnutls_int.h>
24 #include <libtasn1.h>
25 #include <gnutls_datum.h>
26 #include <gnutls_global.h>
27 #include <gnutls_errors.h>
28 #include <gnutls_str.h>
29 #include <gnutls_x509.h>
30 #include <gnutls_num.h>
31 #include <x509_b64.h>
32 #include "x509_int.h"
33 #include <common.h>
35 struct oid2string
37 const char *oid;
38 const char *ldap_desc;
39 int choice; /* of type DirectoryString */
40 int printable;
41 const char *asn_desc; /* description in the pkix file */
44 /* This list contains all the OIDs that may be
45 * contained in a rdnSequence and are printable.
47 static const struct oid2string _oid2str[] = {
48 /* PKIX
50 {"1.3.6.1.5.5.7.9.1", "dateOfBirth", 0, 1, "PKIX1.GeneralizedTime"},
51 {"1.3.6.1.5.5.7.9.2", "placeOfBirth", 0, 1, "PKIX1.DirectoryString"},
52 {"1.3.6.1.5.5.7.9.3", "gender", 0, 1, "PKIX1.PrintableString"},
53 {"1.3.6.1.5.5.7.9.4", "countryOfCitizenship", 0, 1,
54 "PKIX1.PrintableString"},
55 {"1.3.6.1.5.5.7.9.5", "countryOfResidence", 0, 1, "PKIX1.PrintableString"},
57 {"2.5.4.6", "C", 0, 1, "PKIX1.PrintableString"},
58 {"2.5.4.9", "STREET", 1, 1, "PKIX1.DirectoryString"},
59 {"2.5.4.12", "T", 1, 1, "PKIX1.DirectoryString"},
60 {"2.5.4.10", "O", 1, 1, "PKIX1.DirectoryString"},
61 {"2.5.4.11", "OU", 1, 1, "PKIX1.DirectoryString"},
62 {"2.5.4.3", "CN", 1, 1, "PKIX1.DirectoryString"},
63 {"2.5.4.7", "L", 1, 1, "PKIX1.DirectoryString"},
64 {"2.5.4.8", "ST", 1, 1, "PKIX1.DirectoryString"},
66 {"2.5.4.5", "serialNumber", 0, 1, "PKIX1.PrintableString"},
67 {"2.5.4.20", "telephoneNumber", 0, 1, "PKIX1.PrintableString"},
68 {"2.5.4.4", "surName", 1, 1, "PKIX1.DirectoryString"},
69 {"2.5.4.43", "initials", 1, 1, "PKIX1.DirectoryString"},
70 {"2.5.4.44", "generationQualifier", 1, 1, "PKIX1.DirectoryString"},
71 {"2.5.4.42", "givenName", 1, 1, "PKIX1.DirectoryString"},
72 {"2.5.4.65", "pseudonym", 1, 1, "PKIX1.DirectoryString"},
73 {"2.5.4.46", "dnQualifier", 0, 1, "PKIX1.PrintableString"},
74 {"2.5.4.17", "postalCode", 1, 1, "PKIX1.DirectoryString"},
75 {"2.5.4.41", "Name", 1, 1, "PKIX1.DirectoryString"},
76 {"2.5.4.15", "businessCategory", 1, 1, "PKIX1.DirectoryString"},
78 {"0.9.2342.19200300.100.1.25", "DC", 0, 1, "PKIX1.IA5String"},
79 {"0.9.2342.19200300.100.1.1", "UID", 1, 1, "PKIX1.DirectoryString"},
81 /* Extended validation
83 {"1.3.6.1.4.1.311.60.2.1.1", "jurisdictionOfIncorporationLocalityName", 1,
84 1, "PKIX1.DirectoryString"},
85 {"1.3.6.1.4.1.311.60.2.1.2",
86 "jurisdictionOfIncorporationStateOrProvinceName", 1, 1,
87 "PKIX1.DirectoryString"},
88 {"1.3.6.1.4.1.311.60.2.1.3", "jurisdictionOfIncorporationCountryName", 0, 1,
89 "PKIX1.PrintableString"},
91 /* PKCS #9
93 {"1.2.840.113549.1.9.1", "EMAIL", 0, 1, "PKIX1.IA5String"},
94 {"1.2.840.113549.1.9.7", NULL, 1, 1, "PKIX1.pkcs-9-challengePassword"},
96 /* friendly name */
97 {"1.2.840.113549.1.9.20", NULL, 0, 1, "PKIX1.BMPString"},
98 /* local key id */
99 {"1.2.840.113549.1.9.21", NULL, 0, 1, "PKIX1.pkcs-9-localKeyId"},
101 /* rfc3920 section 5.1.1 */
102 {"1.3.6.1.5.5.7.8.5", "XmppAddr", 0, 1, "PKIX1.UTF8String"},
104 {NULL, NULL, 0, 0, ""}
107 /* Returns 1 if the data defined by the OID are printable.
110 _gnutls_x509_oid_data_printable (const char *oid)
112 unsigned int i = 0;
116 if (strcmp (_oid2str[i].oid, oid) == 0)
117 return _oid2str[i].printable;
118 i++;
120 while (_oid2str[i].oid != NULL);
122 return 0;
126 * gnutls_x509_dn_oid_known:
127 * @oid: holds an Object Identifier in a null terminated string
129 * This function will inform about known DN OIDs. This is useful since
130 * functions like gnutls_x509_crt_set_dn_by_oid() use the information
131 * on known OIDs to properly encode their input. Object Identifiers
132 * that are not known are not encoded by these functions, and their
133 * input is stored directly into the ASN.1 structure. In that case of
134 * unknown OIDs, you have the responsibility of DER encoding your
135 * data.
137 * Returns: 1 on known OIDs and 0 otherwise.
140 gnutls_x509_dn_oid_known (const char *oid)
142 unsigned int i = 0;
146 if (strcmp (_oid2str[i].oid, oid) == 0)
147 return 1;
148 i++;
150 while (_oid2str[i].oid != NULL);
152 return 0;
155 /* Returns 1 if the data defined by the OID are of a choice
156 * type.
159 _gnutls_x509_oid_data_choice (const char *oid)
161 unsigned int i = 0;
165 if (strcmp (_oid2str[i].oid, oid) == 0)
166 return _oid2str[i].choice;
167 i++;
169 while (_oid2str[i].oid != NULL);
171 return 0;
175 * gnutls_x509_dn_oid_name:
176 * @oid: holds an Object Identifier in a null terminated string
177 * @flags: 0 or GNUTLS_X509_DN_OID_*
179 * This function will return the name of a known DN OID. If
180 * %GNUTLS_X509_DN_OID_RETURN_OID is specified this function
181 * will return the given OID if no descriptive name has been
182 * found.
184 * Returns: A null terminated string or NULL otherwise.
186 * Since: 3.0
188 const char*
189 gnutls_x509_dn_oid_name (const char *oid, unsigned int flags)
191 unsigned int i = 0;
195 if (strcmp (_oid2str[i].oid, oid) == 0)
196 return _oid2str[i].ldap_desc;
197 i++;
199 while (_oid2str[i].oid != NULL);
201 if (flags & GNUTLS_X509_DN_OID_RETURN_OID) return oid;
202 else return NULL;
205 const char *
206 _gnutls_x509_oid2asn_string (const char *oid)
208 unsigned int i = 0;
212 if (strcmp (_oid2str[i].oid, oid) == 0)
213 return _oid2str[i].asn_desc;
214 i++;
216 while (_oid2str[i].oid != NULL);
218 return NULL;
222 /* This function will convert an attribute value, specified by the OID,
223 * to a string. The result will be a null terminated string.
225 * res may be null. This will just return the res_size, needed to
226 * hold the string.
229 _gnutls_x509_oid_data2string (const char *oid, void *value,
230 int value_size, char *res, size_t * res_size)
232 char str[MAX_STRING_LEN], tmpname[128];
233 const char *aname = NULL;
234 int choice = -1, len = -1, result;
235 ASN1_TYPE tmpasn = ASN1_TYPE_EMPTY;
236 char asn1_err[ASN1_MAX_ERROR_DESCRIPTION_SIZE] = "";
238 if (value == NULL || value_size <= 0 || res_size == NULL)
240 gnutls_assert ();
241 return GNUTLS_E_INVALID_REQUEST;
244 if (_gnutls_x509_oid_data_printable (oid) == 0)
246 gnutls_assert ();
247 return GNUTLS_E_INTERNAL_ERROR;
250 aname = _gnutls_x509_oid2asn_string (oid);
251 choice = _gnutls_x509_oid_data_choice (oid);
253 if (aname == NULL)
255 gnutls_assert ();
256 return GNUTLS_E_INTERNAL_ERROR;
259 if ((result =
260 asn1_create_element (_gnutls_get_pkix (), aname,
261 &tmpasn)) != ASN1_SUCCESS)
263 gnutls_assert ();
264 return _gnutls_asn2err (result);
267 if ((result =
268 asn1_der_decoding (&tmpasn, value, value_size,
269 asn1_err)) != ASN1_SUCCESS)
271 gnutls_assert ();
272 _gnutls_debug_log ("asn1_der_decoding: %s:%s\n", str, asn1_err);
273 asn1_delete_structure (&tmpasn);
274 return _gnutls_asn2err (result);
277 /* If this is a choice then we read the choice. Otherwise it
278 * is the value;
280 len = sizeof (str) - 1;
281 if ((result = asn1_read_value (tmpasn, "", str, &len)) != ASN1_SUCCESS)
282 { /* CHOICE */
283 gnutls_assert ();
284 asn1_delete_structure (&tmpasn);
285 return _gnutls_asn2err (result);
288 if (choice == 0)
290 str[len] = 0;
292 /* Refuse to deal with strings containing NULs. */
293 if (strlen (str) != (size_t)len)
294 return GNUTLS_E_ASN1_DER_ERROR;
296 if (res)
297 _gnutls_str_cpy (res, *res_size, str);
298 *res_size = (size_t)len;
300 asn1_delete_structure (&tmpasn);
302 else
303 { /* choice */
304 int non_printable = 0, teletex = 0;
305 int ucs2 = 0;
306 str[len] = 0;
308 /* Note that we do not support strings other than
309 * UTF-8 (thus ASCII as well).
311 if (strcmp (str, "printableString") != 0 && strcmp (str, "bmpString") != 0 &&
312 strcmp (str, "ia5String") != 0 && strcmp (str, "utf8String") != 0)
314 non_printable = 1;
316 if (strcmp (str, "teletexString") == 0)
317 teletex = 1;
319 if (strcmp (str, "bmpString") == 0)
320 ucs2 = 1;
322 _gnutls_str_cpy (tmpname, sizeof (tmpname), str);
324 len = sizeof (str) - 1;
325 if ((result =
326 asn1_read_value (tmpasn, tmpname, str, &len)) != ASN1_SUCCESS)
328 asn1_delete_structure (&tmpasn);
329 return _gnutls_asn2err (result);
332 asn1_delete_structure (&tmpasn);
334 if (ucs2 != 0)
336 gnutls_datum_t td;
338 result = _gnutls_ucs2_to_utf8(str, len, &td);
339 if (result < 0)
341 /* could not convert. Handle it as non-printable */
342 non_printable = 1;
343 ucs2 = 0;
345 else
347 if (td.size >= sizeof(str))
349 gnutls_free(td.data);
350 return gnutls_assert_val(GNUTLS_E_ASN1_DER_ERROR);
352 memcpy(str, td.data, td.size);
353 len = td.size;
355 gnutls_free(td.data);
358 else if (teletex != 0)
360 int ascii = 0, i;
361 /* HACK: if the teletex string contains only ascii
362 * characters then treat it as printable.
364 for (i = 0; i < len; i++)
365 if (!isascii (str[i]))
366 ascii = 1;
368 if (ascii == 0)
369 non_printable = 0;
372 if (non_printable == 0)
374 str[len] = 0;
376 /* Refuse to deal with strings containing NULs. */
377 if (strlen (str) != (size_t)len)
378 return gnutls_assert_val(GNUTLS_E_ASN1_DER_ERROR);
380 if (res)
381 _gnutls_str_cpy (res, *res_size, str);
382 *res_size = (size_t)len;
384 else
386 result = _gnutls_x509_data2hex (str, (size_t)len, res, res_size);
387 if (result < 0)
388 return gnutls_assert_val(result);
392 return 0;
396 /* Converts a data string to an LDAP rfc2253 hex string
397 * something like '#01020304'
400 _gnutls_x509_data2hex (const void * data, size_t data_size,
401 void * _out, size_t * sizeof_out)
403 char *res;
404 char escaped[MAX_STRING_LEN];
405 unsigned int size;
406 char* out = _out;
408 if (2 * data_size + 1 > MAX_STRING_LEN)
410 gnutls_assert ();
411 return GNUTLS_E_INTERNAL_ERROR;
414 res = _gnutls_bin2hex (data, data_size, escaped, sizeof (escaped), NULL);
415 if (!res)
417 gnutls_assert ();
418 return GNUTLS_E_INTERNAL_ERROR;
421 size = strlen (res) + 1;
422 if (size + 1 > *sizeof_out)
424 *sizeof_out = size;
425 return GNUTLS_E_SHORT_MEMORY_BUFFER;
427 *sizeof_out = size; /* -1 for the null +1 for the '#' */
429 if (out)
431 out[0] = '#';
432 out[1] = 0;
433 _gnutls_str_cat (out, *sizeof_out, res);
436 return 0;
440 /* TIME functions
441 * Convertions between generalized or UTC time to time_t
445 /* This is an emulations of the struct tm.
446 * Since we do not use libc's functions, we don't need to
447 * depend on the libc structure.
449 typedef struct fake_tm
451 int tm_mon;
452 int tm_year; /* FULL year - ie 1971 */
453 int tm_mday;
454 int tm_hour;
455 int tm_min;
456 int tm_sec;
457 } fake_tm;
459 /* The mktime_utc function is due to Russ Allbery (rra@stanford.edu),
460 * who placed it under public domain:
463 /* The number of days in each month.
465 static const int MONTHDAYS[] = {
466 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
469 /* Whether a given year is a leap year. */
470 #define ISLEAP(year) \
471 (((year) % 4) == 0 && (((year) % 100) != 0 || ((year) % 400) == 0))
474 ** Given a struct tm representing a calendar time in UTC, convert it to
475 ** seconds since epoch. Returns (time_t) -1 if the time is not
476 ** convertable. Note that this function does not canonicalize the provided
477 ** struct tm, nor does it allow out of range values or years before 1970.
479 static time_t
480 mktime_utc (const struct fake_tm *tm)
482 time_t result = 0;
483 int i;
485 /* We do allow some ill-formed dates, but we don't do anything special
486 * with them and our callers really shouldn't pass them to us. Do
487 * explicitly disallow the ones that would cause invalid array accesses
488 * or other algorithm problems.
490 if (tm->tm_mon < 0 || tm->tm_mon > 11 || tm->tm_year < 1970)
491 return (time_t) - 1;
493 /* Convert to a time_t.
495 for (i = 1970; i < tm->tm_year; i++)
496 result += 365 + ISLEAP (i);
497 for (i = 0; i < tm->tm_mon; i++)
498 result += MONTHDAYS[i];
499 if (tm->tm_mon > 1 && ISLEAP (tm->tm_year))
500 result++;
501 result = 24 * (result + tm->tm_mday - 1) + tm->tm_hour;
502 result = 60 * result + tm->tm_min;
503 result = 60 * result + tm->tm_sec;
504 return result;
508 /* this one will parse dates of the form:
509 * month|day|hour|minute|sec* (2 chars each)
510 * and year is given. Returns a time_t date.
512 static time_t
513 time2gtime (const char *ttime, int year)
515 char xx[4];
516 struct fake_tm etime;
518 if (strlen (ttime) < 8)
520 gnutls_assert ();
521 return (time_t) - 1;
524 etime.tm_year = year;
526 /* In order to work with 32 bit
527 * time_t.
529 if (sizeof (time_t) <= 4 && etime.tm_year >= 2038)
530 return (time_t) 2145914603; /* 2037-12-31 23:23:23 */
532 if (etime.tm_year < 1970)
533 return (time_t) 0;
535 xx[2] = 0;
537 /* get the month
539 memcpy (xx, ttime, 2); /* month */
540 etime.tm_mon = atoi (xx) - 1;
541 ttime += 2;
543 /* get the day
545 memcpy (xx, ttime, 2); /* day */
546 etime.tm_mday = atoi (xx);
547 ttime += 2;
549 /* get the hour
551 memcpy (xx, ttime, 2); /* hour */
552 etime.tm_hour = atoi (xx);
553 ttime += 2;
555 /* get the minutes
557 memcpy (xx, ttime, 2); /* minutes */
558 etime.tm_min = atoi (xx);
559 ttime += 2;
561 if (strlen (ttime) >= 2)
563 memcpy (xx, ttime, 2);
564 etime.tm_sec = atoi (xx);
566 else
567 etime.tm_sec = 0;
569 return mktime_utc (&etime);
573 /* returns a time_t value that contains the given time.
574 * The given time is expressed as:
575 * YEAR(2)|MONTH(2)|DAY(2)|HOUR(2)|MIN(2)|SEC(2)*
577 * (seconds are optional)
579 static time_t
580 utcTime2gtime (const char *ttime)
582 char xx[3];
583 int year;
585 if (strlen (ttime) < 10)
587 gnutls_assert ();
588 return (time_t) - 1;
590 xx[2] = 0;
591 /* get the year
593 memcpy (xx, ttime, 2); /* year */
594 year = atoi (xx);
595 ttime += 2;
597 if (year > 49)
598 year += 1900;
599 else
600 year += 2000;
602 return time2gtime (ttime, year);
605 /* returns a time_t value that contains the given time.
606 * The given time is expressed as:
607 * YEAR(4)|MONTH(2)|DAY(2)|HOUR(2)|MIN(2)|SEC(2)*
609 time_t
610 _gnutls_x509_generalTime2gtime (const char *ttime)
612 char xx[5];
613 int year;
615 if (strlen (ttime) < 12)
617 gnutls_assert ();
618 return (time_t) - 1;
621 if (strchr (ttime, 'Z') == 0)
623 gnutls_assert ();
624 /* sorry we don't support it yet
626 return (time_t) - 1;
628 xx[4] = 0;
630 /* get the year
632 memcpy (xx, ttime, 4); /* year */
633 year = atoi (xx);
634 ttime += 4;
636 return time2gtime (ttime, year);
639 static int
640 gtime2generalTime (time_t gtime, char *str_time, size_t str_time_size)
642 size_t ret;
643 struct tm _tm;
645 if (!gmtime_r (&gtime, &_tm))
647 gnutls_assert ();
648 return GNUTLS_E_INTERNAL_ERROR;
651 ret = strftime (str_time, str_time_size, "%Y%m%d%H%M%SZ", &_tm);
652 if (!ret)
654 gnutls_assert ();
655 return GNUTLS_E_SHORT_MEMORY_BUFFER;
659 return 0;
663 /* Extracts the time in time_t from the ASN1_TYPE given. When should
664 * be something like "tbsCertList.thisUpdate".
666 #define MAX_TIME 64
667 time_t
668 _gnutls_x509_get_time (ASN1_TYPE c2, const char *when, int nochoice)
670 char ttime[MAX_TIME];
671 char name[128];
672 time_t c_time = (time_t) - 1;
673 int len, result;
675 len = sizeof (ttime) - 1;
676 result = asn1_read_value (c2, when, ttime, &len);
677 if (result != ASN1_SUCCESS)
679 gnutls_assert ();
680 return (time_t) (-1);
683 if (nochoice != 0)
685 c_time = _gnutls_x509_generalTime2gtime (ttime);
687 else
689 _gnutls_str_cpy (name, sizeof (name), when);
691 /* choice */
692 if (strcmp (ttime, "generalTime") == 0)
694 _gnutls_str_cat (name, sizeof (name), ".generalTime");
695 len = sizeof (ttime) - 1;
696 result = asn1_read_value (c2, name, ttime, &len);
697 if (result == ASN1_SUCCESS)
698 c_time = _gnutls_x509_generalTime2gtime (ttime);
700 else
701 { /* UTCTIME */
702 _gnutls_str_cat (name, sizeof (name), ".utcTime");
703 len = sizeof (ttime) - 1;
704 result = asn1_read_value (c2, name, ttime, &len);
705 if (result == ASN1_SUCCESS)
706 c_time = utcTime2gtime (ttime);
709 /* We cannot handle dates after 2031 in 32 bit machines.
710 * a time_t of 64bits has to be used.
712 if (result != ASN1_SUCCESS)
714 gnutls_assert ();
715 return (time_t) (-1);
719 return c_time;
722 /* Sets the time in time_t in the ASN1_TYPE given. Where should
723 * be something like "tbsCertList.thisUpdate".
726 _gnutls_x509_set_time (ASN1_TYPE c2, const char *where, time_t tim, int nochoice)
728 char str_time[MAX_TIME];
729 char name[128];
730 int result, len;
732 if (nochoice != 0)
734 result = gtime2generalTime( tim, str_time, sizeof(str_time));
735 if (result < 0)
736 return gnutls_assert_val(result);
738 len = strlen (str_time);
739 result = asn1_write_value(c2, where, str_time, len);
740 if (result != ASN1_SUCCESS)
741 return gnutls_assert_val(_gnutls_asn2err (result));
743 return 0;
746 _gnutls_str_cpy (name, sizeof (name), where);
748 if ((result = asn1_write_value (c2, name, "generalTime", 1)) < 0)
750 gnutls_assert ();
751 return _gnutls_asn2err (result);
754 result = gtime2generalTime (tim, str_time, sizeof (str_time));
755 if (result < 0)
757 gnutls_assert ();
758 return result;
761 _gnutls_str_cat (name, sizeof (name), ".generalTime");
763 len = strlen (str_time);
764 result = asn1_write_value (c2, name, str_time, len);
765 if (result != ASN1_SUCCESS)
767 gnutls_assert ();
768 return _gnutls_asn2err (result);
771 return 0;
775 gnutls_x509_subject_alt_name_t
776 _gnutls_x509_san_find_type (char *str_type)
778 if (strcmp (str_type, "dNSName") == 0)
779 return GNUTLS_SAN_DNSNAME;
780 if (strcmp (str_type, "rfc822Name") == 0)
781 return GNUTLS_SAN_RFC822NAME;
782 if (strcmp (str_type, "uniformResourceIdentifier") == 0)
783 return GNUTLS_SAN_URI;
784 if (strcmp (str_type, "iPAddress") == 0)
785 return GNUTLS_SAN_IPADDRESS;
786 if (strcmp (str_type, "otherName") == 0)
787 return GNUTLS_SAN_OTHERNAME;
788 if (strcmp (str_type, "directoryName") == 0)
789 return GNUTLS_SAN_DN;
790 return (gnutls_x509_subject_alt_name_t) - 1;
793 /* A generic export function. Will export the given ASN.1 encoded data
794 * to PEM or DER raw data.
797 _gnutls_x509_export_int_named (ASN1_TYPE asn1_data, const char *name,
798 gnutls_x509_crt_fmt_t format,
799 const char *pem_header,
800 unsigned char *output_data,
801 size_t * output_data_size)
803 int ret;
804 gnutls_datum_t out;
805 size_t size;
807 ret = _gnutls_x509_export_int_named2 (asn1_data, name,
808 format, pem_header, &out);
809 if (ret < 0)
810 return gnutls_assert_val(ret);
812 if (format == GNUTLS_X509_FMT_PEM)
813 size = out.size+1;
814 else
815 size = out.size;
817 if (*output_data_size < size)
819 *output_data_size = size;
820 ret = gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
821 goto cleanup;
824 *output_data_size = (size_t)out.size;
825 if (output_data)
827 memcpy (output_data, out.data, (size_t)out.size);
828 if (format == GNUTLS_X509_FMT_PEM)
829 output_data[out.size] = 0;
832 ret = 0;
834 cleanup:
835 gnutls_free (out.data);
837 return ret;
840 /* A generic export function. Will export the given ASN.1 encoded data
841 * to PEM or DER raw data.
844 _gnutls_x509_export_int_named2 (ASN1_TYPE asn1_data, const char *name,
845 gnutls_x509_crt_fmt_t format,
846 const char *pem_header,
847 gnutls_datum_t *out)
849 int ret;
851 if (format == GNUTLS_X509_FMT_DER)
853 ret = _gnutls_x509_der_encode(asn1_data, name, out, 0);
854 if (ret < 0)
855 return gnutls_assert_val(ret);
857 else
858 { /* PEM */
859 gnutls_datum_t tmp;
861 ret = _gnutls_x509_der_encode (asn1_data, name, &tmp, 0);
862 if (ret < 0)
863 return gnutls_assert_val(ret);
865 ret = _gnutls_fbase64_encode (pem_header, tmp.data, tmp.size, out);
866 _gnutls_free_datum (&tmp);
868 if (ret < 0)
869 return gnutls_assert_val(ret);
872 return 0;
875 /* Decodes an octet string. Leave string_type null for a normal
876 * octet string. Otherwise put something like BMPString, PrintableString
877 * etc.
880 _gnutls_x509_decode_string (const char *string_type,
881 const uint8_t * der, size_t der_size,
882 gnutls_datum_t * output)
884 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
885 int result;
886 char strname[64];
888 if (string_type == NULL) /* assume octet string */
889 _gnutls_str_cpy (strname, sizeof (strname), "PKIX1.pkcs-7-Data");
890 else
892 _gnutls_str_cpy (strname, sizeof (strname), "PKIX1.");
893 _gnutls_str_cat (strname, sizeof (strname), string_type);
896 if ((result = asn1_create_element
897 (_gnutls_get_pkix (), strname, &c2)) != ASN1_SUCCESS)
899 gnutls_assert ();
900 result = _gnutls_asn2err (result);
901 goto cleanup;
904 result = asn1_der_decoding (&c2, der, der_size, NULL);
905 if (result != ASN1_SUCCESS)
907 gnutls_assert ();
908 result = _gnutls_asn2err (result);
909 goto cleanup;
912 result = _gnutls_x509_read_value(c2, "", output);
913 if (result < 0)
915 gnutls_assert ();
916 goto cleanup;
919 /* This is allowed since _gnutls_x509_read_value allocates one more */
920 output->data[output->size] = 0;
922 result = 0;
924 cleanup:
925 if (c2)
926 asn1_delete_structure (&c2);
928 return result;
932 /* Reads a value from an ASN1 tree, and puts the output
933 * in an allocated variable in the given datum.
935 * Note that this function always places allocates one plus
936 * the required data size (to allow for a null byte).
939 _gnutls_x509_read_value (ASN1_TYPE c, const char *root,
940 gnutls_datum_t * ret)
942 int len = 0, result;
943 uint8_t *tmp = NULL;
945 result = asn1_read_value (c, root, NULL, &len);
946 if (result != ASN1_MEM_ERROR)
948 gnutls_assert ();
949 result = _gnutls_asn2err (result);
950 return result;
953 tmp = gnutls_malloc ((size_t)len+1);
954 if (tmp == NULL)
956 gnutls_assert ();
957 result = GNUTLS_E_MEMORY_ERROR;
958 goto cleanup;
961 result = asn1_read_value (c, root, tmp, &len);
962 if (result != ASN1_SUCCESS)
964 gnutls_assert ();
965 result = _gnutls_asn2err (result);
966 goto cleanup;
969 ret->data = tmp;
970 ret->size = (unsigned)len;
972 return 0;
974 cleanup:
975 gnutls_free (tmp);
976 return result;
979 /* Reads a value from an ASN1 tree, and puts the output
980 * in an allocated variable in the given datum.
982 * Note that this function always places a null character
983 * at the end of a readable string value (which is not accounted into size)
986 _gnutls_x509_read_string (ASN1_TYPE c, const char *root,
987 gnutls_datum_t * ret, x509_string_type type)
989 int len = 0, result;
990 size_t slen;
991 uint8_t *tmp = NULL;
993 result = asn1_read_value (c, root, NULL, &len);
994 if (result != ASN1_MEM_ERROR)
996 gnutls_assert ();
997 result = _gnutls_asn2err (result);
998 return result;
1001 if (type == RV_BIT_STRING)
1002 len /= 8;
1004 tmp = gnutls_malloc ((size_t)len+1);
1005 if (tmp == NULL)
1007 gnutls_assert ();
1008 result = GNUTLS_E_MEMORY_ERROR;
1009 goto cleanup;
1012 result = asn1_read_value (c, root, tmp, &len);
1013 if (result != ASN1_SUCCESS)
1015 gnutls_assert ();
1016 result = _gnutls_asn2err (result);
1017 goto cleanup;
1020 if (type == RV_BIT_STRING)
1021 len /= 8;
1023 /* Extract the STRING.
1025 if (type == RV_IA5STRING || type == RV_UTF8STRING || type == RV_OCTET_STRING)
1027 const char* sname;
1028 slen = (size_t)len;
1030 if (type == RV_UTF8STRING)
1031 sname = "UTF8String";
1032 else if (type == RV_IA5STRING)
1033 sname = "IA5String";
1034 else
1035 sname = NULL;
1037 result = _gnutls_x509_decode_string (sname, tmp, slen, ret);
1038 if (result < 0)
1040 gnutls_assert ();
1041 goto cleanup;
1043 gnutls_free(tmp);
1045 else
1047 ret->data = tmp;
1048 ret->size = (unsigned)len;
1051 return 0;
1053 cleanup:
1054 gnutls_free (tmp);
1055 return result;
1058 /* The string type should be IA5String, UTF8String etc. Leave
1059 * null for octet string */
1060 int _gnutls_x509_encode_string(const char* string_type,
1061 const void* input_data, size_t input_size,
1062 gnutls_datum_t* output)
1064 int ret;
1065 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
1066 char strname[64];
1068 _gnutls_str_cpy (strname, sizeof (strname), "PKIX1.");
1069 if (string_type == NULL)
1070 _gnutls_str_cat (strname, sizeof (strname), "pkcs-7-Data");
1071 else
1072 _gnutls_str_cat (strname, sizeof (strname), string_type);
1074 if ((ret = asn1_create_element
1075 (_gnutls_get_pkix (), strname, &c2)) != ASN1_SUCCESS)
1077 gnutls_assert ();
1078 ret = _gnutls_asn2err (ret);
1079 goto cleanup;
1082 ret = asn1_write_value (c2, "", input_data, input_size);
1083 if (ret != ASN1_SUCCESS)
1085 gnutls_assert ();
1086 ret = _gnutls_asn2err (ret);
1087 goto cleanup;
1090 ret = _gnutls_x509_der_encode(c2, "", output, 0);
1091 if (ret < 0)
1093 gnutls_assert ();
1094 goto cleanup;
1097 ret = 0;
1099 cleanup:
1100 asn1_delete_structure (&c2);
1101 return ret;
1104 /* DER Encodes the src ASN1_TYPE and stores it to
1105 * the given datum. If str is non zero then the data are encoded as
1106 * an OCTET STRING.
1109 _gnutls_x509_der_encode (ASN1_TYPE src, const char *src_name,
1110 gnutls_datum_t * res, int str)
1112 int size, result;
1113 int asize;
1114 uint8_t *data = NULL;
1115 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
1117 size = 0;
1118 result = asn1_der_coding (src, src_name, NULL, &size, NULL);
1119 if (result != ASN1_MEM_ERROR)
1121 gnutls_assert ();
1122 result = _gnutls_asn2err (result);
1123 goto cleanup;
1126 /* allocate data for the der
1129 if (str)
1130 size += 16; /* for later to include the octet tags */
1131 asize = size;
1133 data = gnutls_malloc ((size_t)size);
1134 if (data == NULL)
1136 gnutls_assert ();
1137 result = GNUTLS_E_MEMORY_ERROR;
1138 goto cleanup;
1141 result = asn1_der_coding (src, src_name, data, &size, NULL);
1142 if (result != ASN1_SUCCESS)
1144 gnutls_assert ();
1145 result = _gnutls_asn2err (result);
1146 goto cleanup;
1149 if (str)
1151 if ((result = asn1_create_element
1152 (_gnutls_get_pkix (), "PKIX1.pkcs-7-Data", &c2)) != ASN1_SUCCESS)
1154 gnutls_assert ();
1155 result = _gnutls_asn2err (result);
1156 goto cleanup;
1159 result = asn1_write_value (c2, "", data, size);
1160 if (result != ASN1_SUCCESS)
1162 gnutls_assert ();
1163 result = _gnutls_asn2err (result);
1164 goto cleanup;
1167 result = asn1_der_coding (c2, "", data, &asize, NULL);
1168 if (result != ASN1_SUCCESS)
1170 gnutls_assert ();
1171 result = _gnutls_asn2err (result);
1172 goto cleanup;
1175 size = asize;
1177 asn1_delete_structure (&c2);
1180 res->data = data;
1181 res->size = (unsigned)size;
1182 return 0;
1184 cleanup:
1185 gnutls_free (data);
1186 asn1_delete_structure (&c2);
1187 return result;
1191 /* DER Encodes the src ASN1_TYPE and stores it to
1192 * dest in dest_name. Useful to encode something and store it
1193 * as OCTET. If str is non null then the data are encoded as
1194 * an OCTET STRING.
1197 _gnutls_x509_der_encode_and_copy (ASN1_TYPE src, const char *src_name,
1198 ASN1_TYPE dest, const char *dest_name,
1199 int str)
1201 int result;
1202 gnutls_datum_t encoded;
1204 result = _gnutls_x509_der_encode (src, src_name, &encoded, str);
1206 if (result < 0)
1208 gnutls_assert ();
1209 return result;
1212 /* Write the data.
1214 result = asn1_write_value (dest, dest_name, encoded.data, (int)encoded.size);
1216 _gnutls_free_datum (&encoded);
1218 if (result != ASN1_SUCCESS)
1220 gnutls_assert ();
1221 return _gnutls_asn2err (result);
1224 return 0;
1227 /* Writes the value of the datum in the given ASN1_TYPE. If str is non
1228 * (0) it encodes it as OCTET STRING.
1231 _gnutls_x509_write_value (ASN1_TYPE c, const char *root,
1232 const gnutls_datum_t * data, x509_string_type type)
1234 int ret;
1235 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
1236 gnutls_datum_t val = { NULL, 0 };
1237 const char* sname = NULL;
1239 if (type == RV_OCTET_STRING || type == RV_IA5STRING || type == RV_UTF8STRING)
1242 if (type == RV_IA5STRING)
1243 sname = "IA5String";
1244 else if (type == RV_UTF8STRING)
1245 sname = "UTF8String";
1247 ret = _gnutls_x509_encode_string(sname, data->data, data->size, &val);
1248 if (ret < 0)
1250 gnutls_assert ();
1251 goto cleanup;
1254 else
1256 val.data = data->data;
1257 val.size = data->size;
1260 /* Write the data.
1262 ret = asn1_write_value (c, root, val.data, val.size);
1263 if (ret != ASN1_SUCCESS)
1265 gnutls_assert ();
1266 ret = _gnutls_asn2err (ret);
1267 goto cleanup;
1270 ret = 0;
1272 cleanup:
1273 asn1_delete_structure (&c2);
1274 if (val.data != data->data)
1275 _gnutls_free_datum (&val);
1276 return ret;
1279 void
1280 _asnstr_append_name (char *name, size_t name_size, const char *part1,
1281 const char *part2)
1283 if (part1[0] != 0)
1285 _gnutls_str_cpy (name, name_size, part1);
1286 _gnutls_str_cat (name, name_size, part2);
1288 else
1289 _gnutls_str_cpy (name, name_size, part2 + 1 /* remove initial dot */ );
1294 /* Encodes and copies the private key parameters into a
1295 * subjectPublicKeyInfo structure.
1299 _gnutls_x509_encode_and_copy_PKI_params (ASN1_TYPE dst,
1300 const char *dst_name,
1301 gnutls_pk_algorithm_t
1302 pk_algorithm, gnutls_pk_params_st * params)
1304 const char *pk;
1305 gnutls_datum_t der = { NULL, 0 };
1306 int result;
1307 char name[128];
1309 pk = _gnutls_x509_pk_to_oid (pk_algorithm);
1310 if (pk == NULL)
1312 gnutls_assert ();
1313 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
1316 /* write the OID
1318 _asnstr_append_name (name, sizeof (name), dst_name, ".algorithm.algorithm");
1320 result = asn1_write_value (dst, name, pk, 1);
1321 if (result != ASN1_SUCCESS)
1323 gnutls_assert ();
1324 return _gnutls_asn2err (result);
1327 result = _gnutls_x509_write_pubkey_params (pk_algorithm, params, &der);
1328 if (result < 0)
1330 gnutls_assert ();
1331 return result;
1334 _asnstr_append_name (name, sizeof (name), dst_name,
1335 ".algorithm.parameters");
1337 result = asn1_write_value (dst, name, der.data, der.size);
1339 _gnutls_free_datum (&der);
1341 if (result != ASN1_SUCCESS)
1343 gnutls_assert ();
1344 return _gnutls_asn2err (result);
1347 result = _gnutls_x509_write_pubkey (pk_algorithm, params, &der);
1348 if (result < 0)
1350 gnutls_assert ();
1351 return result;
1354 /* Write the DER parameters. (in bits)
1356 _asnstr_append_name (name, sizeof (name), dst_name,
1357 ".subjectPublicKey");
1358 result = asn1_write_value (dst, name, der.data, der.size * 8);
1359 _gnutls_free_datum (&der);
1361 if (result != ASN1_SUCCESS)
1363 gnutls_assert ();
1364 return _gnutls_asn2err (result);
1367 return 0;
1370 /* Encodes and public key parameters into a
1371 * subjectPublicKeyInfo structure and stores it in der.
1374 _gnutls_x509_encode_PKI_params (gnutls_datum_t *der,
1375 gnutls_pk_algorithm_t
1376 pk_algorithm, gnutls_pk_params_st * params)
1378 int ret;
1379 ASN1_TYPE tmp;
1381 ret = asn1_create_element (_gnutls_get_pkix (),
1382 "PKIX1.Certificate", &tmp);
1383 if (ret != ASN1_SUCCESS)
1385 gnutls_assert ();
1386 return _gnutls_asn2err (ret);
1389 ret = _gnutls_x509_encode_and_copy_PKI_params (tmp,
1390 "tbsCertificate.subjectPublicKeyInfo",
1391 pk_algorithm, params);
1392 if (ret != ASN1_SUCCESS)
1394 gnutls_assert ();
1395 ret = _gnutls_asn2err (ret);
1396 goto cleanup;
1399 ret = _gnutls_x509_der_encode(tmp, "tbsCertificate.subjectPublicKeyInfo", der, 0);
1401 cleanup:
1402 asn1_delete_structure (&tmp);
1404 return ret;
1407 /* Reads and returns the PK algorithm of the given certificate-like
1408 * ASN.1 structure. src_name should be something like "tbsCertificate.subjectPublicKeyInfo".
1411 _gnutls_x509_get_pk_algorithm (ASN1_TYPE src, const char *src_name,
1412 unsigned int *bits)
1414 int result;
1415 int algo;
1416 char oid[64];
1417 int len;
1418 gnutls_pk_params_st params;
1419 char name[128];
1421 gnutls_pk_params_init(&params);
1423 _asnstr_append_name (name, sizeof (name), src_name, ".algorithm.algorithm");
1424 len = sizeof (oid);
1425 result = asn1_read_value (src, name, oid, &len);
1427 if (result != ASN1_SUCCESS)
1429 gnutls_assert ();
1430 return _gnutls_asn2err (result);
1433 algo = _gnutls_x509_oid2pk_algorithm (oid);
1434 if (algo == GNUTLS_PK_UNKNOWN)
1436 _gnutls_debug_log
1437 ("%s: unknown public key algorithm: %s\n", __func__, oid);
1440 if (bits == NULL)
1442 return algo;
1445 /* Now read the parameters' bits
1447 result = _gnutls_get_asn_mpis(src, src_name, &params);
1448 if (result < 0)
1449 return gnutls_assert_val(result);
1451 bits[0] = pubkey_to_bits(algo, &params);
1453 gnutls_pk_params_release(&params);
1454 return algo;
1457 /* Reads the DER signed data from the certificate and allocates space and
1458 * returns them into signed_data.
1461 _gnutls_x509_get_signed_data (ASN1_TYPE src, const char *src_name,
1462 gnutls_datum_t * signed_data)
1464 gnutls_datum_t der;
1465 int start, end, result;
1467 result = _gnutls_x509_der_encode (src, "", &der, 0);
1468 if (result < 0)
1470 gnutls_assert ();
1471 return result;
1474 /* Get the signed data
1476 result = asn1_der_decoding_startEnd (src, der.data, der.size,
1477 src_name, &start, &end);
1478 if (result != ASN1_SUCCESS)
1480 result = _gnutls_asn2err (result);
1481 gnutls_assert ();
1482 goto cleanup;
1485 result = _gnutls_set_datum (signed_data, &der.data[start], end - start + 1);
1487 if (result < 0)
1489 gnutls_assert ();
1490 goto cleanup;
1493 result = 0;
1495 cleanup:
1496 _gnutls_free_datum (&der);
1498 return result;
1502 * gnutls_x509_get_signature_algorithm:
1503 * @src: should contain an ASN1_TYPE structure
1504 * @src_name: the description of the signature field
1506 * This function will return a value of the #gnutls_sign_algorithm_t
1507 * enumeration that is the signature algorithm that has been used to
1508 * sign this certificate.
1510 * Returns: a #gnutls_sign_algorithm_t value, or a negative error code on
1511 * error.
1514 _gnutls_x509_get_signature_algorithm (ASN1_TYPE src, const char *src_name)
1516 int result;
1517 gnutls_datum_t sa;
1519 /* Read the signature algorithm. Note that parameters are not
1520 * read. They will be read from the issuer's certificate if needed.
1522 result =
1523 _gnutls_x509_read_value (src, src_name, &sa);
1525 if (result < 0)
1527 gnutls_assert ();
1528 return result;
1531 result = _gnutls_x509_oid2sign_algorithm ( (char*)sa.data);
1533 _gnutls_free_datum (&sa);
1535 return result;
1539 /* Reads the DER signature from the certificate and allocates space and
1540 * returns them into signed_data.
1543 _gnutls_x509_get_signature (ASN1_TYPE src, const char *src_name,
1544 gnutls_datum_t * signature)
1546 int result, len;
1547 unsigned int bits;
1549 signature->data = NULL;
1550 signature->size = 0;
1552 /* Read the signature
1554 len = 0;
1555 result = asn1_read_value (src, src_name, NULL, &len);
1557 if (result != ASN1_MEM_ERROR)
1559 result = _gnutls_asn2err (result);
1560 gnutls_assert ();
1561 goto cleanup;
1564 bits = len;
1565 if (bits % 8 != 0)
1567 gnutls_assert ();
1568 result = GNUTLS_E_CERTIFICATE_ERROR;
1569 goto cleanup;
1572 len = bits / 8;
1574 signature->data = gnutls_malloc (len);
1575 if (signature->data == NULL)
1577 gnutls_assert ();
1578 result = GNUTLS_E_MEMORY_ERROR;
1579 return result;
1582 /* read the bit string of the signature
1584 bits = len;
1585 result = asn1_read_value (src, src_name, signature->data, (int*)&bits);
1587 if (result != ASN1_SUCCESS)
1589 result = _gnutls_asn2err (result);
1590 gnutls_assert ();
1591 goto cleanup;
1594 signature->size = len;
1596 return 0;
1598 cleanup:
1599 return result;