2 * Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009, 2010 Free Software
5 * Author: Nikos Mavrogiannopoulos
7 * This file is part of GnuTLS.
9 * The GnuTLS is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 2.1 of
12 * the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
26 #include <gnutls_int.h>
28 #include <gnutls_datum.h>
29 #include <gnutls_global.h>
30 #include <gnutls_errors.h>
31 #include <gnutls_str.h>
33 #include <gnutls_num.h>
35 /* This file includes all the required to parse an X.509 Distriguished
36 * Name (you need a parser just to read a name in the X.509 protoocols!!!)
39 /* Converts the given OID to an ldap acceptable string or
43 oid2ldap_string (const char *oid)
47 ret = _gnutls_x509_oid2ldap_string (oid);
51 /* else return the OID in dotted format */
55 /* Escapes a string following the rules from RFC2253.
58 str_escape (char *str, char *buffer, unsigned int buffer_size)
62 if (str == NULL || buffer == NULL)
65 str_length = MIN (strlen (str), buffer_size - 1);
67 for (i = j = 0; i < str_length; i++)
69 if (str[i] == ',' || str[i] == '+' || str[i] == '"'
70 || str[i] == '\\' || str[i] == '<' || str[i] == '>'
77 /* null terminate the string */
83 /* Parses an X509 DN in the asn1_struct, and puts the output into
84 * the string buf. The output is an LDAP encoded DN.
86 * asn1_rdn_name must be a string in the form "tbsCertificate.issuer.rdnSequence".
87 * That is to point in the rndSequence.
90 _gnutls_x509_parse_dn (ASN1_TYPE asn1_struct,
91 const char *asn1_rdn_name, char *buf,
94 gnutls_buffer_st out_str;
96 char tmpbuffer1[ASN1_MAX_NAME_SIZE];
97 char tmpbuffer2[ASN1_MAX_NAME_SIZE];
98 char tmpbuffer3[ASN1_MAX_NAME_SIZE];
99 opaque value[MAX_STRING_LEN], *value2 = NULL;
100 char *escaped = NULL;
101 const char *ldap_desc;
102 char oid[MAX_OID_SIZE];
105 size_t sizeof_string, sizeof_escaped;
107 if (sizeof_buf == NULL)
110 return GNUTLS_E_INVALID_REQUEST;
113 if (*sizeof_buf > 0 && buf)
118 _gnutls_buffer_init (&out_str);
125 /* create a string like "tbsCertList.issuer.rdnSequence.?1"
127 if (asn1_rdn_name[0] != 0)
128 snprintf (tmpbuffer1, sizeof (tmpbuffer1), "%s.?%u", asn1_rdn_name,
131 snprintf (tmpbuffer1, sizeof (tmpbuffer1), "?%u", k1);
133 len = sizeof (value) - 1;
134 result = asn1_read_value (asn1_struct, tmpbuffer1, value, &len);
136 if (result == ASN1_ELEMENT_NOT_FOUND)
141 if (result != ASN1_VALUE_NOT_FOUND)
144 result = _gnutls_asn2err (result);
151 { /* Move to the attibute type and values
155 if (tmpbuffer1[0] != 0)
156 snprintf (tmpbuffer2, sizeof (tmpbuffer2), "%s.?%u", tmpbuffer1,
159 snprintf (tmpbuffer2, sizeof (tmpbuffer2), "?%u", k2);
161 /* Try to read the RelativeDistinguishedName attributes.
164 len = sizeof (value) - 1;
165 result = asn1_read_value (asn1_struct, tmpbuffer2, value, &len);
167 if (result == ASN1_ELEMENT_NOT_FOUND)
169 if (result != ASN1_VALUE_NOT_FOUND)
172 result = _gnutls_asn2err (result);
178 _gnutls_str_cpy (tmpbuffer3, sizeof (tmpbuffer3), tmpbuffer2);
179 _gnutls_str_cat (tmpbuffer3, sizeof (tmpbuffer3), ".type");
181 len = sizeof (oid) - 1;
182 result = asn1_read_value (asn1_struct, tmpbuffer3, oid, &len);
184 if (result == ASN1_ELEMENT_NOT_FOUND)
186 else if (result != ASN1_SUCCESS)
189 result = _gnutls_asn2err (result);
195 _gnutls_str_cpy (tmpbuffer3, sizeof (tmpbuffer3), tmpbuffer2);
196 _gnutls_str_cat (tmpbuffer3, sizeof (tmpbuffer3), ".value");
199 result = asn1_read_value (asn1_struct, tmpbuffer3, NULL, &len);
201 value2 = gnutls_malloc (len);
205 result = GNUTLS_E_MEMORY_ERROR;
209 result = asn1_read_value (asn1_struct, tmpbuffer3, value2, &len);
211 if (result != ASN1_SUCCESS)
214 result = _gnutls_asn2err (result);
217 #define STR_APPEND(y) if ((result=_gnutls_buffer_append_str( &out_str, y)) < 0) { \
221 /* The encodings of adjoining RelativeDistinguishedNames are separated
222 * by a comma character (',' ASCII 44).
225 /* Where there is a multi-valued RDN, the outputs from adjoining
226 * AttributeTypeAndValues are separated by a plus ('+' ASCII 43)
230 { /* the first time do not append a comma */
232 { /* adjoining multi-value RDN */
241 ldap_desc = oid2ldap_string (oid);
242 printable = _gnutls_x509_oid_data_printable (oid);
244 /* leading #, hex encoded value and terminating NULL */
245 sizeof_escaped = 2 * len + 2;
247 escaped = gnutls_malloc (sizeof_escaped);
251 result = GNUTLS_E_MEMORY_ERROR;
255 sizeof_string = 2 * len + 2; /* in case it is not printable */
257 string = gnutls_malloc (sizeof_string);
261 result = GNUTLS_E_MEMORY_ERROR;
265 STR_APPEND (ldap_desc);
271 _gnutls_x509_oid_data2string (oid,
273 string, &sizeof_string);
275 if (!printable || result < 0)
277 _gnutls_x509_data2hex (value2, len, string, &sizeof_string);
283 ("Found OID: '%s' with value '%s'\n",
284 oid, _gnutls_bin2hex (value2, len, escaped, sizeof_escaped,
288 STR_APPEND (str_escape (string, escaped, sizeof_escaped));
289 gnutls_free (string);
292 gnutls_free (escaped);
294 gnutls_free (value2);
303 if (out_str.length >= (unsigned int) *sizeof_buf)
306 *sizeof_buf = out_str.length + 1;
307 result = GNUTLS_E_SHORT_MEMORY_BUFFER;
313 _gnutls_buffer_pop_data (&out_str, buf, sizeof_buf);
314 buf[*sizeof_buf] = 0;
317 *sizeof_buf = out_str.length;
322 gnutls_free (value2);
323 gnutls_free (string);
324 gnutls_free (escaped);
325 _gnutls_buffer_clear (&out_str);
329 /* Parses an X509 DN in the asn1_struct, and searches for the
330 * given OID in the DN.
332 * If raw_flag == 0, the output will be encoded in the LDAP way. (#hex for non printable)
333 * Otherwise the raw DER data are returned.
335 * asn1_rdn_name must be a string in the form "tbsCertificate.issuer.rdnSequence".
336 * That is to point in the rndSequence.
338 * indx specifies which OID to return. Ie 0 means return the first specified
339 * OID found, 1 the second etc.
342 _gnutls_x509_parse_dn_oid (ASN1_TYPE asn1_struct,
343 const char *asn1_rdn_name,
344 const char *given_oid, int indx,
345 unsigned int raw_flag,
346 void *buf, size_t * sizeof_buf)
349 char tmpbuffer1[ASN1_MAX_NAME_SIZE];
350 char tmpbuffer2[ASN1_MAX_NAME_SIZE];
351 char tmpbuffer3[ASN1_MAX_NAME_SIZE];
353 char oid[MAX_OID_SIZE];
368 /* create a string like "tbsCertList.issuer.rdnSequence.?1"
370 if (asn1_rdn_name[0] != 0)
371 snprintf (tmpbuffer1, sizeof (tmpbuffer1), "%s.?%u", asn1_rdn_name,
374 snprintf (tmpbuffer1, sizeof (tmpbuffer1), "?%u", k1);
376 len = sizeof (value) - 1;
377 result = asn1_read_value (asn1_struct, tmpbuffer1, value, &len);
379 if (result == ASN1_ELEMENT_NOT_FOUND)
385 if (result != ASN1_VALUE_NOT_FOUND)
388 result = _gnutls_asn2err (result);
395 { /* Move to the attibute type and values
399 if (tmpbuffer1[0] != 0)
400 snprintf (tmpbuffer2, sizeof (tmpbuffer2), "%s.?%u", tmpbuffer1,
403 snprintf (tmpbuffer2, sizeof (tmpbuffer2), "?%u", k2);
405 /* Try to read the RelativeDistinguishedName attributes.
408 len = sizeof (value) - 1;
409 result = asn1_read_value (asn1_struct, tmpbuffer2, value, &len);
411 if (result == ASN1_ELEMENT_NOT_FOUND)
415 if (result != ASN1_VALUE_NOT_FOUND)
418 result = _gnutls_asn2err (result);
424 _gnutls_str_cpy (tmpbuffer3, sizeof (tmpbuffer3), tmpbuffer2);
425 _gnutls_str_cat (tmpbuffer3, sizeof (tmpbuffer3), ".type");
427 len = sizeof (oid) - 1;
428 result = asn1_read_value (asn1_struct, tmpbuffer3, oid, &len);
430 if (result == ASN1_ELEMENT_NOT_FOUND)
432 else if (result != ASN1_SUCCESS)
435 result = _gnutls_asn2err (result);
439 if (strcmp (oid, given_oid) == 0 && indx == i++)
440 { /* Found the OID */
444 _gnutls_str_cpy (tmpbuffer3, sizeof (tmpbuffer3), tmpbuffer2);
445 _gnutls_str_cat (tmpbuffer3, sizeof (tmpbuffer3), ".value");
448 result = asn1_read_value (asn1_struct, tmpbuffer3, buf, &len);
450 if (result != ASN1_SUCCESS)
453 if (result == ASN1_MEM_ERROR)
455 result = _gnutls_asn2err (result);
461 if ((unsigned) len > *sizeof_buf)
464 result = GNUTLS_E_SHORT_MEMORY_BUFFER;
473 { /* parse data. raw_flag == 0 */
474 printable = _gnutls_x509_oid_data_printable (oid);
478 _gnutls_x509_oid_data2string (oid, buf, len,
482 _gnutls_x509_data2hex (buf, len, cbuf, sizeof_buf);
492 } /* raw_flag == 0 */
502 result = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
509 /* Parses an X509 DN in the asn1_struct, and returns the requested
512 * asn1_rdn_name must be a string in the form "tbsCertificate.issuer.rdnSequence".
513 * That is to point in the rndSequence.
515 * indx specifies which OID to return. Ie 0 means return the first specified
516 * OID found, 1 the second etc.
519 _gnutls_x509_get_dn_oid (ASN1_TYPE asn1_struct,
520 const char *asn1_rdn_name,
521 int indx, void *_oid, size_t * sizeof_oid)
524 char tmpbuffer1[ASN1_MAX_NAME_SIZE];
525 char tmpbuffer2[ASN1_MAX_NAME_SIZE];
526 char tmpbuffer3[ASN1_MAX_NAME_SIZE];
528 char oid[MAX_OID_SIZE];
537 /* create a string like "tbsCertList.issuer.rdnSequence.?1"
539 if (asn1_rdn_name[0] != 0)
540 snprintf (tmpbuffer1, sizeof (tmpbuffer1), "%s.?%u", asn1_rdn_name,
543 snprintf (tmpbuffer1, sizeof (tmpbuffer1), "?%u", k1);
545 len = sizeof (value) - 1;
546 result = asn1_read_value (asn1_struct, tmpbuffer1, value, &len);
548 if (result == ASN1_ELEMENT_NOT_FOUND)
554 if (result != ASN1_VALUE_NOT_FOUND)
557 result = _gnutls_asn2err (result);
564 { /* Move to the attibute type and values
568 if (tmpbuffer1[0] != 0)
569 snprintf (tmpbuffer2, sizeof (tmpbuffer2), "%s.?%u", tmpbuffer1,
572 snprintf (tmpbuffer2, sizeof (tmpbuffer2), "?%u", k2);
574 /* Try to read the RelativeDistinguishedName attributes.
577 len = sizeof (value) - 1;
578 result = asn1_read_value (asn1_struct, tmpbuffer2, value, &len);
580 if (result == ASN1_ELEMENT_NOT_FOUND)
584 if (result != ASN1_VALUE_NOT_FOUND)
587 result = _gnutls_asn2err (result);
593 _gnutls_str_cpy (tmpbuffer3, sizeof (tmpbuffer3), tmpbuffer2);
594 _gnutls_str_cat (tmpbuffer3, sizeof (tmpbuffer3), ".type");
596 len = sizeof (oid) - 1;
597 result = asn1_read_value (asn1_struct, tmpbuffer3, oid, &len);
599 if (result == ASN1_ELEMENT_NOT_FOUND)
601 else if (result != ASN1_SUCCESS)
604 result = _gnutls_asn2err (result);
609 { /* Found the OID */
611 len = strlen (oid) + 1;
613 if (*sizeof_oid < (unsigned) len)
617 return GNUTLS_E_SHORT_MEMORY_BUFFER;
620 memcpy (_oid, oid, len);
621 *sizeof_oid = len - 1;
633 result = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
639 /* This will encode and write the AttributeTypeAndValue field.
640 * 'multi' must be zero if writing an AttributeTypeAndValue, and 1 if Attribute.
641 * In all cases only one value is written.
644 _gnutls_x509_encode_and_write_attribute (const char *given_oid,
645 ASN1_TYPE asn1_struct,
648 int sizeof_data, int multi)
650 const char *val_name;
651 const opaque *data = _data;
657 /* Find how to encode the data.
659 val_name = _gnutls_x509_oid2asn_string (given_oid);
660 if (val_name == NULL)
663 _gnutls_x509_log ("Cannot find OID: %s\n", given_oid);
664 return GNUTLS_E_X509_UNSUPPORTED_OID;
667 result = asn1_create_element (_gnutls_get_pkix (), val_name, &c2);
668 if (result != ASN1_SUCCESS)
671 return _gnutls_asn2err (result);
676 if ((result = _gnutls_x509_oid_data_choice (given_oid)) > 0)
678 const char *string_type;
681 string_type = "printableString";
683 /* Check if the data is plain ascii, and use
684 * the UTF8 string type if not.
686 for (i = 0; i < sizeof_data; i++)
688 if (!isascii (data[i]))
690 string_type = "utf8String";
695 /* if the type is a CHOICE then write the
698 result = asn1_write_value (c2, "", string_type, 1);
699 if (result != ASN1_SUCCESS)
702 result = _gnutls_asn2err (result);
706 _gnutls_str_cpy (tmp, sizeof (tmp), string_type);
709 result = asn1_write_value (c2, tmp, data, sizeof_data);
710 if (result != ASN1_SUCCESS)
713 result = _gnutls_asn2err (result);
718 /* write the data (value)
721 _gnutls_str_cpy (tmp, sizeof (tmp), where);
722 _gnutls_str_cat (tmp, sizeof (tmp), ".value");
725 { /* if not writing an AttributeTypeAndValue, but an Attribute */
726 _gnutls_str_cat (tmp, sizeof (tmp), "s"); /* values */
728 result = asn1_write_value (asn1_struct, tmp, "NEW", 1);
729 if (result != ASN1_SUCCESS)
732 result = _gnutls_asn2err (result);
736 _gnutls_str_cat (tmp, sizeof (tmp), ".?LAST");
740 result = _gnutls_x509_der_encode_and_copy (c2, "", asn1_struct, tmp, 0);
744 result = _gnutls_asn2err (result);
750 _gnutls_str_cpy (tmp, sizeof (tmp), where);
751 _gnutls_str_cat (tmp, sizeof (tmp), ".type");
753 result = asn1_write_value (asn1_struct, tmp, given_oid, 1);
754 if (result != ASN1_SUCCESS)
757 result = _gnutls_asn2err (result);
764 asn1_delete_structure (&c2);
768 /* This will write the AttributeTypeAndValue field. The data must be already DER encoded.
769 * 'multi' must be zero if writing an AttributeTypeAndValue, and 1 if Attribute.
770 * In all cases only one value is written.
773 _gnutls_x509_write_attribute (const char *given_oid,
774 ASN1_TYPE asn1_struct, const char *where,
775 const void *_data, int sizeof_data)
780 /* write the data (value)
783 _gnutls_str_cpy (tmp, sizeof (tmp), where);
784 _gnutls_str_cat (tmp, sizeof (tmp), ".value");
786 result = asn1_write_value (asn1_struct, tmp, _data, sizeof_data);
790 return _gnutls_asn2err (result);
795 _gnutls_str_cpy (tmp, sizeof (tmp), where);
796 _gnutls_str_cat (tmp, sizeof (tmp), ".type");
798 result = asn1_write_value (asn1_struct, tmp, given_oid, 1);
799 if (result != ASN1_SUCCESS)
802 return _gnutls_asn2err (result);
809 /* Decodes an X.509 Attribute (if multi==1) or an AttributeTypeAndValue
812 * octet_string should be non zero if we are to decode octet strings after
815 * The output is allocated and stored in value.
818 _gnutls_x509_decode_and_read_attribute (ASN1_TYPE asn1_struct,
819 const char *where, char *oid,
820 int oid_size, gnutls_datum_t * value,
821 int multi, int octet_string)
828 _gnutls_str_cpy (tmpbuffer, sizeof (tmpbuffer), where);
829 _gnutls_str_cat (tmpbuffer, sizeof (tmpbuffer), ".type");
832 result = asn1_read_value (asn1_struct, tmpbuffer, oid, &len);
834 if (result != ASN1_SUCCESS)
837 result = _gnutls_asn2err (result);
844 _gnutls_str_cpy (tmpbuffer, sizeof (tmpbuffer), where);
845 _gnutls_str_cat (tmpbuffer, sizeof (tmpbuffer), ".value");
848 _gnutls_str_cat (tmpbuffer, sizeof (tmpbuffer), "s.?1"); /* .values.?1 */
851 _gnutls_x509_read_value (asn1_struct, tmpbuffer, value, octet_string);
862 /* Sets an X509 DN in the asn1_struct, and puts the given OID in the DN.
863 * The input is assumed to be raw data.
865 * asn1_rdn_name must be a string in the form "tbsCertificate.issuer".
866 * That is to point before the rndSequence.
870 _gnutls_x509_set_dn_oid (ASN1_TYPE asn1_struct,
871 const char *asn1_name, const char *given_oid,
872 int raw_flag, const char *name, int sizeof_name)
875 char tmp[ASN1_MAX_NAME_SIZE], asn1_rdn_name[ASN1_MAX_NAME_SIZE];
877 if (sizeof_name == 0 || name == NULL)
880 return GNUTLS_E_INVALID_REQUEST;
883 /* create the rdnSequence
885 result = asn1_write_value (asn1_struct, asn1_name, "rdnSequence", 1);
886 if (result != ASN1_SUCCESS)
889 return _gnutls_asn2err (result);
892 _gnutls_str_cpy (asn1_rdn_name, sizeof (asn1_rdn_name), asn1_name);
893 _gnutls_str_cat (asn1_rdn_name, sizeof (asn1_rdn_name), ".rdnSequence");
895 /* create a new element
897 result = asn1_write_value (asn1_struct, asn1_rdn_name, "NEW", 1);
898 if (result != ASN1_SUCCESS)
901 return _gnutls_asn2err (result);
904 _gnutls_str_cpy (tmp, sizeof (tmp), asn1_rdn_name);
905 _gnutls_str_cat (tmp, sizeof (tmp), ".?LAST");
907 /* create the set with only one element
909 result = asn1_write_value (asn1_struct, tmp, "NEW", 1);
910 if (result != ASN1_SUCCESS)
913 return _gnutls_asn2err (result);
917 /* Encode and write the data
919 _gnutls_str_cpy (tmp, sizeof (tmp), asn1_rdn_name);
920 _gnutls_str_cat (tmp, sizeof (tmp), ".?LAST.?LAST");
925 _gnutls_x509_encode_and_write_attribute (given_oid,
927 tmp, name, sizeof_name, 0);
932 _gnutls_x509_write_attribute (given_oid, asn1_struct,
933 tmp, name, sizeof_name);
946 * gnutls_x509_dn_init:
947 * @dn: the object to be initialized
949 * This function initializes a #gnutls_x509_dn_t structure.
951 * The object returned must be deallocated using
952 * gnutls_x509_dn_deinit().
954 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
955 * negative error value.
960 gnutls_x509_dn_init (gnutls_x509_dn_t * dn)
963 ASN1_TYPE tmpdn = ASN1_TYPE_EMPTY;
966 asn1_create_element (_gnutls_get_pkix (),
967 "PKIX1.Name", &tmpdn)) != ASN1_SUCCESS)
970 return _gnutls_asn2err (result);
979 * gnutls_x509_dn_import:
980 * @dn: the structure that will hold the imported DN
981 * @data: should contain a DER encoded RDN sequence
983 * This function parses an RDN sequence and stores the result to a
984 * #gnutls_x509_dn_t structure. The structure must have been initialized
985 * with gnutls_x509_dn_init(). You may use gnutls_x509_dn_get_rdn_ava() to
988 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
989 * negative error value.
994 gnutls_x509_dn_import (gnutls_x509_dn_t dn, const gnutls_datum_t * data)
997 char err[ASN1_MAX_ERROR_DESCRIPTION_SIZE];
999 result = asn1_der_decoding ((ASN1_TYPE *) & dn,
1000 data->data, data->size, err);
1001 if (result != ASN1_SUCCESS)
1003 /* couldn't decode DER */
1004 _gnutls_x509_log ("ASN.1 Decoding error: %s\n", err);
1006 return _gnutls_asn2err (result);
1013 * gnutls_x509_dn_deinit:
1014 * @dn: a DN opaque object pointer.
1016 * This function deallocates the DN object as returned by
1017 * gnutls_x509_dn_import().
1022 gnutls_x509_dn_deinit (gnutls_x509_dn_t dn)
1024 asn1_delete_structure ((ASN1_TYPE *) & dn);
1028 * gnutls_x509_rdn_get:
1029 * @idn: should contain a DER encoded RDN sequence
1030 * @buf: a pointer to a structure to hold the peer's name
1031 * @sizeof_buf: holds the size of @buf
1033 * This function will return the name of the given RDN sequence. The
1034 * name will be in the form "C=xxxx,O=yyyy,CN=zzzz" as described in
1037 * Returns: On success, %GNUTLS_E_SUCCESS is returned, or
1038 * %GNUTLS_E_SHORT_MEMORY_BUFFER is returned and *@sizeof_buf is
1039 * updated if the provided buffer is not long enough, otherwise a
1040 * negative error value.
1043 gnutls_x509_rdn_get (const gnutls_datum_t * idn,
1044 char *buf, size_t * sizeof_buf)
1047 ASN1_TYPE dn = ASN1_TYPE_EMPTY;
1049 if (sizeof_buf == 0)
1052 return GNUTLS_E_INVALID_REQUEST;
1060 asn1_create_element (_gnutls_get_pkix (),
1061 "PKIX1.Name", &dn)) != ASN1_SUCCESS)
1064 return _gnutls_asn2err (result);
1067 result = asn1_der_decoding (&dn, idn->data, idn->size, NULL);
1068 if (result != ASN1_SUCCESS)
1070 /* couldn't decode DER */
1072 asn1_delete_structure (&dn);
1073 return _gnutls_asn2err (result);
1076 result = _gnutls_x509_parse_dn (dn, "rdnSequence", buf, sizeof_buf);
1078 asn1_delete_structure (&dn);
1084 * gnutls_x509_rdn_get_by_oid:
1085 * @idn: should contain a DER encoded RDN sequence
1086 * @oid: an Object Identifier
1087 * @indx: In case multiple same OIDs exist in the RDN indicates which
1088 * to send. Use 0 for the first one.
1089 * @raw_flag: If non zero then the raw DER data are returned.
1090 * @buf: a pointer to a structure to hold the peer's name
1091 * @sizeof_buf: holds the size of @buf
1093 * This function will return the name of the given Object identifier,
1094 * of the RDN sequence. The name will be encoded using the rules
1097 * Returns: On success, %GNUTLS_E_SUCCESS is returned, or
1098 * %GNUTLS_E_SHORT_MEMORY_BUFFER is returned and *@sizeof_buf is
1099 * updated if the provided buffer is not long enough, otherwise a
1100 * negative error value.
1103 gnutls_x509_rdn_get_by_oid (const gnutls_datum_t * idn, const char *oid,
1104 int indx, unsigned int raw_flag,
1105 void *buf, size_t * sizeof_buf)
1108 ASN1_TYPE dn = ASN1_TYPE_EMPTY;
1110 if (sizeof_buf == 0)
1112 return GNUTLS_E_INVALID_REQUEST;
1116 asn1_create_element (_gnutls_get_pkix (),
1117 "PKIX1.Name", &dn)) != ASN1_SUCCESS)
1120 return _gnutls_asn2err (result);
1123 result = asn1_der_decoding (&dn, idn->data, idn->size, NULL);
1124 if (result != ASN1_SUCCESS)
1126 /* couldn't decode DER */
1128 asn1_delete_structure (&dn);
1129 return _gnutls_asn2err (result);
1133 _gnutls_x509_parse_dn_oid (dn, "rdnSequence", oid, indx,
1134 raw_flag, buf, sizeof_buf);
1136 asn1_delete_structure (&dn);
1142 * gnutls_x509_rdn_get_oid:
1143 * @idn: should contain a DER encoded RDN sequence
1144 * @indx: Indicates which OID to return. Use 0 for the first one.
1145 * @buf: a pointer to a structure to hold the peer's name OID
1146 * @sizeof_buf: holds the size of @buf
1148 * This function will return the specified Object identifier, of the
1151 * Returns: On success, %GNUTLS_E_SUCCESS is returned, or
1152 * %GNUTLS_E_SHORT_MEMORY_BUFFER is returned and *@sizeof_buf is
1153 * updated if the provided buffer is not long enough, otherwise a
1154 * negative error value.
1159 gnutls_x509_rdn_get_oid (const gnutls_datum_t * idn,
1160 int indx, void *buf, size_t * sizeof_buf)
1163 ASN1_TYPE dn = ASN1_TYPE_EMPTY;
1165 if (sizeof_buf == 0)
1167 return GNUTLS_E_INVALID_REQUEST;
1171 asn1_create_element (_gnutls_get_pkix (),
1172 "PKIX1.Name", &dn)) != ASN1_SUCCESS)
1175 return _gnutls_asn2err (result);
1178 result = asn1_der_decoding (&dn, idn->data, idn->size, NULL);
1179 if (result != ASN1_SUCCESS)
1181 /* couldn't decode DER */
1183 asn1_delete_structure (&dn);
1184 return _gnutls_asn2err (result);
1187 result = _gnutls_x509_get_dn_oid (dn, "rdnSequence", indx, buf, sizeof_buf);
1189 asn1_delete_structure (&dn);
1195 * Compares the DER encoded part of a DN.
1197 * FIXME: use a real DN comparison algorithm.
1199 * Returns 1 if the DN's match and zero if they don't match. Otherwise
1200 * a negative value is returned to indicate error.
1203 _gnutls_x509_compare_raw_dn (const gnutls_datum_t * dn1,
1204 const gnutls_datum_t * dn2)
1207 if (dn1->size != dn2->size)
1212 if (memcmp (dn1->data, dn2->data, dn2->size) != 0)
1217 return 1; /* they match */
1221 * gnutls_x509_dn_export:
1222 * @dn: Holds the opaque DN object
1223 * @format: the format of output params. One of PEM or DER.
1224 * @output_data: will contain a DN PEM or DER encoded
1225 * @output_data_size: holds the size of output_data (and will be
1226 * replaced by the actual size of parameters)
1228 * This function will export the DN to DER or PEM format.
1230 * If the buffer provided is not long enough to hold the output, then
1231 * *@output_data_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER
1234 * If the structure is PEM encoded, it will have a header
1237 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
1238 * negative error value.
1241 gnutls_x509_dn_export (gnutls_x509_dn_t dn,
1242 gnutls_x509_crt_fmt_t format, void *output_data,
1243 size_t * output_data_size)
1245 ASN1_TYPE asn1 = dn;
1250 return GNUTLS_E_INVALID_REQUEST;
1253 return _gnutls_x509_export_int_named (asn1, "rdnSequence",
1255 output_data, output_data_size);