File: | lib/x509/dn.c |
Location: | line 181, column 11 |
Description: | Value stored to 'result' is never read |
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 | */ |
39 | static char * |
40 | str_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 | */ |
71 | int |
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); |
Value stored to 'result' is never read | |
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 | |
303 | cleanup: |
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 | */ |
323 | int |
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 | |
486 | cleanup: |
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 | */ |
500 | int |
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 | |
617 | cleanup: |
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 | */ |
625 | int |
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) |
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 | |
745 | error: |
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 | */ |
754 | static 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 | */ |
799 | int |
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 | */ |
851 | int |
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 | **/ |
941 | int |
942 | gnutls_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 | **/ |
975 | int |
976 | gnutls_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 | **/ |
1003 | void |
1004 | gnutls_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 | **/ |
1024 | int |
1025 | gnutls_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 | **/ |
1084 | int |
1085 | gnutls_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 | **/ |
1140 | int |
1141 | gnutls_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 | */ |
1184 | int |
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 | **/ |
1222 | int |
1223 | gnutls_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 | } |