2 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free
3 * Software Foundation, Inc.
5 * Author: Nikos Mavrogiannopoulos
7 * This file is part of GnuTLS.
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.
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.
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,
26 #include <gnutls_int.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>
41 const char *ldap_desc;
42 int choice; /* of type DirectoryString */
44 const char *asn_desc; /* description in the pkix file */
47 /* This list contains all the OIDs that may be
48 * contained in a rdnSequence and are printable.
50 static const struct oid2string _oid2str[] = {
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"},
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"},
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"},
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"},
84 /* Extended validation
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"},
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"},
100 {"1.2.840.113549.1.9.20", NULL, 0, 1, "PKIX1.BMPString"},
102 {"1.2.840.113549.1.9.21", NULL, 0, 1, "PKIX1.pkcs-9-localKeyId"},
104 /* rfc3920 section 5.1.1 */
105 {"1.3.6.1.5.5.7.8.5", "XmppAddr", 0, 1, "PKIX1.UTF8String"},
107 {NULL, NULL, 0, 0, ""}
110 /* Returns 1 if the data defined by the OID are printable.
113 _gnutls_x509_oid_data_printable (const char *oid)
119 if (strcmp (_oid2str[i].oid, oid) == 0)
120 return _oid2str[i].printable;
123 while (_oid2str[i].oid != NULL);
129 * gnutls_x509_dn_oid_known:
130 * @oid: holds an Object Identifier in a null terminated string
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
140 * Returns: 1 on known OIDs and 0 otherwise.
143 gnutls_x509_dn_oid_known (const char *oid)
149 if (strcmp (_oid2str[i].oid, oid) == 0)
153 while (_oid2str[i].oid != NULL);
158 /* Returns 1 if the data defined by the OID are of a choice
162 _gnutls_x509_oid_data_choice (const char *oid)
168 if (strcmp (_oid2str[i].oid, oid) == 0)
169 return _oid2str[i].choice;
172 while (_oid2str[i].oid != NULL);
178 _gnutls_x509_oid2ldap_string (const char *oid)
184 if (strcmp (_oid2str[i].oid, oid) == 0)
185 return _oid2str[i].ldap_desc;
188 while (_oid2str[i].oid != NULL);
194 _gnutls_x509_oid2asn_string (const char *oid)
200 if (strcmp (_oid2str[i].oid, oid) == 0)
201 return _oid2str[i].asn_desc;
204 while (_oid2str[i].oid != NULL);
210 /* This function will convert an attribute value, specified by the OID,
211 * to a string. The result will be a null terminated string.
213 * res may be null. This will just return the res_size, needed to
217 _gnutls_x509_oid_data2string (const char *oid, void *value,
218 int value_size, char *res, size_t * res_size)
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] = "";
226 if (value == NULL || value_size <= 0 || res_size == NULL)
229 return GNUTLS_E_INVALID_REQUEST;
232 if (_gnutls_x509_oid_data_printable (oid) == 0)
235 return GNUTLS_E_INTERNAL_ERROR;
238 ANAME = _gnutls_x509_oid2asn_string (oid);
239 CHOICE = _gnutls_x509_oid_data_choice (oid);
244 return GNUTLS_E_INTERNAL_ERROR;
248 asn1_create_element (_gnutls_get_pkix (), ANAME,
249 &tmpasn)) != ASN1_SUCCESS)
252 return _gnutls_asn2err (result);
256 asn1_der_decoding (&tmpasn, value, value_size,
257 asn1_err)) != ASN1_SUCCESS)
260 _gnutls_x509_log ("asn1_der_decoding: %s:%s\n", str, asn1_err);
261 asn1_delete_structure (&tmpasn);
262 return _gnutls_asn2err (result);
265 /* If this is a choice then we read the choice. Otherwise it
268 len = sizeof (str) - 1;
269 if ((result = asn1_read_value (tmpasn, "", str, &len)) != ASN1_SUCCESS)
272 asn1_delete_structure (&tmpasn);
273 return _gnutls_asn2err (result);
280 /* Refuse to deal with strings containing NULs. */
281 if (strlen (str) != len)
282 return GNUTLS_E_ASN1_DER_ERROR;
285 _gnutls_str_cpy (res, *res_size, str);
288 asn1_delete_structure (&tmpasn);
292 int non_printable = 0, teletex = 0;
295 /* Note that we do not support strings other than
296 * UTF-8 (thus ASCII as well).
298 if (strcmp (str, "printableString") != 0 &&
299 strcmp (str, "ia5String") != 0 && strcmp (str, "utf8String") != 0)
303 if (strcmp (str, "teletexString") == 0)
307 _gnutls_str_cpy (tmpname, sizeof (tmpname), str);
309 len = sizeof (str) - 1;
311 asn1_read_value (tmpasn, tmpname, str, &len)) != ASN1_SUCCESS)
313 asn1_delete_structure (&tmpasn);
314 return _gnutls_asn2err (result);
317 asn1_delete_structure (&tmpasn);
322 /* HACK: if the teletex string contains only ascii
323 * characters then treat it as printable.
325 for (i = 0; i < len; i++)
326 if (!isascii (str[i]))
333 if (non_printable == 0)
337 /* Refuse to deal with strings containing NULs. */
338 if (strlen (str) != len)
339 return GNUTLS_E_ASN1_DER_ERROR;
342 _gnutls_str_cpy (res, *res_size, str);
347 result = _gnutls_x509_data2hex (str, len, res, res_size);
360 /* Converts a data string to an LDAP rfc2253 hex string
361 * something like '#01020304'
364 _gnutls_x509_data2hex (const opaque * data, size_t data_size,
365 opaque * out, size_t * sizeof_out)
368 char escaped[MAX_STRING_LEN];
371 if (2 * data_size + 1 > MAX_STRING_LEN)
374 return GNUTLS_E_INTERNAL_ERROR;
377 res = _gnutls_bin2hex (data, data_size, escaped, sizeof (escaped), NULL);
381 return GNUTLS_E_INTERNAL_ERROR;
384 size = strlen (res) + 1;
385 if (size + 1 > *sizeof_out)
388 return GNUTLS_E_SHORT_MEMORY_BUFFER;
390 *sizeof_out = size; /* -1 for the null +1 for the '#' */
403 * Convertions between generalized or UTC time to time_t
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.
411 typedef struct fake_tm
414 int tm_year; /* FULL year - ie 1971 */
421 /* The mktime_utc function is due to Russ Allbery (rra@stanford.edu),
422 * who placed it under public domain:
425 /* The number of days in each month.
427 static const int MONTHDAYS[] = {
428 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
431 /* Whether a given year is a leap year. */
432 #define ISLEAP(year) \
433 (((year) % 4) == 0 && (((year) % 100) != 0 || ((year) % 400) == 0))
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.
442 mktime_utc (const struct fake_tm *tm)
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.
452 if (tm->tm_mon < 0 || tm->tm_mon > 11 || tm->tm_year < 1970)
455 /* Convert to a time_t.
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))
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;
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.
475 _gnutls_x509_time2gtime (const char *ttime, int year)
478 struct fake_tm etime;
481 if (strlen (ttime) < 8)
487 etime.tm_year = year;
489 /* In order to work with 32 bit
492 if (sizeof (time_t) <= 4 && etime.tm_year >= 2038)
493 return (time_t) 2145914603; /* 2037-12-31 23:23:23 */
495 if (etime.tm_year < 1970)
502 memcpy (xx, ttime, 2); /* month */
503 etime.tm_mon = atoi (xx) - 1;
508 memcpy (xx, ttime, 2); /* day */
509 etime.tm_mday = atoi (xx);
514 memcpy (xx, ttime, 2); /* hour */
515 etime.tm_hour = atoi (xx);
520 memcpy (xx, ttime, 2); /* minutes */
521 etime.tm_min = atoi (xx);
524 if (strlen (ttime) >= 2)
526 memcpy (xx, ttime, 2);
527 etime.tm_sec = atoi (xx);
533 ret = mktime_utc (&etime);
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)*
543 * (seconds are optional)
546 _gnutls_x509_utcTime2gtime (const char *ttime)
551 if (strlen (ttime) < 10)
559 memcpy (xx, ttime, 2); /* year */
568 return _gnutls_x509_time2gtime (ttime, year);
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)
576 _gnutls_x509_gtime2utcTime (time_t gtime, char *str_time, int str_time_size)
581 if (!gmtime_r (>ime, &_tm))
584 return GNUTLS_E_INTERNAL_ERROR;
587 ret = strftime (str_time, str_time_size, "%y%m%d%H%M%SZ", &_tm);
591 return GNUTLS_E_SHORT_MEMORY_BUFFER;
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)*
604 _gnutls_x509_generalTime2gtime (const char *ttime)
609 if (strlen (ttime) < 12)
615 if (strchr (ttime, 'Z') == 0)
618 /* sorry we don't support it yet
626 memcpy (xx, ttime, 4); /* year */
630 return _gnutls_x509_time2gtime (ttime, year);
634 /* Extracts the time in time_t from the ASN1_TYPE given. When should
635 * be something like "tbsCertList.thisUpdate".
639 _gnutls_x509_get_time (ASN1_TYPE c2, const char *when)
641 char ttime[MAX_TIME];
643 time_t c_time = (time_t) - 1;
646 _gnutls_str_cpy (name, sizeof (name), when);
648 len = sizeof (ttime) - 1;
649 if ((result = asn1_read_value (c2, name, ttime, &len)) < 0)
652 return (time_t) (-1);
656 if (strcmp (ttime, "generalTime") == 0)
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);
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);
675 /* We cannot handle dates after 2031 in 32 bit machines.
676 * a time_t of 64bits has to be used.
679 if (result != ASN1_SUCCESS)
682 return (time_t) (-1);
687 /* Sets the time in time_t in the ASN1_TYPE given. Where should
688 * be something like "tbsCertList.thisUpdate".
691 _gnutls_x509_set_time (ASN1_TYPE c2, const char *where, time_t tim)
693 char str_time[MAX_TIME];
697 _gnutls_str_cpy (name, sizeof (name), where);
699 if ((result = asn1_write_value (c2, name, "utcTime", 1)) < 0)
702 return _gnutls_asn2err (result);
705 result = _gnutls_x509_gtime2utcTime (tim, str_time, sizeof (str_time));
712 _gnutls_str_cat (name, sizeof (name), ".utcTime");
714 len = strlen (str_time);
715 result = asn1_write_value (c2, name, str_time, len);
716 if (result != ASN1_SUCCESS)
719 return _gnutls_asn2err (result);
726 gnutls_x509_subject_alt_name_t
727 _gnutls_x509_san_find_type (char *str_type)
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;
744 /* A generic export function. Will export the given ASN.1 encoded data
745 * to PEM or DER raw data.
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)
756 if (format == GNUTLS_X509_FMT_DER)
759 if (output_data == NULL)
760 *output_data_size = 0;
762 len = *output_data_size;
765 asn1_der_coding (asn1_data, name, output_data, &len,
766 NULL)) != ASN1_SUCCESS)
768 *output_data_size = len;
769 if (result == ASN1_MEM_ERROR)
771 return GNUTLS_E_SHORT_MEMORY_BUFFER;
774 return _gnutls_asn2err (result);
777 *output_data_size = len;
785 result = _gnutls_x509_der_encode (asn1_data, name, &tmp, 0);
792 result = _gnutls_fbase64_encode (pem_header, tmp.data, tmp.size, &out);
794 _gnutls_free_datum (&tmp);
805 return GNUTLS_E_INTERNAL_ERROR;
808 if ((unsigned) result > *output_data_size)
812 *output_data_size = result;
813 return GNUTLS_E_SHORT_MEMORY_BUFFER;
816 *output_data_size = result;
820 memcpy (output_data, out, result);
822 /* do not include the null character into output size.
824 *output_data_size = result - 1;
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)
840 return _gnutls_x509_export_int_named (asn1_data, "",
841 format, pem_header, output_data,
845 /* Decodes an octet string. Leave string_type null for a normal
846 * octet string. Otherwise put something like BMPString, PrintableString
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)
854 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
855 int result, tmp_output_size;
858 if (string_type == NULL)
859 _gnutls_str_cpy (strname, sizeof (strname), "PKIX1.pkcs-7-Data");
862 _gnutls_str_cpy (strname, sizeof (strname), "PKIX1.");
863 _gnutls_str_cat (strname, sizeof (strname), string_type);
866 if ((result = asn1_create_element
867 (_gnutls_get_pkix (), strname, &c2)) != ASN1_SUCCESS)
870 result = _gnutls_asn2err (result);
874 result = asn1_der_decoding (&c2, der, der_size, NULL);
875 if (result != ASN1_SUCCESS)
878 result = _gnutls_asn2err (result);
882 tmp_output_size = *output_size;
883 result = asn1_read_value (c2, "", output, &tmp_output_size);
884 *output_size = tmp_output_size;
886 if (result != ASN1_SUCCESS)
889 result = _gnutls_asn2err (result);
897 asn1_delete_structure (&c2);
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
910 _gnutls_x509_read_value (ASN1_TYPE c, const char *root,
911 gnutls_datum_t * ret, int flags)
917 result = asn1_read_value (c, root, NULL, &len);
918 if (result != ASN1_MEM_ERROR)
921 result = _gnutls_asn2err (result);
928 tmp = gnutls_malloc (len);
932 result = GNUTLS_E_MEMORY_ERROR;
936 result = asn1_read_value (c, root, tmp, &len);
937 if (result != ASN1_SUCCESS)
940 result = _gnutls_asn2err (result);
947 /* Extract the OCTET STRING.
953 result = _gnutls_x509_decode_octet_string (NULL, tmp, slen, tmp, &slen);
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
978 _gnutls_x509_der_encode (ASN1_TYPE src, const char *src_name,
979 gnutls_datum_t * res, int str)
984 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
987 result = asn1_der_coding (src, src_name, NULL, &size, NULL);
988 if (result != ASN1_MEM_ERROR)
991 result = _gnutls_asn2err (result);
995 /* allocate data for the der
999 size += 16; /* for later to include the octet tags */
1002 data = gnutls_malloc (size);
1006 result = GNUTLS_E_MEMORY_ERROR;
1010 result = asn1_der_coding (src, src_name, data, &size, NULL);
1011 if (result != ASN1_SUCCESS)
1014 result = _gnutls_asn2err (result);
1020 if ((result = asn1_create_element
1021 (_gnutls_get_pkix (), "PKIX1.pkcs-7-Data", &c2)) != ASN1_SUCCESS)
1024 result = _gnutls_asn2err (result);
1028 result = asn1_write_value (c2, "", data, size);
1029 if (result != ASN1_SUCCESS)
1032 result = _gnutls_asn2err (result);
1036 result = asn1_der_coding (c2, "", data, &asize, NULL);
1037 if (result != ASN1_SUCCESS)
1040 result = _gnutls_asn2err (result);
1046 asn1_delete_structure (&c2);
1055 asn1_delete_structure (&c2);
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
1066 _gnutls_x509_der_encode_and_copy (ASN1_TYPE src, const char *src_name,
1067 ASN1_TYPE dest, const char *dest_name,
1071 gnutls_datum_t encoded;
1073 result = _gnutls_x509_der_encode (src, src_name, &encoded, str);
1083 result = asn1_write_value (dest, dest_name, encoded.data, encoded.size);
1085 _gnutls_free_datum (&encoded);
1087 if (result != ASN1_SUCCESS)
1090 return _gnutls_asn2err (result);
1096 /* Writes the value of the datum in the given ASN1_TYPE. If str is non
1097 * zero it encodes it as OCTET STRING.
1100 _gnutls_x509_write_value (ASN1_TYPE c, const char *root,
1101 const gnutls_datum_t * data, int str)
1104 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
1105 gnutls_datum_t val = { NULL, 0 };
1109 /* Convert it to OCTET STRING
1111 if ((result = asn1_create_element
1112 (_gnutls_get_pkix (), "PKIX1.pkcs-7-Data", &c2)) != ASN1_SUCCESS)
1115 result = _gnutls_asn2err (result);
1119 result = asn1_write_value (c2, "", data->data, data->size);
1120 if (result != ASN1_SUCCESS)
1123 result = _gnutls_asn2err (result);
1127 result = _gnutls_x509_der_encode (c2, "", &val, 0);
1137 val.data = data->data;
1138 val.size = data->size;
1143 result = asn1_write_value (c, root, val.data, val.size);
1144 if (result != ASN1_SUCCESS)
1147 result = _gnutls_asn2err (result);
1154 asn1_delete_structure (&c2);
1155 if (val.data != data->data)
1156 _gnutls_free_datum (&val);
1161 _asnstr_append_name (char *name, size_t name_size, const char *part1,
1166 _gnutls_str_cpy (name, name_size, part1);
1167 _gnutls_str_cat (name, name_size, part2);
1170 _gnutls_str_cpy (name, name_size, part2 + 1 /* remove initial dot */ );
1174 /* Encodes and copies the private key parameters into a
1175 * subjectPublicKeyInfo structure.
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,
1186 gnutls_datum_t der = { NULL, 0 };
1190 pk = _gnutls_x509_pk_to_oid (pk_algorithm);
1194 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
1199 _asnstr_append_name (name, sizeof (name), dst_name, ".algorithm.algorithm");
1201 result = asn1_write_value (dst, name, pk, 1);
1202 if (result != ASN1_SUCCESS)
1205 return _gnutls_asn2err (result);
1208 if (pk_algorithm == GNUTLS_PK_RSA)
1210 /* disable parameters, which are not used in RSA.
1212 _asnstr_append_name (name, sizeof (name), dst_name,
1213 ".algorithm.parameters");
1215 result = asn1_write_value (dst, name, ASN1_NULL, ASN1_NULL_SIZE);
1216 if (result != ASN1_SUCCESS)
1219 return _gnutls_asn2err (result);
1222 result = _gnutls_x509_write_rsa_params (params, params_size, &der);
1229 /* Write the DER parameters. (in bits)
1231 _asnstr_append_name (name, sizeof (name), dst_name,
1232 ".subjectPublicKey");
1233 result = asn1_write_value (dst, name, der.data, der.size * 8);
1235 _gnutls_free_datum (&der);
1237 if (result != ASN1_SUCCESS)
1240 return _gnutls_asn2err (result);
1243 else if (pk_algorithm == GNUTLS_PK_DSA)
1246 result = _gnutls_x509_write_dsa_params (params, params_size, &der);
1253 /* Write the DER parameters.
1255 _asnstr_append_name (name, sizeof (name), dst_name,
1256 ".algorithm.parameters");
1257 result = asn1_write_value (dst, name, der.data, der.size);
1259 _gnutls_free_datum (&der);
1261 if (result != ASN1_SUCCESS)
1264 return _gnutls_asn2err (result);
1267 result = _gnutls_x509_write_dsa_public_key (params, params_size, &der);
1274 _asnstr_append_name (name, sizeof (name), dst_name,
1275 ".subjectPublicKey");
1276 result = asn1_write_value (dst, name, der.data, der.size * 8);
1278 _gnutls_free_datum (&der);
1280 if (result != ASN1_SUCCESS)
1283 return _gnutls_asn2err (result);
1288 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
1293 /* Reads and returns the PK algorithm of the given certificate-like
1294 * ASN.1 structure. src_name should be something like "tbsCertificate.subjectPublicKeyInfo".
1297 _gnutls_x509_get_pk_algorithm (ASN1_TYPE src, const char *src_name,
1305 bigint_t params[MAX_PUBLIC_PARAMS_SIZE];
1309 _asnstr_append_name (name, sizeof (name), src_name, ".algorithm.algorithm");
1311 result = asn1_read_value (src, name, oid, &len);
1313 if (result != ASN1_SUCCESS)
1316 return _gnutls_asn2err (result);
1319 algo = _gnutls_x509_oid2pk_algorithm (oid);
1320 if (algo == GNUTLS_PK_UNKNOWN)
1323 ("%s: unknown public key algorithm: %s\n", __func__, oid);
1331 /* Now read the parameters' bits
1333 _asnstr_append_name (name, sizeof (name), src_name, ".subjectPublicKey");
1336 result = asn1_read_value (src, name, NULL, &len);
1337 if (result != ASN1_MEM_ERROR)
1340 return _gnutls_asn2err (result);
1346 return GNUTLS_E_CERTIFICATE_ERROR;
1351 str = gnutls_malloc (len);
1355 return GNUTLS_E_MEMORY_ERROR;
1358 _asnstr_append_name (name, sizeof (name), src_name, ".subjectPublicKey");
1360 result = asn1_read_value (src, name, str, &len);
1362 if (result != ASN1_SUCCESS)
1366 return _gnutls_asn2err (result);
1375 if ((result = _gnutls_x509_read_rsa_params (str, len, params)) < 0)
1381 bits[0] = _gnutls_mpi_get_nbits (params[0]);
1383 _gnutls_mpi_release (¶ms[0]);
1384 _gnutls_mpi_release (¶ms[1]);
1390 if ((result = _gnutls_x509_read_dsa_pubkey (str, len, params)) < 0)
1396 bits[0] = _gnutls_mpi_get_nbits (params[3]);
1398 _gnutls_mpi_release (¶ms[3]);
1407 /* Reads the DER signed data from the certificate and allocates space and
1408 * returns them into signed_data.
1411 _gnutls_x509_get_signed_data (ASN1_TYPE src, const char *src_name,
1412 gnutls_datum_t * signed_data)
1415 int start, end, result;
1417 result = _gnutls_x509_der_encode (src, "", &der, 0);
1424 /* Get the signed data
1426 result = asn1_der_decoding_startEnd (src, der.data, der.size,
1427 src_name, &start, &end);
1428 if (result != ASN1_SUCCESS)
1430 result = _gnutls_asn2err (result);
1435 result = _gnutls_set_datum (signed_data, &der.data[start], end - start + 1);
1446 _gnutls_free_datum (&der);
1451 /* Reads the DER signature from the certificate and allocates space and
1452 * returns them into signed_data.
1455 _gnutls_x509_get_signature (ASN1_TYPE src, const char *src_name,
1456 gnutls_datum_t * signature)
1458 int bits, result, len;
1460 signature->data = NULL;
1461 signature->size = 0;
1463 /* Read the signature
1466 result = asn1_read_value (src, src_name, NULL, &bits);
1468 if (result != ASN1_MEM_ERROR)
1470 result = _gnutls_asn2err (result);
1478 result = GNUTLS_E_CERTIFICATE_ERROR;
1484 signature->data = gnutls_malloc (len);
1485 if (signature->data == NULL)
1488 result = GNUTLS_E_MEMORY_ERROR;
1492 /* read the bit string of the signature
1495 result = asn1_read_value (src, src_name, signature->data, &bits);
1497 if (result != ASN1_SUCCESS)
1499 result = _gnutls_asn2err (result);
1504 signature->size = len;