aboutsummaryrefslogtreecommitdiff
path: root/src/daemon/https/x509/dn.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/daemon/https/x509/dn.c')
-rw-r--r--src/daemon/https/x509/dn.c545
1 files changed, 0 insertions, 545 deletions
diff --git a/src/daemon/https/x509/dn.c b/src/daemon/https/x509/dn.c
deleted file mode 100644
index fb4fa57e..00000000
--- a/src/daemon/https/x509/dn.c
+++ /dev/null
@@ -1,545 +0,0 @@
1/*
2 * Copyright (C) 2003, 2004, 2005, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library 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 2.1 of
11 * the License, or (at your option) any later version.
12 *
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.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25#include <gnutls_int.h>
26#include <libtasn1.h>
27#include <gnutls_datum.h>
28#include <gnutls_global.h>
29#include <gnutls_errors.h>
30#include <gnutls_str.h>
31#include <common.h>
32#include <gnutls_num.h>
33#include <dn.h>
34
35/* This file includes all the required to parse an X.509 Distriguished
36 * Name (you need a parser just to read a name in the X.509 protoocols!!!)
37 */
38
39/* Converts the given OID to an ldap acceptable string or
40 * a dotted OID.
41 */
42static const char *
43oid2ldap_string (const char *oid)
44{
45 const char *ret;
46
47 ret = MHD__gnutls_x509_oid2ldap_string (oid);
48 if (ret)
49 return ret;
50
51 /* else return the OID in dotted format */
52 return oid;
53}
54
55/* Escapes a string following the rules from RFC2253.
56 */
57static char *
58str_escape (char *str, char *buffer, unsigned int buffer_size)
59{
60 int str_length, j, i;
61
62 if (str == NULL || buffer == NULL)
63 return NULL;
64
65 str_length = MIN (strlen (str), buffer_size - 1);
66
67 for (i = j = 0; i < str_length; i++)
68 {
69 if (str[i] == ',' || str[i] == '+' || str[i] == '"'
70 || str[i] == '\\' || str[i] == '<' || str[i] == '>'
71 || str[i] == ';')
72 buffer[j++] = '\\';
73
74 buffer[j++] = str[i];
75 }
76
77 /* null terminate the string */
78 buffer[j] = 0;
79
80 return buffer;
81}
82
83/* Parses an X509 DN in the MHD__asn1_struct, and puts the output into
84 * the string buf. The output is an LDAP encoded DN.
85 *
86 * MHD__asn1_rdn_name must be a string in the form "tbsCertificate.issuer.rdnSequence".
87 * That is to point in the rndSequence.
88 */
89int
90MHD__gnutls_x509_parse_dn (ASN1_TYPE MHD__asn1_struct,
91 const char *MHD__asn1_rdn_name, char *buf,
92 size_t * sizeof_buf)
93{
94 MHD_gtls_string out_str;
95 int k2, k1, result;
96 char tmpbuffer1[MAX_NAME_SIZE];
97 char tmpbuffer2[MAX_NAME_SIZE];
98 char tmpbuffer3[MAX_NAME_SIZE];
99 opaque value[MAX_STRING_LEN], *value2 = NULL;
100 char *escaped = NULL;
101 const char *ldap_desc;
102 char oid[128];
103 int len, printable;
104 char *string = NULL;
105 size_t sizeof_string, sizeof_escaped;
106
107 if (sizeof_buf == NULL)
108 {
109 MHD_gnutls_assert ();
110 return GNUTLS_E_INVALID_REQUEST;
111 }
112
113 if (*sizeof_buf > 0 && buf)
114 buf[0] = 0;
115 else
116 *sizeof_buf = 0;
117
118 MHD_gtls_string_init (&out_str, MHD_gnutls_malloc, MHD_gnutls_realloc,
119 MHD_gnutls_free);
120
121 k1 = 0;
122 do
123 {
124
125 k1++;
126 /* create a string like "tbsCertList.issuer.rdnSequence.?1"
127 */
128 if (MHD__asn1_rdn_name[0] != 0)
129 snprintf (tmpbuffer1, sizeof (tmpbuffer1), "%s.?%u",
130 MHD__asn1_rdn_name, k1);
131 else
132 snprintf (tmpbuffer1, sizeof (tmpbuffer1), "?%u", k1);
133
134 len = sizeof (value) - 1;
135 result =
136 MHD__asn1_read_value (MHD__asn1_struct, tmpbuffer1, value, &len);
137
138 if (result == ASN1_ELEMENT_NOT_FOUND)
139 {
140 break;
141 }
142
143 if (result != ASN1_VALUE_NOT_FOUND)
144 {
145 MHD_gnutls_assert ();
146 result = MHD_gtls_asn2err (result);
147 goto cleanup;
148 }
149
150 k2 = 0;
151
152 do
153 { /* Move to the attibute type and values
154 */
155 k2++;
156
157 if (tmpbuffer1[0] != 0)
158 snprintf (tmpbuffer2, sizeof (tmpbuffer2), "%s.?%u", tmpbuffer1,
159 k2);
160 else
161 snprintf (tmpbuffer2, sizeof (tmpbuffer2), "?%u", k2);
162
163 /* Try to read the RelativeDistinguishedName attributes.
164 */
165
166 len = sizeof (value) - 1;
167 result =
168 MHD__asn1_read_value (MHD__asn1_struct, tmpbuffer2, value, &len);
169
170 if (result == ASN1_ELEMENT_NOT_FOUND)
171 break;
172 if (result != ASN1_VALUE_NOT_FOUND)
173 {
174 MHD_gnutls_assert ();
175 result = MHD_gtls_asn2err (result);
176 goto cleanup;
177 }
178
179 /* Read the OID
180 */
181 MHD_gtls_str_cpy (tmpbuffer3, sizeof (tmpbuffer3), tmpbuffer2);
182 MHD_gtls_str_cat (tmpbuffer3, sizeof (tmpbuffer3), ".type");
183
184 len = sizeof (oid) - 1;
185 result =
186 MHD__asn1_read_value (MHD__asn1_struct, tmpbuffer3, oid, &len);
187
188 if (result == ASN1_ELEMENT_NOT_FOUND)
189 break;
190 else if (result != ASN1_SUCCESS)
191 {
192 MHD_gnutls_assert ();
193 result = MHD_gtls_asn2err (result);
194 goto cleanup;
195 }
196
197 /* Read the Value
198 */
199 MHD_gtls_str_cpy (tmpbuffer3, sizeof (tmpbuffer3), tmpbuffer2);
200 MHD_gtls_str_cat (tmpbuffer3, sizeof (tmpbuffer3), ".value");
201
202 len = 0;
203 result =
204 MHD__asn1_read_value (MHD__asn1_struct, tmpbuffer3, NULL, &len);
205
206 value2 = MHD_gnutls_malloc (len);
207 if (value2 == NULL)
208 {
209 MHD_gnutls_assert ();
210 result = GNUTLS_E_MEMORY_ERROR;
211 goto cleanup;
212 }
213
214 result =
215 MHD__asn1_read_value (MHD__asn1_struct, tmpbuffer3, value2, &len);
216
217 if (result != ASN1_SUCCESS)
218 {
219 MHD_gnutls_assert ();
220 result = MHD_gtls_asn2err (result);
221 goto cleanup;
222 }
223#define STR_APPEND(y) if ((result=MHD_gtls_string_append_str( &out_str, y)) < 0) { \
224 MHD_gnutls_assert(); \
225 goto cleanup; \
226}
227 /* The encodings of adjoining RelativeDistinguishedNames are separated
228 * by a comma character (',' ASCII 44).
229 */
230
231 /* Where there is a multi-valued RDN, the outputs from adjoining
232 * AttributeTypeAndValues are separated by a plus ('+' ASCII 43)
233 * character.
234 */
235 if (k1 != 1)
236 { /* the first time do not append a comma */
237 if (k2 != 1)
238 { /* adjoining multi-value RDN */
239 STR_APPEND ("+");
240 }
241 else
242 {
243 STR_APPEND (",");
244 }
245 }
246
247 ldap_desc = oid2ldap_string (oid);
248 printable = MHD__gnutls_x509_oid_data_printable (oid);
249
250 sizeof_escaped = 2 * len + 1;
251
252 escaped = MHD_gnutls_malloc (sizeof_escaped);
253 if (escaped == NULL)
254 {
255 MHD_gnutls_assert ();
256 result = GNUTLS_E_MEMORY_ERROR;
257 goto cleanup;
258 }
259
260 sizeof_string = 2 * len + 2; /* in case it is not printable */
261
262 string = MHD_gnutls_malloc (sizeof_string);
263 if (string == NULL)
264 {
265 MHD_gnutls_assert ();
266 result = GNUTLS_E_MEMORY_ERROR;
267 goto cleanup;
268 }
269
270 STR_APPEND (ldap_desc);
271 STR_APPEND ("=");
272 result = 0;
273
274 if (printable)
275 result =
276 MHD__gnutls_x509_oid_data2string (oid,
277 value2, len,
278 string, &sizeof_string);
279
280 if (!printable || result < 0)
281 result =
282 MHD__gnutls_x509_data2hex ((const unsigned char *) value2, len,
283 (unsigned char *) string,
284 &sizeof_string);
285
286 if (result < 0)
287 {
288 MHD_gnutls_assert ();
289 MHD__gnutls_x509_log
290 ("Found OID: '%s' with value '%s'\n",
291 oid, MHD_gtls_bin2hex (value2, len, escaped,
292 sizeof_escaped));
293 goto cleanup;
294 }
295 STR_APPEND (str_escape (string, escaped, sizeof_escaped));
296 MHD_gnutls_free (string);
297 string = NULL;
298
299 MHD_gnutls_free (escaped);
300 escaped = NULL;
301 MHD_gnutls_free (value2);
302 value2 = NULL;
303
304 }
305 while (1);
306
307 }
308 while (1);
309
310 if (out_str.length >= (unsigned int) *sizeof_buf)
311 {
312 MHD_gnutls_assert ();
313 *sizeof_buf = out_str.length + 1;
314 result = GNUTLS_E_SHORT_MEMORY_BUFFER;
315 goto cleanup;
316 }
317
318 if (buf)
319 {
320 memcpy (buf, out_str.data, out_str.length);
321 buf[out_str.length] = 0;
322 }
323 *sizeof_buf = out_str.length;
324
325 result = 0;
326
327cleanup:
328 MHD_gnutls_free (value2);
329 MHD_gnutls_free (string);
330 MHD_gnutls_free (escaped);
331 MHD_gtls_string_clear (&out_str);
332 return result;
333}
334
335/* Parses an X509 DN in the MHD__asn1_struct, and searches for the
336 * given OID in the DN.
337 *
338 * If raw_flag == 0, the output will be encoded in the LDAP way. (#hex for non printable)
339 * Otherwise the raw DER data are returned.
340 *
341 * MHD__asn1_rdn_name must be a string in the form "tbsCertificate.issuer.rdnSequence".
342 * That is to point in the rndSequence.
343 *
344 * indx specifies which OID to return. Ie 0 means return the first specified
345 * OID found, 1 the second etc.
346 */
347int
348MHD__gnutls_x509_parse_dn_oid (ASN1_TYPE MHD__asn1_struct,
349 const char *MHD__asn1_rdn_name,
350 const char *given_oid, int indx,
351 unsigned int raw_flag,
352 void *buf, size_t * sizeof_buf)
353{
354 int k2, k1, result;
355 char tmpbuffer1[MAX_NAME_SIZE];
356 char tmpbuffer2[MAX_NAME_SIZE];
357 char tmpbuffer3[MAX_NAME_SIZE];
358 opaque value[256];
359 char oid[128];
360 int len, printable;
361 int i = 0;
362 char *cbuf = buf;
363
364 if (cbuf == NULL)
365 *sizeof_buf = 0;
366 else
367 cbuf[0] = 0;
368
369 k1 = 0;
370 do
371 {
372
373 k1++;
374 /* create a string like "tbsCertList.issuer.rdnSequence.?1"
375 */
376 if (MHD__asn1_rdn_name[0] != 0)
377 snprintf (tmpbuffer1, sizeof (tmpbuffer1), "%s.?%u",
378 MHD__asn1_rdn_name, k1);
379 else
380 snprintf (tmpbuffer1, sizeof (tmpbuffer1), "?%u", k1);
381
382 len = sizeof (value) - 1;
383 result =
384 MHD__asn1_read_value (MHD__asn1_struct, tmpbuffer1, value, &len);
385
386 if (result == ASN1_ELEMENT_NOT_FOUND)
387 {
388 MHD_gnutls_assert ();
389 break;
390 }
391
392 if (result != ASN1_VALUE_NOT_FOUND)
393 {
394 MHD_gnutls_assert ();
395 result = MHD_gtls_asn2err (result);
396 goto cleanup;
397 }
398
399 k2 = 0;
400
401 do
402 { /* Move to the attibute type and values
403 */
404 k2++;
405
406 if (tmpbuffer1[0] != 0)
407 snprintf (tmpbuffer2, sizeof (tmpbuffer2), "%s.?%u", tmpbuffer1,
408 k2);
409 else
410 snprintf (tmpbuffer2, sizeof (tmpbuffer2), "?%u", k2);
411
412 /* Try to read the RelativeDistinguishedName attributes.
413 */
414
415 len = sizeof (value) - 1;
416 result =
417 MHD__asn1_read_value (MHD__asn1_struct, tmpbuffer2, value, &len);
418
419 if (result == ASN1_ELEMENT_NOT_FOUND)
420 {
421 break;
422 }
423 if (result != ASN1_VALUE_NOT_FOUND)
424 {
425 MHD_gnutls_assert ();
426 result = MHD_gtls_asn2err (result);
427 goto cleanup;
428 }
429
430 /* Read the OID
431 */
432 MHD_gtls_str_cpy (tmpbuffer3, sizeof (tmpbuffer3), tmpbuffer2);
433 MHD_gtls_str_cat (tmpbuffer3, sizeof (tmpbuffer3), ".type");
434
435 len = sizeof (oid) - 1;
436 result =
437 MHD__asn1_read_value (MHD__asn1_struct, tmpbuffer3, oid, &len);
438
439 if (result == ASN1_ELEMENT_NOT_FOUND)
440 break;
441 else if (result != ASN1_SUCCESS)
442 {
443 MHD_gnutls_assert ();
444 result = MHD_gtls_asn2err (result);
445 goto cleanup;
446 }
447
448 if (strcmp (oid, given_oid) == 0 && indx == i++)
449 { /* Found the OID */
450
451 /* Read the Value
452 */
453 MHD_gtls_str_cpy (tmpbuffer3, sizeof (tmpbuffer3), tmpbuffer2);
454 MHD_gtls_str_cat (tmpbuffer3, sizeof (tmpbuffer3), ".value");
455
456 len = *sizeof_buf;
457 result =
458 MHD__asn1_read_value (MHD__asn1_struct, tmpbuffer3, buf,
459 &len);
460
461 if (result != ASN1_SUCCESS)
462 {
463 MHD_gnutls_assert ();
464 if (result == ASN1_MEM_ERROR)
465 *sizeof_buf = len;
466 result = MHD_gtls_asn2err (result);
467 goto cleanup;
468 }
469
470 if (raw_flag != 0)
471 {
472 if ((unsigned) len > *sizeof_buf)
473 {
474 *sizeof_buf = len;
475 result = GNUTLS_E_SHORT_MEMORY_BUFFER;
476 goto cleanup;
477 }
478 *sizeof_buf = len;
479
480 return 0;
481
482 }
483 else
484 { /* parse data. raw_flag == 0 */
485 printable = MHD__gnutls_x509_oid_data_printable (oid);
486
487 if (printable == 1)
488 result =
489 MHD__gnutls_x509_oid_data2string (oid, buf, len,
490 cbuf, sizeof_buf);
491 else
492 result =
493 MHD__gnutls_x509_data2hex (buf, len,
494 (unsigned char *) cbuf,
495 sizeof_buf);
496
497 if (result < 0)
498 {
499 MHD_gnutls_assert ();
500 goto cleanup;
501 }
502
503 return 0;
504
505 } /* raw_flag == 0 */
506 }
507 }
508 while (1);
509
510 }
511 while (1);
512
513 MHD_gnutls_assert ();
514
515 result = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
516
517cleanup:
518 return result;
519}
520
521/*
522 * Compares the DER encoded part of a DN.
523 *
524 * FIXME: use a real DN comparison algorithm.
525 *
526 * Returns 1 if the DN's match and zero if they don't match. Otherwise
527 * a negative value is returned to indicate error.
528 */
529int
530MHD__gnutls_x509_compare_raw_dn (const MHD_gnutls_datum_t * dn1,
531 const MHD_gnutls_datum_t * dn2)
532{
533
534 if (dn1->size != dn2->size)
535 {
536 MHD_gnutls_assert ();
537 return 0;
538 }
539 if (memcmp (dn1->data, dn2->data, dn2->size) != 0)
540 {
541 MHD_gnutls_assert ();
542 return 0;
543 }
544 return 1; /* they match */
545}