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>
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>
38 const char *ldap_desc
;
39 int choice
; /* of type DirectoryString */
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
[] = {
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"},
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"},
97 {"1.2.840.113549.1.9.20", NULL
, 0, 1, "PKIX1.BMPString"},
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
)
116 if (strcmp (_oid2str
[i
].oid
, oid
) == 0)
117 return _oid2str
[i
].printable
;
120 while (_oid2str
[i
].oid
!= NULL
);
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
137 * Returns: 1 on known OIDs and 0 otherwise.
140 gnutls_x509_dn_oid_known (const char *oid
)
146 if (strcmp (_oid2str
[i
].oid
, oid
) == 0)
150 while (_oid2str
[i
].oid
!= NULL
);
155 /* Returns 1 if the data defined by the OID are of a choice
159 _gnutls_x509_oid_data_choice (const char *oid
)
165 if (strcmp (_oid2str
[i
].oid
, oid
) == 0)
166 return _oid2str
[i
].choice
;
169 while (_oid2str
[i
].oid
!= NULL
);
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
184 * Returns: A null terminated string or NULL otherwise.
189 gnutls_x509_dn_oid_name (const char *oid
, unsigned int flags
)
195 if (strcmp (_oid2str
[i
].oid
, oid
) == 0)
196 return _oid2str
[i
].ldap_desc
;
199 while (_oid2str
[i
].oid
!= NULL
);
201 if (flags
& GNUTLS_X509_DN_OID_RETURN_OID
) return oid
;
206 _gnutls_x509_oid2asn_string (const char *oid
)
212 if (strcmp (_oid2str
[i
].oid
, oid
) == 0)
213 return _oid2str
[i
].asn_desc
;
216 while (_oid2str
[i
].oid
!= 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
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
)
241 return GNUTLS_E_INVALID_REQUEST
;
244 if (_gnutls_x509_oid_data_printable (oid
) == 0)
247 return GNUTLS_E_INTERNAL_ERROR
;
250 aname
= _gnutls_x509_oid2asn_string (oid
);
251 choice
= _gnutls_x509_oid_data_choice (oid
);
256 return GNUTLS_E_INTERNAL_ERROR
;
260 asn1_create_element (_gnutls_get_pkix (), aname
,
261 &tmpasn
)) != ASN1_SUCCESS
)
264 return _gnutls_asn2err (result
);
268 asn1_der_decoding (&tmpasn
, value
, value_size
,
269 asn1_err
)) != ASN1_SUCCESS
)
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
280 len
= sizeof (str
) - 1;
281 if ((result
= asn1_read_value (tmpasn
, "", str
, &len
)) != ASN1_SUCCESS
)
284 asn1_delete_structure (&tmpasn
);
285 return _gnutls_asn2err (result
);
292 /* Refuse to deal with strings containing NULs. */
293 if (strlen (str
) != (size_t)len
)
294 return GNUTLS_E_ASN1_DER_ERROR
;
297 _gnutls_str_cpy (res
, *res_size
, str
);
298 *res_size
= (size_t)len
;
300 asn1_delete_structure (&tmpasn
);
304 int non_printable
= 0, teletex
= 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)
316 if (strcmp (str
, "teletexString") == 0)
319 if (strcmp (str
, "bmpString") == 0)
322 _gnutls_str_cpy (tmpname
, sizeof (tmpname
), str
);
324 len
= sizeof (str
) - 1;
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
);
338 result
= _gnutls_ucs2_to_utf8(str
, len
, &td
);
341 /* could not convert. Handle it as non-printable */
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
);
355 gnutls_free(td
.data
);
358 else if (teletex
!= 0)
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
]))
372 if (non_printable
== 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
);
381 _gnutls_str_cpy (res
, *res_size
, str
);
382 *res_size
= (size_t)len
;
386 result
= _gnutls_x509_data2hex (str
, (size_t)len
, res
, res_size
);
388 return gnutls_assert_val(result
);
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
)
404 char escaped
[MAX_STRING_LEN
];
408 if (2 * data_size
+ 1 > MAX_STRING_LEN
)
411 return GNUTLS_E_INTERNAL_ERROR
;
414 res
= _gnutls_bin2hex (data
, data_size
, escaped
, sizeof (escaped
), NULL
);
418 return GNUTLS_E_INTERNAL_ERROR
;
421 size
= strlen (res
) + 1;
422 if (size
+ 1 > *sizeof_out
)
425 return GNUTLS_E_SHORT_MEMORY_BUFFER
;
427 *sizeof_out
= size
; /* -1 for the null +1 for the '#' */
433 _gnutls_str_cat (out
, *sizeof_out
, res
);
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
452 int tm_year
; /* FULL year - ie 1971 */
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.
480 mktime_utc (const struct fake_tm
*tm
)
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)
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
))
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
;
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.
513 time2gtime (const char *ttime
, int year
)
516 struct fake_tm etime
;
518 if (strlen (ttime
) < 8)
524 etime
.tm_year
= year
;
526 /* In order to work with 32 bit
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)
539 memcpy (xx
, ttime
, 2); /* month */
540 etime
.tm_mon
= atoi (xx
) - 1;
545 memcpy (xx
, ttime
, 2); /* day */
546 etime
.tm_mday
= atoi (xx
);
551 memcpy (xx
, ttime
, 2); /* hour */
552 etime
.tm_hour
= atoi (xx
);
557 memcpy (xx
, ttime
, 2); /* minutes */
558 etime
.tm_min
= atoi (xx
);
561 if (strlen (ttime
) >= 2)
563 memcpy (xx
, ttime
, 2);
564 etime
.tm_sec
= atoi (xx
);
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)
580 utcTime2gtime (const char *ttime
)
585 if (strlen (ttime
) < 10)
593 memcpy (xx
, ttime
, 2); /* year */
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)*
610 _gnutls_x509_generalTime2gtime (const char *ttime
)
615 if (strlen (ttime
) < 12)
621 if (strchr (ttime
, 'Z') == 0)
624 /* sorry we don't support it yet
632 memcpy (xx
, ttime
, 4); /* year */
636 return time2gtime (ttime
, year
);
640 gtime2generalTime (time_t gtime
, char *str_time
, size_t str_time_size
)
645 if (!gmtime_r (>ime
, &_tm
))
648 return GNUTLS_E_INTERNAL_ERROR
;
651 ret
= strftime (str_time
, str_time_size
, "%Y%m%d%H%M%SZ", &_tm
);
655 return GNUTLS_E_SHORT_MEMORY_BUFFER
;
663 /* Extracts the time in time_t from the ASN1_TYPE given. When should
664 * be something like "tbsCertList.thisUpdate".
668 _gnutls_x509_get_time (ASN1_TYPE c2
, const char *when
, int nochoice
)
670 char ttime
[MAX_TIME
];
672 time_t c_time
= (time_t) - 1;
675 len
= sizeof (ttime
) - 1;
676 result
= asn1_read_value (c2
, when
, ttime
, &len
);
677 if (result
!= ASN1_SUCCESS
)
680 return (time_t) (-1);
685 c_time
= _gnutls_x509_generalTime2gtime (ttime
);
689 _gnutls_str_cpy (name
, sizeof (name
), when
);
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
);
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
)
715 return (time_t) (-1);
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
];
734 result
= gtime2generalTime( tim
, str_time
, sizeof(str_time
));
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
));
746 _gnutls_str_cpy (name
, sizeof (name
), where
);
748 if ((result
= asn1_write_value (c2
, name
, "generalTime", 1)) < 0)
751 return _gnutls_asn2err (result
);
754 result
= gtime2generalTime (tim
, str_time
, sizeof (str_time
));
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
)
768 return _gnutls_asn2err (result
);
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
)
807 ret
= _gnutls_x509_export_int_named2 (asn1_data
, name
,
808 format
, pem_header
, &out
);
810 return gnutls_assert_val(ret
);
812 if (format
== GNUTLS_X509_FMT_PEM
)
817 if (*output_data_size
< size
)
819 *output_data_size
= size
;
820 ret
= gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER
);
824 *output_data_size
= (size_t)out
.size
;
827 memcpy (output_data
, out
.data
, (size_t)out
.size
);
828 if (format
== GNUTLS_X509_FMT_PEM
)
829 output_data
[out
.size
] = 0;
835 gnutls_free (out
.data
);
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
,
851 if (format
== GNUTLS_X509_FMT_DER
)
853 ret
= _gnutls_x509_der_encode(asn1_data
, name
, out
, 0);
855 return gnutls_assert_val(ret
);
861 ret
= _gnutls_x509_der_encode (asn1_data
, name
, &tmp
, 0);
863 return gnutls_assert_val(ret
);
865 ret
= _gnutls_fbase64_encode (pem_header
, tmp
.data
, tmp
.size
, out
);
866 _gnutls_free_datum (&tmp
);
869 return gnutls_assert_val(ret
);
875 /* Decodes an octet string. Leave string_type null for a normal
876 * octet string. Otherwise put something like BMPString, PrintableString
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
;
888 if (string_type
== NULL
) /* assume octet string */
889 _gnutls_str_cpy (strname
, sizeof (strname
), "PKIX1.pkcs-7-Data");
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
)
900 result
= _gnutls_asn2err (result
);
904 result
= asn1_der_decoding (&c2
, der
, der_size
, NULL
);
905 if (result
!= ASN1_SUCCESS
)
908 result
= _gnutls_asn2err (result
);
912 result
= _gnutls_x509_read_value(c2
, "", output
);
919 /* This is allowed since _gnutls_x509_read_value allocates one more */
920 output
->data
[output
->size
] = 0;
926 asn1_delete_structure (&c2
);
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
)
945 result
= asn1_read_value (c
, root
, NULL
, &len
);
946 if (result
!= ASN1_MEM_ERROR
)
949 result
= _gnutls_asn2err (result
);
953 tmp
= gnutls_malloc ((size_t)len
+1);
957 result
= GNUTLS_E_MEMORY_ERROR
;
961 result
= asn1_read_value (c
, root
, tmp
, &len
);
962 if (result
!= ASN1_SUCCESS
)
965 result
= _gnutls_asn2err (result
);
970 ret
->size
= (unsigned)len
;
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
)
993 result
= asn1_read_value (c
, root
, NULL
, &len
);
994 if (result
!= ASN1_MEM_ERROR
)
997 result
= _gnutls_asn2err (result
);
1001 if (type
== RV_BIT_STRING
)
1004 tmp
= gnutls_malloc ((size_t)len
+1);
1008 result
= GNUTLS_E_MEMORY_ERROR
;
1012 result
= asn1_read_value (c
, root
, tmp
, &len
);
1013 if (result
!= ASN1_SUCCESS
)
1016 result
= _gnutls_asn2err (result
);
1020 if (type
== RV_BIT_STRING
)
1023 /* Extract the STRING.
1025 if (type
== RV_IA5STRING
|| type
== RV_UTF8STRING
|| type
== RV_OCTET_STRING
)
1030 if (type
== RV_UTF8STRING
)
1031 sname
= "UTF8String";
1032 else if (type
== RV_IA5STRING
)
1033 sname
= "IA5String";
1037 result
= _gnutls_x509_decode_string (sname
, tmp
, slen
, ret
);
1048 ret
->size
= (unsigned)len
;
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
)
1065 ASN1_TYPE c2
= ASN1_TYPE_EMPTY
;
1068 _gnutls_str_cpy (strname
, sizeof (strname
), "PKIX1.");
1069 if (string_type
== NULL
)
1070 _gnutls_str_cat (strname
, sizeof (strname
), "pkcs-7-Data");
1072 _gnutls_str_cat (strname
, sizeof (strname
), string_type
);
1074 if ((ret
= asn1_create_element
1075 (_gnutls_get_pkix (), strname
, &c2
)) != ASN1_SUCCESS
)
1078 ret
= _gnutls_asn2err (ret
);
1082 ret
= asn1_write_value (c2
, "", input_data
, input_size
);
1083 if (ret
!= ASN1_SUCCESS
)
1086 ret
= _gnutls_asn2err (ret
);
1090 ret
= _gnutls_x509_der_encode(c2
, "", output
, 0);
1100 asn1_delete_structure (&c2
);
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
1109 _gnutls_x509_der_encode (ASN1_TYPE src
, const char *src_name
,
1110 gnutls_datum_t
* res
, int str
)
1114 uint8_t *data
= NULL
;
1115 ASN1_TYPE c2
= ASN1_TYPE_EMPTY
;
1118 result
= asn1_der_coding (src
, src_name
, NULL
, &size
, NULL
);
1119 if (result
!= ASN1_MEM_ERROR
)
1122 result
= _gnutls_asn2err (result
);
1126 /* allocate data for the der
1130 size
+= 16; /* for later to include the octet tags */
1133 data
= gnutls_malloc ((size_t)size
);
1137 result
= GNUTLS_E_MEMORY_ERROR
;
1141 result
= asn1_der_coding (src
, src_name
, data
, &size
, NULL
);
1142 if (result
!= ASN1_SUCCESS
)
1145 result
= _gnutls_asn2err (result
);
1151 if ((result
= asn1_create_element
1152 (_gnutls_get_pkix (), "PKIX1.pkcs-7-Data", &c2
)) != ASN1_SUCCESS
)
1155 result
= _gnutls_asn2err (result
);
1159 result
= asn1_write_value (c2
, "", data
, size
);
1160 if (result
!= ASN1_SUCCESS
)
1163 result
= _gnutls_asn2err (result
);
1167 result
= asn1_der_coding (c2
, "", data
, &asize
, NULL
);
1168 if (result
!= ASN1_SUCCESS
)
1171 result
= _gnutls_asn2err (result
);
1177 asn1_delete_structure (&c2
);
1181 res
->size
= (unsigned)size
;
1186 asn1_delete_structure (&c2
);
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
1197 _gnutls_x509_der_encode_and_copy (ASN1_TYPE src
, const char *src_name
,
1198 ASN1_TYPE dest
, const char *dest_name
,
1202 gnutls_datum_t encoded
;
1204 result
= _gnutls_x509_der_encode (src
, src_name
, &encoded
, str
);
1214 result
= asn1_write_value (dest
, dest_name
, encoded
.data
, (int)encoded
.size
);
1216 _gnutls_free_datum (&encoded
);
1218 if (result
!= ASN1_SUCCESS
)
1221 return _gnutls_asn2err (result
);
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
)
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
);
1256 val
.data
= data
->data
;
1257 val
.size
= data
->size
;
1262 ret
= asn1_write_value (c
, root
, val
.data
, val
.size
);
1263 if (ret
!= ASN1_SUCCESS
)
1266 ret
= _gnutls_asn2err (ret
);
1273 asn1_delete_structure (&c2
);
1274 if (val
.data
!= data
->data
)
1275 _gnutls_free_datum (&val
);
1280 _asnstr_append_name (char *name
, size_t name_size
, const char *part1
,
1285 _gnutls_str_cpy (name
, name_size
, part1
);
1286 _gnutls_str_cat (name
, name_size
, part2
);
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
)
1305 gnutls_datum_t der
= { NULL
, 0 };
1309 pk
= _gnutls_x509_pk_to_oid (pk_algorithm
);
1313 return GNUTLS_E_UNKNOWN_PK_ALGORITHM
;
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
)
1324 return _gnutls_asn2err (result
);
1327 result
= _gnutls_x509_write_pubkey_params (pk_algorithm
, params
, &der
);
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
)
1344 return _gnutls_asn2err (result
);
1347 result
= _gnutls_x509_write_pubkey (pk_algorithm
, params
, &der
);
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
)
1364 return _gnutls_asn2err (result
);
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
)
1381 ret
= asn1_create_element (_gnutls_get_pkix (),
1382 "PKIX1.Certificate", &tmp
);
1383 if (ret
!= ASN1_SUCCESS
)
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
)
1395 ret
= _gnutls_asn2err (ret
);
1399 ret
= _gnutls_x509_der_encode(tmp
, "tbsCertificate.subjectPublicKeyInfo", der
, 0);
1402 asn1_delete_structure (&tmp
);
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
,
1418 gnutls_pk_params_st params
;
1421 gnutls_pk_params_init(¶ms
);
1423 _asnstr_append_name (name
, sizeof (name
), src_name
, ".algorithm.algorithm");
1425 result
= asn1_read_value (src
, name
, oid
, &len
);
1427 if (result
!= ASN1_SUCCESS
)
1430 return _gnutls_asn2err (result
);
1433 algo
= _gnutls_x509_oid2pk_algorithm (oid
);
1434 if (algo
== GNUTLS_PK_UNKNOWN
)
1437 ("%s: unknown public key algorithm: %s\n", __func__
, oid
);
1445 /* Now read the parameters' bits
1447 result
= _gnutls_get_asn_mpis(src
, src_name
, ¶ms
);
1449 return gnutls_assert_val(result
);
1451 bits
[0] = pubkey_to_bits(algo
, ¶ms
);
1453 gnutls_pk_params_release(¶ms
);
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
)
1465 int start
, end
, result
;
1467 result
= _gnutls_x509_der_encode (src
, "", &der
, 0);
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
);
1485 result
= _gnutls_set_datum (signed_data
, &der
.data
[start
], end
- start
+ 1);
1496 _gnutls_free_datum (&der
);
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
1514 _gnutls_x509_get_signature_algorithm (ASN1_TYPE src
, const char *src_name
)
1519 /* Read the signature algorithm. Note that parameters are not
1520 * read. They will be read from the issuer's certificate if needed.
1523 _gnutls_x509_read_value (src
, src_name
, &sa
);
1531 result
= _gnutls_x509_oid2sign_algorithm ( (char*)sa
.data
);
1533 _gnutls_free_datum (&sa
);
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
)
1549 signature
->data
= NULL
;
1550 signature
->size
= 0;
1552 /* Read the signature
1555 result
= asn1_read_value (src
, src_name
, NULL
, &len
);
1557 if (result
!= ASN1_MEM_ERROR
)
1559 result
= _gnutls_asn2err (result
);
1568 result
= GNUTLS_E_CERTIFICATE_ERROR
;
1574 signature
->data
= gnutls_malloc (len
);
1575 if (signature
->data
== NULL
)
1578 result
= GNUTLS_E_MEMORY_ERROR
;
1582 /* read the bit string of the signature
1585 result
= asn1_read_value (src
, src_name
, signature
->data
, (int*)&bits
);
1587 if (result
!= ASN1_SUCCESS
)
1589 result
= _gnutls_asn2err (result
);
1594 signature
->size
= len
;