Use the new asn1_read_node_value()
[gnutls.git] / lib / x509 / common.c
blob052eb7cd732fcd75210300daf83ab1c19f378bbc
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 str[len] = 0;
307 /* Note that we do not support strings other than
308 * UTF-8 (thus ASCII as well).
310 if (strcmp (str, "printableString") != 0 &&
311 strcmp (str, "ia5String") != 0 && strcmp (str, "utf8String") != 0)
313 non_printable = 1;
315 if (strcmp (str, "teletexString") == 0)
316 teletex = 1;
319 _gnutls_str_cpy (tmpname, sizeof (tmpname), str);
321 len = sizeof (str) - 1;
322 if ((result =
323 asn1_read_value (tmpasn, tmpname, str, &len)) != ASN1_SUCCESS)
325 asn1_delete_structure (&tmpasn);
326 return _gnutls_asn2err (result);
329 asn1_delete_structure (&tmpasn);
331 if (teletex != 0)
333 int ascii = 0, i;
334 /* HACK: if the teletex string contains only ascii
335 * characters then treat it as printable.
337 for (i = 0; i < len; i++)
338 if (!isascii (str[i]))
339 ascii = 1;
341 if (ascii == 0)
342 non_printable = 0;
345 if (non_printable == 0)
347 str[len] = 0;
349 /* Refuse to deal with strings containing NULs. */
350 if (strlen (str) != (size_t)len)
351 return GNUTLS_E_ASN1_DER_ERROR;
353 if (res)
354 _gnutls_str_cpy (res, *res_size, str);
355 *res_size = (size_t)len;
357 else
359 result = _gnutls_x509_data2hex (str, (size_t)len, res, res_size);
360 if (result < 0)
362 gnutls_assert ();
363 return result;
368 return 0;
372 /* Converts a data string to an LDAP rfc2253 hex string
373 * something like '#01020304'
376 _gnutls_x509_data2hex (const void * data, size_t data_size,
377 void * _out, size_t * sizeof_out)
379 char *res;
380 char escaped[MAX_STRING_LEN];
381 unsigned int size;
382 char* out = _out;
384 if (2 * data_size + 1 > MAX_STRING_LEN)
386 gnutls_assert ();
387 return GNUTLS_E_INTERNAL_ERROR;
390 res = _gnutls_bin2hex (data, data_size, escaped, sizeof (escaped), NULL);
391 if (!res)
393 gnutls_assert ();
394 return GNUTLS_E_INTERNAL_ERROR;
397 size = strlen (res) + 1;
398 if (size + 1 > *sizeof_out)
400 *sizeof_out = size;
401 return GNUTLS_E_SHORT_MEMORY_BUFFER;
403 *sizeof_out = size; /* -1 for the null +1 for the '#' */
405 if (out)
407 out[0] = '#';
408 out[1] = 0;
409 _gnutls_str_cat (out, *sizeof_out, res);
412 return 0;
416 /* TIME functions
417 * Convertions between generalized or UTC time to time_t
421 /* This is an emulations of the struct tm.
422 * Since we do not use libc's functions, we don't need to
423 * depend on the libc structure.
425 typedef struct fake_tm
427 int tm_mon;
428 int tm_year; /* FULL year - ie 1971 */
429 int tm_mday;
430 int tm_hour;
431 int tm_min;
432 int tm_sec;
433 } fake_tm;
435 /* The mktime_utc function is due to Russ Allbery (rra@stanford.edu),
436 * who placed it under public domain:
439 /* The number of days in each month.
441 static const int MONTHDAYS[] = {
442 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
445 /* Whether a given year is a leap year. */
446 #define ISLEAP(year) \
447 (((year) % 4) == 0 && (((year) % 100) != 0 || ((year) % 400) == 0))
450 ** Given a struct tm representing a calendar time in UTC, convert it to
451 ** seconds since epoch. Returns (time_t) -1 if the time is not
452 ** convertable. Note that this function does not canonicalize the provided
453 ** struct tm, nor does it allow out of range values or years before 1970.
455 static time_t
456 mktime_utc (const struct fake_tm *tm)
458 time_t result = 0;
459 int i;
461 /* We do allow some ill-formed dates, but we don't do anything special
462 * with them and our callers really shouldn't pass them to us. Do
463 * explicitly disallow the ones that would cause invalid array accesses
464 * or other algorithm problems.
466 if (tm->tm_mon < 0 || tm->tm_mon > 11 || tm->tm_year < 1970)
467 return (time_t) - 1;
469 /* Convert to a time_t.
471 for (i = 1970; i < tm->tm_year; i++)
472 result += 365 + ISLEAP (i);
473 for (i = 0; i < tm->tm_mon; i++)
474 result += MONTHDAYS[i];
475 if (tm->tm_mon > 1 && ISLEAP (tm->tm_year))
476 result++;
477 result = 24 * (result + tm->tm_mday - 1) + tm->tm_hour;
478 result = 60 * result + tm->tm_min;
479 result = 60 * result + tm->tm_sec;
480 return result;
484 /* this one will parse dates of the form:
485 * month|day|hour|minute|sec* (2 chars each)
486 * and year is given. Returns a time_t date.
488 static time_t
489 time2gtime (const char *ttime, int year)
491 char xx[4];
492 struct fake_tm etime;
494 if (strlen (ttime) < 8)
496 gnutls_assert ();
497 return (time_t) - 1;
500 etime.tm_year = year;
502 /* In order to work with 32 bit
503 * time_t.
505 if (sizeof (time_t) <= 4 && etime.tm_year >= 2038)
506 return (time_t) 2145914603; /* 2037-12-31 23:23:23 */
508 if (etime.tm_year < 1970)
509 return (time_t) 0;
511 xx[2] = 0;
513 /* get the month
515 memcpy (xx, ttime, 2); /* month */
516 etime.tm_mon = atoi (xx) - 1;
517 ttime += 2;
519 /* get the day
521 memcpy (xx, ttime, 2); /* day */
522 etime.tm_mday = atoi (xx);
523 ttime += 2;
525 /* get the hour
527 memcpy (xx, ttime, 2); /* hour */
528 etime.tm_hour = atoi (xx);
529 ttime += 2;
531 /* get the minutes
533 memcpy (xx, ttime, 2); /* minutes */
534 etime.tm_min = atoi (xx);
535 ttime += 2;
537 if (strlen (ttime) >= 2)
539 memcpy (xx, ttime, 2);
540 etime.tm_sec = atoi (xx);
541 ttime += 2;
543 else
544 etime.tm_sec = 0;
546 return mktime_utc (&etime);
550 /* returns a time_t value that contains the given time.
551 * The given time is expressed as:
552 * YEAR(2)|MONTH(2)|DAY(2)|HOUR(2)|MIN(2)|SEC(2)*
554 * (seconds are optional)
556 static time_t
557 utcTime2gtime (const char *ttime)
559 char xx[3];
560 int year;
562 if (strlen (ttime) < 10)
564 gnutls_assert ();
565 return (time_t) - 1;
567 xx[2] = 0;
568 /* get the year
570 memcpy (xx, ttime, 2); /* year */
571 year = atoi (xx);
572 ttime += 2;
574 if (year > 49)
575 year += 1900;
576 else
577 year += 2000;
579 return time2gtime (ttime, year);
582 /* returns a time_t value that contains the given time.
583 * The given time is expressed as:
584 * YEAR(4)|MONTH(2)|DAY(2)|HOUR(2)|MIN(2)|SEC(2)*
586 time_t
587 _gnutls_x509_generalTime2gtime (const char *ttime)
589 char xx[5];
590 int year;
592 if (strlen (ttime) < 12)
594 gnutls_assert ();
595 return (time_t) - 1;
598 if (strchr (ttime, 'Z') == 0)
600 gnutls_assert ();
601 /* sorry we don't support it yet
603 return (time_t) - 1;
605 xx[4] = 0;
607 /* get the year
609 memcpy (xx, ttime, 4); /* year */
610 year = atoi (xx);
611 ttime += 4;
613 return time2gtime (ttime, year);
616 static int
617 gtime2generalTime (time_t gtime, char *str_time, size_t str_time_size)
619 size_t ret;
620 struct tm _tm;
622 if (!gmtime_r (&gtime, &_tm))
624 gnutls_assert ();
625 return GNUTLS_E_INTERNAL_ERROR;
628 ret = strftime (str_time, str_time_size, "%Y%m%d%H%M%SZ", &_tm);
629 if (!ret)
631 gnutls_assert ();
632 return GNUTLS_E_SHORT_MEMORY_BUFFER;
636 return 0;
640 /* Extracts the time in time_t from the ASN1_TYPE given. When should
641 * be something like "tbsCertList.thisUpdate".
643 #define MAX_TIME 64
644 time_t
645 _gnutls_x509_get_time (ASN1_TYPE c2, const char *when, int nochoice)
647 char ttime[MAX_TIME];
648 char name[128];
649 time_t c_time = (time_t) - 1;
650 int len, result;
652 len = sizeof (ttime) - 1;
653 result = asn1_read_value (c2, when, ttime, &len);
654 if (result != ASN1_SUCCESS)
656 gnutls_assert ();
657 return (time_t) (-1);
660 if (nochoice != 0)
662 c_time = _gnutls_x509_generalTime2gtime (ttime);
664 else
666 _gnutls_str_cpy (name, sizeof (name), when);
668 /* CHOICE */
669 if (strcmp (ttime, "generalTime") == 0)
671 _gnutls_str_cat (name, sizeof (name), ".generalTime");
672 len = sizeof (ttime) - 1;
673 result = asn1_read_value (c2, name, ttime, &len);
674 if (result == ASN1_SUCCESS)
675 c_time = _gnutls_x509_generalTime2gtime (ttime);
677 else
678 { /* UTCTIME */
679 _gnutls_str_cat (name, sizeof (name), ".utcTime");
680 len = sizeof (ttime) - 1;
681 result = asn1_read_value (c2, name, ttime, &len);
682 if (result == ASN1_SUCCESS)
683 c_time = utcTime2gtime (ttime);
686 /* We cannot handle dates after 2031 in 32 bit machines.
687 * a time_t of 64bits has to be used.
689 if (result != ASN1_SUCCESS)
691 gnutls_assert ();
692 return (time_t) (-1);
696 return c_time;
699 /* Sets the time in time_t in the ASN1_TYPE given. Where should
700 * be something like "tbsCertList.thisUpdate".
703 _gnutls_x509_set_time (ASN1_TYPE c2, const char *where, time_t tim, int nochoice)
705 char str_time[MAX_TIME];
706 char name[128];
707 int result, len;
709 if (nochoice != 0)
711 result = gtime2generalTime( tim, str_time, sizeof(str_time));
712 if (result < 0)
713 return gnutls_assert_val(result);
715 len = strlen (str_time);
716 result = asn1_write_value(c2, where, str_time, len);
717 if (result != ASN1_SUCCESS)
718 return gnutls_assert_val(_gnutls_asn2err (result));
720 return 0;
723 _gnutls_str_cpy (name, sizeof (name), where);
725 if ((result = asn1_write_value (c2, name, "generalTime", 1)) < 0)
727 gnutls_assert ();
728 return _gnutls_asn2err (result);
731 result = gtime2generalTime (tim, str_time, sizeof (str_time));
732 if (result < 0)
734 gnutls_assert ();
735 return result;
738 _gnutls_str_cat (name, sizeof (name), ".generalTime");
740 len = strlen (str_time);
741 result = asn1_write_value (c2, name, str_time, len);
742 if (result != ASN1_SUCCESS)
744 gnutls_assert ();
745 return _gnutls_asn2err (result);
748 return 0;
752 gnutls_x509_subject_alt_name_t
753 _gnutls_x509_san_find_type (char *str_type)
755 if (strcmp (str_type, "dNSName") == 0)
756 return GNUTLS_SAN_DNSNAME;
757 if (strcmp (str_type, "rfc822Name") == 0)
758 return GNUTLS_SAN_RFC822NAME;
759 if (strcmp (str_type, "uniformResourceIdentifier") == 0)
760 return GNUTLS_SAN_URI;
761 if (strcmp (str_type, "iPAddress") == 0)
762 return GNUTLS_SAN_IPADDRESS;
763 if (strcmp (str_type, "otherName") == 0)
764 return GNUTLS_SAN_OTHERNAME;
765 if (strcmp (str_type, "directoryName") == 0)
766 return GNUTLS_SAN_DN;
767 return (gnutls_x509_subject_alt_name_t) - 1;
770 /* A generic export function. Will export the given ASN.1 encoded data
771 * to PEM or DER raw data.
774 _gnutls_x509_export_int_named (ASN1_TYPE asn1_data, const char *name,
775 gnutls_x509_crt_fmt_t format,
776 const char *pem_header,
777 unsigned char *output_data,
778 size_t * output_data_size)
780 int result, len;
782 if (format == GNUTLS_X509_FMT_DER)
785 if (output_data == NULL)
786 *output_data_size = 0;
788 len = *output_data_size;
790 if ((result =
791 asn1_der_coding (asn1_data, name, output_data, &len,
792 NULL)) != ASN1_SUCCESS)
794 *output_data_size = (size_t)len;
795 if (result == ASN1_MEM_ERROR)
797 return GNUTLS_E_SHORT_MEMORY_BUFFER;
799 gnutls_assert ();
800 return _gnutls_asn2err (result);
803 *output_data_size = (size_t)len;
806 else
807 { /* PEM */
808 uint8_t *out;
809 gnutls_datum_t tmp;
811 result = _gnutls_x509_der_encode (asn1_data, name, &tmp, 0);
812 if (result < 0)
814 gnutls_assert ();
815 return result;
818 result = _gnutls_fbase64_encode (pem_header, tmp.data, tmp.size, &out);
820 _gnutls_free_datum (&tmp);
822 if (result < 0)
824 gnutls_assert ();
825 return result;
828 if (result == 0)
829 { /* oooops */
830 gnutls_assert ();
831 return GNUTLS_E_INTERNAL_ERROR;
834 if ((size_t) result > *output_data_size)
836 gnutls_assert ();
837 gnutls_free (out);
838 *output_data_size = (size_t)result;
839 return GNUTLS_E_SHORT_MEMORY_BUFFER;
842 *output_data_size = (size_t)result;
844 if (output_data)
846 memcpy (output_data, out, (size_t)result);
848 /* do not include the null character into output size.
850 *output_data_size = (size_t)result - 1;
852 gnutls_free (out);
856 return 0;
860 _gnutls_x509_export_int (ASN1_TYPE asn1_data,
861 gnutls_x509_crt_fmt_t format,
862 const char *pem_header,
863 unsigned char *output_data,
864 size_t * output_data_size)
866 return _gnutls_x509_export_int_named (asn1_data, "",
867 format, pem_header, output_data,
868 output_data_size);
871 /* Decodes an octet string. Leave string_type null for a normal
872 * octet string. Otherwise put something like BMPString, PrintableString
873 * etc.
876 _gnutls_x509_decode_octet_string (const char *string_type,
877 const uint8_t * der, size_t der_size,
878 uint8_t * output, size_t * output_size)
880 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
881 int result, tmp_output_size;
882 char strname[64];
884 if (string_type == NULL)
885 _gnutls_str_cpy (strname, sizeof (strname), "PKIX1.pkcs-7-Data");
886 else
888 _gnutls_str_cpy (strname, sizeof (strname), "PKIX1.");
889 _gnutls_str_cat (strname, sizeof (strname), string_type);
892 if ((result = asn1_create_element
893 (_gnutls_get_pkix (), strname, &c2)) != ASN1_SUCCESS)
895 gnutls_assert ();
896 result = _gnutls_asn2err (result);
897 goto cleanup;
900 result = asn1_der_decoding (&c2, der, der_size, NULL);
901 if (result != ASN1_SUCCESS)
903 gnutls_assert ();
904 result = _gnutls_asn2err (result);
905 goto cleanup;
908 tmp_output_size = *output_size;
909 result = asn1_read_value (c2, "", output, &tmp_output_size);
910 *output_size = (size_t)tmp_output_size;
912 if (result != ASN1_SUCCESS)
914 gnutls_assert ();
915 result = _gnutls_asn2err (result);
916 goto cleanup;
919 result = 0;
921 cleanup:
922 if (c2)
923 asn1_delete_structure (&c2);
925 return result;
929 /* Reads a value from an ASN1 tree, and puts the output
930 * in an allocated variable in the given datum.
931 * flags == 0 do nothing with the DER output
932 * flags == 1 parse the DER output as OCTET STRING
933 * flags == 2 the value is a BIT STRING
936 _gnutls_x509_read_value (ASN1_TYPE c, const char *root,
937 gnutls_datum_t * ret, int flags)
939 int len = 0, result;
940 size_t slen;
941 uint8_t *tmp = NULL;
943 result = asn1_read_value (c, root, NULL, &len);
944 if (result != ASN1_MEM_ERROR)
946 gnutls_assert ();
947 result = _gnutls_asn2err (result);
948 return result;
951 if (flags == 2)
952 len /= 8;
954 tmp = gnutls_malloc ((size_t)len);
955 if (tmp == NULL)
957 gnutls_assert ();
958 result = GNUTLS_E_MEMORY_ERROR;
959 goto cleanup;
962 result = asn1_read_value (c, root, tmp, &len);
963 if (result != ASN1_SUCCESS)
965 gnutls_assert ();
966 result = _gnutls_asn2err (result);
967 goto cleanup;
970 if (flags == 2)
971 len /= 8;
973 /* Extract the OCTET STRING.
976 if (flags == 1)
978 slen = (size_t)len;
979 result = _gnutls_x509_decode_octet_string (NULL, tmp, slen, tmp, &slen);
980 if (result < 0)
982 gnutls_assert ();
983 goto cleanup;
985 len = slen;
988 ret->data = tmp;
989 ret->size = (unsigned)len;
991 return 0;
993 cleanup:
994 gnutls_free (tmp);
995 return result;
999 /* DER Encodes the src ASN1_TYPE and stores it to
1000 * the given datum. If str is non zero then the data are encoded as
1001 * an OCTET STRING.
1004 _gnutls_x509_der_encode (ASN1_TYPE src, const char *src_name,
1005 gnutls_datum_t * res, int str)
1007 int size, result;
1008 int asize;
1009 uint8_t *data = NULL;
1010 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
1012 size = 0;
1013 result = asn1_der_coding (src, src_name, NULL, &size, NULL);
1014 if (result != ASN1_MEM_ERROR)
1016 gnutls_assert ();
1017 result = _gnutls_asn2err (result);
1018 goto cleanup;
1021 /* allocate data for the der
1024 if (str)
1025 size += 16; /* for later to include the octet tags */
1026 asize = size;
1028 data = gnutls_malloc ((size_t)size);
1029 if (data == NULL)
1031 gnutls_assert ();
1032 result = GNUTLS_E_MEMORY_ERROR;
1033 goto cleanup;
1036 result = asn1_der_coding (src, src_name, data, &size, NULL);
1037 if (result != ASN1_SUCCESS)
1039 gnutls_assert ();
1040 result = _gnutls_asn2err (result);
1041 goto cleanup;
1044 if (str)
1046 if ((result = asn1_create_element
1047 (_gnutls_get_pkix (), "PKIX1.pkcs-7-Data", &c2)) != ASN1_SUCCESS)
1049 gnutls_assert ();
1050 result = _gnutls_asn2err (result);
1051 goto cleanup;
1054 result = asn1_write_value (c2, "", data, size);
1055 if (result != ASN1_SUCCESS)
1057 gnutls_assert ();
1058 result = _gnutls_asn2err (result);
1059 goto cleanup;
1062 result = asn1_der_coding (c2, "", data, &asize, NULL);
1063 if (result != ASN1_SUCCESS)
1065 gnutls_assert ();
1066 result = _gnutls_asn2err (result);
1067 goto cleanup;
1070 size = asize;
1072 asn1_delete_structure (&c2);
1075 res->data = data;
1076 res->size = (unsigned)size;
1077 return 0;
1079 cleanup:
1080 gnutls_free (data);
1081 asn1_delete_structure (&c2);
1082 return result;
1086 /* DER Encodes the src ASN1_TYPE and stores it to
1087 * dest in dest_name. Useful to encode something and store it
1088 * as OCTET. If str is non null then the data are encoded as
1089 * an OCTET STRING.
1092 _gnutls_x509_der_encode_and_copy (ASN1_TYPE src, const char *src_name,
1093 ASN1_TYPE dest, const char *dest_name,
1094 int str)
1096 int result;
1097 gnutls_datum_t encoded;
1099 result = _gnutls_x509_der_encode (src, src_name, &encoded, str);
1101 if (result < 0)
1103 gnutls_assert ();
1104 return result;
1107 /* Write the data.
1109 result = asn1_write_value (dest, dest_name, encoded.data, (int)encoded.size);
1111 _gnutls_free_datum (&encoded);
1113 if (result != ASN1_SUCCESS)
1115 gnutls_assert ();
1116 return _gnutls_asn2err (result);
1119 return 0;
1122 /* Writes the value of the datum in the given ASN1_TYPE. If str is non
1123 * (0) it encodes it as OCTET STRING.
1126 _gnutls_x509_write_value (ASN1_TYPE c, const char *root,
1127 const gnutls_datum_t * data, int str)
1129 int result;
1130 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
1131 gnutls_datum_t val = { NULL, 0 };
1133 if (str)
1135 /* Convert it to OCTET STRING
1137 if ((result = asn1_create_element
1138 (_gnutls_get_pkix (), "PKIX1.pkcs-7-Data", &c2)) != ASN1_SUCCESS)
1140 gnutls_assert ();
1141 result = _gnutls_asn2err (result);
1142 goto cleanup;
1145 result = asn1_write_value (c2, "", data->data, data->size);
1146 if (result != ASN1_SUCCESS)
1148 gnutls_assert ();
1149 result = _gnutls_asn2err (result);
1150 goto cleanup;
1153 result = _gnutls_x509_der_encode (c2, "", &val, 0);
1154 if (result < 0)
1156 gnutls_assert ();
1157 goto cleanup;
1161 else
1163 val.data = data->data;
1164 val.size = data->size;
1167 /* Write the data.
1169 result = asn1_write_value (c, root, val.data, val.size);
1170 if (result != ASN1_SUCCESS)
1172 gnutls_assert ();
1173 result = _gnutls_asn2err (result);
1174 goto cleanup;
1177 result = 0;
1179 cleanup:
1180 asn1_delete_structure (&c2);
1181 if (val.data != data->data)
1182 _gnutls_free_datum (&val);
1183 return result;
1186 void
1187 _asnstr_append_name (char *name, size_t name_size, const char *part1,
1188 const char *part2)
1190 if (part1[0] != 0)
1192 _gnutls_str_cpy (name, name_size, part1);
1193 _gnutls_str_cat (name, name_size, part2);
1195 else
1196 _gnutls_str_cpy (name, name_size, part2 + 1 /* remove initial dot */ );
1201 /* Encodes and copies the private key parameters into a
1202 * subjectPublicKeyInfo structure.
1206 _gnutls_x509_encode_and_copy_PKI_params (ASN1_TYPE dst,
1207 const char *dst_name,
1208 gnutls_pk_algorithm_t
1209 pk_algorithm, gnutls_pk_params_st * params)
1211 const char *pk;
1212 gnutls_datum_t der = { NULL, 0 };
1213 int result;
1214 char name[128];
1216 pk = _gnutls_x509_pk_to_oid (pk_algorithm);
1217 if (pk == NULL)
1219 gnutls_assert ();
1220 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
1223 /* write the OID
1225 _asnstr_append_name (name, sizeof (name), dst_name, ".algorithm.algorithm");
1227 result = asn1_write_value (dst, name, pk, 1);
1228 if (result != ASN1_SUCCESS)
1230 gnutls_assert ();
1231 return _gnutls_asn2err (result);
1234 result = _gnutls_x509_write_pubkey_params (pk_algorithm, params, &der);
1235 if (result < 0)
1237 gnutls_assert ();
1238 return result;
1241 _asnstr_append_name (name, sizeof (name), dst_name,
1242 ".algorithm.parameters");
1244 result = asn1_write_value (dst, name, der.data, der.size);
1246 _gnutls_free_datum (&der);
1248 if (result != ASN1_SUCCESS)
1250 gnutls_assert ();
1251 return _gnutls_asn2err (result);
1254 result = _gnutls_x509_write_pubkey (pk_algorithm, params, &der);
1255 if (result < 0)
1257 gnutls_assert ();
1258 return result;
1261 /* Write the DER parameters. (in bits)
1263 _asnstr_append_name (name, sizeof (name), dst_name,
1264 ".subjectPublicKey");
1265 result = asn1_write_value (dst, name, der.data, der.size * 8);
1266 _gnutls_free_datum (&der);
1268 if (result != ASN1_SUCCESS)
1270 gnutls_assert ();
1271 return _gnutls_asn2err (result);
1274 return 0;
1277 /* Encodes and public key parameters into a
1278 * subjectPublicKeyInfo structure and stores it in der.
1281 _gnutls_x509_encode_PKI_params (gnutls_datum_t *der,
1282 gnutls_pk_algorithm_t
1283 pk_algorithm, gnutls_pk_params_st * params)
1285 int ret;
1286 ASN1_TYPE tmp;
1288 ret = asn1_create_element (_gnutls_get_pkix (),
1289 "PKIX1.Certificate", &tmp);
1290 if (ret != ASN1_SUCCESS)
1292 gnutls_assert ();
1293 return _gnutls_asn2err (ret);
1296 ret = _gnutls_x509_encode_and_copy_PKI_params (tmp,
1297 "tbsCertificate.subjectPublicKeyInfo",
1298 pk_algorithm, params);
1299 if (ret != ASN1_SUCCESS)
1301 gnutls_assert ();
1302 ret = _gnutls_asn2err (ret);
1303 goto cleanup;
1306 ret = _gnutls_x509_der_encode(tmp, "tbsCertificate.subjectPublicKeyInfo", der, 0);
1308 cleanup:
1309 asn1_delete_structure (&tmp);
1311 return ret;
1314 /* Reads and returns the PK algorithm of the given certificate-like
1315 * ASN.1 structure. src_name should be something like "tbsCertificate.subjectPublicKeyInfo".
1318 _gnutls_x509_get_pk_algorithm (ASN1_TYPE src, const char *src_name,
1319 unsigned int *bits)
1321 int result;
1322 int algo;
1323 char oid[64];
1324 int len;
1325 gnutls_pk_params_st params;
1326 char name[128];
1328 gnutls_pk_params_init(&params);
1330 _asnstr_append_name (name, sizeof (name), src_name, ".algorithm.algorithm");
1331 len = sizeof (oid);
1332 result = asn1_read_value (src, name, oid, &len);
1334 if (result != ASN1_SUCCESS)
1336 gnutls_assert ();
1337 return _gnutls_asn2err (result);
1340 algo = _gnutls_x509_oid2pk_algorithm (oid);
1341 if (algo == GNUTLS_PK_UNKNOWN)
1343 _gnutls_debug_log
1344 ("%s: unknown public key algorithm: %s\n", __func__, oid);
1347 if (bits == NULL)
1349 return algo;
1352 /* Now read the parameters' bits
1354 result = _gnutls_get_asn_mpis(src, src_name, &params);
1355 if (result < 0)
1356 return gnutls_assert_val(result);
1358 bits[0] = pubkey_to_bits(algo, &params);
1360 gnutls_pk_params_release(&params);
1361 return algo;
1364 /* Reads the DER signed data from the certificate and allocates space and
1365 * returns them into signed_data.
1368 _gnutls_x509_get_signed_data (ASN1_TYPE src, const char *src_name,
1369 gnutls_datum_t * signed_data)
1371 gnutls_datum_t der;
1372 int start, end, result;
1374 result = _gnutls_x509_der_encode (src, "", &der, 0);
1375 if (result < 0)
1377 gnutls_assert ();
1378 return result;
1381 /* Get the signed data
1383 result = asn1_der_decoding_startEnd (src, der.data, der.size,
1384 src_name, &start, &end);
1385 if (result != ASN1_SUCCESS)
1387 result = _gnutls_asn2err (result);
1388 gnutls_assert ();
1389 goto cleanup;
1392 result = _gnutls_set_datum (signed_data, &der.data[start], end - start + 1);
1394 if (result < 0)
1396 gnutls_assert ();
1397 goto cleanup;
1400 result = 0;
1402 cleanup:
1403 _gnutls_free_datum (&der);
1405 return result;
1409 * gnutls_x509_get_signature_algorithm:
1410 * @src: should contain an ASN1_TYPE structure
1411 * @src_name: the description of the signature field
1413 * This function will return a value of the #gnutls_sign_algorithm_t
1414 * enumeration that is the signature algorithm that has been used to
1415 * sign this certificate.
1417 * Returns: a #gnutls_sign_algorithm_t value, or a negative error code on
1418 * error.
1421 _gnutls_x509_get_signature_algorithm (ASN1_TYPE src, const char *src_name)
1423 int result;
1424 gnutls_datum_t sa;
1426 /* Read the signature algorithm. Note that parameters are not
1427 * read. They will be read from the issuer's certificate if needed.
1429 result =
1430 _gnutls_x509_read_value (src, src_name, &sa, 0);
1432 if (result < 0)
1434 gnutls_assert ();
1435 return result;
1438 result = _gnutls_x509_oid2sign_algorithm ( (char*)sa.data);
1440 _gnutls_free_datum (&sa);
1442 return result;
1446 /* Reads the DER signature from the certificate and allocates space and
1447 * returns them into signed_data.
1450 _gnutls_x509_get_signature (ASN1_TYPE src, const char *src_name,
1451 gnutls_datum_t * signature)
1453 int result, len;
1454 unsigned int bits;
1456 signature->data = NULL;
1457 signature->size = 0;
1459 /* Read the signature
1461 len = 0;
1462 result = asn1_read_value (src, src_name, NULL, &len);
1464 if (result != ASN1_MEM_ERROR)
1466 result = _gnutls_asn2err (result);
1467 gnutls_assert ();
1468 goto cleanup;
1471 bits = len;
1472 if (bits % 8 != 0)
1474 gnutls_assert ();
1475 result = GNUTLS_E_CERTIFICATE_ERROR;
1476 goto cleanup;
1479 len = bits / 8;
1481 signature->data = gnutls_malloc (len);
1482 if (signature->data == NULL)
1484 gnutls_assert ();
1485 result = GNUTLS_E_MEMORY_ERROR;
1486 return result;
1489 /* read the bit string of the signature
1491 bits = len;
1492 result = asn1_read_value (src, src_name, signature->data, (int*)&bits);
1494 if (result != ASN1_SUCCESS)
1496 result = _gnutls_asn2err (result);
1497 gnutls_assert ();
1498 goto cleanup;
1501 signature->size = len;
1503 return 0;
1505 cleanup:
1506 return result;