Bug Summary

File:lib/x509/dn.c
Location:line 658, column 8
Description:Although the value stored to 'result' is used in the enclosing expression, the value is never actually read from 'result'

Annotated Source Code

1/*
2 * Copyright (C) 2003-2005, 2007-2010, 2012 Free Software Foundation,
3 * Inc.
4 *
5 * Author: Nikos Mavrogiannopoulos
6 *
7 * This file is part of GnuTLS.
8 *
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 3 of
12 * the License, or (at your option) any later version.
13 *
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.
18 *
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>
21 *
22 */
23
24#include <gnutls_int.h>
25#include <libtasn1.h>
26#include <gnutls_datumgnutls_datum_t.h>
27#include <gnutls_global.h>
28#include <gnutls_errors.h>
29#include <gnutls_str.h>
30#include <common.h>
31#include <gnutls_num.h>
32
33/* This file includes all the required to parse an X.509 Distriguished
34 * Name (you need a parser just to read a name in the X.509 protoocols!!!)
35 */
36
37/* Escapes a string following the rules from RFC4514.
38 */
39static char *
40str_escape (char *str, char *buffer, unsigned int buffer_size)
41{
42 int str_length, j, i;
43
44 if (str == NULL((void*)0) || buffer == NULL((void*)0))
45 return NULL((void*)0);
46
47 str_length = MIN (strlen (str), buffer_size - 1)(((strlen (str))<(buffer_size - 1))?(strlen (str)):(buffer_size
- 1))
;
48
49 for (i = j = 0; i < str_length; i++)
50 {
51 if (str[i] == ',' || str[i] == '+' || str[i] == '"'
52 || str[i] == '\\' || str[i] == '<' || str[i] == '>'
53 || str[i] == ';')
54 buffer[j++] = '\\';
55
56 buffer[j++] = str[i];
57 }
58
59 /* null terminate the string */
60 buffer[j] = 0;
61
62 return buffer;
63}
64
65/* Parses an X509 DN in the asn1_struct, and puts the output into
66 * the string buf. The output is an LDAP encoded DN.
67 *
68 * asn1_rdn_name must be a string in the form "tbsCertificate.issuer.rdnSequence".
69 * That is to point in the rndSequence.
70 */
71int
72_gnutls_x509_parse_dn (ASN1_TYPE asn1_struct,
73 const char *asn1_rdn_name, char *buf,
74 size_t * sizeof_buf)
75{
76 gnutls_buffer_st out_str;
77 int k2, k1, result;
78 char tmpbuffer1[ASN1_MAX_NAME_SIZE128];
79 char tmpbuffer2[ASN1_MAX_NAME_SIZE128];
80 char tmpbuffer3[ASN1_MAX_NAME_SIZE128];
81 opaque value[MAX_STRING_LEN512], *value2 = NULL((void*)0);
82 char *escaped = NULL((void*)0);
83 const char *ldap_desc;
84 char oid[MAX_OID_SIZE128];
85 int len, printable;
86 char *string = NULL((void*)0);
87 size_t sizeof_string, sizeof_escaped;
88
89 if (sizeof_buf == NULL((void*)0))
90 {
91 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "dn.c",91); } while(0);
;
92 return GNUTLS_E_INVALID_REQUEST-50;
93 }
94
95 if (*sizeof_buf > 0 && buf)
96 buf[0] = 0;
97 else
98 *sizeof_buf = 0;
99
100 _gnutls_buffer_init (&out_str);
101
102 k1 = 0;
103 do
104 {
105
106 k1++;
107 /* create a string like "tbsCertList.issuer.rdnSequence.?1"
108 */
109 if (asn1_rdn_name[0] != 0)
110 snprintf (tmpbuffer1, sizeof (tmpbuffer1), "%s.?%u", asn1_rdn_name,
111 k1);
112 else
113 snprintf (tmpbuffer1, sizeof (tmpbuffer1), "?%u", k1);
114
115 len = sizeof (value) - 1;
116 result = asn1_read_value (asn1_struct, tmpbuffer1, value, &len);
117
118 if (result == ASN1_ELEMENT_NOT_FOUND2)
119 {
120 break;
121 }
122
123 if (result != ASN1_VALUE_NOT_FOUND5)
124 {
125 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "dn.c",125); } while(0);
;
126 result = _gnutls_asn2err (result);
127 goto cleanup;
128 }
129
130 k2 = 0;
131
132 do
133 { /* Move to the attibute type and values
134 */
135 k2++;
136
137 if (tmpbuffer1[0] != 0)
138 snprintf (tmpbuffer2, sizeof (tmpbuffer2), "%s.?%u", tmpbuffer1,
139 k2);
140 else
141 snprintf (tmpbuffer2, sizeof (tmpbuffer2), "?%u", k2);
142
143 /* Try to read the RelativeDistinguishedName attributes.
144 */
145
146 len = sizeof (value) - 1;
147 result = asn1_read_value (asn1_struct, tmpbuffer2, value, &len);
148
149 if (result == ASN1_ELEMENT_NOT_FOUND2)
150 break;
151 if (result != ASN1_VALUE_NOT_FOUND5)
152 {
153 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "dn.c",153); } while(0);
;
154 result = _gnutls_asn2err (result);
155 goto cleanup;
156 }
157
158 /* Read the OID
159 */
160 _gnutls_str_cpy (tmpbuffer3, sizeof (tmpbuffer3), tmpbuffer2);
161 _gnutls_str_cat (tmpbuffer3, sizeof (tmpbuffer3), ".type");
162
163 len = sizeof (oid) - 1;
164 result = asn1_read_value (asn1_struct, tmpbuffer3, oid, &len);
165
166 if (result == ASN1_ELEMENT_NOT_FOUND2)
167 break;
168 else if (result != ASN1_SUCCESS0)
169 {
170 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "dn.c",170); } while(0);
;
171 result = _gnutls_asn2err (result);
172 goto cleanup;
173 }
174
175 /* Read the Value
176 */
177 _gnutls_str_cpy (tmpbuffer3, sizeof (tmpbuffer3), tmpbuffer2);
178 _gnutls_str_cat (tmpbuffer3, sizeof (tmpbuffer3), ".value");
179
180 len = 0;
181 result = asn1_read_value (asn1_struct, tmpbuffer3, NULL((void*)0), &len);
182
183 value2 = gnutls_malloc (len);
184 if (value2 == NULL((void*)0))
185 {
186 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "dn.c",186); } while(0);
;
187 result = GNUTLS_E_MEMORY_ERROR-25;
188 goto cleanup;
189 }
190
191 result = asn1_read_value (asn1_struct, tmpbuffer3, value2, &len);
192
193 if (result != ASN1_SUCCESS0)
194 {
195 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "dn.c",195); } while(0);
;
196 result = _gnutls_asn2err (result);
197 goto cleanup;
198 }
199#define STR_APPEND(y)if ((result=_gnutls_buffer_append_str( &out_str, y)) <
0) { do { if (__builtin_expect((_gnutls_log_level >= 2), 0
)) _gnutls_log( 2, "ASSERT: %s:%d\n", "dn.c",199); } while(0)
;; goto cleanup; }
if ((result=_gnutls_buffer_append_str( &out_str, y)) < 0) { \
200 gnutls_assert()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "dn.c",200); } while(0);
; \
201 goto cleanup; \
202}
203 /* The encodings of adjoining RelativeDistinguishedNames are separated
204 * by a comma character (',' ASCII 44).
205 */
206
207 /* Where there is a multi-valued RDN, the outputs from adjoining
208 * AttributeTypeAndValues are separated by a plus ('+' ASCII 43)
209 * character.
210 */
211 if (k1 != 1)
212 { /* the first time do not append a comma */
213 if (k2 != 1)
214 { /* adjoining multi-value RDN */
215 STR_APPEND ("+")if ((result=_gnutls_buffer_append_str( &out_str, "+")) <
0) { do { if (__builtin_expect((_gnutls_log_level >= 2), 0
)) _gnutls_log( 2, "ASSERT: %s:%d\n", "dn.c",215); } while(0)
;; goto cleanup; }
;
216 }
217 else
218 {
219 STR_APPEND (",")if ((result=_gnutls_buffer_append_str( &out_str, ",")) <
0) { do { if (__builtin_expect((_gnutls_log_level >= 2), 0
)) _gnutls_log( 2, "ASSERT: %s:%d\n", "dn.c",219); } while(0)
;; goto cleanup; }
;
220 }
221 }
222
223 ldap_desc = gnutls_x509_dn_oid_name (oid, GNUTLS_X509_DN_OID_RETURN_OID1);
224 printable = _gnutls_x509_oid_data_printable (oid);
225
226 /* leading #, hex encoded value and terminating NULL */
227 sizeof_escaped = 2 * len + 2;
228
229 escaped = gnutls_malloc (sizeof_escaped);
230 if (escaped == NULL((void*)0))
231 {
232 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "dn.c",232); } while(0);
;
233 result = GNUTLS_E_MEMORY_ERROR-25;
234 goto cleanup;
235 }
236
237 sizeof_string = 2 * len + 2; /* in case it is not printable */
238
239 string = gnutls_malloc (sizeof_string);
240 if (string == NULL((void*)0))
241 {
242 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "dn.c",242); } while(0);
;
243 result = GNUTLS_E_MEMORY_ERROR-25;
244 goto cleanup;
245 }
246
247 STR_APPEND (ldap_desc)if ((result=_gnutls_buffer_append_str( &out_str, ldap_desc
)) < 0) { do { if (__builtin_expect((_gnutls_log_level >=
2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n", "dn.c",247); } while
(0);; goto cleanup; }
;
248 STR_APPEND ("=")if ((result=_gnutls_buffer_append_str( &out_str, "=")) <
0) { do { if (__builtin_expect((_gnutls_log_level >= 2), 0
)) _gnutls_log( 2, "ASSERT: %s:%d\n", "dn.c",248); } while(0)
;; goto cleanup; }
;
249 result = 0;
250
251 if (printable)
252 result =
253 _gnutls_x509_oid_data2string (oid,
254 value2, len,
255 string, &sizeof_string);
256
257 if (!printable || result < 0)
258 result =
259 _gnutls_x509_data2hex (value2, len, string, &sizeof_string);
260
261 if (result < 0)
262 {
263 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "dn.c",263); } while(0);
;
264 _gnutls_debug_logdo { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "Found OID: '%s' with value '%s'\n", oid, _gnutls_bin2hex
(value2, len, escaped, sizeof_escaped, ((void*)0))); } while
(0)
265 ("Found OID: '%s' with value '%s'\n",do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "Found OID: '%s' with value '%s'\n", oid, _gnutls_bin2hex
(value2, len, escaped, sizeof_escaped, ((void*)0))); } while
(0)
266 oid, _gnutls_bin2hex (value2, len, escaped, sizeof_escaped,do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "Found OID: '%s' with value '%s'\n", oid, _gnutls_bin2hex
(value2, len, escaped, sizeof_escaped, ((void*)0))); } while
(0)
267 NULL))do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "Found OID: '%s' with value '%s'\n", oid, _gnutls_bin2hex
(value2, len, escaped, sizeof_escaped, ((void*)0))); } while
(0)
;
268 goto cleanup;
269 }
270 STR_APPEND (str_escape (string, escaped, sizeof_escaped))if ((result=_gnutls_buffer_append_str( &out_str, str_escape
(string, escaped, sizeof_escaped))) < 0) { do { if (__builtin_expect
((_gnutls_log_level >= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n"
, "dn.c",270); } while(0);; goto cleanup; }
;
271 gnutls_free (string);
272 string = NULL((void*)0);
273
274 gnutls_free (escaped);
275 escaped = NULL((void*)0);
276 gnutls_free (value2);
277 value2 = NULL((void*)0);
278
279 }
280 while (1);
281
282 }
283 while (1);
284
285 if (out_str.length >= (unsigned int) *sizeof_buf)
286 {
287 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "dn.c",287); } while(0);
;
288 *sizeof_buf = out_str.length + 1;
289 result = GNUTLS_E_SHORT_MEMORY_BUFFER-51;
290 goto cleanup;
291 }
292
293 if (buf)
294 {
295 _gnutls_buffer_pop_data (&out_str, buf, sizeof_buf);
296 buf[*sizeof_buf] = 0;
297 }
298 else
299 *sizeof_buf = out_str.length;
300
301 result = 0;
302
303cleanup:
304 gnutls_free (value2);
305 gnutls_free (string);
306 gnutls_free (escaped);
307 _gnutls_buffer_clear (&out_str);
308 return result;
309}
310
311/* Parses an X509 DN in the asn1_struct, and searches for the
312 * given OID in the DN.
313 *
314 * If raw_flag == 0, the output will be encoded in the LDAP way. (#hex for non printable)
315 * Otherwise the raw DER data are returned.
316 *
317 * asn1_rdn_name must be a string in the form "tbsCertificate.issuer.rdnSequence".
318 * That is to point in the rndSequence.
319 *
320 * indx specifies which OID to return. Ie 0 means return the first specified
321 * OID found, 1 the second etc.
322 */
323int
324_gnutls_x509_parse_dn_oid (ASN1_TYPE asn1_struct,
325 const char *asn1_rdn_name,
326 const char *given_oid, int indx,
327 unsigned int raw_flag,
328 void *buf, size_t * sizeof_buf)
329{
330 int k2, k1, result;
331 char tmpbuffer1[ASN1_MAX_NAME_SIZE128];
332 char tmpbuffer2[ASN1_MAX_NAME_SIZE128];
333 char tmpbuffer3[ASN1_MAX_NAME_SIZE128];
334 opaque value[256];
335 char oid[MAX_OID_SIZE128];
336 int len, printable;
337 int i = 0;
338 char *cbuf = buf;
339
340 if (cbuf == NULL((void*)0))
341 *sizeof_buf = 0;
342 else
343 cbuf[0] = 0;
344
345 k1 = 0;
346 do
347 {
348
349 k1++;
350 /* create a string like "tbsCertList.issuer.rdnSequence.?1"
351 */
352 if (asn1_rdn_name[0] != 0)
353 snprintf (tmpbuffer1, sizeof (tmpbuffer1), "%s.?%u", asn1_rdn_name,
354 k1);
355 else
356 snprintf (tmpbuffer1, sizeof (tmpbuffer1), "?%u", k1);
357
358 len = sizeof (value) - 1;
359 result = asn1_read_value (asn1_struct, tmpbuffer1, value, &len);
360
361 if (result == ASN1_ELEMENT_NOT_FOUND2)
362 {
363 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "dn.c",363); } while(0);
;
364 break;
365 }
366
367 if (result != ASN1_VALUE_NOT_FOUND5)
368 {
369 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "dn.c",369); } while(0);
;
370 result = _gnutls_asn2err (result);
371 goto cleanup;
372 }
373
374 k2 = 0;
375
376 do
377 { /* Move to the attibute type and values
378 */
379 k2++;
380
381 if (tmpbuffer1[0] != 0)
382 snprintf (tmpbuffer2, sizeof (tmpbuffer2), "%s.?%u", tmpbuffer1,
383 k2);
384 else
385 snprintf (tmpbuffer2, sizeof (tmpbuffer2), "?%u", k2);
386
387 /* Try to read the RelativeDistinguishedName attributes.
388 */
389
390 len = sizeof (value) - 1;
391 result = asn1_read_value (asn1_struct, tmpbuffer2, value, &len);
392
393 if (result == ASN1_ELEMENT_NOT_FOUND2)
394 {
395 break;
396 }
397 if (result != ASN1_VALUE_NOT_FOUND5)
398 {
399 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "dn.c",399); } while(0);
;
400 result = _gnutls_asn2err (result);
401 goto cleanup;
402 }
403
404 /* Read the OID
405 */
406 _gnutls_str_cpy (tmpbuffer3, sizeof (tmpbuffer3), tmpbuffer2);
407 _gnutls_str_cat (tmpbuffer3, sizeof (tmpbuffer3), ".type");
408
409 len = sizeof (oid) - 1;
410 result = asn1_read_value (asn1_struct, tmpbuffer3, oid, &len);
411
412 if (result == ASN1_ELEMENT_NOT_FOUND2)
413 break;
414 else if (result != ASN1_SUCCESS0)
415 {
416 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "dn.c",416); } while(0);
;
417 result = _gnutls_asn2err (result);
418 goto cleanup;
419 }
420
421 if (strcmp (oid, given_oid) == 0 && indx == i++)
422 { /* Found the OID */
423
424 /* Read the Value
425 */
426 _gnutls_str_cpy (tmpbuffer3, sizeof (tmpbuffer3), tmpbuffer2);
427 _gnutls_str_cat (tmpbuffer3, sizeof (tmpbuffer3), ".value");
428
429 len = *sizeof_buf;
430 result = asn1_read_value (asn1_struct, tmpbuffer3, buf, &len);
431
432 if (result != ASN1_SUCCESS0)
433 {
434 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "dn.c",434); } while(0);
;
435 if (result == ASN1_MEM_ERROR12)
436 *sizeof_buf = len;
437 result = _gnutls_asn2err (result);
438 goto cleanup;
439 }
440
441 if (raw_flag != 0)
442 {
443 if ((unsigned) len > *sizeof_buf)
444 {
445 *sizeof_buf = len;
446 result = GNUTLS_E_SHORT_MEMORY_BUFFER-51;
447 goto cleanup;
448 }
449 *sizeof_buf = len;
450
451 return 0;
452
453 }
454 else
455 { /* parse data. raw_flag == 0 */
456 printable = _gnutls_x509_oid_data_printable (oid);
457
458 if (printable == 1)
459 result =
460 _gnutls_x509_oid_data2string (oid, buf, len,
461 cbuf, sizeof_buf);
462 else
463 result =
464 _gnutls_x509_data2hex (buf, len, cbuf, sizeof_buf);
465
466 if (result < 0)
467 {
468 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "dn.c",468); } while(0);
;
469 goto cleanup;
470 }
471
472 return 0;
473
474 } /* raw_flag == 0 */
475 }
476 }
477 while (1);
478
479 }
480 while (1);
481
482 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "dn.c",482); } while(0);
;
483
484 result = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE-56;
485
486cleanup:
487 return result;
488}
489
490
491/* Parses an X509 DN in the asn1_struct, and returns the requested
492 * DN OID.
493 *
494 * asn1_rdn_name must be a string in the form "tbsCertificate.issuer.rdnSequence".
495 * That is to point in the rndSequence.
496 *
497 * indx specifies which OID to return. Ie 0 means return the first specified
498 * OID found, 1 the second etc.
499 */
500int
501_gnutls_x509_get_dn_oid (ASN1_TYPE asn1_struct,
502 const char *asn1_rdn_name,
503 int indx, void *_oid, size_t * sizeof_oid)
504{
505 int k2, k1, result;
506 char tmpbuffer1[ASN1_MAX_NAME_SIZE128];
507 char tmpbuffer2[ASN1_MAX_NAME_SIZE128];
508 char tmpbuffer3[ASN1_MAX_NAME_SIZE128];
509 char value[256];
510 char oid[MAX_OID_SIZE128];
511 int len;
512 int i = 0;
513
514 k1 = 0;
515 do
516 {
517
518 k1++;
519 /* create a string like "tbsCertList.issuer.rdnSequence.?1"
520 */
521 if (asn1_rdn_name[0] != 0)
522 snprintf (tmpbuffer1, sizeof (tmpbuffer1), "%s.?%u", asn1_rdn_name,
523 k1);
524 else
525 snprintf (tmpbuffer1, sizeof (tmpbuffer1), "?%u", k1);
526
527 len = sizeof (value) - 1;
528 result = asn1_read_value (asn1_struct, tmpbuffer1, value, &len);
529
530 if (result == ASN1_ELEMENT_NOT_FOUND2)
531 {
532 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "dn.c",532); } while(0);
;
533 break;
534 }
535
536 if (result != ASN1_VALUE_NOT_FOUND5)
537 {
538 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "dn.c",538); } while(0);
;
539 result = _gnutls_asn2err (result);
540 goto cleanup;
541 }
542
543 k2 = 0;
544
545 do
546 { /* Move to the attibute type and values
547 */
548 k2++;
549
550 if (tmpbuffer1[0] != 0)
551 snprintf (tmpbuffer2, sizeof (tmpbuffer2), "%s.?%u", tmpbuffer1,
552 k2);
553 else
554 snprintf (tmpbuffer2, sizeof (tmpbuffer2), "?%u", k2);
555
556 /* Try to read the RelativeDistinguishedName attributes.
557 */
558
559 len = sizeof (value) - 1;
560 result = asn1_read_value (asn1_struct, tmpbuffer2, value, &len);
561
562 if (result == ASN1_ELEMENT_NOT_FOUND2)
563 {
564 break;
565 }
566 if (result != ASN1_VALUE_NOT_FOUND5)
567 {
568 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "dn.c",568); } while(0);
;
569 result = _gnutls_asn2err (result);
570 goto cleanup;
571 }
572
573 /* Read the OID
574 */
575 _gnutls_str_cpy (tmpbuffer3, sizeof (tmpbuffer3), tmpbuffer2);
576 _gnutls_str_cat (tmpbuffer3, sizeof (tmpbuffer3), ".type");
577
578 len = sizeof (oid) - 1;
579 result = asn1_read_value (asn1_struct, tmpbuffer3, oid, &len);
580
581 if (result == ASN1_ELEMENT_NOT_FOUND2)
582 break;
583 else if (result != ASN1_SUCCESS0)
584 {
585 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "dn.c",585); } while(0);
;
586 result = _gnutls_asn2err (result);
587 goto cleanup;
588 }
589
590 if (indx == i++)
591 { /* Found the OID */
592
593 len = strlen (oid) + 1;
594
595 if (*sizeof_oid < (unsigned) len)
596 {
597 *sizeof_oid = len;
598 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "dn.c",598); } while(0);
;
599 return GNUTLS_E_SHORT_MEMORY_BUFFER-51;
600 }
601
602 memcpy (_oid, oid, len);
603 *sizeof_oid = len - 1;
604
605 return 0;
606 }
607 }
608 while (1);
609
610 }
611 while (1);
612
613 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "dn.c",613); } while(0);
;
614
615 result = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE-56;
616
617cleanup:
618 return result;
619}
620
621/* This will encode and write the AttributeTypeAndValue field.
622 * 'multi' must be (0) if writing an AttributeTypeAndValue, and 1 if Attribute.
623 * In all cases only one value is written.
624 */
625int
626_gnutls_x509_encode_and_write_attribute (const char *given_oid,
627 ASN1_TYPE asn1_struct,
628 const char *where,
629 const void *_data,
630 int sizeof_data, int multi)
631{
632 const char *val_name;
633 const opaque *data = _data;
634 char tmp[128];
635 ASN1_TYPE c2;
636 int result;
637
638
639 /* Find how to encode the data.
640 */
641 val_name = _gnutls_x509_oid2asn_string (given_oid);
642 if (val_name == NULL((void*)0))
643 {
644 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "dn.c",644); } while(0);
;
645 _gnutls_debug_log ("Cannot find OID: %s\n", given_oid)do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "Cannot find OID: %s\n", given_oid); } while(0)
;
646 return GNUTLS_E_X509_UNSUPPORTED_OID-205;
647 }
648
649 result = asn1_create_element (_gnutls_get_pkix ()((ASN1_TYPE) _gnutls_pkix1_asn), val_name, &c2);
650 if (result != ASN1_SUCCESS0)
651 {
652 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "dn.c",652); } while(0);
;
653 return _gnutls_asn2err (result);
654 }
655
656 tmp[0] = 0;
657
658 if ((result = _gnutls_x509_oid_data_choice (given_oid)) > 0)
Although the value stored to 'result' is used in the enclosing expression, the value is never actually read from 'result'
659 {
660 const char *string_type;
661 int i;
662
663 string_type = "printableString";
664
665 /* Check if the data is plain ascii, and use
666 * the UTF8 string type if not.
667 */
668 for (i = 0; i < sizeof_data; i++)
669 {
670 if (!isascii (data[i])(((data[i]) & ~0x7f) == 0))
671 {
672 string_type = "utf8String";
673 break;
674 }
675 }
676
677 /* if the type is a CHOICE then write the
678 * type we'll use.
679 */
680 result = asn1_write_value (c2, "", string_type, 1);
681 if (result != ASN1_SUCCESS0)
682 {
683 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "dn.c",683); } while(0);
;
684 result = _gnutls_asn2err (result);
685 goto error;
686 }
687
688 _gnutls_str_cpy (tmp, sizeof (tmp), string_type);
689 }
690
691 result = asn1_write_value (c2, tmp, data, sizeof_data);
692 if (result != ASN1_SUCCESS0)
693 {
694 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "dn.c",694); } while(0);
;
695 result = _gnutls_asn2err (result);
696 goto error;
697 }
698
699
700 /* write the data (value)
701 */
702
703 _gnutls_str_cpy (tmp, sizeof (tmp), where);
704 _gnutls_str_cat (tmp, sizeof (tmp), ".value");
705
706 if (multi != 0)
707 { /* if not writing an AttributeTypeAndValue, but an Attribute */
708 _gnutls_str_cat (tmp, sizeof (tmp), "s"); /* values */
709
710 result = asn1_write_value (asn1_struct, tmp, "NEW", 1);
711 if (result != ASN1_SUCCESS0)
712 {
713 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "dn.c",713); } while(0);
;
714 result = _gnutls_asn2err (result);
715 goto error;
716 }
717
718 _gnutls_str_cat (tmp, sizeof (tmp), ".?LAST");
719
720 }
721
722 result = _gnutls_x509_der_encode_and_copy (c2, "", asn1_struct, tmp, 0);
723 if (result < 0)
724 {
725 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "dn.c",725); } while(0);
;
726 result = _gnutls_asn2err (result);
727 goto error;
728 }
729
730 /* write the type
731 */
732 _gnutls_str_cpy (tmp, sizeof (tmp), where);
733 _gnutls_str_cat (tmp, sizeof (tmp), ".type");
734
735 result = asn1_write_value (asn1_struct, tmp, given_oid, 1);
736 if (result != ASN1_SUCCESS0)
737 {
738 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "dn.c",738); } while(0);
;
739 result = _gnutls_asn2err (result);
740 goto error;
741 }
742
743 result = 0;
744
745error:
746 asn1_delete_structure (&c2);
747 return result;
748}
749
750/* This will write the AttributeTypeAndValue field. The data must be already DER encoded.
751 * 'multi' must be (0) if writing an AttributeTypeAndValue, and 1 if Attribute.
752 * In all cases only one value is written.
753 */
754static int
755_gnutls_x509_write_attribute (const char *given_oid,
756 ASN1_TYPE asn1_struct, const char *where,
757 const void *_data, int sizeof_data)
758{
759 char tmp[128];
760 int result;
761
762 /* write the data (value)
763 */
764
765 _gnutls_str_cpy (tmp, sizeof (tmp), where);
766 _gnutls_str_cat (tmp, sizeof (tmp), ".value");
767
768 result = asn1_write_value (asn1_struct, tmp, _data, sizeof_data);
769 if (result < 0)
770 {
771 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "dn.c",771); } while(0);
;
772 return _gnutls_asn2err (result);
773 }
774
775 /* write the type
776 */
777 _gnutls_str_cpy (tmp, sizeof (tmp), where);
778 _gnutls_str_cat (tmp, sizeof (tmp), ".type");
779
780 result = asn1_write_value (asn1_struct, tmp, given_oid, 1);
781 if (result != ASN1_SUCCESS0)
782 {
783 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "dn.c",783); } while(0);
;
784 return _gnutls_asn2err (result);
785 }
786
787 return 0;
788}
789
790
791/* Decodes an X.509 Attribute (if multi==1) or an AttributeTypeAndValue
792 * otherwise.
793 *
794 * octet_string should be non (0) if we are to decode octet strings after
795 * decoding.
796 *
797 * The output is allocated and stored in value.
798 */
799int
800_gnutls_x509_decode_and_read_attribute (ASN1_TYPE asn1_struct,
801 const char *where, char *oid,
802 int oid_size, gnutls_datum_t * value,
803 int multi, int octet_string)
804{
805 char tmpbuffer[128];
806 int len, result;
807
808 /* Read the OID
809 */
810 _gnutls_str_cpy (tmpbuffer, sizeof (tmpbuffer), where);
811 _gnutls_str_cat (tmpbuffer, sizeof (tmpbuffer), ".type");
812
813 len = oid_size - 1;
814 result = asn1_read_value (asn1_struct, tmpbuffer, oid, &len);
815
816 if (result != ASN1_SUCCESS0)
817 {
818 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "dn.c",818); } while(0);
;
819 result = _gnutls_asn2err (result);
820 return result;
821 }
822
823 /* Read the Value
824 */
825
826 _gnutls_str_cpy (tmpbuffer, sizeof (tmpbuffer), where);
827 _gnutls_str_cat (tmpbuffer, sizeof (tmpbuffer), ".value");
828
829 if (multi)
830 _gnutls_str_cat (tmpbuffer, sizeof (tmpbuffer), "s.?1"); /* .values.?1 */
831
832 result =
833 _gnutls_x509_read_value (asn1_struct, tmpbuffer, value, octet_string);
834 if (result < 0)
835 {
836 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "dn.c",836); } while(0);
;
837 return result;
838 }
839
840 return 0;
841
842}
843
844/* Sets an X509 DN in the asn1_struct, and puts the given OID in the DN.
845 * The input is assumed to be raw data.
846 *
847 * asn1_rdn_name must be a string in the form "tbsCertificate.issuer".
848 * That is to point before the rndSequence.
849 *
850 */
851int
852_gnutls_x509_set_dn_oid (ASN1_TYPE asn1_struct,
853 const char *asn1_name, const char *given_oid,
854 int raw_flag, const char *name, int sizeof_name)
855{
856 int result;
857 char tmp[ASN1_MAX_NAME_SIZE128], asn1_rdn_name[ASN1_MAX_NAME_SIZE128];
858
859 if (sizeof_name == 0 || name == NULL((void*)0))
860 {
861 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "dn.c",861); } while(0);
;
862 return GNUTLS_E_INVALID_REQUEST-50;
863 }
864
865 /* create the rdnSequence
866 */
867 result = asn1_write_value (asn1_struct, asn1_name, "rdnSequence", 1);
868 if (result != ASN1_SUCCESS0)
869 {
870 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "dn.c",870); } while(0);
;
871 return _gnutls_asn2err (result);
872 }
873
874 _gnutls_str_cpy (asn1_rdn_name, sizeof (asn1_rdn_name), asn1_name);
875 _gnutls_str_cat (asn1_rdn_name, sizeof (asn1_rdn_name), ".rdnSequence");
876
877 /* create a new element
878 */
879 result = asn1_write_value (asn1_struct, asn1_rdn_name, "NEW", 1);
880 if (result != ASN1_SUCCESS0)
881 {
882 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "dn.c",882); } while(0);
;
883 return _gnutls_asn2err (result);
884 }
885
886 _gnutls_str_cpy (tmp, sizeof (tmp), asn1_rdn_name);
887 _gnutls_str_cat (tmp, sizeof (tmp), ".?LAST");
888
889 /* create the set with only one element
890 */
891 result = asn1_write_value (asn1_struct, tmp, "NEW", 1);
892 if (result != ASN1_SUCCESS0)
893 {
894 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "dn.c",894); } while(0);
;
895 return _gnutls_asn2err (result);
896 }
897
898
899 /* Encode and write the data
900 */
901 _gnutls_str_cpy (tmp, sizeof (tmp), asn1_rdn_name);
902 _gnutls_str_cat (tmp, sizeof (tmp), ".?LAST.?LAST");
903
904 if (!raw_flag)
905 {
906 result =
907 _gnutls_x509_encode_and_write_attribute (given_oid,
908 asn1_struct,
909 tmp, name, sizeof_name, 0);
910 }
911 else
912 {
913 result =
914 _gnutls_x509_write_attribute (given_oid, asn1_struct,
915 tmp, name, sizeof_name);
916 }
917
918 if (result < 0)
919 {
920 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "dn.c",920); } while(0);
;
921 return result;
922 }
923
924 return 0;
925}
926
927/**
928 * gnutls_x509_dn_init:
929 * @dn: the object to be initialized
930 *
931 * This function initializes a #gnutls_x509_dn_t structure.
932 *
933 * The object returned must be deallocated using
934 * gnutls_x509_dn_deinit().
935 *
936 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
937 * negative error value.
938 *
939 * Since: 2.4.0
940 **/
941int
942gnutls_x509_dn_init (gnutls_x509_dn_t * dn)
943{
944 int result;
945 ASN1_TYPE tmpdn = ASN1_TYPE_EMPTY((void*)0);
946
947 if ((result =
948 asn1_create_element (_gnutls_get_pkix ()((ASN1_TYPE) _gnutls_pkix1_asn),
949 "PKIX1.Name", &tmpdn)) != ASN1_SUCCESS0)
950 {
951 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "dn.c",951); } while(0);
;
952 return _gnutls_asn2err (result);
953 }
954
955 *dn = tmpdn;
956
957 return 0;
958}
959
960/**
961 * gnutls_x509_dn_import:
962 * @dn: the structure that will hold the imported DN
963 * @data: should contain a DER encoded RDN sequence
964 *
965 * This function parses an RDN sequence and stores the result to a
966 * #gnutls_x509_dn_t structure. The structure must have been initialized
967 * with gnutls_x509_dn_init(). You may use gnutls_x509_dn_get_rdn_ava() to
968 * decode the DN.
969 *
970 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
971 * negative error value.
972 *
973 * Since: 2.4.0
974 **/
975int
976gnutls_x509_dn_import (gnutls_x509_dn_t dn, const gnutls_datum_t * data)
977{
978 int result;
979 char err[ASN1_MAX_ERROR_DESCRIPTION_SIZE128];
980
981 result = asn1_der_decoding ((ASN1_TYPE *) & dn,
982 data->data, data->size, err);
983 if (result != ASN1_SUCCESS0)
984 {
985 /* couldn't decode DER */
986 _gnutls_debug_log ("ASN.1 Decoding error: %s\n", err)do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASN.1 Decoding error: %s\n", err); } while(0)
;
987 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "dn.c",987); } while(0);
;
988 return _gnutls_asn2err (result);
989 }
990
991 return 0;
992}
993
994/**
995 * gnutls_x509_dn_deinit:
996 * @dn: a DN opaque object pointer.
997 *
998 * This function deallocates the DN object as returned by
999 * gnutls_x509_dn_import().
1000 *
1001 * Since: 2.4.0
1002 **/
1003void
1004gnutls_x509_dn_deinit (gnutls_x509_dn_t dn)
1005{
1006 asn1_delete_structure ((ASN1_TYPE *) & dn);
1007}
1008
1009/**
1010 * gnutls_x509_rdn_get:
1011 * @idn: should contain a DER encoded RDN sequence
1012 * @buf: a pointer to a structure to hold the peer's name
1013 * @sizeof_buf: holds the size of @buf
1014 *
1015 * This function will return the name of the given RDN sequence. The
1016 * name will be in the form "C=xxxx,O=yyyy,CN=zzzz" as described in
1017 * RFC4514.
1018 *
1019 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, or
1020 * %GNUTLS_E_SHORT_MEMORY_BUFFER is returned and *@sizeof_buf is
1021 * updated if the provided buffer is not long enough, otherwise a
1022 * negative error value.
1023 **/
1024int
1025gnutls_x509_rdn_get (const gnutls_datum_t * idn,
1026 char *buf, size_t * sizeof_buf)
1027{
1028 int result;
1029 ASN1_TYPE dn = ASN1_TYPE_EMPTY((void*)0);
1030
1031 if (sizeof_buf == 0)
1032 {
1033 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "dn.c",1033); } while(0);
;
1034 return GNUTLS_E_INVALID_REQUEST-50;
1035 }
1036
1037 if (buf)
1038 buf[0] = 0;
1039
1040
1041 if ((result =
1042 asn1_create_element (_gnutls_get_pkix ()((ASN1_TYPE) _gnutls_pkix1_asn),
1043 "PKIX1.Name", &dn)) != ASN1_SUCCESS0)
1044 {
1045 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "dn.c",1045); } while(0);
;
1046 return _gnutls_asn2err (result);
1047 }
1048
1049 result = asn1_der_decoding (&dn, idn->data, idn->size, NULL((void*)0));
1050 if (result != ASN1_SUCCESS0)
1051 {
1052 /* couldn't decode DER */
1053 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "dn.c",1053); } while(0);
;
1054 asn1_delete_structure (&dn);
1055 return _gnutls_asn2err (result);
1056 }
1057
1058 result = _gnutls_x509_parse_dn (dn, "rdnSequence", buf, sizeof_buf);
1059
1060 asn1_delete_structure (&dn);
1061 return result;
1062
1063}
1064
1065/**
1066 * gnutls_x509_rdn_get_by_oid:
1067 * @idn: should contain a DER encoded RDN sequence
1068 * @oid: an Object Identifier
1069 * @indx: In case multiple same OIDs exist in the RDN indicates which
1070 * to send. Use 0 for the first one.
1071 * @raw_flag: If non (0) then the raw DER data are returned.
1072 * @buf: a pointer to a structure to hold the peer's name
1073 * @sizeof_buf: holds the size of @buf
1074 *
1075 * This function will return the name of the given Object identifier,
1076 * of the RDN sequence. The name will be encoded using the rules
1077 * from RFC4514.
1078 *
1079 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, or
1080 * %GNUTLS_E_SHORT_MEMORY_BUFFER is returned and *@sizeof_buf is
1081 * updated if the provided buffer is not long enough, otherwise a
1082 * negative error value.
1083 **/
1084int
1085gnutls_x509_rdn_get_by_oid (const gnutls_datum_t * idn, const char *oid,
1086 int indx, unsigned int raw_flag,
1087 void *buf, size_t * sizeof_buf)
1088{
1089 int result;
1090 ASN1_TYPE dn = ASN1_TYPE_EMPTY((void*)0);
1091
1092 if (sizeof_buf == 0)
1093 {
1094 return GNUTLS_E_INVALID_REQUEST-50;
1095 }
1096
1097 if ((result =
1098 asn1_create_element (_gnutls_get_pkix ()((ASN1_TYPE) _gnutls_pkix1_asn),
1099 "PKIX1.Name", &dn)) != ASN1_SUCCESS0)
1100 {
1101 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "dn.c",1101); } while(0);
;
1102 return _gnutls_asn2err (result);
1103 }
1104
1105 result = asn1_der_decoding (&dn, idn->data, idn->size, NULL((void*)0));
1106 if (result != ASN1_SUCCESS0)
1107 {
1108 /* couldn't decode DER */
1109 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "dn.c",1109); } while(0);
;
1110 asn1_delete_structure (&dn);
1111 return _gnutls_asn2err (result);
1112 }
1113
1114 result =
1115 _gnutls_x509_parse_dn_oid (dn, "rdnSequence", oid, indx,
1116 raw_flag, buf, sizeof_buf);
1117
1118 asn1_delete_structure (&dn);
1119 return result;
1120
1121}
1122
1123/**
1124 * gnutls_x509_rdn_get_oid:
1125 * @idn: should contain a DER encoded RDN sequence
1126 * @indx: Indicates which OID to return. Use 0 for the first one.
1127 * @buf: a pointer to a structure to hold the peer's name OID
1128 * @sizeof_buf: holds the size of @buf
1129 *
1130 * This function will return the specified Object identifier, of the
1131 * RDN sequence.
1132 *
1133 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, or
1134 * %GNUTLS_E_SHORT_MEMORY_BUFFER is returned and *@sizeof_buf is
1135 * updated if the provided buffer is not long enough, otherwise a
1136 * negative error value.
1137 *
1138 * Since: 2.4.0
1139 **/
1140int
1141gnutls_x509_rdn_get_oid (const gnutls_datum_t * idn,
1142 int indx, void *buf, size_t * sizeof_buf)
1143{
1144 int result;
1145 ASN1_TYPE dn = ASN1_TYPE_EMPTY((void*)0);
1146
1147 if (sizeof_buf == 0)
1148 {
1149 return GNUTLS_E_INVALID_REQUEST-50;
1150 }
1151
1152 if ((result =
1153 asn1_create_element (_gnutls_get_pkix ()((ASN1_TYPE) _gnutls_pkix1_asn),
1154 "PKIX1.Name", &dn)) != ASN1_SUCCESS0)
1155 {
1156 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "dn.c",1156); } while(0);
;
1157 return _gnutls_asn2err (result);
1158 }
1159
1160 result = asn1_der_decoding (&dn, idn->data, idn->size, NULL((void*)0));
1161 if (result != ASN1_SUCCESS0)
1162 {
1163 /* couldn't decode DER */
1164 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "dn.c",1164); } while(0);
;
1165 asn1_delete_structure (&dn);
1166 return _gnutls_asn2err (result);
1167 }
1168
1169 result = _gnutls_x509_get_dn_oid (dn, "rdnSequence", indx, buf, sizeof_buf);
1170
1171 asn1_delete_structure (&dn);
1172 return result;
1173
1174}
1175
1176/*
1177 * Compares the DER encoded part of a DN.
1178 *
1179 * FIXME: use a real DN comparison algorithm.
1180 *
1181 * Returns 1 if the DN's match and (0) if they don't match. Otherwise
1182 * a negative error code is returned to indicate error.
1183 */
1184int
1185_gnutls_x509_compare_raw_dn (const gnutls_datum_t * dn1,
1186 const gnutls_datum_t * dn2)
1187{
1188
1189 if (dn1->size != dn2->size)
1190 {
1191 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "dn.c",1191); } while(0);
;
1192 return 0;
1193 }
1194 if (memcmp (dn1->data, dn2->data, dn2->size) != 0)
1195 {
1196 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "dn.c",1196); } while(0);
;
1197 return 0;
1198 }
1199 return 1; /* they match */
1200}
1201
1202/**
1203 * gnutls_x509_dn_export:
1204 * @dn: Holds the opaque DN object
1205 * @format: the format of output params. One of PEM or DER.
1206 * @output_data: will contain a DN PEM or DER encoded
1207 * @output_data_size: holds the size of output_data (and will be
1208 * replaced by the actual size of parameters)
1209 *
1210 * This function will export the DN to DER or PEM format.
1211 *
1212 * If the buffer provided is not long enough to hold the output, then
1213 * *@output_data_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER
1214 * will be returned.
1215 *
1216 * If the structure is PEM encoded, it will have a header
1217 * of "BEGIN NAME".
1218 *
1219 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1220 * negative error value.
1221 **/
1222int
1223gnutls_x509_dn_export (gnutls_x509_dn_t dn,
1224 gnutls_x509_crt_fmt_t format, void *output_data,
1225 size_t * output_data_size)
1226{
1227 ASN1_TYPE asn1 = dn;
1228
1229 if (asn1 == NULL((void*)0))
1230 {
1231 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "dn.c",1231); } while(0);
;
1232 return GNUTLS_E_INVALID_REQUEST-50;
1233 }
1234
1235 return _gnutls_x509_export_int_named (asn1, "rdnSequence",
1236 format, "NAME",
1237 output_data, output_data_size);
1238}