aboutsummaryrefslogtreecommitdiff
path: root/src/daemon/https/x509/common.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/daemon/https/x509/common.c')
-rw-r--r--src/daemon/https/x509/common.c686
1 files changed, 0 insertions, 686 deletions
diff --git a/src/daemon/https/x509/common.c b/src/daemon/https/x509/common.c
index 2dabe3e9..9134597e 100644
--- a/src/daemon/https/x509/common.c
+++ b/src/daemon/https/x509/common.c
@@ -35,692 +35,6 @@
35#include <mpi.h> 35#include <mpi.h>
36#include <time.h> 36#include <time.h>
37 37
38typedef struct _oid2string
39{
40 const char *oid;
41 const char *ldap_desc;
42 int choice; /* of type DirectoryString */
43 int printable;
44} oid2string;
45
46/* This list contains all the OIDs that may be
47 * contained in a rdnSequence and are printable.
48 */
49static const oid2string _oid2str[] = {
50 /* PKIX
51 */
52 {"1.3.6.1.5.5.7.9.1",
53 "dateOfBirth",
54 0,
55 1},
56 {"1.3.6.1.5.5.7.9.2",
57 "placeOfBirth",
58 0,
59 1},
60 {"1.3.6.1.5.5.7.9.3",
61 "gender",
62 0,
63 1},
64 {"1.3.6.1.5.5.7.9.4",
65 "countryOfCitizenship",
66 0,
67 1},
68 {"1.3.6.1.5.5.7.9.5",
69 "countryOfResidence",
70 0,
71 1},
72
73 {"2.5.4.6",
74 "C",
75 0,
76 1},
77 {"2.5.4.9",
78 "STREET",
79 1,
80 1},
81 {"2.5.4.12",
82 "T",
83 1,
84 1},
85 {"2.5.4.10",
86 "O",
87 1,
88 1},
89 {"2.5.4.11",
90 "OU",
91 1,
92 1},
93 {"2.5.4.3",
94 "CN",
95 1,
96 1},
97 {"2.5.4.7",
98 "L",
99 1,
100 1},
101 {"2.5.4.8",
102 "ST",
103 1,
104 1},
105
106 {"2.5.4.5",
107 "serialNumber",
108 0,
109 1},
110 {"2.5.4.20",
111 "telephoneNumber",
112 0,
113 1},
114 {"2.5.4.4",
115 "surName",
116 1,
117 1},
118 {"2.5.4.43",
119 "initials",
120 1,
121 1},
122 {"2.5.4.44",
123 "generationQualifier",
124 1,
125 1},
126 {"2.5.4.42",
127 "givenName",
128 1,
129 1},
130 {"2.5.4.65",
131 "pseudonym",
132 1,
133 1},
134 {"2.5.4.46",
135 "dnQualifier",
136 0,
137 1},
138
139 {"0.9.2342.19200300.100.1.25",
140 "DC",
141 0,
142 1},
143 {"0.9.2342.19200300.100.1.1",
144 "UID",
145 1,
146 1},
147
148 /* PKCS #9
149 */
150 {"1.2.840.113549.1.9.1",
151 "EMAIL",
152 0,
153 1},
154 {"1.2.840.113549.1.9.7",
155 NULL,
156 1,
157 1},
158
159 /* friendly name */
160 {"1.2.840.113549.1.9.20",
161 NULL,
162 0,
163 1},
164 {NULL,
165 NULL,
166 0,
167 0}
168};
169
170/* Returns 1 if the data defined by the OID are printable.
171 */
172int
173MHD__gnutls_x509_oid_data_printable (const char *oid)
174{
175 int i = 0;
176
177 do
178 {
179 if (strcmp (_oid2str[i].oid, oid) == 0)
180 return _oid2str[i].printable;
181 i++;
182 }
183 while (_oid2str[i].oid != NULL);
184
185 return 0;
186}
187
188/**
189 * MHD_gnutls_x509_dn_oid_known - This function will return true if the given OID is known
190 * @oid: holds an Object Identifier in a null terminated string
191 *
192 * This function will inform about known DN OIDs. This is useful since functions
193 * like MHD_gnutls_x509_crt_set_dn_by_oid() use the information on known
194 * OIDs to properly encode their input. Object Identifiers that are not
195 * known are not encoded by these functions, and their input is stored directly
196 * into the ASN.1 structure. In that case of unknown OIDs, you have
197 * the responsibility of DER encoding your data.
198 *
199 * Returns 1 on known OIDs and 0 otherwise.
200 *
201 **/
202int
203MHD_gnutls_x509_dn_oid_known (const char *oid)
204{
205 int i = 0;
206
207 do
208 {
209 if (strcmp (_oid2str[i].oid, oid) == 0)
210 return 1;
211 i++;
212 }
213 while (_oid2str[i].oid != NULL);
214
215 return 0;
216}
217
218/* Returns 1 if the data defined by the OID are of a choice
219 * type.
220 */
221static int
222MHD__gnutls_x509_oid_data_choice (const char *oid)
223{
224 int i = 0;
225
226 do
227 {
228 if (strcmp (_oid2str[i].oid, oid) == 0)
229 return _oid2str[i].choice;
230 i++;
231 }
232 while (_oid2str[i].oid != NULL);
233
234 return 0;
235}
236
237const char *
238MHD__gnutls_x509_oid2ldap_string (const char *oid)
239{
240 int i = 0;
241
242 do
243 {
244 if (strcmp (_oid2str[i].oid, oid) == 0)
245 return _oid2str[i].ldap_desc;
246 i++;
247 }
248 while (_oid2str[i].oid != NULL);
249
250 return NULL;
251}
252
253/* This function will convert an attribute value, specified by the OID,
254 * to a string. The result will be a null terminated string.
255 *
256 * res may be null. This will just return the res_size, needed to
257 * hold the string.
258 */
259int
260MHD__gnutls_x509_oid_data2string (const char *oid,
261 void *value,
262 int value_size, char *res,
263 size_t * res_size)
264{
265 char str[MAX_STRING_LEN], tmpname[128];
266 const char *ANAME = NULL;
267 int CHOICE = -1, len = -1, result;
268 ASN1_TYPE tmpasn = ASN1_TYPE_EMPTY;
269 char MHD__asn1_err[MAX_ERROR_DESCRIPTION_SIZE] = "";
270
271 if (value == NULL || value_size <= 0 || res_size == NULL)
272 {
273 MHD_gnutls_assert ();
274 return GNUTLS_E_INVALID_REQUEST;
275 }
276
277 if (MHD__gnutls_x509_oid_data_printable (oid) == 0)
278 {
279 MHD_gnutls_assert ();
280 return GNUTLS_E_INTERNAL_ERROR;
281 }
282
283 ANAME = MHD__asn1_find_structure_from_oid (MHD__gnutls_get_pkix (), oid);
284 CHOICE = MHD__gnutls_x509_oid_data_choice (oid);
285
286 if (ANAME == NULL)
287 {
288 MHD_gnutls_assert ();
289 return GNUTLS_E_INTERNAL_ERROR;
290 }
291
292 MHD_gtls_str_cpy (str, sizeof (str), "PKIX1.");
293 MHD_gtls_str_cat (str, sizeof (str), ANAME);
294
295 if ((result = MHD__asn1_create_element (MHD__gnutls_get_pkix (), str,
296 &tmpasn)) != ASN1_SUCCESS)
297 {
298 MHD_gnutls_assert ();
299 return MHD_gtls_asn2err (result);
300 }
301
302 if ((result =
303 MHD__asn1_der_decoding (&tmpasn, value, value_size,
304 MHD__asn1_err)) != ASN1_SUCCESS)
305 {
306 MHD_gnutls_assert ();
307 MHD__gnutls_x509_log ("MHD__asn1_der_decoding: %s:%s\n", str,
308 MHD__asn1_err);
309 MHD__asn1_delete_structure (&tmpasn);
310 return MHD_gtls_asn2err (result);
311 }
312
313 /* If this is a choice then we read the choice. Otherwise it
314 * is the value;
315 */
316 len = sizeof (str) - 1;
317 if ((result = MHD__asn1_read_value (tmpasn, "", str, &len)) != ASN1_SUCCESS)
318 { /* CHOICE */
319 MHD_gnutls_assert ();
320 MHD__asn1_delete_structure (&tmpasn);
321 return MHD_gtls_asn2err (result);
322 }
323
324 if (CHOICE == 0)
325 {
326 str[len] = 0;
327
328 if (res)
329 MHD_gtls_str_cpy (res, *res_size, str);
330 *res_size = len;
331
332 MHD__asn1_delete_structure (&tmpasn);
333 }
334 else
335 { /* CHOICE */
336 int non_printable = 0, teletex = 0;
337 str[len] = 0;
338
339 /* Note that we do not support strings other than
340 * UTF-8 (thus ASCII as well).
341 */
342 if (strcmp (str, "printableString") != 0
343 && strcmp (str, "ia5String") != 0
344 && strcmp (str, "utf8String") != 0)
345 {
346 non_printable = 1;
347 }
348 if (strcmp (str, "teletexString") == 0)
349 teletex = 1;
350
351 MHD_gtls_str_cpy (tmpname, sizeof (tmpname), str);
352
353 len = sizeof (str) - 1;
354 if ((result = MHD__asn1_read_value (tmpasn, tmpname, str, &len))
355 != ASN1_SUCCESS)
356 {
357 MHD__asn1_delete_structure (&tmpasn);
358 return MHD_gtls_asn2err (result);
359 }
360
361 MHD__asn1_delete_structure (&tmpasn);
362
363 if (teletex != 0)
364 {
365 int ascii = 0, i;
366 /* HACK: if the teletex string contains only ascii
367 * characters then treat it as printable.
368 */
369 for (i = 0; i < len; i++)
370 if (!isascii (str[i]))
371 ascii = 1;
372
373 if (ascii == 0)
374 non_printable = 0;
375 }
376
377 if (res)
378 {
379 if (non_printable == 0)
380 {
381 str[len] = 0;
382 MHD_gtls_str_cpy (res, *res_size, str);
383 *res_size = len;
384 }
385 else
386 {
387 result =
388 MHD__gnutls_x509_data2hex ((const unsigned char *) str, len,
389 (unsigned char *) res, res_size);
390 if (result < 0)
391 {
392 MHD_gnutls_assert ();
393 return result;
394 }
395 }
396 }
397
398 }
399
400 return 0;
401}
402
403/* Converts a data string to an LDAP rfc2253 hex string
404 * something like '#01020304'
405 */
406int
407MHD__gnutls_x509_data2hex (const opaque * data,
408 size_t data_size, opaque * out,
409 size_t * sizeof_out)
410{
411 char *res;
412 char escaped[MAX_STRING_LEN];
413 unsigned int size;
414
415 if (2 * data_size + 1 > MAX_STRING_LEN)
416 {
417 MHD_gnutls_assert ();
418 return GNUTLS_E_INTERNAL_ERROR;
419 }
420 res = MHD_gtls_bin2hex (data, data_size, escaped, sizeof (escaped));
421 if (!res)
422 {
423 MHD_gnutls_assert ();
424 return GNUTLS_E_INTERNAL_ERROR;
425 }
426
427 size = strlen (res) + 1;
428 if (size + 1 > *sizeof_out)
429 {
430 *sizeof_out = size;
431 return GNUTLS_E_SHORT_MEMORY_BUFFER;
432 }
433 *sizeof_out = size; /* -1 for the null +1 for the '#' */
434
435 if (out)
436 {
437 strcpy ((char*) out, "#");
438 strcat ((char*) out, res);
439 }
440 return 0;
441}
442
443/* TIME functions
444 * Convertions between generalized or UTC time to time_t
445 *
446 */
447
448/* This is an emulations of the struct tm.
449 * Since we do not use libc's functions, we don't need to
450 * depend on the libc structure.
451 */
452typedef struct fake_tm
453{
454 int tm_mon;
455 int tm_year; /* FULL year - ie 1971 */
456 int tm_mday;
457 int tm_hour;
458 int tm_min;
459 int tm_sec;
460} fake_tm;
461
462/* The mktime_utc function is due to Russ Allbery (rra@stanford.edu),
463 * who placed it under public domain:
464 */
465
466/* The number of days in each month.
467 */
468static const int MONTHDAYS[] = { 31,
469 28,
470 31,
471 30,
472 31,
473 30,
474 31,
475 31,
476 30,
477 31,
478 30,
479 31
480};
481
482/* Whether a given year is a leap year. */
483#define ISLEAP(year) \
484 (((year) % 4) == 0 && (((year) % 100) != 0 || ((year) % 400) == 0))
485
486/*
487 ** Given a struct tm representing a calendar time in UTC, convert it to
488 ** seconds since epoch. Returns (time_t) -1 if the time is not
489 ** convertable. Note that this function does not canonicalize the provided
490 ** struct tm, nor does it allow out of range values or years before 1970.
491 */
492static time_t
493mktime_utc (const struct fake_tm *tm)
494{
495 time_t result = 0;
496 int i;
497
498 /* We do allow some ill-formed dates, but we don't do anything special
499 * with them and our callers really shouldn't pass them to us. Do
500 * explicitly disallow the ones that would cause invalid array accesses
501 * or other algorithm problems.
502 */
503 if (tm->tm_mon < 0 || tm->tm_mon > 11 || tm->tm_year < 1970)
504 return (time_t) - 1;
505
506 /* Convert to a time_t.
507 */
508 for (i = 1970; i < tm->tm_year; i++)
509 result += 365 + ISLEAP (i);
510 for (i = 0; i < tm->tm_mon; i++)
511 result += MONTHDAYS[i];
512 if (tm->tm_mon > 1 && ISLEAP (tm->tm_year))
513 result++;
514 result = 24 * (result + tm->tm_mday - 1) + tm->tm_hour;
515 result = 60 * result + tm->tm_min;
516 result = 60 * result + tm->tm_sec;
517 return result;
518}
519
520/* this one will parse dates of the form:
521 * month|day|hour|minute|sec* (2 chars each)
522 * and year is given. Returns a time_t date.
523 */
524static time_t
525MHD__gnutls_x509_time2gtime (const char *ttime, int year)
526{
527 char xx[3];
528 struct fake_tm etime;
529 time_t ret;
530
531 if (strlen (ttime) < 8)
532 {
533 MHD_gnutls_assert ();
534 return (time_t) - 1;
535 }
536
537 etime.tm_year = year;
538
539 /* In order to work with 32 bit
540 * time_t.
541 */
542 if (sizeof (time_t) <= 4 && etime.tm_year >= 2038)
543 return (time_t) 2145914603; /* 2037-12-31 23:23:23 */
544
545 xx[2] = 0;
546
547 /* get the month
548 */
549 memcpy (xx, ttime, 2); /* month */
550 etime.tm_mon = atoi (xx) - 1;
551 ttime += 2;
552
553 /* get the day
554 */
555 memcpy (xx, ttime, 2); /* day */
556 etime.tm_mday = atoi (xx);
557 ttime += 2;
558
559 /* get the hour
560 */
561 memcpy (xx, ttime, 2); /* hour */
562 etime.tm_hour = atoi (xx);
563 ttime += 2;
564
565 /* get the minutes
566 */
567 memcpy (xx, ttime, 2); /* minutes */
568 etime.tm_min = atoi (xx);
569 ttime += 2;
570
571 if (strlen (ttime) >= 2)
572 {
573 memcpy (xx, ttime, 2);
574 etime.tm_sec = atoi (xx);
575 ttime += 2;
576 }
577 else
578 etime.tm_sec = 0;
579
580 ret = mktime_utc (&etime);
581
582 return ret;
583}
584
585/* returns a time_t value that contains the given time.
586 * The given time is expressed as:
587 * YEAR(2)|MONTH(2)|DAY(2)|HOUR(2)|MIN(2)|SEC(2)*
588 *
589 * (seconds are optional)
590 */
591static time_t
592MHD__gnutls_x509_utcTime2gtime (const char *ttime)
593{
594 char xx[3];
595 int year;
596
597 if (strlen (ttime) < 10)
598 {
599 MHD_gnutls_assert ();
600 return (time_t) - 1;
601 }
602 xx[2] = 0;
603 /* get the year
604 */
605 memcpy (xx, ttime, 2); /* year */
606 year = atoi (xx);
607 ttime += 2;
608
609 if (year > 49)
610 year += 1900;
611 else
612 year += 2000;
613
614 return MHD__gnutls_x509_time2gtime (ttime, year);
615}
616
617/* returns a time_t value that contains the given time.
618 * The given time is expressed as:
619 * YEAR(4)|MONTH(2)|DAY(2)|HOUR(2)|MIN(2)|SEC(2)*
620 */
621static time_t
622MHD__gnutls_x509_generalTime2gtime (const char *ttime)
623{
624 char xx[5];
625 int year;
626
627 if (strlen (ttime) < 12)
628 {
629 MHD_gnutls_assert ();
630 return (time_t) - 1;
631 }
632
633 if (strchr (ttime, 'Z') == 0)
634 {
635 MHD_gnutls_assert ();
636 /* sorry we don't support it yet
637 */
638 return (time_t) - 1;
639 }
640 xx[4] = 0;
641
642 /* get the year
643 */
644 memcpy (xx, ttime, 4); /* year */
645 year = atoi (xx);
646 ttime += 4;
647
648 return MHD__gnutls_x509_time2gtime (ttime, year);
649
650}
651
652/* Extracts the time in time_t from the ASN1_TYPE given. When should
653 * be something like "tbsCertList.thisUpdate".
654 */
655#define MAX_TIME 64
656time_t
657MHD__gnutls_x509_get_time (ASN1_TYPE c2, const char *when)
658{
659 char ttime[MAX_TIME];
660 char name[128];
661 time_t c_time = (time_t) - 1;
662 int len, result;
663
664 MHD_gtls_str_cpy (name, sizeof (name), when);
665
666 len = sizeof (ttime) - 1;
667 if ((result = MHD__asn1_read_value (c2, name, ttime, &len)) < 0)
668 {
669 MHD_gnutls_assert ();
670 return (time_t) (-1);
671 }
672
673 /* CHOICE */
674 if (strcmp (ttime, "generalTime") == 0)
675 {
676
677 MHD_gtls_str_cat (name, sizeof (name), ".generalTime");
678 len = sizeof (ttime) - 1;
679 result = MHD__asn1_read_value (c2, name, ttime, &len);
680 if (result == ASN1_SUCCESS)
681 c_time = MHD__gnutls_x509_generalTime2gtime (ttime);
682 }
683 else
684 { /* UTCTIME */
685
686 MHD_gtls_str_cat (name, sizeof (name), ".utcTime");
687 len = sizeof (ttime) - 1;
688 result = MHD__asn1_read_value (c2, name, ttime, &len);
689 if (result == ASN1_SUCCESS)
690 c_time = MHD__gnutls_x509_utcTime2gtime (ttime);
691 }
692
693 /* We cannot handle dates after 2031 in 32 bit machines.
694 * a time_t of 64bits has to be used.
695 */
696
697 if (result != ASN1_SUCCESS)
698 {
699 MHD_gnutls_assert ();
700 return (time_t) (-1);
701 }
702 return c_time;
703}
704
705
706MHD_gnutls_x509_subject_alt_name_t
707MHD__gnutls_x509_san_find_type (char *str_type)
708{
709 if (strcmp (str_type, "dNSName") == 0)
710 return GNUTLS_SAN_DNSNAME;
711 if (strcmp (str_type, "rfc822Name") == 0)
712 return GNUTLS_SAN_RFC822NAME;
713 if (strcmp (str_type, "uniformResourceIdentifier") == 0)
714 return GNUTLS_SAN_URI;
715 if (strcmp (str_type, "iPAddress") == 0)
716 return GNUTLS_SAN_IPADDRESS;
717 if (strcmp (str_type, "otherName") == 0)
718 return GNUTLS_SAN_OTHERNAME;
719 if (strcmp (str_type, "directoryName") == 0)
720 return GNUTLS_SAN_DN;
721 return (MHD_gnutls_x509_subject_alt_name_t) - 1;
722}
723
724/* A generic export function. Will export the given ASN.1 encoded data 38/* A generic export function. Will export the given ASN.1 encoded data
725 * to PEM or DER raw data. 39 * to PEM or DER raw data.
726 */ 40 */