corrected copyright notices
[gnutls.git] / lib / x509 / common.c
blob02f9fdacf4abd861cd479ee0fd023d82bc03d8f3
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 oid_to_string
37 const char *oid;
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[] = {
48 /* PKIX
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},
90 /* PKCS #9
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},
95 /* friendly name */
96 {"1.2.840.113549.1.9.20", NULL, NULL, ASN1_ETYPE_BMP_STRING},
97 /* local key id */
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)
108 unsigned int i = 0;
112 if (strcmp (_oid2str[i].oid, oid) == 0)
113 return &_oid2str[i];
114 i++;
116 while (_oid2str[i].oid != NULL);
118 return 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
132 * data.
134 * Returns: 1 on known OIDs and 0 otherwise.
137 gnutls_x509_dn_oid_known (const char *oid)
139 unsigned int i = 0;
143 if (strcmp (_oid2str[i].oid, oid) == 0)
144 return 1;
145 i++;
147 while (_oid2str[i].oid != NULL);
149 return 0;
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
160 * found.
162 * Returns: A null terminated string or NULL otherwise.
164 * Since: 3.0
166 const char*
167 gnutls_x509_dn_oid_name (const char *oid, unsigned int flags)
169 unsigned int i = 0;
173 if (strcmp (_oid2str[i].oid, oid) == 0)
174 return _oid2str[i].ldap_desc;
175 i++;
177 while (_oid2str[i].oid != NULL);
179 if (flags & GNUTLS_X509_DN_OID_RETURN_OID) return oid;
180 else return NULL;
183 static int
184 make_printable_string(unsigned etype, const gnutls_datum_t *input, gnutls_datum_t *out)
186 int printable = 0;
187 int ret;
188 unsigned int i;
189 size_t size;
191 if (etype == ASN1_ETYPE_BMP_STRING)
193 ret = _gnutls_ucs2_to_utf8(input->data, input->size, out);
194 if (ret < 0)
196 /* could not convert. Handle it as non-printable */
197 printable = 0;
199 else
200 printable = 1;
202 else if (etype == ASN1_ETYPE_TELETEX_STRING)
204 int ascii = 0;
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]))
210 ascii = 1;
212 if (ascii == 0)
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;
223 printable = 1;
226 else if (etype != ASN1_ETYPE_UNIVERSAL_STRING) /* supported but not printable */
227 return GNUTLS_E_INVALID_REQUEST;
229 if (printable == 0)
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);
236 size = out->size;
237 ret = _gnutls_x509_data2hex (input->data, input->size, out->data, &size);
238 if (ret < 0)
240 gnutls_assert();
241 goto cleanup;
243 out->size = size;
246 return 0;
248 cleanup:
249 _gnutls_free_datum(out);
250 return ret;
253 static int
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] = "";
261 unsigned int etype;
262 gnutls_datum_t td;
264 if (oentry->asn_desc == NULL)
266 gnutls_assert ();
267 return GNUTLS_E_INTERNAL_ERROR;
270 if ((result =
271 asn1_create_element (_gnutls_get_pkix (), oentry->asn_desc,
272 &tmpasn)) != ASN1_SUCCESS)
274 gnutls_assert ();
275 return _gnutls_asn2err (result);
278 if ((result =
279 asn1_der_decoding (&tmpasn, value, value_size,
280 asn1_err)) != ASN1_SUCCESS)
282 gnutls_assert ();
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)
292 { /* CHOICE */
293 gnutls_assert ();
294 asn1_delete_structure (&tmpasn);
295 return _gnutls_asn2err (result);
298 str[len] = 0;
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);
315 if (result < 0)
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);
324 if (result < 0)
325 return gnutls_assert_val(result);
327 else
329 out->data = td.data;
330 out->size = td.size;
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);
341 return 0;
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
349 * hold the string.
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;
356 int ret;
357 size_t size;
359 if (value == NULL || value_size <= 0)
361 gnutls_assert ();
362 return GNUTLS_E_INVALID_REQUEST;
365 oentry = get_oid_entry(oid);
366 if (oentry == NULL)
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);
373 size = str->size;
374 ret = _gnutls_x509_data2hex (value, value_size, str->data, &size);
375 if (ret < 0)
377 gnutls_assert();
378 gnutls_free(str->data);
379 return ret;
381 str->size = size;
382 return 0;
385 if (oentry->asn_desc != NULL)
386 { /* complex */
387 ret = decode_complex_string(oentry, value, value_size, str);
388 if (ret < 0)
389 return gnutls_assert_val(ret);
391 else
393 ret = _gnutls_x509_decode_string(oentry->etype, value, value_size,
394 str);
395 if (ret < 0)
397 return gnutls_assert_val(ret);
401 return 0;
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)
412 char *res;
413 char escaped[MAX_STRING_LEN];
414 unsigned int size;
415 char* out = _out;
417 if (2 * data_size + 1 > MAX_STRING_LEN)
419 gnutls_assert ();
420 return GNUTLS_E_INTERNAL_ERROR;
423 res = _gnutls_bin2hex (data, data_size, escaped, sizeof (escaped), NULL);
424 if (!res)
426 gnutls_assert ();
427 return GNUTLS_E_INTERNAL_ERROR;
430 size = strlen (res) + 1;
431 if (size + 1 > *sizeof_out)
433 *sizeof_out = size;
434 return GNUTLS_E_SHORT_MEMORY_BUFFER;
436 *sizeof_out = size; /* -1 for the null +1 for the '#' */
438 if (out)
440 out[0] = '#';
441 out[1] = 0;
442 _gnutls_str_cat (out, *sizeof_out, res);
445 return 0;
449 /* TIME functions
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
460 int tm_mon;
461 int tm_year; /* FULL year - ie 1971 */
462 int tm_mday;
463 int tm_hour;
464 int tm_min;
465 int tm_sec;
466 } fake_tm;
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.
488 static time_t
489 mktime_utc (const struct fake_tm *tm)
491 time_t result = 0;
492 int i;
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)
500 return (time_t) - 1;
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))
509 result++;
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;
513 return result;
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.
521 static time_t
522 time2gtime (const char *ttime, int year)
524 char xx[4];
525 struct fake_tm etime;
527 if (strlen (ttime) < 8)
529 gnutls_assert ();
530 return (time_t) - 1;
533 etime.tm_year = year;
535 /* In order to work with 32 bit
536 * time_t.
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)
542 return (time_t) 0;
544 xx[2] = 0;
546 /* get the month
548 memcpy (xx, ttime, 2); /* month */
549 etime.tm_mon = atoi (xx) - 1;
550 ttime += 2;
552 /* get the day
554 memcpy (xx, ttime, 2); /* day */
555 etime.tm_mday = atoi (xx);
556 ttime += 2;
558 /* get the hour
560 memcpy (xx, ttime, 2); /* hour */
561 etime.tm_hour = atoi (xx);
562 ttime += 2;
564 /* get the minutes
566 memcpy (xx, ttime, 2); /* minutes */
567 etime.tm_min = atoi (xx);
568 ttime += 2;
570 if (strlen (ttime) >= 2)
572 memcpy (xx, ttime, 2);
573 etime.tm_sec = atoi (xx);
575 else
576 etime.tm_sec = 0;
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)
588 static time_t
589 utcTime2gtime (const char *ttime)
591 char xx[3];
592 int year;
594 if (strlen (ttime) < 10)
596 gnutls_assert ();
597 return (time_t) - 1;
599 xx[2] = 0;
600 /* get the year
602 memcpy (xx, ttime, 2); /* year */
603 year = atoi (xx);
604 ttime += 2;
606 if (year > 49)
607 year += 1900;
608 else
609 year += 2000;
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)*
618 time_t
619 _gnutls_x509_generalTime2gtime (const char *ttime)
621 char xx[5];
622 int year;
624 if (strlen (ttime) < 12)
626 gnutls_assert ();
627 return (time_t) - 1;
630 if (strchr (ttime, 'Z') == 0)
632 gnutls_assert ();
633 /* sorry we don't support it yet
635 return (time_t) - 1;
637 xx[4] = 0;
639 /* get the year
641 memcpy (xx, ttime, 4); /* year */
642 year = atoi (xx);
643 ttime += 4;
645 return time2gtime (ttime, year);
648 static int
649 gtime2generalTime (time_t gtime, char *str_time, size_t str_time_size)
651 size_t ret;
652 struct tm _tm;
654 if (!gmtime_r (&gtime, &_tm))
656 gnutls_assert ();
657 return GNUTLS_E_INTERNAL_ERROR;
660 ret = strftime (str_time, str_time_size, "%Y%m%d%H%M%SZ", &_tm);
661 if (!ret)
663 gnutls_assert ();
664 return GNUTLS_E_SHORT_MEMORY_BUFFER;
668 return 0;
672 /* Extracts the time in time_t from the ASN1_TYPE given. When should
673 * be something like "tbsCertList.thisUpdate".
675 #define MAX_TIME 64
676 time_t
677 _gnutls_x509_get_time (ASN1_TYPE c2, const char *when, int nochoice)
679 char ttime[MAX_TIME];
680 char name[128];
681 time_t c_time = (time_t) - 1;
682 int len, result;
684 len = sizeof (ttime) - 1;
685 result = asn1_read_value (c2, when, ttime, &len);
686 if (result != ASN1_SUCCESS)
688 gnutls_assert ();
689 return (time_t) (-1);
692 if (nochoice != 0)
694 c_time = _gnutls_x509_generalTime2gtime (ttime);
696 else
698 _gnutls_str_cpy (name, sizeof (name), when);
700 /* choice */
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);
709 else
710 { /* UTCTIME */
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)
723 gnutls_assert ();
724 return (time_t) (-1);
728 return c_time;
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];
738 char name[128];
739 int result, len;
741 if (nochoice != 0)
743 result = gtime2generalTime( tim, str_time, sizeof(str_time));
744 if (result < 0)
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));
752 return 0;
755 _gnutls_str_cpy (name, sizeof (name), where);
757 if ((result = asn1_write_value (c2, name, "generalTime", 1)) < 0)
759 gnutls_assert ();
760 return _gnutls_asn2err (result);
763 result = gtime2generalTime (tim, str_time, sizeof (str_time));
764 if (result < 0)
766 gnutls_assert ();
767 return result;
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)
776 gnutls_assert ();
777 return _gnutls_asn2err (result);
780 return 0;
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)
812 int ret;
813 gnutls_datum_t out;
814 size_t size;
816 ret = _gnutls_x509_export_int_named2 (asn1_data, name,
817 format, pem_header, &out);
818 if (ret < 0)
819 return gnutls_assert_val(ret);
821 if (format == GNUTLS_X509_FMT_PEM)
822 size = out.size+1;
823 else
824 size = out.size;
826 if (*output_data_size < size)
828 *output_data_size = size;
829 ret = gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
830 goto cleanup;
833 *output_data_size = (size_t)out.size;
834 if (output_data)
836 memcpy (output_data, out.data, (size_t)out.size);
837 if (format == GNUTLS_X509_FMT_PEM)
838 output_data[out.size] = 0;
841 ret = 0;
843 cleanup:
844 gnutls_free (out.data);
846 return ret;
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,
856 gnutls_datum_t *out)
858 int ret;
860 if (format == GNUTLS_X509_FMT_DER)
862 ret = _gnutls_x509_der_encode(asn1_data, name, out, 0);
863 if (ret < 0)
864 return gnutls_assert_val(ret);
866 else
867 { /* PEM */
868 gnutls_datum_t tmp;
870 ret = _gnutls_x509_der_encode (asn1_data, name, &tmp, 0);
871 if (ret < 0)
872 return gnutls_assert_val(ret);
874 ret = _gnutls_fbase64_encode (pem_header, tmp.data, tmp.size, out);
875 _gnutls_free_datum (&tmp);
877 if (ret < 0)
878 return gnutls_assert_val(ret);
881 return 0;
884 /* Decodes an octet string. The etype specifies the string type.
885 * The returned string is always null terminated (but null is not
886 * included in size).
889 _gnutls_x509_decode_string (unsigned int etype,
890 const uint8_t * der, size_t der_size,
891 gnutls_datum_t * output)
893 int ret;
894 const uint8_t *str;
895 unsigned int str_size;
896 gnutls_datum_t td;
898 ret = asn1_decode_simple_der (etype, der, der_size, &str, &str_size);
899 if (ret != ASN1_SUCCESS)
901 gnutls_assert ();
902 ret = _gnutls_asn2err (ret);
903 return ret;
906 td.size = str_size;
907 td.data = gnutls_malloc(str_size+1);
908 if (td.data == NULL)
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;
919 ret = 0;
921 else if (ret <= 0)
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);
936 return ret;
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)
950 int len = 0, result;
951 uint8_t *tmp = NULL;
952 unsigned int etype;
954 result = asn1_read_value_type (c, root, NULL, &len, &etype);
955 if (result != ASN1_MEM_ERROR)
957 gnutls_assert ();
958 result = _gnutls_asn2err (result);
959 return result;
962 if (etype == ASN1_ETYPE_BIT_STRING)
964 len /= 8;
965 len++;
968 tmp = gnutls_malloc ((size_t)len+1);
969 if (tmp == NULL)
971 gnutls_assert ();
972 result = GNUTLS_E_MEMORY_ERROR;
973 goto cleanup;
976 result = asn1_read_value (c, root, tmp, &len);
977 if (result != ASN1_SUCCESS)
979 gnutls_assert ();
980 result = _gnutls_asn2err (result);
981 goto cleanup;
984 if (etype == ASN1_ETYPE_BIT_STRING)
986 ret->size = len / 8;
987 if (len % 8 > 0)
988 ret->size++;
990 else ret->size = (unsigned)len;
992 ret->data = tmp;
994 return 0;
996 cleanup:
997 gnutls_free (tmp);
998 return result;
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;
1012 size_t slen;
1013 uint8_t *tmp = NULL;
1014 unsigned rtype;
1016 result = asn1_read_value_type (c, root, NULL, &len, &rtype);
1017 if (result != ASN1_MEM_ERROR)
1019 gnutls_assert ();
1020 result = _gnutls_asn2err (result);
1021 return result;
1024 if (rtype == ASN1_ETYPE_BIT_STRING)
1025 len /= 8;
1027 tmp = gnutls_malloc ((size_t)len+1);
1028 if (tmp == NULL)
1030 gnutls_assert ();
1031 result = GNUTLS_E_MEMORY_ERROR;
1032 goto cleanup;
1035 result = asn1_read_value (c, root, tmp, &len);
1036 if (result != ASN1_SUCCESS)
1038 gnutls_assert ();
1039 result = _gnutls_asn2err (result);
1040 goto cleanup;
1043 if (rtype == ASN1_ETYPE_BIT_STRING)
1044 len /= 8;
1046 /* Extract the STRING.
1048 slen = (size_t)len;
1050 result = _gnutls_x509_decode_string (etype, tmp, slen, ret);
1051 if (result < 0)
1053 gnutls_assert ();
1054 goto cleanup;
1056 gnutls_free(tmp);
1058 return 0;
1060 cleanup:
1061 gnutls_free (tmp);
1062 return result;
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;
1073 int ret;
1075 tl_size = sizeof(tl);
1076 ret = asn1_encode_simple_der (etype, input_data, input_size, tl, &tl_size);
1077 if (ret != ASN1_SUCCESS)
1079 gnutls_assert ();
1080 ret = _gnutls_asn2err (ret);
1081 return 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;
1093 return 0;
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
1098 * an OCTET STRING.
1101 _gnutls_x509_der_encode (ASN1_TYPE src, const char *src_name,
1102 gnutls_datum_t * res, int str)
1104 int size, result;
1105 int asize;
1106 uint8_t *data = NULL;
1107 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
1109 size = 0;
1110 result = asn1_der_coding (src, src_name, NULL, &size, NULL);
1111 if (result != ASN1_MEM_ERROR)
1113 gnutls_assert ();
1114 result = _gnutls_asn2err (result);
1115 goto cleanup;
1118 /* allocate data for the der
1121 if (str)
1122 size += 16; /* for later to include the octet tags */
1123 asize = size;
1125 data = gnutls_malloc ((size_t)size);
1126 if (data == NULL)
1128 gnutls_assert ();
1129 result = GNUTLS_E_MEMORY_ERROR;
1130 goto cleanup;
1133 result = asn1_der_coding (src, src_name, data, &size, NULL);
1134 if (result != ASN1_SUCCESS)
1136 gnutls_assert ();
1137 result = _gnutls_asn2err (result);
1138 goto cleanup;
1141 if (str)
1143 if ((result = asn1_create_element
1144 (_gnutls_get_pkix (), "PKIX1.pkcs-7-Data", &c2)) != ASN1_SUCCESS)
1146 gnutls_assert ();
1147 result = _gnutls_asn2err (result);
1148 goto cleanup;
1151 result = asn1_write_value (c2, "", data, size);
1152 if (result != ASN1_SUCCESS)
1154 gnutls_assert ();
1155 result = _gnutls_asn2err (result);
1156 goto cleanup;
1159 result = asn1_der_coding (c2, "", data, &asize, NULL);
1160 if (result != ASN1_SUCCESS)
1162 gnutls_assert ();
1163 result = _gnutls_asn2err (result);
1164 goto cleanup;
1167 size = asize;
1169 asn1_delete_structure (&c2);
1172 res->data = data;
1173 res->size = (unsigned)size;
1174 return 0;
1176 cleanup:
1177 gnutls_free (data);
1178 asn1_delete_structure (&c2);
1179 return result;
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
1186 * an OCTET STRING.
1189 _gnutls_x509_der_encode_and_copy (ASN1_TYPE src, const char *src_name,
1190 ASN1_TYPE dest, const char *dest_name,
1191 int str)
1193 int result;
1194 gnutls_datum_t encoded;
1196 result = _gnutls_x509_der_encode (src, src_name, &encoded, str);
1198 if (result < 0)
1200 gnutls_assert ();
1201 return result;
1204 /* Write the data.
1206 result = asn1_write_value (dest, dest_name, encoded.data, (int)encoded.size);
1208 _gnutls_free_datum (&encoded);
1210 if (result != ASN1_SUCCESS)
1212 gnutls_assert ();
1213 return _gnutls_asn2err (result);
1216 return 0;
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)
1225 int ret;
1227 /* Write the data.
1229 ret = asn1_write_value (c, root, data->data, data->size);
1230 if (ret != ASN1_SUCCESS)
1232 gnutls_assert ();
1233 return _gnutls_asn2err (ret);
1236 return 0;
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)
1245 int ret;
1246 gnutls_datum_t val = { NULL, 0 };
1248 ret = _gnutls_x509_encode_string(etype, data->data, data->size, &val);
1249 if (ret < 0)
1250 return gnutls_assert_val(ret);
1252 /* Write the data.
1254 ret = asn1_write_value (c, root, val.data, val.size);
1255 if (ret != ASN1_SUCCESS)
1257 gnutls_assert ();
1258 ret = _gnutls_asn2err (ret);
1259 goto cleanup;
1262 ret = 0;
1264 cleanup:
1265 _gnutls_free_datum (&val);
1266 return ret;
1269 void
1270 _asnstr_append_name (char *name, size_t name_size, const char *part1,
1271 const char *part2)
1273 if (part1[0] != 0)
1275 _gnutls_str_cpy (name, name_size, part1);
1276 _gnutls_str_cat (name, name_size, part2);
1278 else
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)
1294 const char *pk;
1295 gnutls_datum_t der = { NULL, 0 };
1296 int result;
1297 char name[128];
1299 pk = _gnutls_x509_pk_to_oid (pk_algorithm);
1300 if (pk == NULL)
1302 gnutls_assert ();
1303 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
1306 /* write the OID
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)
1313 gnutls_assert ();
1314 return _gnutls_asn2err (result);
1317 result = _gnutls_x509_write_pubkey_params (pk_algorithm, params, &der);
1318 if (result < 0)
1320 gnutls_assert ();
1321 return result;
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)
1333 gnutls_assert ();
1334 return _gnutls_asn2err (result);
1337 result = _gnutls_x509_write_pubkey (pk_algorithm, params, &der);
1338 if (result < 0)
1340 gnutls_assert ();
1341 return result;
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)
1353 gnutls_assert ();
1354 return _gnutls_asn2err (result);
1357 return 0;
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)
1368 int ret;
1369 ASN1_TYPE tmp;
1371 ret = asn1_create_element (_gnutls_get_pkix (),
1372 "PKIX1.Certificate", &tmp);
1373 if (ret != ASN1_SUCCESS)
1375 gnutls_assert ();
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)
1384 gnutls_assert ();
1385 ret = _gnutls_asn2err (ret);
1386 goto cleanup;
1389 ret = _gnutls_x509_der_encode(tmp, "tbsCertificate.subjectPublicKeyInfo", der, 0);
1391 cleanup:
1392 asn1_delete_structure (&tmp);
1394 return ret;
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,
1402 unsigned int *bits)
1404 int result;
1405 int algo;
1406 char oid[64];
1407 int len;
1408 gnutls_pk_params_st params;
1409 char name[128];
1411 gnutls_pk_params_init(&params);
1413 _asnstr_append_name (name, sizeof (name), src_name, ".algorithm.algorithm");
1414 len = sizeof (oid);
1415 result = asn1_read_value (src, name, oid, &len);
1417 if (result != ASN1_SUCCESS)
1419 gnutls_assert ();
1420 return _gnutls_asn2err (result);
1423 algo = _gnutls_x509_oid2pk_algorithm (oid);
1424 if (algo == GNUTLS_PK_UNKNOWN)
1426 _gnutls_debug_log
1427 ("%s: unknown public key algorithm: %s\n", __func__, oid);
1430 if (bits == NULL)
1432 return algo;
1435 /* Now read the parameters' bits
1437 result = _gnutls_get_asn_mpis(src, src_name, &params);
1438 if (result < 0)
1439 return gnutls_assert_val(result);
1441 bits[0] = pubkey_to_bits(algo, &params);
1443 gnutls_pk_params_release(&params);
1444 return algo;
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)
1454 gnutls_datum_t der;
1455 int start, end, result;
1457 result = _gnutls_x509_der_encode (src, "", &der, 0);
1458 if (result < 0)
1460 gnutls_assert ();
1461 return result;
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);
1471 gnutls_assert ();
1472 goto cleanup;
1475 result = _gnutls_set_datum (signed_data, &der.data[start], end - start + 1);
1477 if (result < 0)
1479 gnutls_assert ();
1480 goto cleanup;
1483 result = 0;
1485 cleanup:
1486 _gnutls_free_datum (&der);
1488 return result;
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
1501 * error.
1504 _gnutls_x509_get_signature_algorithm (ASN1_TYPE src, const char *src_name)
1506 int result;
1507 gnutls_datum_t sa;
1509 /* Read the signature algorithm. Note that parameters are not
1510 * read. They will be read from the issuer's certificate if needed.
1512 result =
1513 _gnutls_x509_read_value (src, src_name, &sa);
1515 if (result < 0)
1517 gnutls_assert ();
1518 return result;
1521 result = _gnutls_x509_oid2sign_algorithm ( (char*)sa.data);
1523 _gnutls_free_datum (&sa);
1525 return result;
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)
1536 int result, len;
1537 unsigned int bits;
1539 signature->data = NULL;
1540 signature->size = 0;
1542 /* Read the signature
1544 len = 0;
1545 result = asn1_read_value (src, src_name, NULL, &len);
1547 if (result != ASN1_MEM_ERROR)
1549 result = _gnutls_asn2err (result);
1550 gnutls_assert ();
1551 goto cleanup;
1554 bits = len;
1555 if (bits % 8 != 0)
1557 gnutls_assert ();
1558 result = GNUTLS_E_CERTIFICATE_ERROR;
1559 goto cleanup;
1562 len = bits / 8;
1564 signature->data = gnutls_malloc (len);
1565 if (signature->data == NULL)
1567 gnutls_assert ();
1568 result = GNUTLS_E_MEMORY_ERROR;
1569 return result;
1572 /* read the bit string of the signature
1574 bits = len;
1575 result = asn1_read_value (src, src_name, signature->data, (int*)&bits);
1577 if (result != ASN1_SUCCESS)
1579 result = _gnutls_asn2err (result);
1580 gnutls_assert ();
1581 goto cleanup;
1584 signature->size = len;
1586 return 0;
1588 cleanup:
1589 return result;
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 == '?')
1599 return 1;
1601 return 0;
1604 static int write_complex_string(ASN1_TYPE asn_struct, const char* where,
1605 const struct oid_to_string* oentry, const uint8_t *data,
1606 size_t data_size)
1608 char tmp[128];
1609 ASN1_TYPE c2;
1610 int result;
1611 const char *string_type;
1612 unsigned int i;
1614 result = asn1_create_element (_gnutls_get_pkix (), oentry->asn_desc, &c2);
1615 if (result != ASN1_SUCCESS)
1617 gnutls_assert ();
1618 return _gnutls_asn2err (result);
1621 tmp[0] = 0;
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";
1633 break;
1637 /* if the type is a CHOICE then write the
1638 * type we'll use.
1640 result = asn1_write_value (c2, "", string_type, 1);
1641 if (result != ASN1_SUCCESS)
1643 gnutls_assert ();
1644 result = _gnutls_asn2err (result);
1645 goto error;
1648 _gnutls_str_cpy (tmp, sizeof (tmp), string_type);
1650 result = asn1_write_value (c2, tmp, data, data_size);
1651 if (result != ASN1_SUCCESS)
1653 gnutls_assert ();
1654 result = _gnutls_asn2err (result);
1655 goto error;
1658 result = _gnutls_x509_der_encode_and_copy (c2, "", asn_struct, where, 0);
1659 if (result < 0)
1661 gnutls_assert ();
1662 goto error;
1665 result = 0;
1667 error:
1668 asn1_delete_structure (&c2);
1669 return result;
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,
1680 const char *where,
1681 const void *_data,
1682 int data_size, int multi)
1684 const uint8_t *data = _data;
1685 char tmp[128];
1686 int result;
1687 const struct oid_to_string* oentry;
1689 oentry = get_oid_entry(given_oid);
1690 if (oentry == NULL)
1692 gnutls_assert ();
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");
1703 if (multi != 0)
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)
1710 gnutls_assert ();
1711 result = _gnutls_asn2err (result);
1712 goto error;
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);
1721 if (result < 0)
1722 return gnutls_assert_val(result);
1724 else /* write a simple string */
1726 gnutls_datum_t td;
1728 td.data = (void*)data;
1729 td.size = data_size;
1730 result = _gnutls_x509_write_string (asn1_struct, tmp, &td, oentry->etype);
1731 if (result < 0)
1733 gnutls_assert ();
1734 goto error;
1738 /* write the type
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)
1746 gnutls_assert ();
1747 result = _gnutls_asn2err (result);
1748 goto error;
1751 result = 0;
1753 error:
1754 return 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
1759 * after the copy.
1761 * The buffer will always be null terminated.
1763 int _gnutls_strdatum_to_buf (gnutls_datum_t * d, void* buf, size_t * buf_size)
1765 int ret;
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);
1772 goto cleanup;
1774 memcpy(buf, d->data, d->size);
1775 _buf[d->size] = 0;
1777 *buf_size = d->size;
1778 ret = 0;
1780 cleanup:
1781 _gnutls_free_datum(d);
1783 return ret;