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>
30 #include <gnutls_num.h>
32 /* This file includes all the required to parse an X.509 Distriguished
33 * Name (you need a parser just to read a name in the X.509 protoocols!!!)
36 /* Escapes a string following the rules from RFC4514.
39 str_escape (char *str
, char *buffer
, unsigned int buffer_size
)
43 if (str
== NULL
|| buffer
== NULL
)
46 str_length
= MIN (strlen (str
), buffer_size
- 1);
48 for (i
= j
= 0; i
< str_length
; i
++)
50 if (str
[i
] == ',' || str
[i
] == '+' || str
[i
] == '"'
51 || str
[i
] == '\\' || str
[i
] == '<' || str
[i
] == '>'
58 /* null terminate the string */
64 /* Parses an X509 DN in the asn1_struct, and puts the output into
65 * the string buf. The output is an LDAP encoded DN.
67 * asn1_rdn_name must be a string in the form "tbsCertificate.issuer.rdnSequence".
68 * That is to point in the rndSequence.
71 _gnutls_x509_parse_dn (ASN1_TYPE asn1_struct
,
72 const char *asn1_rdn_name
, char *buf
,
75 gnutls_buffer_st out_str
;
77 char tmpbuffer1
[ASN1_MAX_NAME_SIZE
];
78 char tmpbuffer2
[ASN1_MAX_NAME_SIZE
];
79 char tmpbuffer3
[ASN1_MAX_NAME_SIZE
];
80 uint8_t value
[MAX_STRING_LEN
], *value2
= NULL
;
82 const char *ldap_desc
;
83 char oid
[MAX_OID_SIZE
];
86 size_t sizeof_string
, sizeof_escaped
;
88 if (sizeof_buf
== NULL
)
91 return GNUTLS_E_INVALID_REQUEST
;
94 if (*sizeof_buf
> 0 && buf
)
99 _gnutls_buffer_init (&out_str
);
106 /* create a string like "tbsCertList.issuer.rdnSequence.?1"
108 if (asn1_rdn_name
[0] != 0)
109 snprintf (tmpbuffer1
, sizeof (tmpbuffer1
), "%s.?%u", asn1_rdn_name
,
112 snprintf (tmpbuffer1
, sizeof (tmpbuffer1
), "?%u", k1
);
114 len
= sizeof (value
) - 1;
115 result
= asn1_read_value (asn1_struct
, tmpbuffer1
, value
, &len
);
117 if (result
== ASN1_ELEMENT_NOT_FOUND
)
122 if (result
!= ASN1_VALUE_NOT_FOUND
)
125 result
= _gnutls_asn2err (result
);
132 { /* Move to the attibute type and values
136 if (tmpbuffer1
[0] != 0)
137 snprintf (tmpbuffer2
, sizeof (tmpbuffer2
), "%s.?%u", tmpbuffer1
,
140 snprintf (tmpbuffer2
, sizeof (tmpbuffer2
), "?%u", k2
);
142 /* Try to read the RelativeDistinguishedName attributes.
145 len
= sizeof (value
) - 1;
146 result
= asn1_read_value (asn1_struct
, tmpbuffer2
, value
, &len
);
148 if (result
== ASN1_ELEMENT_NOT_FOUND
)
150 if (result
!= ASN1_VALUE_NOT_FOUND
)
153 result
= _gnutls_asn2err (result
);
159 _gnutls_str_cpy (tmpbuffer3
, sizeof (tmpbuffer3
), tmpbuffer2
);
160 _gnutls_str_cat (tmpbuffer3
, sizeof (tmpbuffer3
), ".type");
162 len
= sizeof (oid
) - 1;
163 result
= asn1_read_value (asn1_struct
, tmpbuffer3
, oid
, &len
);
165 if (result
== ASN1_ELEMENT_NOT_FOUND
)
167 else if (result
!= ASN1_SUCCESS
)
170 result
= _gnutls_asn2err (result
);
176 _gnutls_str_cpy (tmpbuffer3
, sizeof (tmpbuffer3
), tmpbuffer2
);
177 _gnutls_str_cat (tmpbuffer3
, sizeof (tmpbuffer3
), ".value");
180 result
= asn1_read_value (asn1_struct
, tmpbuffer3
, NULL
, &len
);
181 if (result
!= ASN1_MEM_ERROR
)
184 result
= _gnutls_asn2err (result
);
188 value2
= gnutls_malloc (len
);
192 result
= GNUTLS_E_MEMORY_ERROR
;
196 result
= asn1_read_value (asn1_struct
, tmpbuffer3
, value2
, &len
);
198 if (result
!= ASN1_SUCCESS
)
201 result
= _gnutls_asn2err (result
);
204 #define STR_APPEND(y) if ((result=_gnutls_buffer_append_str( &out_str, y)) < 0) { \
208 /* The encodings of adjoining RelativeDistinguishedNames are separated
209 * by a comma character (',' ASCII 44).
212 /* Where there is a multi-valued RDN, the outputs from adjoining
213 * AttributeTypeAndValues are separated by a plus ('+' ASCII 43)
217 { /* the first time do not append a comma */
219 { /* adjoining multi-value RDN */
228 ldap_desc
= gnutls_x509_dn_oid_name (oid
, GNUTLS_X509_DN_OID_RETURN_OID
);
229 printable
= _gnutls_x509_oid_data_printable (oid
);
231 /* leading #, hex encoded value and terminating NULL */
232 sizeof_escaped
= 2 * len
+ 2;
234 escaped
= gnutls_malloc (sizeof_escaped
);
238 result
= GNUTLS_E_MEMORY_ERROR
;
242 sizeof_string
= 2 * len
+ 2; /* in case it is not printable */
244 string
= gnutls_malloc (sizeof_string
);
248 result
= GNUTLS_E_MEMORY_ERROR
;
252 STR_APPEND (ldap_desc
);
258 _gnutls_x509_oid_data2string (oid
,
260 string
, &sizeof_string
);
262 if (!printable
|| result
< 0)
264 _gnutls_x509_data2hex (value2
, len
, string
, &sizeof_string
);
270 ("Found OID: '%s' with value '%s'\n",
271 oid
, _gnutls_bin2hex (value2
, len
, escaped
, sizeof_escaped
,
275 STR_APPEND (str_escape (string
, escaped
, sizeof_escaped
));
276 gnutls_free (string
);
279 gnutls_free (escaped
);
281 gnutls_free (value2
);
290 if (out_str
.length
>= (unsigned int) *sizeof_buf
)
293 *sizeof_buf
= out_str
.length
+ 1;
294 result
= GNUTLS_E_SHORT_MEMORY_BUFFER
;
300 _gnutls_buffer_pop_data (&out_str
, buf
, sizeof_buf
);
301 buf
[*sizeof_buf
] = 0;
304 *sizeof_buf
= out_str
.length
;
309 gnutls_free (value2
);
310 gnutls_free (string
);
311 gnutls_free (escaped
);
312 _gnutls_buffer_clear (&out_str
);
316 /* Parses an X509 DN in the asn1_struct, and searches for the
317 * given OID in the DN.
319 * If raw_flag == 0, the output will be encoded in the LDAP way. (#hex for non printable)
320 * Otherwise the raw DER data are returned.
322 * asn1_rdn_name must be a string in the form "tbsCertificate.issuer.rdnSequence".
323 * That is to point in the rndSequence.
325 * indx specifies which OID to return. Ie 0 means return the first specified
326 * OID found, 1 the second etc.
329 _gnutls_x509_parse_dn_oid (ASN1_TYPE asn1_struct
,
330 const char *asn1_rdn_name
,
331 const char *given_oid
, int indx
,
332 unsigned int raw_flag
,
333 void *buf
, size_t * sizeof_buf
)
336 char tmpbuffer1
[ASN1_MAX_NAME_SIZE
];
337 char tmpbuffer2
[ASN1_MAX_NAME_SIZE
];
338 char tmpbuffer3
[ASN1_MAX_NAME_SIZE
];
340 char oid
[MAX_OID_SIZE
];
355 /* create a string like "tbsCertList.issuer.rdnSequence.?1"
357 if (asn1_rdn_name
[0] != 0)
358 snprintf (tmpbuffer1
, sizeof (tmpbuffer1
), "%s.?%u", asn1_rdn_name
,
361 snprintf (tmpbuffer1
, sizeof (tmpbuffer1
), "?%u", k1
);
363 len
= sizeof (value
) - 1;
364 result
= asn1_read_value (asn1_struct
, tmpbuffer1
, value
, &len
);
366 if (result
== ASN1_ELEMENT_NOT_FOUND
)
372 if (result
!= ASN1_VALUE_NOT_FOUND
)
375 result
= _gnutls_asn2err (result
);
382 { /* Move to the attibute type and values
386 if (tmpbuffer1
[0] != 0)
387 snprintf (tmpbuffer2
, sizeof (tmpbuffer2
), "%s.?%u", tmpbuffer1
,
390 snprintf (tmpbuffer2
, sizeof (tmpbuffer2
), "?%u", k2
);
392 /* Try to read the RelativeDistinguishedName attributes.
395 len
= sizeof (value
) - 1;
396 result
= asn1_read_value (asn1_struct
, tmpbuffer2
, value
, &len
);
398 if (result
== ASN1_ELEMENT_NOT_FOUND
)
402 if (result
!= ASN1_VALUE_NOT_FOUND
)
405 result
= _gnutls_asn2err (result
);
411 _gnutls_str_cpy (tmpbuffer3
, sizeof (tmpbuffer3
), tmpbuffer2
);
412 _gnutls_str_cat (tmpbuffer3
, sizeof (tmpbuffer3
), ".type");
414 len
= sizeof (oid
) - 1;
415 result
= asn1_read_value (asn1_struct
, tmpbuffer3
, oid
, &len
);
417 if (result
== ASN1_ELEMENT_NOT_FOUND
)
419 else if (result
!= ASN1_SUCCESS
)
422 result
= _gnutls_asn2err (result
);
426 if (strcmp (oid
, given_oid
) == 0 && indx
== i
++)
427 { /* Found the OID */
431 _gnutls_str_cpy (tmpbuffer3
, sizeof (tmpbuffer3
), tmpbuffer2
);
432 _gnutls_str_cat (tmpbuffer3
, sizeof (tmpbuffer3
), ".value");
435 result
= asn1_read_value (asn1_struct
, tmpbuffer3
, buf
, &len
);
437 if (result
!= ASN1_SUCCESS
)
440 if (result
== ASN1_MEM_ERROR
)
442 result
= _gnutls_asn2err (result
);
448 if ((unsigned) len
> *sizeof_buf
)
451 result
= GNUTLS_E_SHORT_MEMORY_BUFFER
;
460 { /* parse data. raw_flag == 0 */
461 printable
= _gnutls_x509_oid_data_printable (oid
);
465 _gnutls_x509_oid_data2string (oid
, buf
, len
,
469 _gnutls_x509_data2hex (buf
, len
, cbuf
, sizeof_buf
);
479 } /* raw_flag == 0 */
489 result
= GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
496 /* Parses an X509 DN in the asn1_struct, and returns the requested
499 * asn1_rdn_name must be a string in the form "tbsCertificate.issuer.rdnSequence".
500 * That is to point in the rndSequence.
502 * indx specifies which OID to return. Ie 0 means return the first specified
503 * OID found, 1 the second etc.
506 _gnutls_x509_get_dn_oid (ASN1_TYPE asn1_struct
,
507 const char *asn1_rdn_name
,
508 int indx
, void *_oid
, size_t * sizeof_oid
)
511 char tmpbuffer1
[ASN1_MAX_NAME_SIZE
];
512 char tmpbuffer2
[ASN1_MAX_NAME_SIZE
];
513 char tmpbuffer3
[ASN1_MAX_NAME_SIZE
];
515 char oid
[MAX_OID_SIZE
];
524 /* create a string like "tbsCertList.issuer.rdnSequence.?1"
526 if (asn1_rdn_name
[0] != 0)
527 snprintf (tmpbuffer1
, sizeof (tmpbuffer1
), "%s.?%u", asn1_rdn_name
,
530 snprintf (tmpbuffer1
, sizeof (tmpbuffer1
), "?%u", k1
);
532 len
= sizeof (value
) - 1;
533 result
= asn1_read_value (asn1_struct
, tmpbuffer1
, value
, &len
);
535 if (result
== ASN1_ELEMENT_NOT_FOUND
)
541 if (result
!= ASN1_VALUE_NOT_FOUND
)
544 result
= _gnutls_asn2err (result
);
551 { /* Move to the attibute type and values
555 if (tmpbuffer1
[0] != 0)
556 snprintf (tmpbuffer2
, sizeof (tmpbuffer2
), "%s.?%u", tmpbuffer1
,
559 snprintf (tmpbuffer2
, sizeof (tmpbuffer2
), "?%u", k2
);
561 /* Try to read the RelativeDistinguishedName attributes.
564 len
= sizeof (value
) - 1;
565 result
= asn1_read_value (asn1_struct
, tmpbuffer2
, value
, &len
);
567 if (result
== ASN1_ELEMENT_NOT_FOUND
)
571 if (result
!= ASN1_VALUE_NOT_FOUND
)
574 result
= _gnutls_asn2err (result
);
580 _gnutls_str_cpy (tmpbuffer3
, sizeof (tmpbuffer3
), tmpbuffer2
);
581 _gnutls_str_cat (tmpbuffer3
, sizeof (tmpbuffer3
), ".type");
583 len
= sizeof (oid
) - 1;
584 result
= asn1_read_value (asn1_struct
, tmpbuffer3
, oid
, &len
);
586 if (result
== ASN1_ELEMENT_NOT_FOUND
)
588 else if (result
!= ASN1_SUCCESS
)
591 result
= _gnutls_asn2err (result
);
596 { /* Found the OID */
598 len
= strlen (oid
) + 1;
600 if (*sizeof_oid
< (unsigned) len
)
604 return GNUTLS_E_SHORT_MEMORY_BUFFER
;
607 memcpy (_oid
, oid
, len
);
608 *sizeof_oid
= len
- 1;
620 result
= GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
626 static int is_printable(char p
)
628 if ((p
>= 'a' && p
<= 'z') || (p
>= 'A' && p
<= 'Z') ||
629 (p
>= '0' && p
<= '9') || p
== ' ' || p
== '(' || p
== ')' ||
630 p
== '(' || p
== '+' || p
== ',' || p
== '-' || p
== '.' ||
631 p
== '/' || p
== ':' || p
== '=' || p
== '?')
637 /* This will encode and write the AttributeTypeAndValue field.
638 * 'multi' must be (0) if writing an AttributeTypeAndValue, and 1 if Attribute.
639 * In all cases only one value is written.
642 _gnutls_x509_encode_and_write_attribute (const char *given_oid
,
643 ASN1_TYPE asn1_struct
,
646 int sizeof_data
, int multi
)
648 const char *val_name
;
649 const uint8_t *data
= _data
;
655 /* Find how to encode the data.
657 val_name
= _gnutls_x509_oid2asn_string (given_oid
);
658 if (val_name
== NULL
)
661 _gnutls_debug_log ("Cannot find OID: %s\n", given_oid
);
662 return GNUTLS_E_X509_UNSUPPORTED_OID
;
665 result
= asn1_create_element (_gnutls_get_pkix (), val_name
, &c2
);
666 if (result
!= ASN1_SUCCESS
)
669 return _gnutls_asn2err (result
);
674 if ((result
= _gnutls_x509_oid_data_choice (given_oid
)) > 0)
676 const char *string_type
;
679 string_type
= "printableString";
681 /* Check if the data is ASN.1 printable, and use
682 * the UTF8 string type if not.
684 for (i
= 0; i
< sizeof_data
; i
++)
686 if (!is_printable (data
[i
]))
688 string_type
= "utf8String";
693 /* if the type is a CHOICE then write the
696 result
= asn1_write_value (c2
, "", string_type
, 1);
697 if (result
!= ASN1_SUCCESS
)
700 result
= _gnutls_asn2err (result
);
704 _gnutls_str_cpy (tmp
, sizeof (tmp
), string_type
);
707 result
= asn1_write_value (c2
, tmp
, data
, sizeof_data
);
708 if (result
!= ASN1_SUCCESS
)
711 result
= _gnutls_asn2err (result
);
716 /* write the data (value)
719 _gnutls_str_cpy (tmp
, sizeof (tmp
), where
);
720 _gnutls_str_cat (tmp
, sizeof (tmp
), ".value");
723 { /* if not writing an AttributeTypeAndValue, but an Attribute */
724 _gnutls_str_cat (tmp
, sizeof (tmp
), "s"); /* values */
726 result
= asn1_write_value (asn1_struct
, tmp
, "NEW", 1);
727 if (result
!= ASN1_SUCCESS
)
730 result
= _gnutls_asn2err (result
);
734 _gnutls_str_cat (tmp
, sizeof (tmp
), ".?LAST");
738 result
= _gnutls_x509_der_encode_and_copy (c2
, "", asn1_struct
, tmp
, 0);
742 result
= _gnutls_asn2err (result
);
748 _gnutls_str_cpy (tmp
, sizeof (tmp
), where
);
749 _gnutls_str_cat (tmp
, sizeof (tmp
), ".type");
751 result
= asn1_write_value (asn1_struct
, tmp
, given_oid
, 1);
752 if (result
!= ASN1_SUCCESS
)
755 result
= _gnutls_asn2err (result
);
762 asn1_delete_structure (&c2
);
766 /* This will write the AttributeTypeAndValue field. The data must be already DER encoded.
767 * 'multi' must be (0) if writing an AttributeTypeAndValue, and 1 if Attribute.
768 * In all cases only one value is written.
771 _gnutls_x509_write_attribute (const char *given_oid
,
772 ASN1_TYPE asn1_struct
, const char *where
,
773 const void *_data
, int sizeof_data
)
778 /* write the data (value)
781 _gnutls_str_cpy (tmp
, sizeof (tmp
), where
);
782 _gnutls_str_cat (tmp
, sizeof (tmp
), ".value");
784 result
= asn1_write_value (asn1_struct
, tmp
, _data
, sizeof_data
);
788 return _gnutls_asn2err (result
);
793 _gnutls_str_cpy (tmp
, sizeof (tmp
), where
);
794 _gnutls_str_cat (tmp
, sizeof (tmp
), ".type");
796 result
= asn1_write_value (asn1_struct
, tmp
, given_oid
, 1);
797 if (result
!= ASN1_SUCCESS
)
800 return _gnutls_asn2err (result
);
807 /* Decodes an X.509 Attribute (if multi==1) or an AttributeTypeAndValue
810 * octet_string should be non-zero if we are to decode octet strings after
813 * The output is allocated and stored in value.
816 _gnutls_x509_decode_and_read_attribute (ASN1_TYPE asn1_struct
,
817 const char *where
, char *oid
,
818 int oid_size
, gnutls_datum_t
* value
,
819 int multi
, int octet_string
)
826 _gnutls_str_cpy (tmpbuffer
, sizeof (tmpbuffer
), where
);
827 _gnutls_str_cat (tmpbuffer
, sizeof (tmpbuffer
), ".type");
830 result
= asn1_read_value (asn1_struct
, tmpbuffer
, oid
, &len
);
832 if (result
!= ASN1_SUCCESS
)
835 result
= _gnutls_asn2err (result
);
842 _gnutls_str_cpy (tmpbuffer
, sizeof (tmpbuffer
), where
);
843 _gnutls_str_cat (tmpbuffer
, sizeof (tmpbuffer
), ".value");
846 _gnutls_str_cat (tmpbuffer
, sizeof (tmpbuffer
), "s.?1"); /* .values.?1 */
849 result
= _gnutls_x509_read_string (asn1_struct
, tmpbuffer
, value
, RV_OCTET_STRING
);
851 result
= _gnutls_x509_read_value (asn1_struct
, tmpbuffer
, value
);
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 (0) 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 (0) 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_debug_log ("ASN.1 Decoding error: %s\n", err
);
1006 return _gnutls_asn2err (result
);
1013 * gnutls_x509_dn_deinit:
1014 * @dn: a DN uint8_t 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 (0) 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 (0) 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 (0) 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 (0) if they don't match. Otherwise
1200 * a negative error code 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 uint8_t 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 (0) 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
);
1259 * gnutls_x509_dn_export2:
1260 * @dn: Holds the uint8_t DN object
1261 * @format: the format of output params. One of PEM or DER.
1262 * @out: will contain a DN PEM or DER encoded
1264 * This function will export the DN to DER or PEM format.
1266 * The output buffer is allocated using gnutls_malloc().
1268 * If the structure is PEM encoded, it will have a header
1271 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1272 * negative error value.
1275 gnutls_x509_dn_export2 (gnutls_x509_dn_t dn
,
1276 gnutls_x509_crt_fmt_t format
, gnutls_datum_t
*out
)
1278 ASN1_TYPE asn1
= dn
;
1283 return GNUTLS_E_INVALID_REQUEST
;
1286 return _gnutls_x509_export_int_named2 (asn1
, "rdnSequence",
1287 format
, "NAME", out
);