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 const char *asn_desc
; /* description in the pkix file if complex type */
40 unsigned int etype
; /* the libtasn1 ASN1_ETYPE or INVALID
41 * if cannot be simply parsed */
44 /* This list contains all the OIDs that may be
45 * contained in a rdnSequence and are printable.
47 static const struct oid_to_string _oid2str
[] = {
50 {"1.3.6.1.5.5.7.9.1", "dateOfBirth", NULL
, ASN1_ETYPE_GENERALIZED_TIME
},
51 {"1.3.6.1.5.5.7.9.2", "placeOfBirth", "PKIX1.DirectoryString", ASN1_ETYPE_INVALID
},
52 {"1.3.6.1.5.5.7.9.3", "gender", NULL
, ASN1_ETYPE_PRINTABLE_STRING
},
53 {"1.3.6.1.5.5.7.9.4", "countryOfCitizenship", NULL
, ASN1_ETYPE_PRINTABLE_STRING
},
54 {"1.3.6.1.5.5.7.9.5", "countryOfResidence", NULL
, ASN1_ETYPE_PRINTABLE_STRING
},
56 {"2.5.4.6", "C", NULL
, ASN1_ETYPE_PRINTABLE_STRING
},
57 {"2.5.4.9", "STREET", "PKIX1.DirectoryString", ASN1_ETYPE_INVALID
},
58 {"2.5.4.12", "T", "PKIX1.DirectoryString", ASN1_ETYPE_INVALID
},
59 {"2.5.4.10", "O", "PKIX1.DirectoryString", ASN1_ETYPE_INVALID
},
60 {"2.5.4.11", "OU", "PKIX1.DirectoryString", ASN1_ETYPE_INVALID
},
61 {"2.5.4.3", "CN", "PKIX1.DirectoryString", ASN1_ETYPE_INVALID
},
62 {"2.5.4.7", "L", "PKIX1.DirectoryString", ASN1_ETYPE_INVALID
},
63 {"2.5.4.8", "ST", "PKIX1.DirectoryString", ASN1_ETYPE_INVALID
},
65 {"2.5.4.5", "serialNumber", NULL
, ASN1_ETYPE_PRINTABLE_STRING
},
66 {"2.5.4.20", "telephoneNumber", NULL
, ASN1_ETYPE_PRINTABLE_STRING
},
67 {"2.5.4.4", "surName", "PKIX1.DirectoryString", ASN1_ETYPE_INVALID
},
68 {"2.5.4.43", "initials", "PKIX1.DirectoryString", ASN1_ETYPE_INVALID
},
69 {"2.5.4.44", "generationQualifier", "PKIX1.DirectoryString", ASN1_ETYPE_INVALID
},
70 {"2.5.4.42", "givenName", "PKIX1.DirectoryString", ASN1_ETYPE_INVALID
},
71 {"2.5.4.65", "pseudonym", "PKIX1.DirectoryString", ASN1_ETYPE_INVALID
},
72 {"2.5.4.46", "dnQualifier", NULL
, ASN1_ETYPE_PRINTABLE_STRING
},
73 {"2.5.4.17", "postalCode", "PKIX1.DirectoryString", ASN1_ETYPE_INVALID
},
74 {"2.5.4.41", "Name", "PKIX1.DirectoryString", ASN1_ETYPE_INVALID
},
75 {"2.5.4.15", "businessCategory", "PKIX1.DirectoryString", ASN1_ETYPE_INVALID
},
77 {"0.9.2342.19200300.100.1.25", "DC", NULL
, ASN1_ETYPE_IA5_STRING
},
78 {"0.9.2342.19200300.100.1.1", "UID", "PKIX1.DirectoryString", ASN1_ETYPE_INVALID
},
80 /* Extended validation
82 {"1.3.6.1.4.1.311.60.2.1.1", "jurisdictionOfIncorporationLocalityName",
83 "PKIX1.DirectoryString", ASN1_ETYPE_INVALID
},
84 {"1.3.6.1.4.1.311.60.2.1.2",
85 "jurisdictionOfIncorporationStateOrProvinceName",
86 "PKIX1.DirectoryString", ASN1_ETYPE_INVALID
},
87 {"1.3.6.1.4.1.311.60.2.1.3", "jurisdictionOfIncorporationCountryName",
88 NULL
, ASN1_ETYPE_PRINTABLE_STRING
},
92 {"1.2.840.113549.1.9.1", "EMAIL", NULL
, ASN1_ETYPE_IA5_STRING
},
93 {"1.2.840.113549.1.9.7", NULL
, "PKIX1.pkcs-9-challengePassword", ASN1_ETYPE_INVALID
},
96 {"1.2.840.113549.1.9.20", NULL
, NULL
, ASN1_ETYPE_BMP_STRING
},
98 {"1.2.840.113549.1.9.21", NULL
, NULL
, ASN1_ETYPE_OCTET_STRING
},
100 /* rfc3920 section 5.1.1 */
101 {"1.3.6.1.5.5.7.8.5", "XmppAddr", NULL
, ASN1_ETYPE_UTF8_STRING
},
103 {NULL
, NULL
, NULL
, 0}
106 static const struct oid_to_string
* get_oid_entry (const char* oid
)
112 if (strcmp (_oid2str
[i
].oid
, oid
) == 0)
116 while (_oid2str
[i
].oid
!= NULL
);
123 * gnutls_x509_dn_oid_known:
124 * @oid: holds an Object Identifier in a null terminated string
126 * This function will inform about known DN OIDs. This is useful since
127 * functions like gnutls_x509_crt_set_dn_by_oid() use the information
128 * on known OIDs to properly encode their input. Object Identifiers
129 * that are not known are not encoded by these functions, and their
130 * input is stored directly into the ASN.1 structure. In that case of
131 * unknown OIDs, you have the responsibility of DER encoding your
134 * Returns: 1 on known OIDs and 0 otherwise.
137 gnutls_x509_dn_oid_known (const char *oid
)
143 if (strcmp (_oid2str
[i
].oid
, oid
) == 0)
147 while (_oid2str
[i
].oid
!= NULL
);
153 * gnutls_x509_dn_oid_name:
154 * @oid: holds an Object Identifier in a null terminated string
155 * @flags: 0 or GNUTLS_X509_DN_OID_*
157 * This function will return the name of a known DN OID. If
158 * %GNUTLS_X509_DN_OID_RETURN_OID is specified this function
159 * will return the given OID if no descriptive name has been
162 * Returns: A null terminated string or NULL otherwise.
167 gnutls_x509_dn_oid_name (const char *oid
, unsigned int flags
)
173 if (strcmp (_oid2str
[i
].oid
, oid
) == 0)
174 return _oid2str
[i
].ldap_desc
;
177 while (_oid2str
[i
].oid
!= NULL
);
179 if (flags
& GNUTLS_X509_DN_OID_RETURN_OID
) return oid
;
184 make_printable_string(unsigned etype
, const gnutls_datum_t
*input
, gnutls_datum_t
*out
)
191 if (etype
== ASN1_ETYPE_BMP_STRING
)
193 ret
= _gnutls_ucs2_to_utf8(input
->data
, input
->size
, out
);
196 /* could not convert. Handle it as non-printable */
202 else if (etype
== ASN1_ETYPE_TELETEX_STRING
)
205 /* HACK: if the teletex string contains only ascii
206 * characters then treat it as printable.
208 for (i
= 0; i
< input
->size
; i
++)
209 if (!isascii (input
->data
[i
]))
214 out
->data
= gnutls_malloc(input
->size
+1);
215 if (out
->data
== NULL
)
216 return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR
);
218 memcpy(out
->data
, input
->data
, input
->size
);
219 out
->size
= input
->size
;
221 out
->data
[out
->size
] = 0;
226 else if (etype
!= ASN1_ETYPE_UNIVERSAL_STRING
) /* supported but not printable */
227 return GNUTLS_E_INVALID_REQUEST
;
230 { /* need to allocate out */
231 out
->size
= input
->size
*2+2;
232 out
->data
= gnutls_malloc(out
->size
);
233 if (out
->data
== NULL
)
234 return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR
);
237 ret
= _gnutls_x509_data2hex (input
->data
, input
->size
, out
->data
, &size
);
249 _gnutls_free_datum(out
);
254 decode_complex_string (const struct oid_to_string
* oentry
, void *value
,
255 int value_size
, gnutls_datum_t
* out
)
257 char str
[MAX_STRING_LEN
], tmpname
[128];
258 int len
= -1, result
;
259 ASN1_TYPE tmpasn
= ASN1_TYPE_EMPTY
;
260 char asn1_err
[ASN1_MAX_ERROR_DESCRIPTION_SIZE
] = "";
264 if (oentry
->asn_desc
== NULL
)
267 return GNUTLS_E_INTERNAL_ERROR
;
271 asn1_create_element (_gnutls_get_pkix (), oentry
->asn_desc
,
272 &tmpasn
)) != ASN1_SUCCESS
)
275 return _gnutls_asn2err (result
);
279 asn1_der_decoding (&tmpasn
, value
, value_size
,
280 asn1_err
)) != ASN1_SUCCESS
)
283 _gnutls_debug_log ("asn1_der_decoding: %s\n", asn1_err
);
284 asn1_delete_structure (&tmpasn
);
285 return _gnutls_asn2err (result
);
288 /* Read the type of choice.
290 len
= sizeof (str
) - 1;
291 if ((result
= asn1_read_value (tmpasn
, "", str
, &len
)) != ASN1_SUCCESS
)
294 asn1_delete_structure (&tmpasn
);
295 return _gnutls_asn2err (result
);
300 /* We set the etype on the strings that may need
301 * some conversion to UTF-8. The INVALID flag indicates
302 * no conversion needed */
303 if (strcmp (str
, "teletexString") == 0)
304 etype
= ASN1_ETYPE_TELETEX_STRING
;
305 else if (strcmp (str
, "bmpString") == 0)
306 etype
= ASN1_ETYPE_BMP_STRING
;
307 else if (strcmp (str
, "universalString") == 0)
308 etype
= ASN1_ETYPE_UNIVERSAL_STRING
;
309 else etype
= ASN1_ETYPE_INVALID
;
311 _gnutls_str_cpy (tmpname
, sizeof (tmpname
), str
);
313 result
= _gnutls_x509_read_value(tmpasn
, tmpname
, &td
);
314 asn1_delete_structure (&tmpasn
);
316 return gnutls_assert_val(result
);
318 if (etype
!= ASN1_ETYPE_INVALID
)
320 result
= make_printable_string(etype
, &td
, out
);
322 _gnutls_free_datum(&td
);
325 return gnutls_assert_val(result
);
331 out
->data
[out
->size
] = 0;
334 /* Refuse to deal with strings containing NULs. */
335 if (strlen ((void*)out
->data
) != (size_t)out
->size
)
337 _gnutls_free_datum(out
);
338 return gnutls_assert_val(GNUTLS_E_ASN1_DER_ERROR
);
345 /* This function will convert an attribute value, specified by the OID,
346 * to a string. The result will be a null terminated string.
348 * res may be null. This will just return the res_size, needed to
352 _gnutls_x509_dn_to_string (const char *oid
, void *value
,
353 int value_size
, gnutls_datum_t
*str
)
355 const struct oid_to_string
* oentry
;
359 if (value
== NULL
|| value_size
<= 0)
362 return GNUTLS_E_INVALID_REQUEST
;
365 oentry
= get_oid_entry(oid
);
367 { /* unknown OID -> hex */
368 str
->size
= value_size
*2+2;
369 str
->data
= gnutls_malloc(str
->size
);
370 if (str
->data
== NULL
)
371 return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR
);
374 ret
= _gnutls_x509_data2hex (value
, value_size
, str
->data
, &size
);
378 gnutls_free(str
->data
);
385 if (oentry
->asn_desc
!= NULL
)
387 ret
= decode_complex_string(oentry
, value
, value_size
, str
);
389 return gnutls_assert_val(ret
);
393 ret
= _gnutls_x509_decode_string(oentry
->etype
, value
, value_size
,
397 return gnutls_assert_val(ret
);
405 /* Converts a data string to an LDAP rfc2253 hex string
406 * something like '#01020304'
409 _gnutls_x509_data2hex (const void * data
, size_t data_size
,
410 void * _out
, size_t * sizeof_out
)
413 char escaped
[MAX_STRING_LEN
];
417 if (2 * data_size
+ 1 > MAX_STRING_LEN
)
420 return GNUTLS_E_INTERNAL_ERROR
;
423 res
= _gnutls_bin2hex (data
, data_size
, escaped
, sizeof (escaped
), NULL
);
427 return GNUTLS_E_INTERNAL_ERROR
;
430 size
= strlen (res
) + 1;
431 if (size
+ 1 > *sizeof_out
)
434 return GNUTLS_E_SHORT_MEMORY_BUFFER
;
436 *sizeof_out
= size
; /* -1 for the null +1 for the '#' */
442 _gnutls_str_cat (out
, *sizeof_out
, res
);
450 * Convertions between generalized or UTC time to time_t
454 /* This is an emulations of the struct tm.
455 * Since we do not use libc's functions, we don't need to
456 * depend on the libc structure.
458 typedef struct fake_tm
461 int tm_year
; /* FULL year - ie 1971 */
468 /* The mktime_utc function is due to Russ Allbery (rra@stanford.edu),
469 * who placed it under public domain:
472 /* The number of days in each month.
474 static const int MONTHDAYS
[] = {
475 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
478 /* Whether a given year is a leap year. */
479 #define ISLEAP(year) \
480 (((year) % 4) == 0 && (((year) % 100) != 0 || ((year) % 400) == 0))
483 ** Given a struct tm representing a calendar time in UTC, convert it to
484 ** seconds since epoch. Returns (time_t) -1 if the time is not
485 ** convertable. Note that this function does not canonicalize the provided
486 ** struct tm, nor does it allow out of range values or years before 1970.
489 mktime_utc (const struct fake_tm
*tm
)
494 /* We do allow some ill-formed dates, but we don't do anything special
495 * with them and our callers really shouldn't pass them to us. Do
496 * explicitly disallow the ones that would cause invalid array accesses
497 * or other algorithm problems.
499 if (tm
->tm_mon
< 0 || tm
->tm_mon
> 11 || tm
->tm_year
< 1970)
502 /* Convert to a time_t.
504 for (i
= 1970; i
< tm
->tm_year
; i
++)
505 result
+= 365 + ISLEAP (i
);
506 for (i
= 0; i
< tm
->tm_mon
; i
++)
507 result
+= MONTHDAYS
[i
];
508 if (tm
->tm_mon
> 1 && ISLEAP (tm
->tm_year
))
510 result
= 24 * (result
+ tm
->tm_mday
- 1) + tm
->tm_hour
;
511 result
= 60 * result
+ tm
->tm_min
;
512 result
= 60 * result
+ tm
->tm_sec
;
517 /* this one will parse dates of the form:
518 * month|day|hour|minute|sec* (2 chars each)
519 * and year is given. Returns a time_t date.
522 time2gtime (const char *ttime
, int year
)
525 struct fake_tm etime
;
527 if (strlen (ttime
) < 8)
533 etime
.tm_year
= year
;
535 /* In order to work with 32 bit
538 if (sizeof (time_t) <= 4 && etime
.tm_year
>= 2038)
539 return (time_t) 2145914603; /* 2037-12-31 23:23:23 */
541 if (etime
.tm_year
< 1970)
548 memcpy (xx
, ttime
, 2); /* month */
549 etime
.tm_mon
= atoi (xx
) - 1;
554 memcpy (xx
, ttime
, 2); /* day */
555 etime
.tm_mday
= atoi (xx
);
560 memcpy (xx
, ttime
, 2); /* hour */
561 etime
.tm_hour
= atoi (xx
);
566 memcpy (xx
, ttime
, 2); /* minutes */
567 etime
.tm_min
= atoi (xx
);
570 if (strlen (ttime
) >= 2)
572 memcpy (xx
, ttime
, 2);
573 etime
.tm_sec
= atoi (xx
);
578 return mktime_utc (&etime
);
582 /* returns a time_t value that contains the given time.
583 * The given time is expressed as:
584 * YEAR(2)|MONTH(2)|DAY(2)|HOUR(2)|MIN(2)|SEC(2)*
586 * (seconds are optional)
589 utcTime2gtime (const char *ttime
)
594 if (strlen (ttime
) < 10)
602 memcpy (xx
, ttime
, 2); /* year */
611 return time2gtime (ttime
, year
);
614 /* returns a time_t value that contains the given time.
615 * The given time is expressed as:
616 * YEAR(4)|MONTH(2)|DAY(2)|HOUR(2)|MIN(2)|SEC(2)*
619 _gnutls_x509_generalTime2gtime (const char *ttime
)
624 if (strlen (ttime
) < 12)
630 if (strchr (ttime
, 'Z') == 0)
633 /* sorry we don't support it yet
641 memcpy (xx
, ttime
, 4); /* year */
645 return time2gtime (ttime
, year
);
649 gtime2generalTime (time_t gtime
, char *str_time
, size_t str_time_size
)
654 if (!gmtime_r (>ime
, &_tm
))
657 return GNUTLS_E_INTERNAL_ERROR
;
660 ret
= strftime (str_time
, str_time_size
, "%Y%m%d%H%M%SZ", &_tm
);
664 return GNUTLS_E_SHORT_MEMORY_BUFFER
;
672 /* Extracts the time in time_t from the ASN1_TYPE given. When should
673 * be something like "tbsCertList.thisUpdate".
677 _gnutls_x509_get_time (ASN1_TYPE c2
, const char *when
, int nochoice
)
679 char ttime
[MAX_TIME
];
681 time_t c_time
= (time_t) - 1;
684 len
= sizeof (ttime
) - 1;
685 result
= asn1_read_value (c2
, when
, ttime
, &len
);
686 if (result
!= ASN1_SUCCESS
)
689 return (time_t) (-1);
694 c_time
= _gnutls_x509_generalTime2gtime (ttime
);
698 _gnutls_str_cpy (name
, sizeof (name
), when
);
701 if (strcmp (ttime
, "generalTime") == 0)
703 _gnutls_str_cat (name
, sizeof (name
), ".generalTime");
704 len
= sizeof (ttime
) - 1;
705 result
= asn1_read_value (c2
, name
, ttime
, &len
);
706 if (result
== ASN1_SUCCESS
)
707 c_time
= _gnutls_x509_generalTime2gtime (ttime
);
711 _gnutls_str_cat (name
, sizeof (name
), ".utcTime");
712 len
= sizeof (ttime
) - 1;
713 result
= asn1_read_value (c2
, name
, ttime
, &len
);
714 if (result
== ASN1_SUCCESS
)
715 c_time
= utcTime2gtime (ttime
);
718 /* We cannot handle dates after 2031 in 32 bit machines.
719 * a time_t of 64bits has to be used.
721 if (result
!= ASN1_SUCCESS
)
724 return (time_t) (-1);
731 /* Sets the time in time_t in the ASN1_TYPE given. Where should
732 * be something like "tbsCertList.thisUpdate".
735 _gnutls_x509_set_time (ASN1_TYPE c2
, const char *where
, time_t tim
, int nochoice
)
737 char str_time
[MAX_TIME
];
743 result
= gtime2generalTime( tim
, str_time
, sizeof(str_time
));
745 return gnutls_assert_val(result
);
747 len
= strlen (str_time
);
748 result
= asn1_write_value(c2
, where
, str_time
, len
);
749 if (result
!= ASN1_SUCCESS
)
750 return gnutls_assert_val(_gnutls_asn2err (result
));
755 _gnutls_str_cpy (name
, sizeof (name
), where
);
757 if ((result
= asn1_write_value (c2
, name
, "generalTime", 1)) < 0)
760 return _gnutls_asn2err (result
);
763 result
= gtime2generalTime (tim
, str_time
, sizeof (str_time
));
770 _gnutls_str_cat (name
, sizeof (name
), ".generalTime");
772 len
= strlen (str_time
);
773 result
= asn1_write_value (c2
, name
, str_time
, len
);
774 if (result
!= ASN1_SUCCESS
)
777 return _gnutls_asn2err (result
);
784 gnutls_x509_subject_alt_name_t
785 _gnutls_x509_san_find_type (char *str_type
)
787 if (strcmp (str_type
, "dNSName") == 0)
788 return GNUTLS_SAN_DNSNAME
;
789 if (strcmp (str_type
, "rfc822Name") == 0)
790 return GNUTLS_SAN_RFC822NAME
;
791 if (strcmp (str_type
, "uniformResourceIdentifier") == 0)
792 return GNUTLS_SAN_URI
;
793 if (strcmp (str_type
, "iPAddress") == 0)
794 return GNUTLS_SAN_IPADDRESS
;
795 if (strcmp (str_type
, "otherName") == 0)
796 return GNUTLS_SAN_OTHERNAME
;
797 if (strcmp (str_type
, "directoryName") == 0)
798 return GNUTLS_SAN_DN
;
799 return (gnutls_x509_subject_alt_name_t
) - 1;
802 /* A generic export function. Will export the given ASN.1 encoded data
803 * to PEM or DER raw data.
806 _gnutls_x509_export_int_named (ASN1_TYPE asn1_data
, const char *name
,
807 gnutls_x509_crt_fmt_t format
,
808 const char *pem_header
,
809 unsigned char *output_data
,
810 size_t * output_data_size
)
816 ret
= _gnutls_x509_export_int_named2 (asn1_data
, name
,
817 format
, pem_header
, &out
);
819 return gnutls_assert_val(ret
);
821 if (format
== GNUTLS_X509_FMT_PEM
)
826 if (*output_data_size
< size
)
828 *output_data_size
= size
;
829 ret
= gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER
);
833 *output_data_size
= (size_t)out
.size
;
836 memcpy (output_data
, out
.data
, (size_t)out
.size
);
837 if (format
== GNUTLS_X509_FMT_PEM
)
838 output_data
[out
.size
] = 0;
844 gnutls_free (out
.data
);
849 /* A generic export function. Will export the given ASN.1 encoded data
850 * to PEM or DER raw data.
853 _gnutls_x509_export_int_named2 (ASN1_TYPE asn1_data
, const char *name
,
854 gnutls_x509_crt_fmt_t format
,
855 const char *pem_header
,
860 if (format
== GNUTLS_X509_FMT_DER
)
862 ret
= _gnutls_x509_der_encode(asn1_data
, name
, out
, 0);
864 return gnutls_assert_val(ret
);
870 ret
= _gnutls_x509_der_encode (asn1_data
, name
, &tmp
, 0);
872 return gnutls_assert_val(ret
);
874 ret
= _gnutls_fbase64_encode (pem_header
, tmp
.data
, tmp
.size
, out
);
875 _gnutls_free_datum (&tmp
);
878 return gnutls_assert_val(ret
);
884 /* Decodes an octet string. The etype specifies the string type.
885 * The returned string is always null terminated (but null is not
889 _gnutls_x509_decode_string (unsigned int etype
,
890 const uint8_t * der
, size_t der_size
,
891 gnutls_datum_t
* output
)
895 unsigned int str_size
;
898 ret
= asn1_decode_simple_der (etype
, der
, der_size
, &str
, &str_size
);
899 if (ret
!= ASN1_SUCCESS
)
902 ret
= _gnutls_asn2err (ret
);
907 td
.data
= gnutls_malloc(str_size
+1);
909 return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR
);
911 memcpy(td
.data
, str
, str_size
);
912 td
.data
[str_size
] = 0;
914 ret
= make_printable_string(etype
, &td
, output
);
915 if (ret
== GNUTLS_E_INVALID_REQUEST
) /* unsupported etype */
917 output
->data
= td
.data
;
918 output
->size
= td
.size
;
923 _gnutls_free_datum(&td
);
926 /* Refuse to deal with strings containing NULs. */
927 if (etype
!= ASN1_ETYPE_OCTET_STRING
)
929 if (strlen ((void*)output
->data
) != (size_t)output
->size
)
931 _gnutls_free_datum(output
);
932 ret
= gnutls_assert_val(GNUTLS_E_ASN1_DER_ERROR
);
940 /* Reads a value from an ASN1 tree, and puts the output
941 * in an allocated variable in the given datum.
943 * Note that this function always places allocates one plus
944 * the required data size (to allow for a null byte).
947 _gnutls_x509_read_value (ASN1_TYPE c
, const char *root
,
948 gnutls_datum_t
* ret
)
954 result
= asn1_read_value_type (c
, root
, NULL
, &len
, &etype
);
955 if (result
!= ASN1_MEM_ERROR
)
958 result
= _gnutls_asn2err (result
);
962 if (etype
== ASN1_ETYPE_BIT_STRING
)
968 tmp
= gnutls_malloc ((size_t)len
+1);
972 result
= GNUTLS_E_MEMORY_ERROR
;
976 result
= asn1_read_value (c
, root
, tmp
, &len
);
977 if (result
!= ASN1_SUCCESS
)
980 result
= _gnutls_asn2err (result
);
984 if (etype
== ASN1_ETYPE_BIT_STRING
)
990 else ret
->size
= (unsigned)len
;
1001 /* Reads a value from an ASN1 tree, then interprets it as the provided
1002 * type of string and returns the output in an allocated variable.
1004 * Note that this function always places a null character
1005 * at the end of a readable string value (which is not accounted into size)
1008 _gnutls_x509_read_string (ASN1_TYPE c
, const char *root
,
1009 gnutls_datum_t
* ret
, unsigned int etype
)
1011 int len
= 0, result
;
1013 uint8_t *tmp
= NULL
;
1016 result
= asn1_read_value_type (c
, root
, NULL
, &len
, &rtype
);
1017 if (result
!= ASN1_MEM_ERROR
)
1020 result
= _gnutls_asn2err (result
);
1024 if (rtype
== ASN1_ETYPE_BIT_STRING
)
1027 tmp
= gnutls_malloc ((size_t)len
+1);
1031 result
= GNUTLS_E_MEMORY_ERROR
;
1035 result
= asn1_read_value (c
, root
, tmp
, &len
);
1036 if (result
!= ASN1_SUCCESS
)
1039 result
= _gnutls_asn2err (result
);
1043 if (rtype
== ASN1_ETYPE_BIT_STRING
)
1046 /* Extract the STRING.
1050 result
= _gnutls_x509_decode_string (etype
, tmp
, slen
, ret
);
1065 /* The string type should be IA5String, UTF8String etc. Leave
1066 * null for octet string */
1067 int _gnutls_x509_encode_string(unsigned int etype
,
1068 const void* input_data
, size_t input_size
,
1069 gnutls_datum_t
* output
)
1071 uint8_t tl
[ASN1_MAX_TL_SIZE
];
1072 unsigned int tl_size
;
1075 tl_size
= sizeof(tl
);
1076 ret
= asn1_encode_simple_der (etype
, input_data
, input_size
, tl
, &tl_size
);
1077 if (ret
!= ASN1_SUCCESS
)
1080 ret
= _gnutls_asn2err (ret
);
1084 output
->data
= gnutls_malloc(tl_size
+ input_size
);
1085 if (output
->data
== NULL
)
1086 return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR
);
1088 memcpy(output
->data
, tl
, tl_size
);
1089 memcpy(output
->data
+tl_size
, input_data
, input_size
);
1091 output
->size
= tl_size
+ input_size
;
1096 /* DER Encodes the src ASN1_TYPE and stores it to
1097 * the given datum. If str is non zero then the data are encoded as
1101 _gnutls_x509_der_encode (ASN1_TYPE src
, const char *src_name
,
1102 gnutls_datum_t
* res
, int str
)
1106 uint8_t *data
= NULL
;
1107 ASN1_TYPE c2
= ASN1_TYPE_EMPTY
;
1110 result
= asn1_der_coding (src
, src_name
, NULL
, &size
, NULL
);
1111 if (result
!= ASN1_MEM_ERROR
)
1114 result
= _gnutls_asn2err (result
);
1118 /* allocate data for the der
1122 size
+= 16; /* for later to include the octet tags */
1125 data
= gnutls_malloc ((size_t)size
);
1129 result
= GNUTLS_E_MEMORY_ERROR
;
1133 result
= asn1_der_coding (src
, src_name
, data
, &size
, NULL
);
1134 if (result
!= ASN1_SUCCESS
)
1137 result
= _gnutls_asn2err (result
);
1143 if ((result
= asn1_create_element
1144 (_gnutls_get_pkix (), "PKIX1.pkcs-7-Data", &c2
)) != ASN1_SUCCESS
)
1147 result
= _gnutls_asn2err (result
);
1151 result
= asn1_write_value (c2
, "", data
, size
);
1152 if (result
!= ASN1_SUCCESS
)
1155 result
= _gnutls_asn2err (result
);
1159 result
= asn1_der_coding (c2
, "", data
, &asize
, NULL
);
1160 if (result
!= ASN1_SUCCESS
)
1163 result
= _gnutls_asn2err (result
);
1169 asn1_delete_structure (&c2
);
1173 res
->size
= (unsigned)size
;
1178 asn1_delete_structure (&c2
);
1183 /* DER Encodes the src ASN1_TYPE and stores it to
1184 * dest in dest_name. Useful to encode something and store it
1185 * as OCTET. If str is non null then the data are encoded as
1189 _gnutls_x509_der_encode_and_copy (ASN1_TYPE src
, const char *src_name
,
1190 ASN1_TYPE dest
, const char *dest_name
,
1194 gnutls_datum_t encoded
;
1196 result
= _gnutls_x509_der_encode (src
, src_name
, &encoded
, str
);
1206 result
= asn1_write_value (dest
, dest_name
, encoded
.data
, (int)encoded
.size
);
1208 _gnutls_free_datum (&encoded
);
1210 if (result
!= ASN1_SUCCESS
)
1213 return _gnutls_asn2err (result
);
1219 /* Writes the value of the datum in the given ASN1_TYPE.
1222 _gnutls_x509_write_value (ASN1_TYPE c
, const char *root
,
1223 const gnutls_datum_t
* data
)
1229 ret
= asn1_write_value (c
, root
, data
->data
, data
->size
);
1230 if (ret
!= ASN1_SUCCESS
)
1233 return _gnutls_asn2err (ret
);
1239 /* Writes the value of the datum in the given ASN1_TYPE as a string.
1242 _gnutls_x509_write_string (ASN1_TYPE c
, const char *root
,
1243 const gnutls_datum_t
* data
, unsigned int etype
)
1246 gnutls_datum_t val
= { NULL
, 0 };
1248 ret
= _gnutls_x509_encode_string(etype
, data
->data
, data
->size
, &val
);
1250 return gnutls_assert_val(ret
);
1254 ret
= asn1_write_value (c
, root
, val
.data
, val
.size
);
1255 if (ret
!= ASN1_SUCCESS
)
1258 ret
= _gnutls_asn2err (ret
);
1265 _gnutls_free_datum (&val
);
1270 _asnstr_append_name (char *name
, size_t name_size
, const char *part1
,
1275 _gnutls_str_cpy (name
, name_size
, part1
);
1276 _gnutls_str_cat (name
, name_size
, part2
);
1279 _gnutls_str_cpy (name
, name_size
, part2
+ 1 /* remove initial dot */ );
1284 /* Encodes and copies the private key parameters into a
1285 * subjectPublicKeyInfo structure.
1289 _gnutls_x509_encode_and_copy_PKI_params (ASN1_TYPE dst
,
1290 const char *dst_name
,
1291 gnutls_pk_algorithm_t
1292 pk_algorithm
, gnutls_pk_params_st
* params
)
1295 gnutls_datum_t der
= { NULL
, 0 };
1299 pk
= _gnutls_x509_pk_to_oid (pk_algorithm
);
1303 return GNUTLS_E_UNKNOWN_PK_ALGORITHM
;
1308 _asnstr_append_name (name
, sizeof (name
), dst_name
, ".algorithm.algorithm");
1310 result
= asn1_write_value (dst
, name
, pk
, 1);
1311 if (result
!= ASN1_SUCCESS
)
1314 return _gnutls_asn2err (result
);
1317 result
= _gnutls_x509_write_pubkey_params (pk_algorithm
, params
, &der
);
1324 _asnstr_append_name (name
, sizeof (name
), dst_name
,
1325 ".algorithm.parameters");
1327 result
= asn1_write_value (dst
, name
, der
.data
, der
.size
);
1329 _gnutls_free_datum (&der
);
1331 if (result
!= ASN1_SUCCESS
)
1334 return _gnutls_asn2err (result
);
1337 result
= _gnutls_x509_write_pubkey (pk_algorithm
, params
, &der
);
1344 /* Write the DER parameters. (in bits)
1346 _asnstr_append_name (name
, sizeof (name
), dst_name
,
1347 ".subjectPublicKey");
1348 result
= asn1_write_value (dst
, name
, der
.data
, der
.size
* 8);
1349 _gnutls_free_datum (&der
);
1351 if (result
!= ASN1_SUCCESS
)
1354 return _gnutls_asn2err (result
);
1360 /* Encodes and public key parameters into a
1361 * subjectPublicKeyInfo structure and stores it in der.
1364 _gnutls_x509_encode_PKI_params (gnutls_datum_t
*der
,
1365 gnutls_pk_algorithm_t
1366 pk_algorithm
, gnutls_pk_params_st
* params
)
1371 ret
= asn1_create_element (_gnutls_get_pkix (),
1372 "PKIX1.Certificate", &tmp
);
1373 if (ret
!= ASN1_SUCCESS
)
1376 return _gnutls_asn2err (ret
);
1379 ret
= _gnutls_x509_encode_and_copy_PKI_params (tmp
,
1380 "tbsCertificate.subjectPublicKeyInfo",
1381 pk_algorithm
, params
);
1382 if (ret
!= ASN1_SUCCESS
)
1385 ret
= _gnutls_asn2err (ret
);
1389 ret
= _gnutls_x509_der_encode(tmp
, "tbsCertificate.subjectPublicKeyInfo", der
, 0);
1392 asn1_delete_structure (&tmp
);
1397 /* Reads and returns the PK algorithm of the given certificate-like
1398 * ASN.1 structure. src_name should be something like "tbsCertificate.subjectPublicKeyInfo".
1401 _gnutls_x509_get_pk_algorithm (ASN1_TYPE src
, const char *src_name
,
1408 gnutls_pk_params_st params
;
1411 gnutls_pk_params_init(¶ms
);
1413 _asnstr_append_name (name
, sizeof (name
), src_name
, ".algorithm.algorithm");
1415 result
= asn1_read_value (src
, name
, oid
, &len
);
1417 if (result
!= ASN1_SUCCESS
)
1420 return _gnutls_asn2err (result
);
1423 algo
= _gnutls_x509_oid2pk_algorithm (oid
);
1424 if (algo
== GNUTLS_PK_UNKNOWN
)
1427 ("%s: unknown public key algorithm: %s\n", __func__
, oid
);
1435 /* Now read the parameters' bits
1437 result
= _gnutls_get_asn_mpis(src
, src_name
, ¶ms
);
1439 return gnutls_assert_val(result
);
1441 bits
[0] = pubkey_to_bits(algo
, ¶ms
);
1443 gnutls_pk_params_release(¶ms
);
1447 /* Reads the DER signed data from the certificate and allocates space and
1448 * returns them into signed_data.
1451 _gnutls_x509_get_signed_data (ASN1_TYPE src
, const char *src_name
,
1452 gnutls_datum_t
* signed_data
)
1455 int start
, end
, result
;
1457 result
= _gnutls_x509_der_encode (src
, "", &der
, 0);
1464 /* Get the signed data
1466 result
= asn1_der_decoding_startEnd (src
, der
.data
, der
.size
,
1467 src_name
, &start
, &end
);
1468 if (result
!= ASN1_SUCCESS
)
1470 result
= _gnutls_asn2err (result
);
1475 result
= _gnutls_set_datum (signed_data
, &der
.data
[start
], end
- start
+ 1);
1486 _gnutls_free_datum (&der
);
1492 * gnutls_x509_get_signature_algorithm:
1493 * @src: should contain an ASN1_TYPE structure
1494 * @src_name: the description of the signature field
1496 * This function will return a value of the #gnutls_sign_algorithm_t
1497 * enumeration that is the signature algorithm that has been used to
1498 * sign this certificate.
1500 * Returns: a #gnutls_sign_algorithm_t value, or a negative error code on
1504 _gnutls_x509_get_signature_algorithm (ASN1_TYPE src
, const char *src_name
)
1509 /* Read the signature algorithm. Note that parameters are not
1510 * read. They will be read from the issuer's certificate if needed.
1513 _gnutls_x509_read_value (src
, src_name
, &sa
);
1521 result
= _gnutls_x509_oid2sign_algorithm ( (char*)sa
.data
);
1523 _gnutls_free_datum (&sa
);
1529 /* Reads the DER signature from the certificate and allocates space and
1530 * returns them into signed_data.
1533 _gnutls_x509_get_signature (ASN1_TYPE src
, const char *src_name
,
1534 gnutls_datum_t
* signature
)
1539 signature
->data
= NULL
;
1540 signature
->size
= 0;
1542 /* Read the signature
1545 result
= asn1_read_value (src
, src_name
, NULL
, &len
);
1547 if (result
!= ASN1_MEM_ERROR
)
1549 result
= _gnutls_asn2err (result
);
1558 result
= GNUTLS_E_CERTIFICATE_ERROR
;
1564 signature
->data
= gnutls_malloc (len
);
1565 if (signature
->data
== NULL
)
1568 result
= GNUTLS_E_MEMORY_ERROR
;
1572 /* read the bit string of the signature
1575 result
= asn1_read_value (src
, src_name
, signature
->data
, (int*)&bits
);
1577 if (result
!= ASN1_SUCCESS
)
1579 result
= _gnutls_asn2err (result
);
1584 signature
->size
= len
;
1592 /* ASN.1 PrintableString rules */
1593 static int is_printable(char p
)
1595 if ((p
>= 'a' && p
<= 'z') || (p
>= 'A' && p
<= 'Z') ||
1596 (p
>= '0' && p
<= '9') || p
== ' ' || p
== '(' || p
== ')' ||
1597 p
== '+' || p
== ',' || p
== '-' || p
== '.' || p
== '/' ||
1598 p
== ':' || p
== '=' || p
== '?')
1604 static int write_complex_string(ASN1_TYPE asn_struct
, const char* where
,
1605 const struct oid_to_string
* oentry
, const uint8_t *data
,
1611 const char *string_type
;
1614 result
= asn1_create_element (_gnutls_get_pkix (), oentry
->asn_desc
, &c2
);
1615 if (result
!= ASN1_SUCCESS
)
1618 return _gnutls_asn2err (result
);
1623 string_type
= "printableString";
1625 /* Check if the data is ASN.1 printable, and use
1626 * the UTF8 string type if not.
1628 for (i
= 0; i
< data_size
; i
++)
1630 if (!is_printable (data
[i
]))
1632 string_type
= "utf8String";
1637 /* if the type is a CHOICE then write the
1640 result
= asn1_write_value (c2
, "", string_type
, 1);
1641 if (result
!= ASN1_SUCCESS
)
1644 result
= _gnutls_asn2err (result
);
1648 _gnutls_str_cpy (tmp
, sizeof (tmp
), string_type
);
1650 result
= asn1_write_value (c2
, tmp
, data
, data_size
);
1651 if (result
!= ASN1_SUCCESS
)
1654 result
= _gnutls_asn2err (result
);
1658 result
= _gnutls_x509_der_encode_and_copy (c2
, "", asn_struct
, where
, 0);
1668 asn1_delete_structure (&c2
);
1673 /* This will encode and write the AttributeTypeAndValue field.
1674 * 'multi' must be (0) if writing an AttributeTypeAndValue, and 1 if Attribute.
1675 * In all cases only one value is written.
1678 _gnutls_x509_encode_and_write_attribute (const char *given_oid
,
1679 ASN1_TYPE asn1_struct
,
1682 int data_size
, int multi
)
1684 const uint8_t *data
= _data
;
1687 const struct oid_to_string
* oentry
;
1689 oentry
= get_oid_entry(given_oid
);
1693 _gnutls_debug_log ("Cannot find OID: %s\n", given_oid
);
1694 return GNUTLS_E_X509_UNSUPPORTED_OID
;
1697 /* write the data (value)
1700 _gnutls_str_cpy (tmp
, sizeof (tmp
), where
);
1701 _gnutls_str_cat (tmp
, sizeof (tmp
), ".value");
1704 { /* if not writing an AttributeTypeAndValue, but an Attribute */
1705 _gnutls_str_cat (tmp
, sizeof (tmp
), "s"); /* values */
1707 result
= asn1_write_value (asn1_struct
, tmp
, "NEW", 1);
1708 if (result
!= ASN1_SUCCESS
)
1711 result
= _gnutls_asn2err (result
);
1715 _gnutls_str_cat (tmp
, sizeof (tmp
), ".?LAST");
1718 if (oentry
->asn_desc
!= NULL
) /* write a complex string API */
1720 result
= write_complex_string(asn1_struct
, tmp
, oentry
, data
, data_size
);
1722 return gnutls_assert_val(result
);
1724 else /* write a simple string */
1728 td
.data
= (void*)data
;
1729 td
.size
= data_size
;
1730 result
= _gnutls_x509_write_string (asn1_struct
, tmp
, &td
, oentry
->etype
);
1740 _gnutls_str_cpy (tmp
, sizeof (tmp
), where
);
1741 _gnutls_str_cat (tmp
, sizeof (tmp
), ".type");
1743 result
= asn1_write_value (asn1_struct
, tmp
, given_oid
, 1);
1744 if (result
!= ASN1_SUCCESS
)
1747 result
= _gnutls_asn2err (result
);
1757 /* copies a datum to a buffer. If it doesn't fit it returns
1758 * GNUTLS_E_SHORT_MEMORY_BUFFER. It always deinitializes the datum
1761 * The buffer will always be null terminated.
1763 int _gnutls_strdatum_to_buf (gnutls_datum_t
* d
, void* buf
, size_t * buf_size
)
1766 uint8_t *_buf
= buf
;
1768 if (buf
== NULL
|| *buf_size
< d
->size
+1)
1770 *buf_size
= d
->size
+1;
1771 ret
= gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER
);
1774 memcpy(buf
, d
->data
, d
->size
);
1777 *buf_size
= d
->size
;
1781 _gnutls_free_datum(d
);