aboutsummaryrefslogtreecommitdiff
path: root/src/daemon/https/x509
diff options
context:
space:
mode:
Diffstat (limited to 'src/daemon/https/x509')
-rw-r--r--src/daemon/https/x509/Makefile.am36
-rw-r--r--src/daemon/https/x509/common.c1491
-rw-r--r--src/daemon/https/x509/common.h126
-rw-r--r--src/daemon/https/x509/crl.c705
-rw-r--r--src/daemon/https/x509/crl_write.c316
-rw-r--r--src/daemon/https/x509/crq.c887
-rw-r--r--src/daemon/https/x509/crq.h30
-rw-r--r--src/daemon/https/x509/dn.c1140
-rw-r--r--src/daemon/https/x509/dn.h58
-rw-r--r--src/daemon/https/x509/dsa.c142
-rw-r--r--src/daemon/https/x509/dsa.h25
-rw-r--r--src/daemon/https/x509/extensions.c1095
-rw-r--r--src/daemon/https/x509/extensions.h68
-rw-r--r--src/daemon/https/x509/mpi.c576
-rw-r--r--src/daemon/https/x509/mpi.h57
-rw-r--r--src/daemon/https/x509/output.c1360
-rw-r--r--src/daemon/https/x509/pkcs12.c1325
-rw-r--r--src/daemon/https/x509/pkcs12.h208
-rw-r--r--src/daemon/https/x509/pkcs12_bag.c770
-rw-r--r--src/daemon/https/x509/pkcs12_encr.c169
-rw-r--r--src/daemon/https/x509/pkcs7.c1023
-rw-r--r--src/daemon/https/x509/pkcs7.h30
-rw-r--r--src/daemon/https/x509/privkey.h31
-rw-r--r--src/daemon/https/x509/privkey_pkcs8.c2219
-rw-r--r--src/daemon/https/x509/rfc2818.h26
-rw-r--r--src/daemon/https/x509/rfc2818_hostname.c160
-rw-r--r--src/daemon/https/x509/sign.c346
-rw-r--r--src/daemon/https/x509/sign.h36
-rw-r--r--src/daemon/https/x509/verify.h34
-rw-r--r--src/daemon/https/x509/x509-api.texi2943
-rw-r--r--src/daemon/https/x509/x509.c2851
-rw-r--r--src/daemon/https/x509/x509.h928
-rw-r--r--src/daemon/https/x509/x509_privkey.c1509
-rw-r--r--src/daemon/https/x509/x509_verify.c1037
-rw-r--r--src/daemon/https/x509/x509_write.c1094
35 files changed, 24851 insertions, 0 deletions
diff --git a/src/daemon/https/x509/Makefile.am b/src/daemon/https/x509/Makefile.am
new file mode 100644
index 00000000..c3a30f03
--- /dev/null
+++ b/src/daemon/https/x509/Makefile.am
@@ -0,0 +1,36 @@
1
2AM_CPPFLAGS = -I./includes \
3-I$(top_srcdir)/src/daemon/https/includes \
4-I$(top_srcdir)/src/daemon/https/minitasn1 \
5-I$(top_srcdir)/src/daemon/https/lgl \
6-I$(top_srcdir)/src/daemon/https/x509 \
7-I$(top_srcdir)/src/daemon/https/tls
8
9noinst_LTLIBRARIES = libx509.la
10
11libx509_la_LDFLAGS = -lgcrypt
12# -l $(top_srcdir)/src/daemon/https/lgl/liblgl.la
13
14libx509_la_SOURCES = \
15common.c \
16crq.c \
17crl.c \
18crl_write.c \
19dn.c \
20dsa.c \
21extensions.c \
22mpi.c \
23pkcs12_bag.c \
24pkcs12.c \
25pkcs12_encr.c \
26pkcs7.c \
27x509_privkey.c \
28privkey_pkcs8.c \
29rfc2818_hostname.c \
30sign.c \
31x509_verify.c \
32x509.c \
33x509_write.c
34# output.c
35
36
diff --git a/src/daemon/https/x509/common.c b/src/daemon/https/x509/common.c
new file mode 100644
index 00000000..98a655c7
--- /dev/null
+++ b/src/daemon/https/x509/common.c
@@ -0,0 +1,1491 @@
1/*
2 * Copyright (C) 2003, 2004, 2005, 2006, 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 <gnutls_x509.h>
32#include <gnutls_num.h>
33#include <x509_b64.h>
34#include <common.h>
35#include <mpi.h>
36#include <time.h>
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
173_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 * 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 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
203gnutls_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 */
221int
222_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 *
238_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
260_gnutls_x509_oid_data2string (const char *oid,
261 void *value,
262 int value_size, char *res, size_t * res_size)
263{
264 char str[MAX_STRING_LEN], tmpname[128];
265 const char *ANAME = NULL;
266 int CHOICE = -1, len = -1, result;
267 ASN1_TYPE tmpasn = ASN1_TYPE_EMPTY;
268 char asn1_err[MAX_ERROR_DESCRIPTION_SIZE] = "";
269
270 if (value == NULL || value_size <= 0 || res_size == NULL)
271 {
272 gnutls_assert ();
273 return GNUTLS_E_INVALID_REQUEST;
274 }
275
276 if (_gnutls_x509_oid_data_printable (oid) == 0)
277 {
278 gnutls_assert ();
279 return GNUTLS_E_INTERNAL_ERROR;
280 }
281
282 ANAME = asn1_find_structure_from_oid (_gnutls_get_pkix (), oid);
283 CHOICE = _gnutls_x509_oid_data_choice (oid);
284
285 if (ANAME == NULL)
286 {
287 gnutls_assert ();
288 return GNUTLS_E_INTERNAL_ERROR;
289 }
290
291 _gnutls_str_cpy (str, sizeof (str), "PKIX1.");
292 _gnutls_str_cat (str, sizeof (str), ANAME);
293
294 if ((result = asn1_create_element (_gnutls_get_pkix (), str,
295 &tmpasn)) != ASN1_SUCCESS)
296 {
297 gnutls_assert ();
298 return _gnutls_asn2err (result);
299 }
300
301 if ((result = asn1_der_decoding (&tmpasn, value, value_size, asn1_err))
302 != ASN1_SUCCESS)
303 {
304 gnutls_assert ();
305 _gnutls_x509_log ("asn1_der_decoding: %s:%s\n", str, asn1_err);
306 asn1_delete_structure (&tmpasn);
307 return _gnutls_asn2err (result);
308 }
309
310 /* If this is a choice then we read the choice. Otherwise it
311 * is the value;
312 */
313 len = sizeof (str) - 1;
314 if ((result = asn1_read_value (tmpasn, "", str, &len)) != ASN1_SUCCESS)
315 { /* CHOICE */
316 gnutls_assert ();
317 asn1_delete_structure (&tmpasn);
318 return _gnutls_asn2err (result);
319 }
320
321 if (CHOICE == 0)
322 {
323 str[len] = 0;
324
325 if (res)
326 _gnutls_str_cpy (res, *res_size, str);
327 *res_size = len;
328
329 asn1_delete_structure (&tmpasn);
330 }
331 else
332 { /* CHOICE */
333 int non_printable = 0, teletex = 0;
334 str[len] = 0;
335
336 /* Note that we do not support strings other than
337 * UTF-8 (thus ASCII as well).
338 */
339 if (strcmp (str, "printableString") != 0
340 && strcmp (str, "ia5String") != 0
341 && strcmp (str, "utf8String") != 0)
342 {
343 non_printable = 1;
344 }
345 if (strcmp (str, "teletexString") == 0)
346 teletex = 1;
347
348 _gnutls_str_cpy (tmpname, sizeof (tmpname), str);
349
350 len = sizeof (str) - 1;
351 if ((result = asn1_read_value (tmpasn, tmpname, str, &len))
352 != ASN1_SUCCESS)
353 {
354 asn1_delete_structure (&tmpasn);
355 return _gnutls_asn2err (result);
356 }
357
358 asn1_delete_structure (&tmpasn);
359
360 if (teletex != 0)
361 {
362 int ascii = 0, i;
363 /* HACK: if the teletex string contains only ascii
364 * characters then treat it as printable.
365 */
366 for (i = 0; i < len; i++)
367 if (!isascii (str[i]))
368 ascii = 1;
369
370 if (ascii == 0)
371 non_printable = 0;
372 }
373
374 if (res)
375 {
376 if (non_printable == 0)
377 {
378 str[len] = 0;
379 _gnutls_str_cpy (res, *res_size, str);
380 *res_size = len;
381 }
382 else
383 {
384 result = _gnutls_x509_data2hex (str, len, res, res_size);
385 if (result < 0)
386 {
387 gnutls_assert ();
388 return result;
389 }
390 }
391 }
392
393 }
394
395 return 0;
396}
397
398/* Converts a data string to an LDAP rfc2253 hex string
399 * something like '#01020304'
400 */
401int
402_gnutls_x509_data2hex (const opaque * data,
403 size_t data_size, opaque * out, size_t * sizeof_out)
404{
405 char *res;
406 char escaped[MAX_STRING_LEN];
407
408 if (2 * data_size + 1 > MAX_STRING_LEN)
409 {
410 gnutls_assert ();
411 return GNUTLS_E_INTERNAL_ERROR;
412 }
413
414 res = _gnutls_bin2hex (data, data_size, escaped, sizeof (escaped));
415
416 if (res)
417 {
418 unsigned int size = strlen (res) + 1;
419 if (size + 1 > *sizeof_out)
420 {
421 *sizeof_out = size;
422 return GNUTLS_E_SHORT_MEMORY_BUFFER;
423 }
424 *sizeof_out = size; /* -1 for the null +1 for the '#' */
425
426 if (out)
427 {
428 strcpy (out, "#");
429 strcat (out, res);
430 }
431
432 return 0;
433 }
434 else
435 {
436 gnutls_assert ();
437 return GNUTLS_E_INTERNAL_ERROR;
438 }
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 */
524time_t
525_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 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 */
591time_t
592_gnutls_x509_utcTime2gtime (const char *ttime)
593{
594 char xx[3];
595 int year;
596
597 if (strlen (ttime) < 10)
598 {
599 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 _gnutls_x509_time2gtime (ttime, year);
615}
616
617/* returns a time value that contains the given time.
618 * The given time is expressed as:
619 * YEAR(2)|MONTH(2)|DAY(2)|HOUR(2)|MIN(2)|SEC(2)
620 */
621int
622_gnutls_x509_gtime2utcTime (time_t gtime, char *str_time, int str_time_size)
623{
624 size_t ret;
625
626#ifdef HAVE_GMTIME_R
627 struct tm _tm;
628
629 gmtime_r (&gtime, &_tm);
630
631 ret = strftime (str_time, str_time_size, "%y%m%d%H%M%SZ", &_tm);
632#else
633 struct tm *_tm;
634
635 _tm = gmtime (&gtime);
636
637 ret = strftime (str_time, str_time_size, "%y%m%d%H%M%SZ", _tm);
638#endif
639
640 if (!ret)
641 {
642 gnutls_assert ();
643 return GNUTLS_E_SHORT_MEMORY_BUFFER;
644 }
645
646 return 0;
647
648}
649
650/* returns a time_t value that contains the given time.
651 * The given time is expressed as:
652 * YEAR(4)|MONTH(2)|DAY(2)|HOUR(2)|MIN(2)|SEC(2)*
653 */
654time_t
655_gnutls_x509_generalTime2gtime (const char *ttime)
656{
657 char xx[5];
658 int year;
659
660 if (strlen (ttime) < 12)
661 {
662 gnutls_assert ();
663 return (time_t) - 1;
664 }
665
666 if (strchr (ttime, 'Z') == 0)
667 {
668 gnutls_assert ();
669 /* sorry we don't support it yet
670 */
671 return (time_t) - 1;
672 }
673 xx[4] = 0;
674
675 /* get the year
676 */
677 memcpy (xx, ttime, 4); /* year */
678 year = atoi (xx);
679 ttime += 4;
680
681 return _gnutls_x509_time2gtime (ttime, year);
682
683}
684
685/* Extracts the time in time_t from the ASN1_TYPE given. When should
686 * be something like "tbsCertList.thisUpdate".
687 */
688#define MAX_TIME 64
689time_t
690_gnutls_x509_get_time (ASN1_TYPE c2, const char *when)
691{
692 char ttime[MAX_TIME];
693 char name[128];
694 time_t c_time = (time_t) - 1;
695 int len, result;
696
697 _gnutls_str_cpy (name, sizeof (name), when);
698
699 len = sizeof (ttime) - 1;
700 if ((result = asn1_read_value (c2, name, ttime, &len)) < 0)
701 {
702 gnutls_assert ();
703 return (time_t) (-1);
704 }
705
706 /* CHOICE */
707 if (strcmp (ttime, "generalTime") == 0)
708 {
709
710 _gnutls_str_cat (name, sizeof (name), ".generalTime");
711 len = sizeof (ttime) - 1;
712 result = asn1_read_value (c2, name, ttime, &len);
713 if (result == ASN1_SUCCESS)
714 c_time = _gnutls_x509_generalTime2gtime (ttime);
715 }
716 else
717 { /* UTCTIME */
718
719 _gnutls_str_cat (name, sizeof (name), ".utcTime");
720 len = sizeof (ttime) - 1;
721 result = asn1_read_value (c2, name, ttime, &len);
722 if (result == ASN1_SUCCESS)
723 c_time = _gnutls_x509_utcTime2gtime (ttime);
724 }
725
726 /* We cannot handle dates after 2031 in 32 bit machines.
727 * a time_t of 64bits has to be used.
728 */
729
730 if (result != ASN1_SUCCESS)
731 {
732 gnutls_assert ();
733 return (time_t) (-1);
734 }
735 return c_time;
736}
737
738/* Sets the time in time_t in the ASN1_TYPE given. Where should
739 * be something like "tbsCertList.thisUpdate".
740 */
741int
742_gnutls_x509_set_time (ASN1_TYPE c2, const char *where, time_t tim)
743{
744 char str_time[MAX_TIME];
745 char name[128];
746 int result, len;
747
748 _gnutls_str_cpy (name, sizeof (name), where);
749
750 if ((result = asn1_write_value (c2, name, "utcTime", 1)) < 0)
751 {
752 gnutls_assert ();
753 return _gnutls_asn2err (result);
754 }
755
756 result = _gnutls_x509_gtime2utcTime (tim, str_time, sizeof (str_time));
757 if (result < 0)
758 {
759 gnutls_assert ();
760 return result;
761 }
762
763 _gnutls_str_cat (name, sizeof (name), ".utcTime");
764
765 len = strlen (str_time);
766 result = asn1_write_value (c2, name, str_time, len);
767 if (result != ASN1_SUCCESS)
768 {
769 gnutls_assert ();
770 return _gnutls_asn2err (result);
771 }
772
773 return 0;
774}
775
776gnutls_x509_subject_alt_name_t
777_gnutls_x509_san_find_type (char *str_type)
778{
779 if (strcmp (str_type, "dNSName") == 0)
780 return GNUTLS_SAN_DNSNAME;
781 if (strcmp (str_type, "rfc822Name") == 0)
782 return GNUTLS_SAN_RFC822NAME;
783 if (strcmp (str_type, "uniformResourceIdentifier") == 0)
784 return GNUTLS_SAN_URI;
785 if (strcmp (str_type, "iPAddress") == 0)
786 return GNUTLS_SAN_IPADDRESS;
787 if (strcmp (str_type, "otherName") == 0)
788 return GNUTLS_SAN_OTHERNAME;
789 if (strcmp (str_type, "directoryName") == 0)
790 return GNUTLS_SAN_DN;
791 return (gnutls_x509_subject_alt_name_t) - 1;
792}
793
794/* A generic export function. Will export the given ASN.1 encoded data
795 * to PEM or DER raw data.
796 */
797int
798_gnutls_x509_export_int (ASN1_TYPE asn1_data,
799 gnutls_x509_crt_fmt_t format,
800 char *pem_header,
801 unsigned char *output_data,
802 size_t * output_data_size)
803{
804 int result, len;
805
806 if (format == GNUTLS_X509_FMT_DER)
807 {
808
809 if (output_data == NULL)
810 *output_data_size = 0;
811
812 len = *output_data_size;
813
814 if ((result = asn1_der_coding (asn1_data, "", output_data, &len,
815 NULL)) != ASN1_SUCCESS)
816 {
817 *output_data_size = len;
818 if (result == ASN1_MEM_ERROR)
819 {
820 return GNUTLS_E_SHORT_MEMORY_BUFFER;
821 }
822 gnutls_assert ();
823 return _gnutls_asn2err (result);
824 }
825
826 *output_data_size = len;
827
828 }
829 else
830 { /* PEM */
831 opaque *out;
832 gnutls_datum_t tmp;
833
834 result = _gnutls_x509_der_encode (asn1_data, "", &tmp, 0);
835 if (result < 0)
836 {
837 gnutls_assert ();
838 return result;
839 }
840
841 result = _gnutls_fbase64_encode (pem_header, tmp.data, tmp.size, &out);
842
843 _gnutls_free_datum (&tmp);
844
845 if (result < 0)
846 {
847 gnutls_assert ();
848 return result;
849 }
850
851 if (result == 0)
852 { /* oooops */
853 gnutls_assert ();
854 return GNUTLS_E_INTERNAL_ERROR;
855 }
856
857 if ((unsigned) result > *output_data_size)
858 {
859 gnutls_assert ();
860 gnutls_free (out);
861 *output_data_size = result;
862 return GNUTLS_E_SHORT_MEMORY_BUFFER;
863 }
864
865 *output_data_size = result;
866
867 if (output_data)
868 {
869 memcpy (output_data, out, result);
870
871 /* do not include the null character into output size.
872 */
873 *output_data_size = result - 1;
874 }
875 gnutls_free (out);
876
877 }
878
879 return 0;
880}
881
882/* Decodes an octet string. Leave string_type null for a normal
883 * octet string. Otherwise put something like BMPString, PrintableString
884 * etc.
885 */
886int
887_gnutls_x509_decode_octet_string (const char *string_type,
888 const opaque * der,
889 size_t der_size,
890 opaque * output, size_t * output_size)
891{
892 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
893 int result, tmp_output_size;
894 char strname[64];
895
896 if (string_type == NULL)
897 _gnutls_str_cpy (strname, sizeof (strname), "PKIX1.pkcs-7-Data");
898 else
899 {
900 _gnutls_str_cpy (strname, sizeof (strname), "PKIX1.");
901 _gnutls_str_cat (strname, sizeof (strname), string_type);
902 }
903
904 if ((result =
905 asn1_create_element (_gnutls_get_pkix (), strname,
906 &c2)) != ASN1_SUCCESS)
907 {
908 gnutls_assert ();
909 result = _gnutls_asn2err (result);
910 goto cleanup;
911 }
912
913 result = asn1_der_decoding (&c2, der, der_size, NULL);
914 if (result != ASN1_SUCCESS)
915 {
916 gnutls_assert ();
917 result = _gnutls_asn2err (result);
918 goto cleanup;
919 }
920
921 tmp_output_size = *output_size;
922 result = asn1_read_value (c2, "", output, &tmp_output_size);
923 *output_size = tmp_output_size;
924
925 if (result != ASN1_SUCCESS)
926 {
927 gnutls_assert ();
928 result = _gnutls_asn2err (result);
929 goto cleanup;
930 }
931
932 return 0;
933
934cleanup:if (c2)
935 asn1_delete_structure (&c2);
936
937 return result;
938}
939
940/* Reads a value from an ASN1 tree, and puts the output
941 * in an allocated variable in the given datum.
942 * flags == 0 do nothing with the DER output
943 * flags == 1 parse the DER output as OCTET STRING
944 * flags == 2 the value is a BIT STRING
945 */
946int
947_gnutls_x509_read_value (ASN1_TYPE c,
948 const char *root, gnutls_datum_t * ret, int flags)
949{
950 int len = 0, result;
951 size_t slen;
952 opaque *tmp = NULL;
953
954 result = asn1_read_value (c, root, NULL, &len);
955 if (result != ASN1_MEM_ERROR)
956 {
957 gnutls_assert ();
958 result = _gnutls_asn2err (result);
959 return result;
960 }
961
962 if (flags == 2)
963 len /= 8;
964
965 tmp = gnutls_malloc (len);
966 if (tmp == NULL)
967 {
968 gnutls_assert ();
969 result = GNUTLS_E_MEMORY_ERROR;
970 goto cleanup;
971 }
972
973 result = asn1_read_value (c, root, tmp, &len);
974 if (result != ASN1_SUCCESS)
975 {
976 gnutls_assert ();
977 result = _gnutls_asn2err (result);
978 goto cleanup;
979 }
980
981 if (flags == 2)
982 len /= 8;
983
984 /* Extract the OCTET STRING.
985 */
986
987 if (flags == 1)
988 {
989 slen = len;
990 result = _gnutls_x509_decode_octet_string (NULL, tmp, slen, tmp, &slen);
991 if (result < 0)
992 {
993 gnutls_assert ();
994 goto cleanup;
995 }
996 len = slen;
997 }
998
999 ret->data = tmp;
1000 ret->size = len;
1001
1002 return 0;
1003
1004cleanup:gnutls_free (tmp);
1005 return result;
1006
1007}
1008
1009/* DER Encodes the src ASN1_TYPE and stores it to
1010 * the given datum. If str is non null then the data are encoded as
1011 * an OCTET STRING.
1012 */
1013int
1014_gnutls_x509_der_encode (ASN1_TYPE src,
1015 const char *src_name, gnutls_datum_t * res, int str)
1016{
1017 int size, result;
1018 int asize;
1019 opaque *data = NULL;
1020 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
1021
1022 size = 0;
1023 result = asn1_der_coding (src, src_name, NULL, &size, NULL);
1024 if (result != ASN1_MEM_ERROR)
1025 {
1026 gnutls_assert ();
1027 result = _gnutls_asn2err (result);
1028 goto cleanup;
1029 }
1030
1031 /* allocate data for the der
1032 */
1033
1034 if (str)
1035 size += 16; /* for later to include the octet tags */
1036 asize = size;
1037
1038 data = gnutls_malloc (size);
1039 if (data == NULL)
1040 {
1041 gnutls_assert ();
1042 result = GNUTLS_E_MEMORY_ERROR;
1043 goto cleanup;
1044 }
1045
1046 result = asn1_der_coding (src, src_name, data, &size, NULL);
1047 if (result != ASN1_SUCCESS)
1048 {
1049 gnutls_assert ();
1050 result = _gnutls_asn2err (result);
1051 goto cleanup;
1052 }
1053
1054 if (str)
1055 {
1056 if ((result =
1057 asn1_create_element (_gnutls_get_pkix (), "PKIX1.pkcs-7-Data",
1058 &c2)) != ASN1_SUCCESS)
1059 {
1060 gnutls_assert ();
1061 result = _gnutls_asn2err (result);
1062 goto cleanup;
1063 }
1064
1065 result = asn1_write_value (c2, "", data, size);
1066 if (result != ASN1_SUCCESS)
1067 {
1068 gnutls_assert ();
1069 result = _gnutls_asn2err (result);
1070 goto cleanup;
1071 }
1072
1073 result = asn1_der_coding (c2, "", data, &asize, NULL);
1074 if (result != ASN1_SUCCESS)
1075 {
1076 gnutls_assert ();
1077 result = _gnutls_asn2err (result);
1078 goto cleanup;
1079 }
1080
1081 size = asize;
1082
1083 asn1_delete_structure (&c2);
1084 }
1085
1086 res->data = data;
1087 res->size = size;
1088 return 0;
1089
1090cleanup:gnutls_free (data);
1091 asn1_delete_structure (&c2);
1092 return result;
1093
1094}
1095
1096/* DER Encodes the src ASN1_TYPE and stores it to
1097 * dest in dest_name. Useful to encode something and store it
1098 * as OCTET. If str is non null then the data are encoded as
1099 * an OCTET STRING.
1100 */
1101int
1102_gnutls_x509_der_encode_and_copy (ASN1_TYPE src,
1103 const char *src_name,
1104 ASN1_TYPE dest,
1105 const char *dest_name, int str)
1106{
1107 int result;
1108 gnutls_datum_t encoded;
1109
1110 result = _gnutls_x509_der_encode (src, src_name, &encoded, str);
1111
1112 if (result < 0)
1113 {
1114 gnutls_assert ();
1115 return result;
1116 }
1117
1118 /* Write the data.
1119 */
1120 result = asn1_write_value (dest, dest_name, encoded.data, encoded.size);
1121
1122 _gnutls_free_datum (&encoded);
1123
1124 if (result != ASN1_SUCCESS)
1125 {
1126 gnutls_assert ();
1127 return _gnutls_asn2err (result);
1128 }
1129
1130 return 0;
1131}
1132
1133/* Writes the value of the datum in the given ASN1_TYPE. If str is non
1134 * zero it encodes it as OCTET STRING.
1135 */
1136int
1137_gnutls_x509_write_value (ASN1_TYPE c,
1138 const char *root,
1139 const gnutls_datum_t * data, int str)
1140{
1141 int result;
1142 int asize;
1143 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
1144 gnutls_datum_t val;
1145
1146 asize = data->size + 16;
1147
1148 val.data = gnutls_malloc (asize);
1149 if (val.data == NULL)
1150 {
1151 gnutls_assert ();
1152 result = GNUTLS_E_MEMORY_ERROR;
1153 goto cleanup;
1154 }
1155
1156 if (str)
1157 {
1158 /* Convert it to OCTET STRING
1159 */
1160 if ((result =
1161 asn1_create_element (_gnutls_get_pkix (), "PKIX1.pkcs-7-Data",
1162 &c2)) != ASN1_SUCCESS)
1163 {
1164 gnutls_assert ();
1165 result = _gnutls_asn2err (result);
1166 goto cleanup;
1167 }
1168
1169 result = asn1_write_value (c2, "", data->data, data->size);
1170 if (result != ASN1_SUCCESS)
1171 {
1172 gnutls_assert ();
1173 result = _gnutls_asn2err (result);
1174 goto cleanup;
1175 }
1176
1177 result = _gnutls_x509_der_encode (c2, "", &val, 0);
1178 if (result < 0)
1179 {
1180 gnutls_assert ();
1181 goto cleanup;
1182 }
1183
1184 }
1185 else
1186 {
1187 val.data = data->data;
1188 val.size = data->size;
1189 }
1190
1191 /* Write the data.
1192 */
1193 result = asn1_write_value (c, root, val.data, val.size);
1194
1195 if (val.data != data->data)
1196 _gnutls_free_datum (&val);
1197
1198 if (result != ASN1_SUCCESS)
1199 {
1200 gnutls_assert ();
1201 return _gnutls_asn2err (result);
1202 }
1203
1204 return 0;
1205
1206cleanup:if (val.data != data->data)
1207 _gnutls_free_datum (&val);
1208 return result;
1209}
1210
1211/* Encodes and copies the private key parameters into a
1212 * subjectPublicKeyInfo structure.
1213 *
1214 */
1215int
1216_gnutls_x509_encode_and_copy_PKI_params (ASN1_TYPE dst,
1217 const char *dst_name,
1218 gnutls_pk_algorithm_t
1219 pk_algorithm,
1220 mpi_t * params, int params_size)
1221{
1222 const char *pk;
1223 gnutls_datum_t der = { NULL,
1224 0
1225 };
1226 int result;
1227 char name[128];
1228
1229 pk = _gnutls_x509_pk_to_oid (pk_algorithm);
1230 if (pk == NULL)
1231 {
1232 gnutls_assert ();
1233 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
1234 }
1235
1236 /* write the OID
1237 */
1238 _gnutls_str_cpy (name, sizeof (name), dst_name);
1239 _gnutls_str_cat (name, sizeof (name), ".algorithm.algorithm");
1240 result = asn1_write_value (dst, name, pk, 1);
1241 if (result != ASN1_SUCCESS)
1242 {
1243 gnutls_assert ();
1244 return _gnutls_asn2err (result);
1245 }
1246
1247 if (pk_algorithm == GNUTLS_PK_RSA)
1248 {
1249 /* disable parameters, which are not used in RSA.
1250 */
1251 _gnutls_str_cpy (name, sizeof (name), dst_name);
1252 _gnutls_str_cat (name, sizeof (name), ".algorithm.parameters");
1253 result = asn1_write_value (dst, name, NULL, 0);
1254 if (result != ASN1_SUCCESS)
1255 {
1256 gnutls_assert ();
1257 return _gnutls_asn2err (result);
1258 }
1259
1260 result = _gnutls_x509_write_rsa_params (params, params_size, &der);
1261 if (result < 0)
1262 {
1263 gnutls_assert ();
1264 return result;
1265 }
1266
1267 /* Write the DER parameters. (in bits)
1268 */
1269 _gnutls_str_cpy (name, sizeof (name), dst_name);
1270 _gnutls_str_cat (name, sizeof (name), ".subjectPublicKey");
1271 result = asn1_write_value (dst, name, der.data, der.size * 8);
1272
1273 _gnutls_free_datum (&der);
1274
1275 if (result != ASN1_SUCCESS)
1276 {
1277 gnutls_assert ();
1278 return _gnutls_asn2err (result);
1279 }
1280 }
1281 else
1282 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
1283
1284 return 0;
1285}
1286
1287/* Reads and returns the PK algorithm of the given certificate-like
1288 * ASN.1 structure. src_name should be something like "tbsCertificate.subjectPublicKeyInfo".
1289 */
1290int
1291_gnutls_x509_get_pk_algorithm (ASN1_TYPE src,
1292 const char *src_name, unsigned int *bits)
1293{
1294 int result;
1295 opaque *str = NULL;
1296 int algo;
1297 char oid[64];
1298 int len;
1299 mpi_t params[MAX_PUBLIC_PARAMS_SIZE];
1300 char name[128];
1301
1302 _gnutls_str_cpy (name, sizeof (name), src_name);
1303 _gnutls_str_cat (name, sizeof (name), ".algorithm.algorithm");
1304
1305 len = sizeof (oid);
1306 result = asn1_read_value (src, name, oid, &len);
1307
1308 if (result != ASN1_SUCCESS)
1309 {
1310 gnutls_assert ();
1311 return _gnutls_asn2err (result);
1312 }
1313
1314 algo = _gnutls_x509_oid2pk_algorithm (oid);
1315
1316 if (bits == NULL)
1317 {
1318 gnutls_free (str);
1319 return algo;
1320 }
1321
1322 /* Now read the parameters' bits
1323 */
1324 _gnutls_str_cpy (name, sizeof (name), src_name);
1325 _gnutls_str_cat (name, sizeof (name), ".subjectPublicKey");
1326
1327 len = 0;
1328 result = asn1_read_value (src, name, NULL, &len);
1329 if (result != ASN1_MEM_ERROR)
1330 {
1331 gnutls_assert ();
1332 return _gnutls_asn2err (result);
1333 }
1334
1335 if (len % 8 != 0)
1336 {
1337 gnutls_assert ();
1338 return GNUTLS_E_CERTIFICATE_ERROR;
1339 }
1340
1341 len /= 8;
1342
1343 str = gnutls_malloc (len);
1344 if (str == NULL)
1345 {
1346 gnutls_assert ();
1347 return GNUTLS_E_MEMORY_ERROR;
1348 }
1349
1350 _gnutls_str_cpy (name, sizeof (name), src_name);
1351 _gnutls_str_cat (name, sizeof (name), ".subjectPublicKey");
1352
1353 result = asn1_read_value (src, name, str, &len);
1354
1355 if (result != ASN1_SUCCESS)
1356 {
1357 gnutls_assert ();
1358 gnutls_free (str);
1359 return _gnutls_asn2err (result);
1360 }
1361
1362 len /= 8;
1363
1364 switch (algo)
1365 {
1366 case GNUTLS_PK_RSA:
1367 {
1368 if ((result = _gnutls_x509_read_rsa_params (str, len, params)) < 0)
1369 {
1370 gnutls_assert ();
1371 return result;
1372 }
1373
1374 bits[0] = _gnutls_mpi_get_nbits (params[0]);
1375
1376 _gnutls_mpi_release (&params[0]);
1377 _gnutls_mpi_release (&params[1]);
1378 }
1379 break;
1380 default:
1381 _gnutls_x509_log
1382 ("_gnutls_x509_get_pk_algorithm: unhandled algorithm %d\n", algo);
1383 }
1384
1385 gnutls_free (str);
1386 return algo;
1387}
1388
1389/* Reads the DER signed data from the certificate and allocates space and
1390 * returns them into signed_data.
1391 */
1392int
1393_gnutls_x509_get_signed_data (ASN1_TYPE src,
1394 const char *src_name,
1395 gnutls_datum_t * signed_data)
1396{
1397 gnutls_datum_t der;
1398 int start, end, result;
1399
1400 result = _gnutls_x509_der_encode (src, "", &der, 0);
1401 if (result < 0)
1402 {
1403 gnutls_assert ();
1404 return result;
1405 }
1406
1407 /* Get the signed data
1408 */
1409 result = asn1_der_decoding_startEnd (src, der.data, der.size, src_name,
1410 &start, &end);
1411 if (result != ASN1_SUCCESS)
1412 {
1413 result = _gnutls_asn2err (result);
1414 gnutls_assert ();
1415 goto cleanup;
1416 }
1417
1418 result = _gnutls_set_datum (signed_data, &der.data[start], end - start + 1);
1419
1420 if (result < 0)
1421 {
1422 gnutls_assert ();
1423 goto cleanup;
1424 }
1425
1426 result = 0;
1427
1428cleanup:_gnutls_free_datum (&der);
1429
1430 return result;
1431}
1432
1433/* Reads the DER signature from the certificate and allocates space and
1434 * returns them into signed_data.
1435 */
1436int
1437_gnutls_x509_get_signature (ASN1_TYPE src,
1438 const char *src_name, gnutls_datum_t * signature)
1439{
1440 int bits, result, len;
1441
1442 signature->data = NULL;
1443 signature->size = 0;
1444
1445 /* Read the signature
1446 */
1447 bits = 0;
1448 result = asn1_read_value (src, src_name, NULL, &bits);
1449
1450 if (result != ASN1_MEM_ERROR)
1451 {
1452 result = _gnutls_asn2err (result);
1453 gnutls_assert ();
1454 goto cleanup;
1455 }
1456
1457 if (bits % 8 != 0)
1458 {
1459 gnutls_assert ();
1460 result = GNUTLS_E_CERTIFICATE_ERROR;
1461 goto cleanup;
1462 }
1463
1464 len = bits / 8;
1465
1466 signature->data = gnutls_malloc (len);
1467 if (signature->data == NULL)
1468 {
1469 gnutls_assert ();
1470 result = GNUTLS_E_MEMORY_ERROR;
1471 return result;
1472 }
1473
1474 /* read the bit string of the signature
1475 */
1476 bits = len;
1477 result = asn1_read_value (src, src_name, signature->data, &bits);
1478
1479 if (result != ASN1_SUCCESS)
1480 {
1481 result = _gnutls_asn2err (result);
1482 gnutls_assert ();
1483 goto cleanup;
1484 }
1485
1486 signature->size = len;
1487
1488 return 0;
1489
1490cleanup:return result;
1491}
diff --git a/src/daemon/https/x509/common.h b/src/daemon/https/x509/common.h
new file mode 100644
index 00000000..0b696810
--- /dev/null
+++ b/src/daemon/https/x509/common.h
@@ -0,0 +1,126 @@
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#ifndef COMMON_H
26# define COMMON_H
27
28#include <gnutls.h>
29#include <gnutls_algorithms.h>
30
31#define MAX_STRING_LEN 512
32
33#define GNUTLS_XML_SHOW_ALL 1
34
35#define PEM_CRL "X509 CRL"
36#define PEM_X509_CERT "X509 CERTIFICATE"
37#define PEM_X509_CERT2 "CERTIFICATE"
38#define PEM_PKCS7 "PKCS7"
39#define PEM_PKCS12 "PKCS12"
40
41/* public key algorithm's OIDs
42 */
43#define PK_PKIX1_RSA_OID "1.2.840.113549.1.1.1"
44#define PK_DSA_OID "1.2.840.10040.4.1"
45#define PK_GOST_R3410_94_OID "1.2.643.2.2.20"
46#define PK_GOST_R3410_2001_OID "1.2.643.2.2.19"
47
48/* signature OIDs
49 */
50#define SIG_DSA_SHA1_OID "1.2.840.10040.4.3"
51#define SIG_RSA_MD5_OID "1.2.840.113549.1.1.4"
52#define SIG_RSA_MD2_OID "1.2.840.113549.1.1.2"
53#define SIG_RSA_SHA1_OID "1.2.840.113549.1.1.5"
54#define SIG_RSA_SHA256_OID "1.2.840.113549.1.1.11"
55#define SIG_RSA_SHA384_OID "1.2.840.113549.1.1.12"
56#define SIG_RSA_SHA512_OID "1.2.840.113549.1.1.13"
57#define SIG_RSA_RMD160_OID "1.3.36.3.3.1.2"
58#define SIG_GOST_R3410_94_OID "1.2.643.2.2.4"
59#define SIG_GOST_R3410_2001_OID "1.2.643.2.2.3"
60
61time_t _gnutls_x509_utcTime2gtime (const char *ttime);
62time_t _gnutls_x509_generalTime2gtime (const char *ttime);
63int _gnutls_x509_set_time (ASN1_TYPE c2, const char *where, time_t tim);
64
65int _gnutls_x509_decode_octet_string (const char *string_type,
66 const opaque * der, size_t der_size,
67 opaque * output, size_t * output_size);
68int _gnutls_x509_oid_data2string (const char *OID, void *value,
69 int value_size, char *res,
70 size_t * res_size);
71int _gnutls_x509_data2hex (const opaque * data, size_t data_size,
72 opaque * out, size_t * sizeof_out);
73
74const char *_gnutls_x509_oid2ldap_string (const char *OID);
75
76int _gnutls_x509_oid_data_choice (const char *OID);
77int _gnutls_x509_oid_data_printable (const char *OID);
78
79time_t _gnutls_x509_get_time (ASN1_TYPE c2, const char *when);
80
81gnutls_x509_subject_alt_name_t _gnutls_x509_san_find_type (char *str_type);
82
83int _gnutls_x509_der_encode_and_copy (ASN1_TYPE src, const char *src_name,
84 ASN1_TYPE dest, const char *dest_name,
85 int str);
86int _gnutls_x509_der_encode (ASN1_TYPE src, const char *src_name,
87 gnutls_datum_t * res, int str);
88
89int _gnutls_x509_export_int (ASN1_TYPE asn1_data,
90 gnutls_x509_crt_fmt_t format, char *pem_header,
91 unsigned char *output_data,
92 size_t * output_data_size);
93
94int _gnutls_x509_read_value (ASN1_TYPE c, const char *root,
95 gnutls_datum_t * ret, int str);
96int _gnutls_x509_write_value (ASN1_TYPE c, const char *root,
97 const gnutls_datum_t * data, int str);
98
99int _gnutls_x509_encode_and_write_attribute (const char *given_oid,
100 ASN1_TYPE asn1_struct,
101 const char *where,
102 const void *data,
103 int sizeof_data, int multi);
104int _gnutls_x509_decode_and_read_attribute (ASN1_TYPE asn1_struct,
105 const char *where, char *oid,
106 int oid_size,
107 gnutls_datum_t * value, int multi,
108 int octet);
109
110int _gnutls_x509_get_pk_algorithm (ASN1_TYPE src, const char *src_name,
111 unsigned int *bits);
112
113int _gnutls_x509_encode_and_copy_PKI_params (ASN1_TYPE dst,
114 const char *dst_name,
115 gnutls_pk_algorithm_t
116 pk_algorithm, mpi_t * params,
117 int params_size);
118int _gnutls_asn1_copy_node (ASN1_TYPE * dst, const char *dst_name,
119 ASN1_TYPE src, const char *src_name);
120
121int _gnutls_x509_get_signed_data (ASN1_TYPE src, const char *src_name,
122 gnutls_datum_t * signed_data);
123int _gnutls_x509_get_signature (ASN1_TYPE src, const char *src_name,
124 gnutls_datum_t * signature);
125
126#endif
diff --git a/src/daemon/https/x509/crl.c b/src/daemon/https/x509/crl.c
new file mode 100644
index 00000000..d3b5c954
--- /dev/null
+++ b/src/daemon/https/x509/crl.c
@@ -0,0 +1,705 @@
1/*
2 * Copyright (C) 2003, 2004, 2005, 2006, 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
28#ifdef ENABLE_PKI
29
30#include <gnutls_datum.h>
31#include <gnutls_global.h>
32#include <gnutls_errors.h>
33#include <common.h>
34#include <x509_b64.h>
35#include <x509.h>
36#include <dn.h>
37
38/**
39 * gnutls_x509_crl_init - This function initializes a gnutls_x509_crl_t structure
40 * @crl: The structure to be initialized
41 *
42 * This function will initialize a CRL structure. CRL stands for
43 * Certificate Revocation List. A revocation list usually contains
44 * lists of certificate serial numbers that have been revoked
45 * by an Authority. The revocation lists are always signed with
46 * the authority's private key.
47 *
48 * Returns 0 on success.
49 *
50 **/
51int
52gnutls_x509_crl_init (gnutls_x509_crl_t * crl)
53{
54 *crl = gnutls_calloc (1, sizeof (gnutls_x509_crl_int));
55
56 if (*crl)
57 {
58 int result = asn1_create_element (_gnutls_get_pkix (),
59 "PKIX1.CertificateList",
60 &(*crl)->crl);
61 if (result != ASN1_SUCCESS)
62 {
63 gnutls_assert ();
64 gnutls_free (*crl);
65 return _gnutls_asn2err (result);
66 }
67 return 0; /* success */
68 }
69 return GNUTLS_E_MEMORY_ERROR;
70}
71
72/**
73 * gnutls_x509_crl_deinit - This function deinitializes memory used by a gnutls_x509_crl_t structure
74 * @crl: The structure to be initialized
75 *
76 * This function will deinitialize a CRL structure.
77 *
78 **/
79void
80gnutls_x509_crl_deinit (gnutls_x509_crl_t crl)
81{
82 if (!crl)
83 return;
84
85 if (crl->crl)
86 asn1_delete_structure (&crl->crl);
87
88 gnutls_free (crl);
89}
90
91/**
92 * gnutls_x509_crl_import - This function will import a DER or PEM encoded CRL
93 * @crl: The structure to store the parsed CRL.
94 * @data: The DER or PEM encoded CRL.
95 * @format: One of DER or PEM
96 *
97 * This function will convert the given DER or PEM encoded CRL
98 * to the native gnutls_x509_crl_t format. The output will be stored in 'crl'.
99 *
100 * If the CRL is PEM encoded it should have a header of "X509 CRL".
101 *
102 * Returns 0 on success.
103 *
104 **/
105int
106gnutls_x509_crl_import (gnutls_x509_crl_t crl,
107 const gnutls_datum_t * data,
108 gnutls_x509_crt_fmt_t format)
109{
110 int result = 0, need_free = 0;
111 gnutls_datum_t _data;
112
113 _data.data = data->data;
114 _data.size = data->size;
115
116 if (crl == NULL)
117 {
118 gnutls_assert ();
119 return GNUTLS_E_INVALID_REQUEST;
120 }
121
122 /* If the CRL is in PEM format then decode it
123 */
124 if (format == GNUTLS_X509_FMT_PEM)
125 {
126 opaque *out;
127
128 result = _gnutls_fbase64_decode (PEM_CRL, data->data, data->size, &out);
129
130 if (result <= 0)
131 {
132 if (result == 0)
133 result = GNUTLS_E_INTERNAL_ERROR;
134 gnutls_assert ();
135 return result;
136 }
137
138 _data.data = out;
139 _data.size = result;
140
141 need_free = 1;
142 }
143
144
145 result = asn1_der_decoding (&crl->crl, _data.data, _data.size, NULL);
146 if (result != ASN1_SUCCESS)
147 {
148 result = _gnutls_asn2err (result);
149 gnutls_assert ();
150 goto cleanup;
151 }
152
153 if (need_free)
154 _gnutls_free_datum (&_data);
155
156 return 0;
157
158cleanup:
159 if (need_free)
160 _gnutls_free_datum (&_data);
161 return result;
162}
163
164
165/**
166 * gnutls_x509_crl_get_issuer_dn - This function returns the CRL's issuer distinguished name
167 * @crl: should contain a gnutls_x509_crl_t structure
168 * @buf: a pointer to a structure to hold the peer's name (may be null)
169 * @sizeof_buf: initially holds the size of @buf
170 *
171 * This function will copy the name of the CRL issuer in the provided buffer. The name
172 * will be in the form "C=xxxx,O=yyyy,CN=zzzz" as described in RFC2253. The output
173 * string will be ASCII or UTF-8 encoded, depending on the certificate data.
174 *
175 * If buf is null then only the size will be filled.
176 *
177 * Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not long enough, and
178 * in that case the sizeof_buf will be updated with the required size, and
179 * 0 on success.
180 *
181 **/
182int
183gnutls_x509_crl_get_issuer_dn (const gnutls_x509_crl_t crl, char *buf,
184 size_t * sizeof_buf)
185{
186 if (crl == NULL)
187 {
188 gnutls_assert ();
189 return GNUTLS_E_INVALID_REQUEST;
190 }
191
192 return _gnutls_x509_parse_dn (crl->crl,
193 "tbsCertList.issuer.rdnSequence",
194 buf, sizeof_buf);
195}
196
197/**
198 * gnutls_x509_crl_get_issuer_dn_by_oid - This function returns the CRL's issuer distinguished name
199 * @crl: should contain a gnutls_x509_crl_t structure
200 * @oid: holds an Object Identified in null terminated string
201 * @indx: In case multiple same OIDs exist in the RDN, this specifies which to send. Use zero to get the first one.
202 * @raw_flag: If non zero returns the raw DER data of the DN part.
203 * @buf: a pointer to a structure to hold the peer's name (may be null)
204 * @sizeof_buf: initially holds the size of @buf
205 *
206 * This function will extract the part of the name of the CRL issuer specified
207 * by the given OID. The output will be encoded as described in RFC2253. The output
208 * string will be ASCII or UTF-8 encoded, depending on the certificate data.
209 *
210 * Some helper macros with popular OIDs can be found in gnutls/x509.h
211 * If raw flag is zero, this function will only return known OIDs as text. Other OIDs
212 * will be DER encoded, as described in RFC2253 -- in hex format with a '\#' prefix.
213 * You can check about known OIDs using gnutls_x509_dn_oid_known().
214 *
215 * If buf is null then only the size will be filled.
216 *
217 * Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not long enough, and
218 * in that case the sizeof_buf will be updated with the required size,
219 * and 0 on success.
220 *
221 **/
222int
223gnutls_x509_crl_get_issuer_dn_by_oid (gnutls_x509_crl_t crl,
224 const char *oid, int indx,
225 unsigned int raw_flag, void *buf,
226 size_t * sizeof_buf)
227{
228 if (crl == NULL)
229 {
230 gnutls_assert ();
231 return GNUTLS_E_INVALID_REQUEST;
232 }
233
234 return _gnutls_x509_parse_dn_oid (crl->crl,
235 "tbsCertList.issuer.rdnSequence",
236 oid, indx, raw_flag, buf, sizeof_buf);
237}
238
239/**
240 * gnutls_x509_crl_get_dn_oid - This function returns the Certificate request issuer's distinguished name OIDs
241 * @crl: should contain a gnutls_x509_crl_t structure
242 * @indx: Specifies which DN OID to send. Use zero to get the first one.
243 * @oid: a pointer to a structure to hold the name (may be null)
244 * @sizeof_oid: initially holds the size of 'oid'
245 *
246 * This function will extract the requested OID of the name of the CRL issuer, specified
247 * by the given index.
248 *
249 * If oid is null then only the size will be filled.
250 *
251 * Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not long enough, and
252 * in that case the sizeof_oid will be updated with the required size.
253 * On success 0 is returned.
254 *
255 **/
256int
257gnutls_x509_crl_get_dn_oid (gnutls_x509_crl_t crl,
258 int indx, void *oid, size_t * sizeof_oid)
259{
260 if (crl == NULL)
261 {
262 gnutls_assert ();
263 return GNUTLS_E_INVALID_REQUEST;
264 }
265
266 return _gnutls_x509_get_dn_oid (crl->crl,
267 "tbsCertList.issuer.rdnSequence", indx,
268 oid, sizeof_oid);
269}
270
271
272/**
273 * gnutls_x509_crl_get_signature_algorithm - This function returns the CRL's signature algorithm
274 * @crl: should contain a gnutls_x509_crl_t structure
275 *
276 * This function will return a value of the gnutls_sign_algorithm_t enumeration that
277 * is the signature algorithm.
278 *
279 * Returns a negative value on error.
280 *
281 **/
282int
283gnutls_x509_crl_get_signature_algorithm (gnutls_x509_crl_t crl)
284{
285 int result;
286 gnutls_datum_t sa;
287
288 if (crl == NULL)
289 {
290 gnutls_assert ();
291 return GNUTLS_E_INVALID_REQUEST;
292 }
293
294 /* Read the signature algorithm. Note that parameters are not
295 * read. They will be read from the issuer's certificate if needed.
296 */
297
298 result =
299 _gnutls_x509_read_value (crl->crl, "signatureAlgorithm.algorithm",
300 &sa, 0);
301
302 if (result < 0)
303 {
304 gnutls_assert ();
305 return result;
306 }
307
308 result = _gnutls_x509_oid2sign_algorithm ((const char *) sa.data);
309
310 _gnutls_free_datum (&sa);
311
312 return result;
313}
314
315/**
316 * gnutls_x509_crl_get_signature - Returns the CRL's signature
317 * @crl: should contain a gnutls_x509_crl_t structure
318 * @sig: a pointer where the signature part will be copied (may be null).
319 * @sizeof_sig: initially holds the size of @sig
320 *
321 * This function will extract the signature field of a CRL.
322 *
323 * Returns 0 on success, and a negative value on error.
324 **/
325int
326gnutls_x509_crl_get_signature (gnutls_x509_crl_t crl,
327 char *sig, size_t * sizeof_sig)
328{
329 int result;
330 int bits, len;
331
332 if (crl == NULL)
333 {
334 gnutls_assert ();
335 return GNUTLS_E_INVALID_REQUEST;
336 }
337
338 bits = 0;
339 result = asn1_read_value (crl->crl, "signature", NULL, &bits);
340 if (result != ASN1_MEM_ERROR)
341 {
342 gnutls_assert ();
343 return _gnutls_asn2err (result);
344 }
345
346 if (bits % 8 != 0)
347 {
348 gnutls_assert ();
349 return GNUTLS_E_CERTIFICATE_ERROR;
350 }
351
352 len = bits / 8;
353
354 if (*sizeof_sig < len)
355 {
356 *sizeof_sig = bits / 8;
357 return GNUTLS_E_SHORT_MEMORY_BUFFER;
358 }
359
360 result = asn1_read_value (crl->crl, "signature", sig, &len);
361 if (result != ASN1_SUCCESS)
362 {
363 gnutls_assert ();
364 return _gnutls_asn2err (result);
365 }
366
367 return 0;
368}
369
370/**
371 * gnutls_x509_crl_get_version - This function returns the CRL's version number
372 * @crl: should contain a gnutls_x509_crl_t structure
373 *
374 * This function will return the version of the specified CRL.
375 *
376 * Returns a negative value on error.
377 *
378 **/
379int
380gnutls_x509_crl_get_version (gnutls_x509_crl_t crl)
381{
382 opaque version[5];
383 int len, result;
384
385 if (crl == NULL)
386 {
387 gnutls_assert ();
388 return GNUTLS_E_INVALID_REQUEST;
389 }
390
391 len = sizeof (version);
392 if ((result =
393 asn1_read_value (crl->crl, "tbsCertList.version", version,
394 &len)) != ASN1_SUCCESS)
395 {
396 gnutls_assert ();
397 return _gnutls_asn2err (result);
398 }
399
400 return (int) version[0] + 1;
401}
402
403/**
404 * gnutls_x509_crl_get_this_update - This function returns the CRL's thisUpdate time
405 * @crl: should contain a gnutls_x509_crl_t structure
406 *
407 * This function will return the time this CRL was issued.
408 *
409 * Returns (time_t)-1 on error.
410 *
411 **/
412time_t
413gnutls_x509_crl_get_this_update (gnutls_x509_crl_t crl)
414{
415 if (crl == NULL)
416 {
417 gnutls_assert ();
418 return (time_t) - 1;
419 }
420
421 return _gnutls_x509_get_time (crl->crl, "tbsCertList.thisUpdate");
422}
423
424/**
425 * gnutls_x509_crl_get_next_update - This function returns the CRL's nextUpdate time
426 * @crl: should contain a gnutls_x509_crl_t structure
427 *
428 * This function will return the time the next CRL will be issued.
429 * This field is optional in a CRL so it might be normal to get
430 * an error instead.
431 *
432 * Returns (time_t)-1 on error.
433 *
434 **/
435time_t
436gnutls_x509_crl_get_next_update (gnutls_x509_crl_t crl)
437{
438 if (crl == NULL)
439 {
440 gnutls_assert ();
441 return (time_t) - 1;
442 }
443
444 return _gnutls_x509_get_time (crl->crl, "tbsCertList.nextUpdate");
445}
446
447/**
448 * gnutls_x509_crl_get_crt_count - This function returns the number of revoked certificates in a CRL
449 * @crl: should contain a gnutls_x509_crl_t structure
450 *
451 * This function will return the number of revoked certificates in the
452 * given CRL.
453 *
454 * Returns a negative value on failure.
455 *
456 **/
457int
458gnutls_x509_crl_get_crt_count (gnutls_x509_crl_t crl)
459{
460
461 int count, result;
462
463 if (crl == NULL)
464 {
465 gnutls_assert ();
466 return GNUTLS_E_INVALID_REQUEST;
467 }
468
469 result =
470 asn1_number_of_elements (crl->crl,
471 "tbsCertList.revokedCertificates", &count);
472
473 if (result != ASN1_SUCCESS)
474 {
475 gnutls_assert ();
476 return 0; /* no certificates */
477 }
478
479 return count;
480}
481
482/**
483 * gnutls_x509_crl_get_crt_serial - This function returns the serial number of a revoked certificate
484 * @crl: should contain a gnutls_x509_crl_t structure
485 * @indx: the index of the certificate to extract (starting from 0)
486 * @serial: where the serial number will be copied
487 * @serial_size: initially holds the size of serial
488 * @t: if non null, will hold the time this certificate was revoked
489 *
490 * This function will return the serial number of the specified, by
491 * the index, revoked certificate.
492 *
493 * Returns a negative value on failure.
494 *
495 **/
496int
497gnutls_x509_crl_get_crt_serial (gnutls_x509_crl_t crl, int indx,
498 unsigned char *serial,
499 size_t * serial_size, time_t * t)
500{
501
502 int result, _serial_size;
503 char serial_name[MAX_NAME_SIZE];
504 char date_name[MAX_NAME_SIZE];
505
506 if (crl == NULL)
507 {
508 gnutls_assert ();
509 return GNUTLS_E_INVALID_REQUEST;
510 }
511
512 snprintf (serial_name, sizeof (serial_name),
513 "tbsCertList.revokedCertificates.?%u.userCertificate", indx + 1);
514 snprintf (date_name, sizeof (date_name),
515 "tbsCertList.revokedCertificates.?%u.revocationDate", indx + 1);
516
517 _serial_size = *serial_size;
518 result = asn1_read_value (crl->crl, serial_name, serial, &_serial_size);
519
520 *serial_size = _serial_size;
521 if (result != ASN1_SUCCESS)
522 {
523 gnutls_assert ();
524 if (result == ASN1_ELEMENT_NOT_FOUND)
525 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
526 return _gnutls_asn2err (result);
527 }
528
529 if (t)
530 {
531 *t = _gnutls_x509_get_time (crl->crl, date_name);
532 }
533
534 return 0;
535}
536
537/*-
538 * _gnutls_x509_crl_get_raw_issuer_dn - This function returns the issuer's DN DER encoded
539 * @crl: should contain a gnutls_x509_crl_t structure
540 * @dn: will hold the starting point of the DN
541 *
542 * This function will return a pointer to the DER encoded DN structure and
543 * the length.
544 *
545 * Returns a negative value on error, and zero on success.
546 *
547 -*/
548int
549_gnutls_x509_crl_get_raw_issuer_dn (gnutls_x509_crl_t crl,
550 gnutls_datum_t * dn)
551{
552 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
553 int result, len1;
554 int start1, end1;
555 gnutls_datum_t crl_signed_data;
556
557 if (crl == NULL)
558 {
559 gnutls_assert ();
560 return GNUTLS_E_INVALID_REQUEST;
561 }
562
563 /* get the issuer of 'crl'
564 */
565 if ((result =
566 asn1_create_element (_gnutls_get_pkix (), "PKIX1.TBSCertList",
567 &c2)) != ASN1_SUCCESS)
568 {
569 gnutls_assert ();
570 return _gnutls_asn2err (result);
571 }
572
573 result =
574 _gnutls_x509_get_signed_data (crl->crl, "tbsCertList", &crl_signed_data);
575 if (result < 0)
576 {
577 gnutls_assert ();
578 goto cleanup;
579 }
580
581 result =
582 asn1_der_decoding (&c2, crl_signed_data.data, crl_signed_data.size, NULL);
583 if (result != ASN1_SUCCESS)
584 {
585 /* couldn't decode DER */
586 gnutls_assert ();
587 asn1_delete_structure (&c2);
588 result = _gnutls_asn2err (result);
589 goto cleanup;
590 }
591
592 result =
593 asn1_der_decoding_startEnd (c2, crl_signed_data.data,
594 crl_signed_data.size, "issuer",
595 &start1, &end1);
596
597 if (result != ASN1_SUCCESS)
598 {
599 gnutls_assert ();
600 result = _gnutls_asn2err (result);
601 goto cleanup;
602 }
603
604 len1 = end1 - start1 + 1;
605
606 _gnutls_set_datum (dn, &crl_signed_data.data[start1], len1);
607
608 result = 0;
609
610cleanup:
611 asn1_delete_structure (&c2);
612 _gnutls_free_datum (&crl_signed_data);
613 return result;
614}
615
616/**
617 * gnutls_x509_crl_export - This function will export the CRL
618 * @crl: Holds the revocation list
619 * @format: the format of output params. One of PEM or DER.
620 * @output_data: will contain a private key PEM or DER encoded
621 * @output_data_size: holds the size of output_data (and will be replaced by the actual size of parameters)
622 *
623 * This function will export the revocation list to DER or PEM format.
624 *
625 * If the buffer provided is not long enough to hold the output, then
626 * GNUTLS_E_SHORT_MEMORY_BUFFER will be returned.
627 *
628 * If the structure is PEM encoded, it will have a header
629 * of "BEGIN X509 CRL".
630 *
631 * Returns 0 on success, and a negative value on failure.
632 *
633 **/
634int
635gnutls_x509_crl_export (gnutls_x509_crl_t crl,
636 gnutls_x509_crt_fmt_t format, void *output_data,
637 size_t * output_data_size)
638{
639 if (crl == NULL)
640 {
641 gnutls_assert ();
642 return GNUTLS_E_INVALID_REQUEST;
643 }
644
645 return _gnutls_x509_export_int (crl->crl, format, PEM_CRL,
646 output_data, output_data_size);
647}
648
649/*-
650 * _gnutls_x509_crl_cpy - This function copies a gnutls_x509_crl_t structure
651 * @dest: The structure where to copy
652 * @src: The structure to be copied
653 *
654 * This function will copy an X.509 certificate structure.
655 *
656 * Returns 0 on success.
657 *
658 -*/
659int
660_gnutls_x509_crl_cpy (gnutls_x509_crl_t dest, gnutls_x509_crl_t src)
661{
662 int ret;
663 size_t der_size;
664 opaque *der;
665 gnutls_datum_t tmp;
666
667 ret = gnutls_x509_crl_export (src, GNUTLS_X509_FMT_DER, NULL, &der_size);
668 if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
669 {
670 gnutls_assert ();
671 return ret;
672 }
673
674 der = gnutls_alloca (der_size);
675 if (der == NULL)
676 {
677 gnutls_assert ();
678 return GNUTLS_E_MEMORY_ERROR;
679 }
680
681 ret = gnutls_x509_crl_export (src, GNUTLS_X509_FMT_DER, der, &der_size);
682 if (ret < 0)
683 {
684 gnutls_assert ();
685 gnutls_afree (der);
686 return ret;
687 }
688
689 tmp.data = der;
690 tmp.size = der_size;
691 ret = gnutls_x509_crl_import (dest, &tmp, GNUTLS_X509_FMT_DER);
692
693 gnutls_afree (der);
694
695 if (ret < 0)
696 {
697 gnutls_assert ();
698 return ret;
699 }
700
701 return 0;
702
703}
704
705#endif
diff --git a/src/daemon/https/x509/crl_write.c b/src/daemon/https/x509/crl_write.c
new file mode 100644
index 00000000..370a492c
--- /dev/null
+++ b/src/daemon/https/x509/crl_write.c
@@ -0,0 +1,316 @@
1/*
2 * Copyright (C) 2003, 2004, 2005 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/* This file contains functions to handle CRL generation.
26 */
27
28#include <gnutls_int.h>
29
30#ifdef ENABLE_PKI
31
32#include <gnutls_datum.h>
33#include <gnutls_global.h>
34#include <gnutls_errors.h>
35#include <common.h>
36#include <gnutls_x509.h>
37#include <x509_b64.h>
38#include <crq.h>
39#include <dn.h>
40#include <mpi.h>
41#include <sign.h>
42#include <extensions.h>
43#include <libtasn1.h>
44
45static void disable_optional_stuff (gnutls_x509_crl_t crl);
46
47/**
48 * gnutls_x509_crl_set_version - This function will set the CRL version
49 * @crl: should contain a gnutls_x509_crl_t structure
50 * @version: holds the version number. For CRLv1 crls must be 1.
51 *
52 * This function will set the version of the CRL. This
53 * must be one for CRL version 1, and so on. The CRLs generated
54 * by gnutls should have a version number of 2.
55 *
56 * Returns 0 on success.
57 *
58 **/
59int
60gnutls_x509_crl_set_version (gnutls_x509_crl_t crl, unsigned int version)
61{
62 int result;
63 char null = version;
64
65 if (crl == NULL)
66 {
67 gnutls_assert ();
68 return GNUTLS_E_INVALID_REQUEST;
69 }
70
71 null -= 1;
72 if (null < 0)
73 null = 0;
74
75 result = asn1_write_value (crl->crl, "tbsCertList.version", &null, 1);
76 if (result != ASN1_SUCCESS)
77 {
78 gnutls_assert ();
79 return _gnutls_asn2err (result);
80 }
81
82 return 0;
83}
84
85/**
86 * gnutls_x509_crl_sign2 - This function will sign a CRL with a key
87 * @crl: should contain a gnutls_x509_crl_t structure
88 * @issuer: is the certificate of the certificate issuer
89 * @issuer_key: holds the issuer's private key
90 * @dig: The message digest to use. GNUTLS_DIG_SHA1 is the safe choice unless you know what you're doing.
91 * @flags: must be 0
92 *
93 * This function will sign the CRL with the issuer's private key, and
94 * will copy the issuer's information into the CRL.
95 *
96 * This must be the last step in a certificate CRL since all
97 * the previously set parameters are now signed.
98 *
99 * Returns 0 on success.
100 *
101 **/
102int
103gnutls_x509_crl_sign2 (gnutls_x509_crl_t crl, gnutls_x509_crt_t issuer,
104 gnutls_x509_privkey_t issuer_key,
105 gnutls_digest_algorithm_t dig, unsigned int flags)
106{
107 int result;
108
109 if (crl == NULL || issuer == NULL)
110 {
111 gnutls_assert ();
112 return GNUTLS_E_INVALID_REQUEST;
113 }
114
115 /* disable all the unneeded OPTIONAL fields.
116 */
117 disable_optional_stuff (crl);
118
119 result = _gnutls_x509_pkix_sign (crl->crl, "tbsCertList",
120 dig, issuer, issuer_key);
121 if (result < 0)
122 {
123 gnutls_assert ();
124 return result;
125 }
126
127 return 0;
128}
129
130/**
131 * gnutls_x509_crl_sign - This function will sign a CRL with a key
132 * @crl: should contain a gnutls_x509_crl_t structure
133 * @issuer: is the certificate of the certificate issuer
134 * @issuer_key: holds the issuer's private key
135 *
136 * This function is the same a gnutls_x509_crl_sign2() with no flags, and
137 * SHA1 as the hash algorithm.
138 *
139 * Returns 0 on success.
140 *
141 **/
142int
143gnutls_x509_crl_sign (gnutls_x509_crl_t crl, gnutls_x509_crt_t issuer,
144 gnutls_x509_privkey_t issuer_key)
145{
146 return gnutls_x509_crl_sign2 (crl, issuer, issuer_key, GNUTLS_DIG_SHA1, 0);
147}
148
149/**
150 * gnutls_x509_crl_set_this_update - This function will set the CRL's issuing time
151 * @crl: should contain a gnutls_x509_crl_t structure
152 * @act_time: The actual time
153 *
154 * This function will set the time this CRL was issued.
155 *
156 * Returns 0 on success, or a negative value in case of an error.
157 *
158 **/
159int
160gnutls_x509_crl_set_this_update (gnutls_x509_crl_t crl, time_t act_time)
161{
162 if (crl == NULL)
163 {
164 gnutls_assert ();
165 return GNUTLS_E_INVALID_REQUEST;
166 }
167
168 return _gnutls_x509_set_time (crl->crl, "tbsCertList.thisUpdate", act_time);
169}
170
171/**
172 * gnutls_x509_crl_set_next_update - This function will set the CRL next update time
173 * @crl: should contain a gnutls_x509_crl_t structure
174 * @exp_time: The actual time
175 *
176 * This function will set the time this CRL will be updated.
177 *
178 * Returns 0 on success, or a negative value in case of an error.
179 *
180 **/
181int
182gnutls_x509_crl_set_next_update (gnutls_x509_crl_t crl, time_t exp_time)
183{
184 if (crl == NULL)
185 {
186 gnutls_assert ();
187 return GNUTLS_E_INVALID_REQUEST;
188 }
189 return _gnutls_x509_set_time (crl->crl, "tbsCertList.nextUpdate", exp_time);
190}
191
192/**
193 * gnutls_x509_crl_set_crt_serial - This function will set a revoked certificate's serial number
194 * @crl: should contain a gnutls_x509_crl_t structure
195 * @serial: The revoked certificate's serial number
196 * @serial_size: Holds the size of the serial field.
197 * @revocation_time: The time this certificate was revoked
198 *
199 * This function will set a revoked certificate's serial number to the CRL.
200 *
201 * Returns 0 on success, or a negative value in case of an error.
202 *
203 **/
204int
205gnutls_x509_crl_set_crt_serial (gnutls_x509_crl_t crl,
206 const void *serial, size_t serial_size,
207 time_t revocation_time)
208{
209 int ret;
210
211 if (crl == NULL)
212 {
213 gnutls_assert ();
214 return GNUTLS_E_INVALID_REQUEST;
215 }
216
217 ret =
218 asn1_write_value (crl->crl, "tbsCertList.revokedCertificates", "NEW", 1);
219 if (ret != ASN1_SUCCESS)
220 {
221 gnutls_assert ();
222 return _gnutls_asn2err (ret);
223 }
224
225 ret =
226 asn1_write_value (crl->crl,
227 "tbsCertList.revokedCertificates.?LAST.userCertificate",
228 serial, serial_size);
229 if (ret != ASN1_SUCCESS)
230 {
231 gnutls_assert ();
232 return _gnutls_asn2err (ret);
233 }
234
235 ret =
236 _gnutls_x509_set_time (crl->crl,
237 "tbsCertList.revokedCertificates.?LAST.revocationDate",
238 revocation_time);
239 if (ret < 0)
240 {
241 gnutls_assert ();
242 return ret;
243 }
244
245 ret =
246 asn1_write_value (crl->crl,
247 "tbsCertList.revokedCertificates.?LAST.crlEntryExtensions",
248 NULL, 0);
249 if (ret != ASN1_SUCCESS)
250 {
251 gnutls_assert ();
252 return _gnutls_asn2err (ret);
253 }
254
255 return 0;
256}
257
258/**
259 * gnutls_x509_crl_set_crt - This function will set a revoked certificate's serial number
260 * @crl: should contain a gnutls_x509_crl_t structure
261 * @crt: should contain a gnutls_x509_crt_t structure with the revoked certificate
262 * @revocation_time: The time this certificate was revoked
263 *
264 * This function will set a revoked certificate's serial number to the CRL.
265 *
266 * Returns 0 on success, or a negative value in case of an error.
267 *
268 **/
269int
270gnutls_x509_crl_set_crt (gnutls_x509_crl_t crl, gnutls_x509_crt_t crt,
271 time_t revocation_time)
272{
273 int ret;
274 opaque serial[128];
275 size_t serial_size;
276
277 if (crl == NULL || crt == NULL)
278 {
279 gnutls_assert ();
280 return GNUTLS_E_INVALID_REQUEST;
281 }
282
283 serial_size = sizeof (serial);
284 ret = gnutls_x509_crt_get_serial (crt, serial, &serial_size);
285 if (ret < 0)
286 {
287 gnutls_assert ();
288 return ret;
289 }
290
291 ret =
292 gnutls_x509_crl_set_crt_serial (crl, serial, serial_size,
293 revocation_time);
294 if (ret < 0)
295 {
296 gnutls_assert ();
297 return _gnutls_asn2err (ret);
298 }
299
300 return 0;
301}
302
303
304/* If OPTIONAL fields have not been initialized then
305 * disable them.
306 */
307static void
308disable_optional_stuff (gnutls_x509_crl_t crl)
309{
310
311 asn1_write_value (crl->crl, "tbsCertList.crlExtensions", NULL, 0);
312
313 return;
314}
315
316#endif /* ENABLE_PKI */
diff --git a/src/daemon/https/x509/crq.c b/src/daemon/https/x509/crq.c
new file mode 100644
index 00000000..8e663d51
--- /dev/null
+++ b/src/daemon/https/x509/crq.c
@@ -0,0 +1,887 @@
1/*
2 * Copyright (C) 2003, 2004, 2005 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/* This file contains functions to handle PKCS #10 certificate requests.
26 */
27
28#include <gnutls_int.h>
29
30#ifdef ENABLE_PKI
31
32#include <gnutls_datum.h>
33#include <gnutls_global.h>
34#include <gnutls_errors.h>
35#include <common.h>
36#include <gnutls_x509.h>
37#include <x509_b64.h>
38#include <crq.h>
39#include <dn.h>
40#include <mpi.h>
41#include <sign.h>
42#include <extensions.h>
43#include <libtasn1.h>
44
45/**
46 * gnutls_x509_crq_init - This function initializes a gnutls_x509_crq_t structure
47 * @crq: The structure to be initialized
48 *
49 * This function will initialize a PKCS10 certificate request structure.
50 *
51 * Returns 0 on success.
52 *
53 **/
54int
55gnutls_x509_crq_init (gnutls_x509_crq_t * crq)
56{
57 *crq = gnutls_calloc (1, sizeof (gnutls_x509_crq_int));
58
59 if (*crq)
60 {
61 int result = asn1_create_element (_gnutls_get_pkix (),
62 "PKIX1.pkcs-10-CertificationRequest",
63 &((*crq)->crq));
64 if (result != ASN1_SUCCESS)
65 {
66 gnutls_assert ();
67 gnutls_free (*crq);
68 return _gnutls_asn2err (result);
69 }
70 return 0; /* success */
71 }
72 return GNUTLS_E_MEMORY_ERROR;
73}
74
75/**
76 * gnutls_x509_crq_deinit - This function deinitializes memory used by a gnutls_x509_crq_t structure
77 * @crq: The structure to be initialized
78 *
79 * This function will deinitialize a CRL structure.
80 *
81 **/
82void
83gnutls_x509_crq_deinit (gnutls_x509_crq_t crq)
84{
85 if (!crq)
86 return;
87
88 if (crq->crq)
89 asn1_delete_structure (&crq->crq);
90
91 gnutls_free (crq);
92}
93
94#define PEM_CRQ "NEW CERTIFICATE REQUEST"
95#define PEM_CRQ2 "CERTIFICATE REQUEST"
96
97/**
98 * gnutls_x509_crq_import - This function will import a DER or PEM encoded Certificate request
99 * @crq: The structure to store the parsed certificate request.
100 * @data: The DER or PEM encoded certificate.
101 * @format: One of DER or PEM
102 *
103 * This function will convert the given DER or PEM encoded Certificate
104 * to the native gnutls_x509_crq_t format. The output will be stored in @cert.
105 *
106 * If the Certificate is PEM encoded it should have a header of "NEW CERTIFICATE REQUEST".
107 *
108 * Returns 0 on success.
109 *
110 **/
111int
112gnutls_x509_crq_import (gnutls_x509_crq_t crq,
113 const gnutls_datum_t * data,
114 gnutls_x509_crt_fmt_t format)
115{
116 int result = 0, need_free = 0;
117 gnutls_datum_t _data;
118
119 if (crq == NULL)
120 {
121 gnutls_assert ();
122 return GNUTLS_E_INVALID_REQUEST;
123 }
124
125 _data.data = data->data;
126 _data.size = data->size;
127
128 /* If the Certificate is in PEM format then decode it
129 */
130 if (format == GNUTLS_X509_FMT_PEM)
131 {
132 opaque *out;
133
134 /* Try the first header */
135 result = _gnutls_fbase64_decode (PEM_CRQ, data->data, data->size, &out);
136
137 if (result <= 0) /* Go for the second header */
138 result =
139 _gnutls_fbase64_decode (PEM_CRQ2, data->data, data->size, &out);
140
141 if (result <= 0)
142 {
143 if (result == 0)
144 result = GNUTLS_E_INTERNAL_ERROR;
145 gnutls_assert ();
146 return result;
147 }
148
149 _data.data = out;
150 _data.size = result;
151
152 need_free = 1;
153 }
154
155 result = asn1_der_decoding (&crq->crq, _data.data, _data.size, NULL);
156 if (result != ASN1_SUCCESS)
157 {
158 result = _gnutls_asn2err (result);
159 gnutls_assert ();
160 goto cleanup;
161 }
162
163 result = 0;
164
165cleanup:
166 if (need_free)
167 _gnutls_free_datum (&_data);
168 return result;
169}
170
171
172
173/**
174 * gnutls_x509_crq_get_dn - This function returns the Certificate request subject's distinguished name
175 * @crq: should contain a gnutls_x509_crq_t structure
176 * @buf: a pointer to a structure to hold the name (may be null)
177 * @sizeof_buf: initially holds the size of @buf
178 *
179 * This function will copy the name of the Certificate request
180 * subject in the provided buffer. The name will be in the form
181 * "C=xxxx,O=yyyy,CN=zzzz" as described in RFC2253. The output string
182 * will be ASCII or UTF-8 encoded, depending on the certificate data.
183 *
184 * If @buf is null then only the size will be filled.
185 *
186 * Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
187 * long enough, and in that case the *sizeof_buf will be updated with
188 * the required size. On success 0 is returned.
189 *
190 **/
191int
192gnutls_x509_crq_get_dn (gnutls_x509_crq_t crq, char *buf, size_t * sizeof_buf)
193{
194 if (crq == NULL)
195 {
196 gnutls_assert ();
197 return GNUTLS_E_INVALID_REQUEST;
198 }
199
200 return _gnutls_x509_parse_dn (crq->crq,
201 "certificationRequestInfo.subject.rdnSequence",
202 buf, sizeof_buf);
203}
204
205/**
206 * gnutls_x509_crq_get_dn_by_oid - This function returns the Certificate request subject's distinguished name
207 * @crq: should contain a gnutls_x509_crq_t structure
208 * @oid: holds an Object Identified in null terminated string
209 * @indx: In case multiple same OIDs exist in the RDN, this specifies
210 * which to send. Use zero to get the first one.
211 * @raw_flag: If non zero returns the raw DER data of the DN part.
212 * @buf: a pointer to a structure to hold the name (may be null)
213 * @sizeof_buf: initially holds the size of @buf
214 *
215 * This function will extract the part of the name of the Certificate
216 * request subject, specified by the given OID. The output will be
217 * encoded as described in RFC2253. The output string will be ASCII
218 * or UTF-8 encoded, depending on the certificate data.
219 *
220 * Some helper macros with popular OIDs can be found in gnutls/x509.h
221 * If raw flag is zero, this function will only return known OIDs as
222 * text. Other OIDs will be DER encoded, as described in RFC2253 --
223 * in hex format with a '\#' prefix. You can check about known OIDs
224 * using gnutls_x509_dn_oid_known().
225 *
226 * If @buf is null then only the size will be filled.
227 *
228 * Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
229 * long enough, and in that case the *sizeof_buf will be updated with
230 * the required size. On success 0 is returned.
231 *
232 **/
233int
234gnutls_x509_crq_get_dn_by_oid (gnutls_x509_crq_t crq, const char *oid,
235 int indx, unsigned int raw_flag,
236 void *buf, size_t * sizeof_buf)
237{
238 if (crq == NULL)
239 {
240 gnutls_assert ();
241 return GNUTLS_E_INVALID_REQUEST;
242 }
243
244 return _gnutls_x509_parse_dn_oid (crq->crq,
245 "certificationRequestInfo.subject.rdnSequence",
246 oid, indx, raw_flag, buf, sizeof_buf);
247}
248
249/**
250 * gnutls_x509_crq_get_dn_oid - This function returns the Certificate request subject's distinguished name OIDs
251 * @crq: should contain a gnutls_x509_crq_t structure
252 * @indx: Specifies which DN OID to send. Use zero to get the first one.
253 * @oid: a pointer to a structure to hold the name (may be null)
254 * @sizeof_oid: initially holds the size of @oid
255 *
256 * This function will extract the requested OID of the name of the
257 * Certificate request subject, specified by the given index.
258 *
259 * If oid is null then only the size will be filled.
260 *
261 * Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
262 * long enough, and in that case the *sizeof_oid will be updated with
263 * the required size. On success 0 is returned.
264 *
265 **/
266int
267gnutls_x509_crq_get_dn_oid (gnutls_x509_crq_t crq,
268 int indx, void *oid, size_t * sizeof_oid)
269{
270 if (crq == NULL)
271 {
272 gnutls_assert ();
273 return GNUTLS_E_INVALID_REQUEST;
274 }
275
276 return _gnutls_x509_get_dn_oid (crq->crq,
277 "certificationRequestInfo.subject.rdnSequence",
278 indx, oid, sizeof_oid);
279}
280
281/* Parses an Attribute list in the asn1_struct, and searches for the
282 * given OID. The index indicates the attribute value to be returned.
283 *
284 * If raw==0 only printable data are returned, or GNUTLS_E_X509_UNSUPPORTED_ATTRIBUTE.
285 *
286 * asn1_attr_name must be a string in the form "certificationRequestInfo.attributes"
287 *
288 */
289static int
290parse_attribute (ASN1_TYPE asn1_struct,
291 const char *attr_name, const char *given_oid, int indx,
292 int raw, char *buf, size_t * sizeof_buf)
293{
294 int k1, result;
295 char tmpbuffer1[MAX_NAME_SIZE];
296 char tmpbuffer3[MAX_NAME_SIZE];
297 char value[200];
298 char oid[128];
299 int len, printable;
300
301 if (*sizeof_buf == 0)
302 {
303 gnutls_assert ();
304 return GNUTLS_E_INVALID_REQUEST;
305 }
306
307 buf[0] = 0;
308
309 k1 = 0;
310 do
311 {
312
313 k1++;
314 /* create a string like "attribute.?1"
315 */
316 if (attr_name[0] != 0)
317 snprintf (tmpbuffer1, sizeof (tmpbuffer1), "%s.?%u", attr_name, k1);
318 else
319 snprintf (tmpbuffer1, sizeof (tmpbuffer1), "?%u", k1);
320
321 len = sizeof (value) - 1;
322 result = asn1_read_value (asn1_struct, tmpbuffer1, value, &len);
323
324 if (result == ASN1_ELEMENT_NOT_FOUND)
325 {
326 gnutls_assert ();
327 break;
328 }
329
330 if (result != ASN1_VALUE_NOT_FOUND)
331 {
332 gnutls_assert ();
333 result = _gnutls_asn2err (result);
334 goto cleanup;
335 }
336
337 /* Move to the attibute type and values
338 */
339 /* Read the OID
340 */
341 _gnutls_str_cpy (tmpbuffer3, sizeof (tmpbuffer3), tmpbuffer1);
342 _gnutls_str_cat (tmpbuffer3, sizeof (tmpbuffer3), ".type");
343
344 len = sizeof (oid) - 1;
345 result = asn1_read_value (asn1_struct, tmpbuffer3, oid, &len);
346
347 if (result == ASN1_ELEMENT_NOT_FOUND)
348 break;
349 else if (result != ASN1_SUCCESS)
350 {
351 gnutls_assert ();
352 result = _gnutls_asn2err (result);
353 goto cleanup;
354 }
355
356 if (strcmp (oid, given_oid) == 0)
357 { /* Found the OID */
358
359 /* Read the Value
360 */
361 snprintf (tmpbuffer3, sizeof (tmpbuffer3), "%s.values.?%u",
362 tmpbuffer1, indx + 1);
363
364 len = sizeof (value) - 1;
365 result = asn1_read_value (asn1_struct, tmpbuffer3, value, &len);
366
367 if (result != ASN1_SUCCESS)
368 {
369 gnutls_assert ();
370 result = _gnutls_asn2err (result);
371 goto cleanup;
372 }
373
374 if (raw == 0)
375 {
376 printable = _gnutls_x509_oid_data_printable (oid);
377 if (printable == 1)
378 {
379 if ((result =
380 _gnutls_x509_oid_data2string
381 (oid, value, len, buf, sizeof_buf)) < 0)
382 {
383 gnutls_assert ();
384 goto cleanup;
385 }
386 return 0;
387 }
388 else
389 {
390 gnutls_assert ();
391 return GNUTLS_E_X509_UNSUPPORTED_ATTRIBUTE;
392 }
393 }
394 else
395 { /* raw!=0 */
396 if (*sizeof_buf > (size_t) len && buf != NULL)
397 {
398 *sizeof_buf = len;
399 memcpy (buf, value, len);
400
401 return 0;
402 }
403 else
404 {
405 *sizeof_buf = len;
406 gnutls_assert ();
407 return GNUTLS_E_SHORT_MEMORY_BUFFER;
408 }
409 }
410 }
411
412 }
413 while (1);
414
415 gnutls_assert ();
416
417 result = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
418
419cleanup:
420 return result;
421}
422
423/**
424 * gnutls_x509_crq_get_challenge_password - This function will get the challenge password
425 * @crq: should contain a gnutls_x509_crq_t structure
426 * @pass: will hold a null terminated password
427 * @sizeof_pass: Initially holds the size of @pass.
428 *
429 * This function will return the challenge password in the
430 * request.
431 *
432 * Returns 0 on success.
433 *
434 **/
435int
436gnutls_x509_crq_get_challenge_password (gnutls_x509_crq_t crq,
437 char *pass, size_t * sizeof_pass)
438{
439 if (crq == NULL)
440 {
441 gnutls_assert ();
442 return GNUTLS_E_INVALID_REQUEST;
443 }
444
445 return parse_attribute (crq->crq, "certificationRequestInfo.attributes",
446 "1.2.840.113549.1.9.7", 0, 0, pass, sizeof_pass);
447}
448
449/**
450 * gnutls_x509_crq_set_attribute_by_oid - This function will set an attribute in the request
451 * @crq: should contain a gnutls_x509_crq_t structure
452 * @oid: holds an Object Identified in null terminated string
453 * @buf: a pointer to a structure that holds the attribute data
454 * @sizeof_buf: holds the size of @buf
455 *
456 * This function will set the attribute in the certificate request specified
457 * by the given Object ID. The attribute must be be DER encoded.
458 *
459 * Returns 0 on success.
460 *
461 **/
462int
463gnutls_x509_crq_set_attribute_by_oid (gnutls_x509_crq_t crq,
464 const char *oid, void *buf,
465 size_t sizeof_buf)
466{
467 int result;
468
469 if (crq == NULL)
470 {
471 gnutls_assert ();
472 return GNUTLS_E_INVALID_REQUEST;
473 }
474
475 /* Add the attribute.
476 */
477 result =
478 asn1_write_value (crq->crq, "certificationRequestInfo.attributes",
479 "NEW", 1);
480 if (result != ASN1_SUCCESS)
481 {
482 gnutls_assert ();
483 return _gnutls_asn2err (result);
484 }
485
486 result =
487 _gnutls_x509_encode_and_write_attribute (oid,
488 crq->crq,
489 "certificationRequestInfo.attributes.?LAST",
490 buf, sizeof_buf, 1);
491
492 if (result < 0)
493 {
494 gnutls_assert ();
495 return result;
496 }
497
498 return 0;
499}
500
501/**
502 * gnutls_x509_crq_get_attribute_by_oid - This function will get an attribute of the request
503 * @crq: should contain a gnutls_x509_crq_t structure
504 * @oid: holds an Object Identified in null terminated string
505 * @indx: In case multiple same OIDs exist in the attribute list, this specifies
506 * which to send. Use zero to get the first one.
507 * @buf: a pointer to a structure to hold the attribute data (may be null)
508 * @sizeof_buf: initially holds the size of @buf
509 *
510 * This function will return the attribute in the certificate request specified
511 * by the given Object ID. The attribute will be DER encoded.
512 *
513 * Returns 0 on success.
514 *
515 **/
516int
517gnutls_x509_crq_get_attribute_by_oid (gnutls_x509_crq_t crq,
518 const char *oid, int indx, void *buf,
519 size_t * sizeof_buf)
520{
521 if (crq == NULL)
522 {
523 gnutls_assert ();
524 return GNUTLS_E_INVALID_REQUEST;
525 }
526
527 return parse_attribute (crq->crq, "certificationRequestInfo.attributes",
528 oid, indx, 1, buf, sizeof_buf);
529}
530
531/**
532 * gnutls_x509_crq_set_dn_by_oid - This function will set the Certificate request subject's distinguished name
533 * @crq: should contain a gnutls_x509_crq_t structure
534 * @oid: holds an Object Identifier in a null terminated string
535 * @raw_flag: must be 0, or 1 if the data are DER encoded
536 * @data: a pointer to the input data
537 * @sizeof_data: holds the size of @data
538 *
539 * This function will set the part of the name of the Certificate request subject, specified
540 * by the given OID. The input string should be ASCII or UTF-8 encoded.
541 *
542 * Some helper macros with popular OIDs can be found in gnutls/x509.h
543 * With this function you can only set the known OIDs. You can test
544 * for known OIDs using gnutls_x509_dn_oid_known(). For OIDs that are
545 * not known (by gnutls) you should properly DER encode your data, and
546 * call this function with raw_flag set.
547 *
548 * Returns 0 on success.
549 *
550 **/
551int
552gnutls_x509_crq_set_dn_by_oid (gnutls_x509_crq_t crq, const char *oid,
553 unsigned int raw_flag, const void *data,
554 unsigned int sizeof_data)
555{
556 if (sizeof_data == 0 || data == NULL || crq == NULL)
557 {
558 return GNUTLS_E_INVALID_REQUEST;
559 }
560
561 return _gnutls_x509_set_dn_oid (crq->crq,
562 "certificationRequestInfo.subject", oid,
563 raw_flag, data, sizeof_data);
564}
565
566/**
567 * gnutls_x509_crq_set_version - This function will set the Certificate request version
568 * @crq: should contain a gnutls_x509_crq_t structure
569 * @version: holds the version number. For v1 Requests must be 1.
570 *
571 * This function will set the version of the certificate request. For
572 * version 1 requests this must be one.
573 *
574 * Returns 0 on success.
575 *
576 **/
577int
578gnutls_x509_crq_set_version (gnutls_x509_crq_t crq, unsigned int version)
579{
580 int result;
581 unsigned char null = version;
582
583 if (crq == NULL)
584 {
585 gnutls_assert ();
586 return GNUTLS_E_INVALID_REQUEST;
587 }
588
589 if (null > 0)
590 null--;
591
592 result =
593 asn1_write_value (crq->crq, "certificationRequestInfo.version", &null, 1);
594 if (result != ASN1_SUCCESS)
595 {
596 gnutls_assert ();
597 return _gnutls_asn2err (result);
598 }
599
600 return 0;
601}
602
603/**
604 * gnutls_x509_crq_get_version - This function returns the Certificate request's version number
605 * @crq: should contain a gnutls_x509_crq_t structure
606 *
607 * This function will return the version of the specified Certificate request.
608 *
609 * Returns a negative value on error.
610 *
611 **/
612int
613gnutls_x509_crq_get_version (gnutls_x509_crq_t crq)
614{
615 opaque version[5];
616 int len, result;
617
618 if (crq == NULL)
619 {
620 gnutls_assert ();
621 return GNUTLS_E_INVALID_REQUEST;
622 }
623
624 len = sizeof (version);
625 if ((result =
626 asn1_read_value (crq->crq, "certificationRequestInfo.version",
627 version, &len)) != ASN1_SUCCESS)
628 {
629
630 if (result == ASN1_ELEMENT_NOT_FOUND)
631 return 1; /* the DEFAULT version */
632 gnutls_assert ();
633 return _gnutls_asn2err (result);
634 }
635
636 return (int) version[0] + 1;
637}
638
639/**
640 * gnutls_x509_crq_set_key - This function will associate the Certificate request with a key
641 * @crq: should contain a gnutls_x509_crq_t structure
642 * @key: holds a private key
643 *
644 * This function will set the public parameters from the given private key to the
645 * request. Only RSA keys are currently supported.
646 *
647 * Returns 0 on success.
648 *
649 **/
650int
651gnutls_x509_crq_set_key (gnutls_x509_crq_t crq, gnutls_x509_privkey_t key)
652{
653 int result;
654
655 if (crq == NULL)
656 {
657 gnutls_assert ();
658 return GNUTLS_E_INVALID_REQUEST;
659 }
660
661 result = _gnutls_x509_encode_and_copy_PKI_params (crq->crq,
662 "certificationRequestInfo.subjectPKInfo",
663 key->pk_algorithm,
664 key->params,
665 key->params_size);
666
667 if (result < 0)
668 {
669 gnutls_assert ();
670 return result;
671 }
672
673 return 0;
674}
675
676/**
677 * gnutls_x509_crq_set_challenge_password - This function will set a challenge password
678 * @crq: should contain a gnutls_x509_crq_t structure
679 * @pass: holds a null terminated password
680 *
681 * This function will set a challenge password to be used when revoking the request.
682 *
683 * Returns 0 on success.
684 *
685 **/
686int
687gnutls_x509_crq_set_challenge_password (gnutls_x509_crq_t crq,
688 const char *pass)
689{
690 int result;
691
692 if (crq == NULL)
693 {
694 gnutls_assert ();
695 return GNUTLS_E_INVALID_REQUEST;
696 }
697
698 /* Add the attribute.
699 */
700 result =
701 asn1_write_value (crq->crq, "certificationRequestInfo.attributes",
702 "NEW", 1);
703 if (result != ASN1_SUCCESS)
704 {
705 gnutls_assert ();
706 return _gnutls_asn2err (result);
707 }
708
709 result =
710 _gnutls_x509_encode_and_write_attribute ("1.2.840.113549.1.9.7",
711 crq->crq,
712 "certificationRequestInfo.attributes.?LAST",
713 pass, strlen (pass), 1);
714
715 if (result < 0)
716 {
717 gnutls_assert ();
718 return result;
719 }
720
721 return 0;
722}
723
724/**
725 * gnutls_x509_crq_sign2 - This function will sign a Certificate request with a key
726 * @crq: should contain a gnutls_x509_crq_t structure
727 * @key: holds a private key
728 * @dig: The message digest to use. GNUTLS_DIG_SHA1 is the safe choice unless you know what you're doing.
729 * @flags: must be 0
730 *
731 * This function will sign the certificate request with a private key.
732 * This must be the same key as the one used in gnutls_x509_crt_set_key() since a
733 * certificate request is self signed.
734 *
735 * This must be the last step in a certificate request generation since all
736 * the previously set parameters are now signed.
737 *
738 * Returns 0 on success.
739 *
740 **/
741int
742gnutls_x509_crq_sign2 (gnutls_x509_crq_t crq, gnutls_x509_privkey_t key,
743 gnutls_digest_algorithm_t dig, unsigned int flags)
744{
745 int result;
746 gnutls_datum_t signature;
747
748 if (crq == NULL)
749 {
750 gnutls_assert ();
751 return GNUTLS_E_INVALID_REQUEST;
752 }
753
754 /* Step 1. Self sign the request.
755 */
756 result =
757 _gnutls_x509_sign_tbs (crq->crq, "certificationRequestInfo",
758 dig, key, &signature);
759
760 if (result < 0)
761 {
762 gnutls_assert ();
763 return result;
764 }
765
766 /* Step 2. write the signature (bits)
767 */
768 result =
769 asn1_write_value (crq->crq, "signature", signature.data,
770 signature.size * 8);
771
772 _gnutls_free_datum (&signature);
773
774 if (result != ASN1_SUCCESS)
775 {
776 gnutls_assert ();
777 return _gnutls_asn2err (result);
778 }
779
780 /* Step 3. Write the signatureAlgorithm field.
781 */
782 result = _gnutls_x509_write_sig_params (crq->crq, "signatureAlgorithm",
783 key->pk_algorithm, dig, key->params,
784 key->params_size);
785 if (result < 0)
786 {
787 gnutls_assert ();
788 return result;
789 }
790
791 return 0;
792}
793
794/**
795 * gnutls_x509_crq_sign - This function will sign a Certificate request with a key
796 * @crq: should contain a gnutls_x509_crq_t structure
797 * @key: holds a private key
798 *
799 * This function is the same a gnutls_x509_crq_sign2() with no flags, and
800 * SHA1 as the hash algorithm.
801 *
802 * Returns 0 on success.
803 *
804 **/
805int
806gnutls_x509_crq_sign (gnutls_x509_crq_t crq, gnutls_x509_privkey_t key)
807{
808 return gnutls_x509_crq_sign2 (crq, key, GNUTLS_DIG_SHA1, 0);
809}
810
811/**
812 * gnutls_x509_crq_export - Export the generated certificate request
813 * @crq: Holds the request
814 * @format: the format of output params. One of PEM or DER.
815 * @output_data: will contain a certificate request PEM or DER encoded
816 * @output_data_size: holds the size of output_data (and will be
817 * replaced by the actual size of parameters)
818 *
819 * This function will export the certificate request to a PKCS10
820 *
821 * If the buffer provided is not long enough to hold the output, then
822 * GNUTLS_E_SHORT_MEMORY_BUFFER will be returned and
823 * *output_data_size will be updated.
824 *
825 * If the structure is PEM encoded, it will have a header of "BEGIN
826 * NEW CERTIFICATE REQUEST".
827 *
828 * Return value: In case of failure a negative value will be
829 * returned, and 0 on success.
830 *
831 **/
832int
833gnutls_x509_crq_export (gnutls_x509_crq_t crq,
834 gnutls_x509_crt_fmt_t format, void *output_data,
835 size_t * output_data_size)
836{
837 if (crq == NULL)
838 {
839 gnutls_assert ();
840 return GNUTLS_E_INVALID_REQUEST;
841 }
842
843 return _gnutls_x509_export_int (crq->crq, format, PEM_CRQ,
844 output_data, output_data_size);
845}
846
847/**
848 * gnutls_x509_crq_get_pk_algorithm - This function returns the certificate request's PublicKey algorithm
849 * @crq: should contain a gnutls_x509_crq_t structure
850 * @bits: if bits is non null it will hold the size of the parameters' in bits
851 *
852 * This function will return the public key algorithm of a PKCS \#10
853 * certificate request.
854 *
855 * If bits is non null, it should have enough size to hold the parameters
856 * size in bits. For RSA the bits returned is the modulus.
857 * For DSA the bits returned are of the public
858 * exponent.
859 *
860 * Returns a member of the gnutls_pk_algorithm_t enumeration on success,
861 * or a negative value on error.
862 *
863 **/
864int
865gnutls_x509_crq_get_pk_algorithm (gnutls_x509_crq_t crq, unsigned int *bits)
866{
867 int result;
868
869 if (crq == NULL)
870 {
871 gnutls_assert ();
872 return GNUTLS_E_INVALID_REQUEST;
873 }
874
875 result =
876 _gnutls_x509_get_pk_algorithm (crq->crq,
877 "certificationRequestInfo.subjectPKInfo",
878 bits);
879 if (result < 0)
880 {
881 gnutls_assert ();
882 }
883
884 return result;
885}
886
887#endif /* ENABLE_PKI */
diff --git a/src/daemon/https/x509/crq.h b/src/daemon/https/x509/crq.h
new file mode 100644
index 00000000..80e600b5
--- /dev/null
+++ b/src/daemon/https/x509/crq.h
@@ -0,0 +1,30 @@
1/*
2 * Copyright (C) 2003, 2004, 2005 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 <x509.h>
26
27typedef struct gnutls_x509_crq_int
28{
29 ASN1_TYPE crq;
30} gnutls_x509_crq_int;
diff --git a/src/daemon/https/x509/dn.c b/src/daemon/https/x509/dn.c
new file mode 100644
index 00000000..c356aac1
--- /dev/null
+++ b/src/daemon/https/x509/dn.c
@@ -0,0 +1,1140 @@
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 = _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 asn1_struct, and puts the output into
84 * the string buf. The output is an LDAP encoded DN.
85 *
86 * asn1_rdn_name must be a string in the form "tbsCertificate.issuer.rdnSequence".
87 * That is to point in the rndSequence.
88 */
89int
90_gnutls_x509_parse_dn (ASN1_TYPE asn1_struct,
91 const char *asn1_rdn_name, char *buf,
92 size_t * sizeof_buf)
93{
94 gnutls_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 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 _gnutls_string_init (&out_str, gnutls_malloc, gnutls_realloc, gnutls_free);
119
120 k1 = 0;
121 do
122 {
123
124 k1++;
125 /* create a string like "tbsCertList.issuer.rdnSequence.?1"
126 */
127 if (asn1_rdn_name[0] != 0)
128 snprintf (tmpbuffer1, sizeof (tmpbuffer1), "%s.?%u", asn1_rdn_name,
129 k1);
130 else
131 snprintf (tmpbuffer1, sizeof (tmpbuffer1), "?%u", k1);
132
133 len = sizeof (value) - 1;
134 result = asn1_read_value (asn1_struct, tmpbuffer1, value, &len);
135
136 if (result == ASN1_ELEMENT_NOT_FOUND)
137 {
138 break;
139 }
140
141 if (result != ASN1_VALUE_NOT_FOUND)
142 {
143 gnutls_assert ();
144 result = _gnutls_asn2err (result);
145 goto cleanup;
146 }
147
148 k2 = 0;
149
150 do
151 { /* Move to the attibute type and values
152 */
153 k2++;
154
155 if (tmpbuffer1[0] != 0)
156 snprintf (tmpbuffer2, sizeof (tmpbuffer2), "%s.?%u", tmpbuffer1,
157 k2);
158 else
159 snprintf (tmpbuffer2, sizeof (tmpbuffer2), "?%u", k2);
160
161 /* Try to read the RelativeDistinguishedName attributes.
162 */
163
164 len = sizeof (value) - 1;
165 result = asn1_read_value (asn1_struct, tmpbuffer2, value, &len);
166
167 if (result == ASN1_ELEMENT_NOT_FOUND)
168 break;
169 if (result != ASN1_VALUE_NOT_FOUND)
170 {
171 gnutls_assert ();
172 result = _gnutls_asn2err (result);
173 goto cleanup;
174 }
175
176 /* Read the OID
177 */
178 _gnutls_str_cpy (tmpbuffer3, sizeof (tmpbuffer3), tmpbuffer2);
179 _gnutls_str_cat (tmpbuffer3, sizeof (tmpbuffer3), ".type");
180
181 len = sizeof (oid) - 1;
182 result = asn1_read_value (asn1_struct, tmpbuffer3, oid, &len);
183
184 if (result == ASN1_ELEMENT_NOT_FOUND)
185 break;
186 else if (result != ASN1_SUCCESS)
187 {
188 gnutls_assert ();
189 result = _gnutls_asn2err (result);
190 goto cleanup;
191 }
192
193 /* Read the Value
194 */
195 _gnutls_str_cpy (tmpbuffer3, sizeof (tmpbuffer3), tmpbuffer2);
196 _gnutls_str_cat (tmpbuffer3, sizeof (tmpbuffer3), ".value");
197
198 len = 0;
199 result = asn1_read_value (asn1_struct, tmpbuffer3, NULL, &len);
200
201 value2 = gnutls_malloc (len);
202 if (value2 == NULL)
203 {
204 gnutls_assert ();
205 result = GNUTLS_E_MEMORY_ERROR;
206 goto cleanup;
207 }
208
209 result = asn1_read_value (asn1_struct, tmpbuffer3, value2, &len);
210
211 if (result != ASN1_SUCCESS)
212 {
213 gnutls_assert ();
214 result = _gnutls_asn2err (result);
215 goto cleanup;
216 }
217#define STR_APPEND(y) if ((result=_gnutls_string_append_str( &out_str, y)) < 0) { \
218 gnutls_assert(); \
219 goto cleanup; \
220}
221 /* The encodings of adjoining RelativeDistinguishedNames are separated
222 * by a comma character (',' ASCII 44).
223 */
224
225 /* Where there is a multi-valued RDN, the outputs from adjoining
226 * AttributeTypeAndValues are separated by a plus ('+' ASCII 43)
227 * character.
228 */
229 if (k1 != 1)
230 { /* the first time do not append a comma */
231 if (k2 != 1)
232 { /* adjoining multi-value RDN */
233 STR_APPEND ("+");
234 }
235 else
236 {
237 STR_APPEND (",");
238 }
239 }
240
241 ldap_desc = oid2ldap_string (oid);
242 printable = _gnutls_x509_oid_data_printable (oid);
243
244 sizeof_escaped = 2 * len + 1;
245
246 escaped = gnutls_malloc (sizeof_escaped);
247 if (escaped == NULL)
248 {
249 gnutls_assert ();
250 result = GNUTLS_E_MEMORY_ERROR;
251 goto cleanup;
252 }
253
254 sizeof_string = 2 * len + 2; /* in case it is not printable */
255
256 string = gnutls_malloc (sizeof_string);
257 if (string == NULL)
258 {
259 gnutls_assert ();
260 result = GNUTLS_E_MEMORY_ERROR;
261 goto cleanup;
262 }
263
264 STR_APPEND (ldap_desc);
265 STR_APPEND ("=");
266 result = 0;
267
268 if (printable)
269 result =
270 _gnutls_x509_oid_data2string (oid,
271 value2, len,
272 string, &sizeof_string);
273
274 if (!printable || result < 0)
275 result =
276 _gnutls_x509_data2hex (value2, len, string, &sizeof_string);
277
278 if (result < 0)
279 {
280 gnutls_assert ();
281 _gnutls_x509_log
282 ("Found OID: '%s' with value '%s'\n",
283 oid, _gnutls_bin2hex (value2, len, escaped, sizeof_escaped));
284 goto cleanup;
285 }
286 STR_APPEND (str_escape (string, escaped, sizeof_escaped));
287 gnutls_free (string);
288 string = NULL;
289
290 gnutls_free (escaped);
291 escaped = NULL;
292 gnutls_free (value2);
293 value2 = NULL;
294
295 }
296 while (1);
297
298 }
299 while (1);
300
301 if (out_str.length >= (unsigned int) *sizeof_buf)
302 {
303 gnutls_assert ();
304 *sizeof_buf = out_str.length + 1;
305 result = GNUTLS_E_SHORT_MEMORY_BUFFER;
306 goto cleanup;
307 }
308
309 if (buf)
310 {
311 memcpy (buf, out_str.data, out_str.length);
312 buf[out_str.length] = 0;
313 }
314 *sizeof_buf = out_str.length;
315
316 result = 0;
317
318cleanup:
319 gnutls_free (value2);
320 gnutls_free (string);
321 gnutls_free (escaped);
322 _gnutls_string_clear (&out_str);
323 return result;
324}
325
326/* Parses an X509 DN in the asn1_struct, and searches for the
327 * given OID in the DN.
328 *
329 * If raw_flag == 0, the output will be encoded in the LDAP way. (#hex for non printable)
330 * Otherwise the raw DER data are returned.
331 *
332 * asn1_rdn_name must be a string in the form "tbsCertificate.issuer.rdnSequence".
333 * That is to point in the rndSequence.
334 *
335 * indx specifies which OID to return. Ie 0 means return the first specified
336 * OID found, 1 the second etc.
337 */
338int
339_gnutls_x509_parse_dn_oid (ASN1_TYPE asn1_struct,
340 const char *asn1_rdn_name,
341 const char *given_oid, int indx,
342 unsigned int raw_flag,
343 void *buf, size_t * sizeof_buf)
344{
345 int k2, k1, result;
346 char tmpbuffer1[MAX_NAME_SIZE];
347 char tmpbuffer2[MAX_NAME_SIZE];
348 char tmpbuffer3[MAX_NAME_SIZE];
349 opaque value[256];
350 char oid[128];
351 int len, printable;
352 int i = 0;
353 char *cbuf = buf;
354
355 if (cbuf == NULL)
356 *sizeof_buf = 0;
357 else
358 cbuf[0] = 0;
359
360 k1 = 0;
361 do
362 {
363
364 k1++;
365 /* create a string like "tbsCertList.issuer.rdnSequence.?1"
366 */
367 if (asn1_rdn_name[0] != 0)
368 snprintf (tmpbuffer1, sizeof (tmpbuffer1), "%s.?%u", asn1_rdn_name,
369 k1);
370 else
371 snprintf (tmpbuffer1, sizeof (tmpbuffer1), "?%u", k1);
372
373 len = sizeof (value) - 1;
374 result = asn1_read_value (asn1_struct, tmpbuffer1, value, &len);
375
376 if (result == ASN1_ELEMENT_NOT_FOUND)
377 {
378 gnutls_assert ();
379 break;
380 }
381
382 if (result != ASN1_VALUE_NOT_FOUND)
383 {
384 gnutls_assert ();
385 result = _gnutls_asn2err (result);
386 goto cleanup;
387 }
388
389 k2 = 0;
390
391 do
392 { /* Move to the attibute type and values
393 */
394 k2++;
395
396 if (tmpbuffer1[0] != 0)
397 snprintf (tmpbuffer2, sizeof (tmpbuffer2), "%s.?%u", tmpbuffer1,
398 k2);
399 else
400 snprintf (tmpbuffer2, sizeof (tmpbuffer2), "?%u", k2);
401
402 /* Try to read the RelativeDistinguishedName attributes.
403 */
404
405 len = sizeof (value) - 1;
406 result = asn1_read_value (asn1_struct, tmpbuffer2, value, &len);
407
408 if (result == ASN1_ELEMENT_NOT_FOUND)
409 {
410 break;
411 }
412 if (result != ASN1_VALUE_NOT_FOUND)
413 {
414 gnutls_assert ();
415 result = _gnutls_asn2err (result);
416 goto cleanup;
417 }
418
419 /* Read the OID
420 */
421 _gnutls_str_cpy (tmpbuffer3, sizeof (tmpbuffer3), tmpbuffer2);
422 _gnutls_str_cat (tmpbuffer3, sizeof (tmpbuffer3), ".type");
423
424 len = sizeof (oid) - 1;
425 result = asn1_read_value (asn1_struct, tmpbuffer3, oid, &len);
426
427 if (result == ASN1_ELEMENT_NOT_FOUND)
428 break;
429 else if (result != ASN1_SUCCESS)
430 {
431 gnutls_assert ();
432 result = _gnutls_asn2err (result);
433 goto cleanup;
434 }
435
436 if (strcmp (oid, given_oid) == 0 && indx == i++)
437 { /* Found the OID */
438
439 /* Read the Value
440 */
441 _gnutls_str_cpy (tmpbuffer3, sizeof (tmpbuffer3), tmpbuffer2);
442 _gnutls_str_cat (tmpbuffer3, sizeof (tmpbuffer3), ".value");
443
444 len = *sizeof_buf;
445 result = asn1_read_value (asn1_struct, tmpbuffer3, buf, &len);
446
447 if (result != ASN1_SUCCESS)
448 {
449 gnutls_assert ();
450 if (result == ASN1_MEM_ERROR)
451 *sizeof_buf = len;
452 result = _gnutls_asn2err (result);
453 goto cleanup;
454 }
455
456 if (raw_flag != 0)
457 {
458 if ((unsigned) len > *sizeof_buf)
459 {
460 *sizeof_buf = len;
461 result = GNUTLS_E_SHORT_MEMORY_BUFFER;
462 goto cleanup;
463 }
464 *sizeof_buf = len;
465
466 return 0;
467
468 }
469 else
470 { /* parse data. raw_flag == 0 */
471 printable = _gnutls_x509_oid_data_printable (oid);
472
473 if (printable == 1)
474 result =
475 _gnutls_x509_oid_data2string (oid, buf, len,
476 cbuf, sizeof_buf);
477 else
478 result =
479 _gnutls_x509_data2hex (buf, len, cbuf, sizeof_buf);
480
481 if (result < 0)
482 {
483 gnutls_assert ();
484 goto cleanup;
485 }
486
487 return 0;
488
489 } /* raw_flag == 0 */
490 }
491 }
492 while (1);
493
494 }
495 while (1);
496
497 gnutls_assert ();
498
499 result = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
500
501cleanup:
502 return result;
503}
504
505
506/* Parses an X509 DN in the asn1_struct, and returns the requested
507 * DN OID.
508 *
509 * asn1_rdn_name must be a string in the form "tbsCertificate.issuer.rdnSequence".
510 * That is to point in the rndSequence.
511 *
512 * indx specifies which OID to return. Ie 0 means return the first specified
513 * OID found, 1 the second etc.
514 */
515int
516_gnutls_x509_get_dn_oid (ASN1_TYPE asn1_struct,
517 const char *asn1_rdn_name,
518 int indx, void *_oid, size_t * sizeof_oid)
519{
520 int k2, k1, result;
521 char tmpbuffer1[MAX_NAME_SIZE];
522 char tmpbuffer2[MAX_NAME_SIZE];
523 char tmpbuffer3[MAX_NAME_SIZE];
524 char value[256];
525 char oid[128];
526 int len;
527 int i = 0;
528
529 k1 = 0;
530 do
531 {
532
533 k1++;
534 /* create a string like "tbsCertList.issuer.rdnSequence.?1"
535 */
536 if (asn1_rdn_name[0] != 0)
537 snprintf (tmpbuffer1, sizeof (tmpbuffer1), "%s.?%u", asn1_rdn_name,
538 k1);
539 else
540 snprintf (tmpbuffer1, sizeof (tmpbuffer1), "?%u", k1);
541
542 len = sizeof (value) - 1;
543 result = asn1_read_value (asn1_struct, tmpbuffer1, value, &len);
544
545 if (result == ASN1_ELEMENT_NOT_FOUND)
546 {
547 gnutls_assert ();
548 break;
549 }
550
551 if (result != ASN1_VALUE_NOT_FOUND)
552 {
553 gnutls_assert ();
554 result = _gnutls_asn2err (result);
555 goto cleanup;
556 }
557
558 k2 = 0;
559
560 do
561 { /* Move to the attibute type and values
562 */
563 k2++;
564
565 if (tmpbuffer1[0] != 0)
566 snprintf (tmpbuffer2, sizeof (tmpbuffer2), "%s.?%u", tmpbuffer1,
567 k2);
568 else
569 snprintf (tmpbuffer2, sizeof (tmpbuffer2), "?%u", k2);
570
571 /* Try to read the RelativeDistinguishedName attributes.
572 */
573
574 len = sizeof (value) - 1;
575 result = asn1_read_value (asn1_struct, tmpbuffer2, value, &len);
576
577 if (result == ASN1_ELEMENT_NOT_FOUND)
578 {
579 break;
580 }
581 if (result != ASN1_VALUE_NOT_FOUND)
582 {
583 gnutls_assert ();
584 result = _gnutls_asn2err (result);
585 goto cleanup;
586 }
587
588 /* Read the OID
589 */
590 _gnutls_str_cpy (tmpbuffer3, sizeof (tmpbuffer3), tmpbuffer2);
591 _gnutls_str_cat (tmpbuffer3, sizeof (tmpbuffer3), ".type");
592
593 len = sizeof (oid) - 1;
594 result = asn1_read_value (asn1_struct, tmpbuffer3, oid, &len);
595
596 if (result == ASN1_ELEMENT_NOT_FOUND)
597 break;
598 else if (result != ASN1_SUCCESS)
599 {
600 gnutls_assert ();
601 result = _gnutls_asn2err (result);
602 goto cleanup;
603 }
604
605 if (indx == i++)
606 { /* Found the OID */
607
608 len = strlen (oid) + 1;
609
610 if (*sizeof_oid < (unsigned) len)
611 {
612 *sizeof_oid = len;
613 gnutls_assert ();
614 return GNUTLS_E_SHORT_MEMORY_BUFFER;
615 }
616
617 memcpy (_oid, oid, len);
618 *sizeof_oid = len - 1;
619
620 return 0;
621 }
622 }
623 while (1);
624
625 }
626 while (1);
627
628 gnutls_assert ();
629
630 result = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
631
632cleanup:
633 return result;
634}
635
636/* This will encode and write the AttributeTypeAndValue field.
637 * 'multi' must be zero if writing an AttributeTypeAndValue, and 1 if Attribute.
638 * In all cases only one value is written.
639 */
640int
641_gnutls_x509_encode_and_write_attribute (const char *given_oid,
642 ASN1_TYPE asn1_struct,
643 const char *where,
644 const void *_data,
645 int sizeof_data, int multi)
646{
647 const char *val_name;
648 const opaque *data = _data;
649 char tmp[128];
650 ASN1_TYPE c2;
651 int result;
652
653
654 /* Find how to encode the data.
655 */
656 val_name = asn1_find_structure_from_oid (_gnutls_get_pkix (), given_oid);
657 if (val_name == NULL)
658 {
659 gnutls_assert ();
660 return GNUTLS_E_X509_UNSUPPORTED_OID;
661 }
662
663 _gnutls_str_cpy (tmp, sizeof (tmp), "PKIX1.");
664 _gnutls_str_cat (tmp, sizeof (tmp), val_name);
665
666 result = asn1_create_element (_gnutls_get_pkix (), tmp, &c2);
667 if (result != ASN1_SUCCESS)
668 {
669 gnutls_assert ();
670 return _gnutls_asn2err (result);
671 }
672
673 tmp[0] = 0;
674
675 if ((result = _gnutls_x509_oid_data_choice (given_oid)) > 0)
676 {
677 char *string_type;
678 int i;
679
680 string_type = "printableString";
681
682 /* Check if the data is plain ascii, and use
683 * the UTF8 string type if not.
684 */
685 for (i = 0; i < sizeof_data; i++)
686 {
687 if (!isascii (data[i]))
688 {
689 string_type = "utf8String";
690 break;
691 }
692 }
693
694 /* if the type is a CHOICE then write the
695 * type we'll use.
696 */
697 result = asn1_write_value (c2, "", string_type, 1);
698 if (result != ASN1_SUCCESS)
699 {
700 gnutls_assert ();
701 asn1_delete_structure (&c2);
702 return _gnutls_asn2err (result);
703 }
704
705 _gnutls_str_cpy (tmp, sizeof (tmp), string_type);
706 }
707
708 result = asn1_write_value (c2, tmp, data, sizeof_data);
709 if (result != ASN1_SUCCESS)
710 {
711 gnutls_assert ();
712 asn1_delete_structure (&c2);
713 return _gnutls_asn2err (result);
714 }
715
716
717 /* write the data (value)
718 */
719
720 _gnutls_str_cpy (tmp, sizeof (tmp), where);
721 _gnutls_str_cat (tmp, sizeof (tmp), ".value");
722
723 if (multi != 0)
724 { /* if not writing an AttributeTypeAndValue, but an Attribute */
725 _gnutls_str_cat (tmp, sizeof (tmp), "s"); /* values */
726
727 result = asn1_write_value (asn1_struct, tmp, "NEW", 1);
728 if (result != ASN1_SUCCESS)
729 {
730 gnutls_assert ();
731 return _gnutls_asn2err (result);
732 }
733
734 _gnutls_str_cat (tmp, sizeof (tmp), ".?LAST");
735
736 }
737
738 result = _gnutls_x509_der_encode_and_copy (c2, "", asn1_struct, tmp, 0);
739 if (result < 0)
740 {
741 gnutls_assert ();
742 return result;
743 }
744
745 /* write the type
746 */
747 _gnutls_str_cpy (tmp, sizeof (tmp), where);
748 _gnutls_str_cat (tmp, sizeof (tmp), ".type");
749
750 result = asn1_write_value (asn1_struct, tmp, given_oid, 1);
751 if (result != ASN1_SUCCESS)
752 {
753 gnutls_assert ();
754 return _gnutls_asn2err (result);
755 }
756
757 return 0;
758}
759
760/* This will write the AttributeTypeAndValue field. The data must be already DER encoded.
761 * 'multi' must be zero if writing an AttributeTypeAndValue, and 1 if Attribute.
762 * In all cases only one value is written.
763 */
764int
765_gnutls_x509_write_attribute (const char *given_oid,
766 ASN1_TYPE asn1_struct, const char *where,
767 const void *_data, int sizeof_data, int multi)
768{
769 char tmp[128];
770 int result;
771
772 /* write the data (value)
773 */
774
775 _gnutls_str_cpy (tmp, sizeof (tmp), where);
776 _gnutls_str_cat (tmp, sizeof (tmp), ".value");
777
778 if (multi != 0)
779 { /* if not writing an AttributeTypeAndValue, but an Attribute */
780 _gnutls_str_cat (tmp, sizeof (tmp), "s"); /* values */
781
782 result = asn1_write_value (asn1_struct, tmp, "NEW", 1);
783 if (result != ASN1_SUCCESS)
784 {
785 gnutls_assert ();
786 return _gnutls_asn2err (result);
787 }
788
789 _gnutls_str_cat (tmp, sizeof (tmp), ".?LAST");
790
791 }
792
793 result = asn1_write_value (asn1_struct, tmp, _data, sizeof_data);
794 if (result < 0)
795 {
796 gnutls_assert ();
797 return _gnutls_asn2err (result);
798 }
799
800 /* write the type
801 */
802 _gnutls_str_cpy (tmp, sizeof (tmp), where);
803 _gnutls_str_cat (tmp, sizeof (tmp), ".type");
804
805 result = asn1_write_value (asn1_struct, tmp, given_oid, 1);
806 if (result != ASN1_SUCCESS)
807 {
808 gnutls_assert ();
809 return _gnutls_asn2err (result);
810 }
811
812 return 0;
813}
814
815
816/* Decodes an X.509 Attribute (if multi==1) or an AttributeTypeAndValue
817 * otherwise.
818 *
819 * octet_string should be non zero if we are to decode octet strings after
820 * decoding.
821 *
822 * The output is allocated and stored in value.
823 */
824int
825_gnutls_x509_decode_and_read_attribute (ASN1_TYPE asn1_struct,
826 const char *where, char *oid,
827 int oid_size, gnutls_datum_t * value,
828 int multi, int octet_string)
829{
830 char tmpbuffer[128];
831 int len, result;
832
833 /* Read the OID
834 */
835 _gnutls_str_cpy (tmpbuffer, sizeof (tmpbuffer), where);
836 _gnutls_str_cat (tmpbuffer, sizeof (tmpbuffer), ".type");
837
838 len = oid_size - 1;
839 result = asn1_read_value (asn1_struct, tmpbuffer, oid, &len);
840
841 if (result != ASN1_SUCCESS)
842 {
843 gnutls_assert ();
844 result = _gnutls_asn2err (result);
845 return result;
846 }
847
848 /* Read the Value
849 */
850
851 _gnutls_str_cpy (tmpbuffer, sizeof (tmpbuffer), where);
852 _gnutls_str_cat (tmpbuffer, sizeof (tmpbuffer), ".value");
853
854 if (multi)
855 _gnutls_str_cat (tmpbuffer, sizeof (tmpbuffer), "s.?1"); /* .values.?1 */
856
857 result =
858 _gnutls_x509_read_value (asn1_struct, tmpbuffer, value, octet_string);
859 if (result < 0)
860 {
861 gnutls_assert ();
862 return result;
863 }
864
865 return 0;
866
867}
868
869/* Sets an X509 DN in the asn1_struct, and puts the given OID in the DN.
870 * The input is assumed to be raw data.
871 *
872 * asn1_rdn_name must be a string in the form "tbsCertificate.issuer".
873 * That is to point before the rndSequence.
874 *
875 */
876int
877_gnutls_x509_set_dn_oid (ASN1_TYPE asn1_struct,
878 const char *asn1_name, const char *given_oid,
879 int raw_flag, const char *name, int sizeof_name)
880{
881 int result;
882 char tmp[MAX_NAME_SIZE], asn1_rdn_name[MAX_NAME_SIZE];
883
884 if (sizeof_name == 0 || name == NULL)
885 {
886 gnutls_assert ();
887 return GNUTLS_E_INVALID_REQUEST;
888 }
889
890 /* create the rdnSequence
891 */
892 result = asn1_write_value (asn1_struct, asn1_name, "rdnSequence", 1);
893 if (result != ASN1_SUCCESS)
894 {
895 gnutls_assert ();
896 return _gnutls_asn2err (result);
897 }
898
899 _gnutls_str_cpy (asn1_rdn_name, sizeof (asn1_rdn_name), asn1_name);
900 _gnutls_str_cat (asn1_rdn_name, sizeof (asn1_rdn_name), ".rdnSequence");
901
902 /* create a new element
903 */
904 result = asn1_write_value (asn1_struct, asn1_rdn_name, "NEW", 1);
905 if (result != ASN1_SUCCESS)
906 {
907 gnutls_assert ();
908 return _gnutls_asn2err (result);
909 }
910
911 _gnutls_str_cpy (tmp, sizeof (tmp), asn1_rdn_name);
912 _gnutls_str_cat (tmp, sizeof (tmp), ".?LAST");
913
914 /* create the set with only one element
915 */
916 result = asn1_write_value (asn1_struct, tmp, "NEW", 1);
917 if (result != ASN1_SUCCESS)
918 {
919 gnutls_assert ();
920 return _gnutls_asn2err (result);
921 }
922
923
924 /* Encode and write the data
925 */
926 _gnutls_str_cpy (tmp, sizeof (tmp), asn1_rdn_name);
927 _gnutls_str_cat (tmp, sizeof (tmp), ".?LAST.?LAST");
928
929 if (!raw_flag)
930 {
931 result =
932 _gnutls_x509_encode_and_write_attribute (given_oid,
933 asn1_struct,
934 tmp, name, sizeof_name, 0);
935 }
936 else
937 {
938 result =
939 _gnutls_x509_write_attribute (given_oid, asn1_struct,
940 tmp, name, sizeof_name, 0);
941 }
942
943 if (result < 0)
944 {
945 gnutls_assert ();
946 return result;
947 }
948
949 return 0;
950}
951
952
953/**
954 * gnutls_x509_rdn_get - This function parses an RDN sequence and returns a string
955 * @idn: should contain a DER encoded RDN sequence
956 * @buf: a pointer to a structure to hold the peer's name
957 * @sizeof_buf: holds the size of @buf
958 *
959 * This function will return the name of the given RDN sequence. The
960 * name will be in the form "C=xxxx,O=yyyy,CN=zzzz" as described in
961 * RFC2253.
962 *
963 * If the provided buffer is not long enough, returns
964 * GNUTLS_E_SHORT_MEMORY_BUFFER and *sizeof_buf will be updated. On
965 * success 0 is returned.
966 *
967 **/
968int
969gnutls_x509_rdn_get (const gnutls_datum_t * idn,
970 char *buf, size_t * sizeof_buf)
971{
972 int result;
973 ASN1_TYPE dn = ASN1_TYPE_EMPTY;
974
975 if (sizeof_buf == 0)
976 {
977 gnutls_assert ();
978 return GNUTLS_E_INVALID_REQUEST;
979 }
980
981 if (buf)
982 buf[0] = 0;
983
984
985 if ((result =
986 asn1_create_element (_gnutls_get_pkix (),
987 "PKIX1.Name", &dn)) != ASN1_SUCCESS)
988 {
989 gnutls_assert ();
990 return _gnutls_asn2err (result);
991 }
992
993 result = asn1_der_decoding (&dn, idn->data, idn->size, NULL);
994 if (result != ASN1_SUCCESS)
995 {
996 /* couldn't decode DER */
997 gnutls_assert ();
998 asn1_delete_structure (&dn);
999 return _gnutls_asn2err (result);
1000 }
1001
1002 result = _gnutls_x509_parse_dn (dn, "rdnSequence", buf, sizeof_buf);
1003
1004 asn1_delete_structure (&dn);
1005 return result;
1006
1007}
1008
1009/**
1010 * gnutls_x509_rdn_get_by_oid - This function parses an RDN sequence and returns a string
1011 * @idn: should contain a DER encoded RDN sequence
1012 * @oid: an Object Identifier
1013 * @indx: In case multiple same OIDs exist in the RDN indicates which
1014 * to send. Use 0 for the first one.
1015 * @raw_flag: If non zero then the raw DER data are returned.
1016 * @buf: a pointer to a structure to hold the peer's name
1017 * @sizeof_buf: holds the size of @buf
1018 *
1019 * This function will return the name of the given Object identifier,
1020 * of the RDN sequence. The name will be encoded using the rules
1021 * from RFC2253.
1022 *
1023 * Returns GNUTLS_E_SHORT_MEMORY_BUFFER and updates *sizeof_buf if
1024 * the provided buffer is not long enough, and 0 on success.
1025 *
1026 **/
1027int
1028gnutls_x509_rdn_get_by_oid (const gnutls_datum_t * idn, const char *oid,
1029 int indx, unsigned int raw_flag,
1030 void *buf, size_t * sizeof_buf)
1031{
1032 int result;
1033 ASN1_TYPE dn = ASN1_TYPE_EMPTY;
1034
1035 if (sizeof_buf == 0)
1036 {
1037 return GNUTLS_E_INVALID_REQUEST;
1038 }
1039
1040 if ((result =
1041 asn1_create_element (_gnutls_get_pkix (),
1042 "PKIX1.Name", &dn)) != ASN1_SUCCESS)
1043 {
1044 gnutls_assert ();
1045 return _gnutls_asn2err (result);
1046 }
1047
1048 result = asn1_der_decoding (&dn, idn->data, idn->size, NULL);
1049 if (result != ASN1_SUCCESS)
1050 {
1051 /* couldn't decode DER */
1052 gnutls_assert ();
1053 asn1_delete_structure (&dn);
1054 return _gnutls_asn2err (result);
1055 }
1056
1057 result =
1058 _gnutls_x509_parse_dn_oid (dn, "rdnSequence", oid, indx,
1059 raw_flag, buf, sizeof_buf);
1060
1061 asn1_delete_structure (&dn);
1062 return result;
1063
1064}
1065
1066/**
1067 * gnutls_x509_rdn_get_oid - This function parses an RDN sequence and returns an OID.
1068 * @idn: should contain a DER encoded RDN sequence
1069 * @indx: Indicates which OID to return. Use 0 for the first one.
1070 * @oid: a pointer to a structure to hold the peer's name OID
1071 * @sizeof_oid: holds the size of @oid
1072 *
1073 * This function will return the specified Object identifier, of the
1074 * RDN sequence.
1075 *
1076 * Returns GNUTLS_E_SHORT_MEMORY_BUFFER and updates *sizeof_buf if
1077 * the provided buffer is not long enough, and 0 on success.
1078 *
1079 **/
1080int
1081gnutls_x509_rdn_get_oid (const gnutls_datum_t * idn,
1082 int indx, void *buf, size_t * sizeof_buf)
1083{
1084 int result;
1085 ASN1_TYPE dn = ASN1_TYPE_EMPTY;
1086
1087 if (sizeof_buf == 0)
1088 {
1089 return GNUTLS_E_INVALID_REQUEST;
1090 }
1091
1092 if ((result =
1093 asn1_create_element (_gnutls_get_pkix (),
1094 "PKIX1.Name", &dn)) != ASN1_SUCCESS)
1095 {
1096 gnutls_assert ();
1097 return _gnutls_asn2err (result);
1098 }
1099
1100 result = asn1_der_decoding (&dn, idn->data, idn->size, NULL);
1101 if (result != ASN1_SUCCESS)
1102 {
1103 /* couldn't decode DER */
1104 gnutls_assert ();
1105 asn1_delete_structure (&dn);
1106 return _gnutls_asn2err (result);
1107 }
1108
1109 result = _gnutls_x509_get_dn_oid (dn, "rdnSequence", indx, buf, sizeof_buf);
1110
1111 asn1_delete_structure (&dn);
1112 return result;
1113
1114}
1115
1116/*
1117 * Compares the DER encoded part of a DN.
1118 *
1119 * FIXME: use a real DN comparison algorithm.
1120 *
1121 * Returns 1 if the DN's match and zero if they don't match. Otherwise
1122 * a negative value is returned to indicate error.
1123 */
1124int
1125_gnutls_x509_compare_raw_dn (const gnutls_datum_t * dn1,
1126 const gnutls_datum_t * dn2)
1127{
1128
1129 if (dn1->size != dn2->size)
1130 {
1131 gnutls_assert ();
1132 return 0;
1133 }
1134 if (memcmp (dn1->data, dn2->data, dn2->size) != 0)
1135 {
1136 gnutls_assert ();
1137 return 0;
1138 }
1139 return 1; /* they match */
1140}
diff --git a/src/daemon/https/x509/dn.h b/src/daemon/https/x509/dn.h
new file mode 100644
index 00000000..93a9262c
--- /dev/null
+++ b/src/daemon/https/x509/dn.h
@@ -0,0 +1,58 @@
1/*
2 * Copyright (C) 2003, 2004, 2005 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#ifndef DN_H
26# define DN_H
27
28/* Some OIDs usually found in Distinguished names
29 */
30#define OID_X520_COUNTRY_NAME "2.5.4.6"
31#define OID_X520_ORGANIZATION_NAME "2.5.4.10"
32#define OID_X520_ORGANIZATIONAL_UNIT_NAME "2.5.4.11"
33#define OID_X520_COMMON_NAME "2.5.4.3"
34#define OID_X520_LOCALITY_NAME "2.5.4.7"
35#define OID_X520_STATE_OR_PROVINCE_NAME "2.5.4.8"
36#define OID_LDAP_DC "0.9.2342.19200300.100.1.25"
37#define OID_LDAP_UID "0.9.2342.19200300.100.1.1"
38#define OID_PKCS9_EMAIL "1.2.840.113549.1.9.1"
39
40int _gnutls_x509_parse_dn (ASN1_TYPE asn1_struct,
41 const char *asn1_rdn_name, char *buf,
42 size_t * sizeof_buf);
43
44int _gnutls_x509_parse_dn_oid (ASN1_TYPE asn1_struct,
45 const char *asn1_rdn_name, const char *oid,
46 int indx, unsigned int raw_flag, void *buf,
47 size_t * sizeof_buf);
48
49int _gnutls_x509_set_dn_oid (ASN1_TYPE asn1_struct,
50 const char *asn1_rdn_name, const char *oid,
51 int raw_flag, const char *name, int sizeof_name);
52
53int _gnutls_x509_get_dn_oid (ASN1_TYPE asn1_struct,
54 const char *asn1_rdn_name,
55 int indx, void *_oid, size_t * sizeof_oid);
56
57
58#endif
diff --git a/src/daemon/https/x509/dsa.c b/src/daemon/https/x509/dsa.c
new file mode 100644
index 00000000..af403911
--- /dev/null
+++ b/src/daemon/https/x509/dsa.c
@@ -0,0 +1,142 @@
1/*
2 * Copyright (C) 2003, 2004, 2005 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/* This file contains code for DSA keys.
26 */
27
28#include <gnutls_int.h>
29#include <gnutls_errors.h>
30#include <gnutls_datum.h>
31#include <debug.h>
32
33/* resarr will contain: p(0), q(1), g(2), y(3), x(4).
34 */
35int
36_gnutls_dsa_generate_params (mpi_t * resarr, int *resarr_len, int bits)
37{
38
39 int ret;
40 gcry_sexp_t parms, key, list;
41
42 /* FIXME: Remove me once we depend on 1.3.1 */
43 if (bits > 1024 && gcry_check_version ("1.3.1") == NULL)
44 {
45 gnutls_assert ();
46 return GNUTLS_E_INVALID_REQUEST;
47 }
48
49 if (bits < 512)
50 {
51 gnutls_assert ();
52 return GNUTLS_E_INVALID_REQUEST;
53 }
54
55 ret = gcry_sexp_build (&parms, NULL, "(genkey(dsa(nbits %d)))", bits);
56 if (ret != 0)
57 {
58 gnutls_assert ();
59 return GNUTLS_E_INTERNAL_ERROR;
60 }
61
62 /* generate the DSA key
63 */
64 ret = gcry_pk_genkey (&key, parms);
65 gcry_sexp_release (parms);
66
67 if (ret != 0)
68 {
69 gnutls_assert ();
70 return GNUTLS_E_INTERNAL_ERROR;
71 }
72
73 list = gcry_sexp_find_token (key, "p", 0);
74 if (list == NULL)
75 {
76 gnutls_assert ();
77 gcry_sexp_release (key);
78 return GNUTLS_E_INTERNAL_ERROR;
79 }
80
81 resarr[0] = gcry_sexp_nth_mpi (list, 1, 0);
82 gcry_sexp_release (list);
83
84 list = gcry_sexp_find_token (key, "q", 0);
85 if (list == NULL)
86 {
87 gnutls_assert ();
88 gcry_sexp_release (key);
89 return GNUTLS_E_INTERNAL_ERROR;
90 }
91
92 resarr[1] = gcry_sexp_nth_mpi (list, 1, 0);
93 gcry_sexp_release (list);
94
95 list = gcry_sexp_find_token (key, "g", 0);
96 if (list == NULL)
97 {
98 gnutls_assert ();
99 gcry_sexp_release (key);
100 return GNUTLS_E_INTERNAL_ERROR;
101 }
102
103 resarr[2] = gcry_sexp_nth_mpi (list, 1, 0);
104 gcry_sexp_release (list);
105
106 list = gcry_sexp_find_token (key, "y", 0);
107 if (list == NULL)
108 {
109 gnutls_assert ();
110 gcry_sexp_release (key);
111 return GNUTLS_E_INTERNAL_ERROR;
112 }
113
114 resarr[3] = gcry_sexp_nth_mpi (list, 1, 0);
115 gcry_sexp_release (list);
116
117
118 list = gcry_sexp_find_token (key, "x", 0);
119 if (list == NULL)
120 {
121 gnutls_assert ();
122 gcry_sexp_release (key);
123 return GNUTLS_E_INTERNAL_ERROR;
124 }
125
126 resarr[4] = gcry_sexp_nth_mpi (list, 1, 0);
127 gcry_sexp_release (list);
128
129
130 gcry_sexp_release (key);
131
132 _gnutls_dump_mpi ("p: ", resarr[0]);
133 _gnutls_dump_mpi ("q: ", resarr[1]);
134 _gnutls_dump_mpi ("g: ", resarr[2]);
135 _gnutls_dump_mpi ("y: ", resarr[3]);
136 _gnutls_dump_mpi ("x: ", resarr[4]);
137
138 *resarr_len = 5;
139
140 return 0;
141
142}
diff --git a/src/daemon/https/x509/dsa.h b/src/daemon/https/x509/dsa.h
new file mode 100644
index 00000000..5489ffa3
--- /dev/null
+++ b/src/daemon/https/x509/dsa.h
@@ -0,0 +1,25 @@
1/*
2 * Copyright (C) 2003, 2004, 2005 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
25int _gnutls_dsa_generate_params (mpi_t * resarr, int *resarr_len, int bits);
diff --git a/src/daemon/https/x509/extensions.c b/src/daemon/https/x509/extensions.c
new file mode 100644
index 00000000..98379add
--- /dev/null
+++ b/src/daemon/https/x509/extensions.c
@@ -0,0 +1,1095 @@
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/* Functions that relate to the X.509 extension parsing.
26 */
27
28#include <gnutls_int.h>
29#include <gnutls_errors.h>
30#include <gnutls_global.h>
31#include <mpi.h>
32#include <libtasn1.h>
33#include <common.h>
34#include <x509.h>
35#include <extensions.h>
36#include <gnutls_datum.h>
37
38/* This function will attempt to return the requested extension found in
39 * the given X509v3 certificate. The return value is allocated and stored into
40 * ret.
41 *
42 * Critical will be either 0 or 1.
43 *
44 * If the extension does not exist, GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will
45 * be returned.
46 */
47int
48_gnutls_x509_crt_get_extension (gnutls_x509_crt_t cert,
49 const char *extension_id, int indx,
50 gnutls_datum_t * ret, unsigned int *_critical)
51{
52 int k, result, len;
53 char name[MAX_NAME_SIZE], name2[MAX_NAME_SIZE];
54 char str[1024];
55 char str_critical[10];
56 int critical = 0;
57 char extnID[128];
58 gnutls_datum_t value;
59 int indx_counter = 0;
60
61 ret->data = NULL;
62 ret->size = 0;
63
64 k = 0;
65 do
66 {
67 k++;
68
69 snprintf (name, sizeof (name), "tbsCertificate.extensions.?%u", k);
70
71 len = sizeof (str) - 1;
72 result = asn1_read_value (cert->cert, name, str, &len);
73
74 /* move to next
75 */
76
77 if (result == ASN1_ELEMENT_NOT_FOUND)
78 {
79 break;
80 }
81
82 do
83 {
84
85 _gnutls_str_cpy (name2, sizeof (name2), name);
86 _gnutls_str_cat (name2, sizeof (name2), ".extnID");
87
88 len = sizeof (extnID) - 1;
89 result = asn1_read_value (cert->cert, name2, extnID, &len);
90
91 if (result == ASN1_ELEMENT_NOT_FOUND)
92 {
93 gnutls_assert ();
94 break;
95 }
96 else if (result != ASN1_SUCCESS)
97 {
98 gnutls_assert ();
99 return _gnutls_asn2err (result);
100 }
101
102 /* Handle Extension
103 */
104 if (strcmp (extnID, extension_id) == 0 && indx == indx_counter++)
105 {
106 /* extension was found
107 */
108
109 /* read the critical status.
110 */
111 _gnutls_str_cpy (name2, sizeof (name2), name);
112 _gnutls_str_cat (name2, sizeof (name2), ".critical");
113
114 len = sizeof (str_critical);
115 result =
116 asn1_read_value (cert->cert, name2, str_critical, &len);
117
118 if (result == ASN1_ELEMENT_NOT_FOUND)
119 {
120 gnutls_assert ();
121 break;
122 }
123 else if (result != ASN1_SUCCESS)
124 {
125 gnutls_assert ();
126 return _gnutls_asn2err (result);
127 }
128
129 if (str_critical[0] == 'T')
130 critical = 1;
131 else
132 critical = 0;
133
134 /* read the value.
135 */
136 _gnutls_str_cpy (name2, sizeof (name2), name);
137 _gnutls_str_cat (name2, sizeof (name2), ".extnValue");
138
139 result = _gnutls_x509_read_value (cert->cert, name2, &value, 0);
140 if (result < 0)
141 {
142 gnutls_assert ();
143 return result;
144 }
145
146 ret->data = value.data;
147 ret->size = value.size;
148
149 if (_critical)
150 *_critical = critical;
151
152 return 0;
153 }
154
155
156 }
157 while (0);
158 }
159 while (1);
160
161 if (result == ASN1_ELEMENT_NOT_FOUND)
162 {
163 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
164 }
165 else
166 {
167 gnutls_assert ();
168 return _gnutls_asn2err (result);
169 }
170}
171
172/* This function will attempt to return the requested extension OID found in
173 * the given X509v3 certificate.
174 *
175 * If you have passed the last extension, GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will
176 * be returned.
177 */
178int
179_gnutls_x509_crt_get_extension_oid (gnutls_x509_crt_t cert,
180 int indx, void *oid, size_t * sizeof_oid)
181{
182 int k, result, len;
183 char name[MAX_NAME_SIZE], name2[MAX_NAME_SIZE];
184 char str[1024];
185 char extnID[128];
186 int indx_counter = 0;
187
188 k = 0;
189 do
190 {
191 k++;
192
193 snprintf (name, sizeof (name), "tbsCertificate.extensions.?%u", k);
194
195 len = sizeof (str) - 1;
196 result = asn1_read_value (cert->cert, name, str, &len);
197
198 /* move to next
199 */
200
201 if (result == ASN1_ELEMENT_NOT_FOUND)
202 {
203 break;
204 }
205
206 do
207 {
208
209 _gnutls_str_cpy (name2, sizeof (name2), name);
210 _gnutls_str_cat (name2, sizeof (name2), ".extnID");
211
212 len = sizeof (extnID) - 1;
213 result = asn1_read_value (cert->cert, name2, extnID, &len);
214
215 if (result == ASN1_ELEMENT_NOT_FOUND)
216 {
217 gnutls_assert ();
218 break;
219 }
220 else if (result != ASN1_SUCCESS)
221 {
222 gnutls_assert ();
223 return _gnutls_asn2err (result);
224 }
225
226 /* Handle Extension
227 */
228 if (indx == indx_counter++)
229 {
230 len = strlen (extnID) + 1;
231
232 if (*sizeof_oid < (unsigned) len)
233 {
234 *sizeof_oid = len;
235 gnutls_assert ();
236 return GNUTLS_E_SHORT_MEMORY_BUFFER;
237 }
238
239 memcpy (oid, extnID, len);
240 *sizeof_oid = len - 1;
241
242 return 0;
243 }
244
245
246 }
247 while (0);
248 }
249 while (1);
250
251 if (result == ASN1_ELEMENT_NOT_FOUND)
252 {
253 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
254 }
255 else
256 {
257 gnutls_assert ();
258 return _gnutls_asn2err (result);
259 }
260}
261
262/* This function will attempt to set the requested extension in
263 * the given X509v3 certificate.
264 *
265 * Critical will be either 0 or 1.
266 */
267static int
268set_extension (ASN1_TYPE asn, const char *extension_id,
269 const gnutls_datum_t * ext_data, unsigned int critical)
270{
271 int result;
272 const char *str;
273
274 /* Add a new extension in the list.
275 */
276 result = asn1_write_value (asn, "tbsCertificate.extensions", "NEW", 1);
277 if (result != ASN1_SUCCESS)
278 {
279 gnutls_assert ();
280 return _gnutls_asn2err (result);
281 }
282
283 result =
284 asn1_write_value (asn, "tbsCertificate.extensions.?LAST.extnID",
285 extension_id, 1);
286 if (result != ASN1_SUCCESS)
287 {
288 gnutls_assert ();
289 return _gnutls_asn2err (result);
290 }
291
292 if (critical == 0)
293 str = "FALSE";
294 else
295 str = "TRUE";
296
297
298 result =
299 asn1_write_value (asn, "tbsCertificate.extensions.?LAST.critical",
300 str, 1);
301 if (result != ASN1_SUCCESS)
302 {
303 gnutls_assert ();
304 return _gnutls_asn2err (result);
305 }
306
307 result =
308 _gnutls_x509_write_value (asn,
309 "tbsCertificate.extensions.?LAST.extnValue",
310 ext_data, 0);
311 if (result < 0)
312 {
313 gnutls_assert ();
314 return result;
315 }
316
317 return 0;
318}
319
320/* Overwrite the given extension (using the index)
321 * index here starts from one.
322 */
323static int
324overwrite_extension (ASN1_TYPE asn, unsigned int indx,
325 const gnutls_datum_t * ext_data, unsigned int critical)
326{
327 char name[MAX_NAME_SIZE], name2[MAX_NAME_SIZE];
328 const char *str;
329 int result;
330
331 snprintf (name, sizeof (name), "tbsCertificate.extensions.?%u", indx);
332
333 if (critical == 0)
334 str = "FALSE";
335 else
336 str = "TRUE";
337
338 _gnutls_str_cpy (name2, sizeof (name2), name);
339 _gnutls_str_cat (name2, sizeof (name2), ".critical");
340
341 result = asn1_write_value (asn, name2, str, 1);
342 if (result != ASN1_SUCCESS)
343 {
344 gnutls_assert ();
345 return _gnutls_asn2err (result);
346 }
347
348 _gnutls_str_cpy (name2, sizeof (name2), name);
349 _gnutls_str_cat (name2, sizeof (name2), ".extnValue");
350
351 result = _gnutls_x509_write_value (asn, name2, ext_data, 0);
352 if (result < 0)
353 {
354 gnutls_assert ();
355 return result;
356 }
357
358 return 0;
359}
360
361/* This function will attempt to overwrite the requested extension with
362 * the given one.
363 *
364 * Critical will be either 0 or 1.
365 */
366int
367_gnutls_x509_crt_set_extension (gnutls_x509_crt_t cert,
368 const char *ext_id,
369 const gnutls_datum_t * ext_data,
370 unsigned int critical)
371{
372 int result;
373 int k, len;
374 char name[MAX_NAME_SIZE], name2[MAX_NAME_SIZE];
375 char extnID[128];
376
377 /* Find the index of the given extension.
378 */
379 k = 0;
380 do
381 {
382 k++;
383
384 snprintf (name, sizeof (name), "tbsCertificate.extensions.?%u", k);
385
386 len = sizeof (extnID) - 1;
387 result = asn1_read_value (cert->cert, name, extnID, &len);
388
389 /* move to next
390 */
391
392 if (result == ASN1_ELEMENT_NOT_FOUND)
393 {
394 break;
395 }
396
397 do
398 {
399
400 _gnutls_str_cpy (name2, sizeof (name2), name);
401 _gnutls_str_cat (name2, sizeof (name2), ".extnID");
402
403 len = sizeof (extnID) - 1;
404 result = asn1_read_value (cert->cert, name2, extnID, &len);
405
406 if (result == ASN1_ELEMENT_NOT_FOUND)
407 {
408 gnutls_assert ();
409 break;
410 }
411 else if (result != ASN1_SUCCESS)
412 {
413 gnutls_assert ();
414 return _gnutls_asn2err (result);
415 }
416
417 /* Handle Extension
418 */
419 if (strcmp (extnID, ext_id) == 0)
420 {
421 /* extension was found
422 */
423 return overwrite_extension (cert->cert, k, ext_data, critical);
424 }
425
426
427 }
428 while (0);
429 }
430 while (1);
431
432 if (result == ASN1_ELEMENT_NOT_FOUND)
433 {
434 return set_extension (cert->cert, ext_id, ext_data, critical);
435 }
436 else
437 {
438 gnutls_assert ();
439 return _gnutls_asn2err (result);
440 }
441
442
443 return 0;
444}
445
446
447/* Here we only extract the KeyUsage field, from the DER encoded
448 * extension.
449 */
450int
451_gnutls_x509_ext_extract_keyUsage (uint16_t * keyUsage,
452 opaque * extnValue, int extnValueLen)
453{
454 ASN1_TYPE ext = ASN1_TYPE_EMPTY;
455 int len, result;
456 uint8_t str[2];
457
458 str[0] = str[1] = 0;
459 *keyUsage = 0;
460
461 if ((result = asn1_create_element
462 (_gnutls_get_pkix (), "PKIX1.KeyUsage", &ext)) != ASN1_SUCCESS)
463 {
464 gnutls_assert ();
465 return _gnutls_asn2err (result);
466 }
467
468 result = asn1_der_decoding (&ext, extnValue, extnValueLen, NULL);
469
470 if (result != ASN1_SUCCESS)
471 {
472 gnutls_assert ();
473 asn1_delete_structure (&ext);
474 return _gnutls_asn2err (result);
475 }
476
477 len = sizeof (str);
478 result = asn1_read_value (ext, "", str, &len);
479 if (result != ASN1_SUCCESS)
480 {
481 gnutls_assert ();
482 asn1_delete_structure (&ext);
483 return 0;
484 }
485
486 *keyUsage = str[0] | (str[1] << 8);
487
488 asn1_delete_structure (&ext);
489
490 return 0;
491}
492
493/* extract the basicConstraints from the DER encoded extension
494 */
495int
496_gnutls_x509_ext_extract_basicConstraints (int *CA,
497 int *pathLenConstraint,
498 opaque * extnValue,
499 int extnValueLen)
500{
501 ASN1_TYPE ext = ASN1_TYPE_EMPTY;
502 char str[128];
503 int len, result;
504
505 if ((result = asn1_create_element
506 (_gnutls_get_pkix (), "PKIX1.BasicConstraints", &ext)) != ASN1_SUCCESS)
507 {
508 gnutls_assert ();
509 return _gnutls_asn2err (result);
510 }
511
512 result = asn1_der_decoding (&ext, extnValue, extnValueLen, NULL);
513 if (result != ASN1_SUCCESS)
514 {
515 gnutls_assert ();
516 asn1_delete_structure (&ext);
517 return _gnutls_asn2err (result);
518 }
519
520 if (pathLenConstraint)
521 {
522 result = _gnutls_x509_read_uint (ext, "pathLenConstraint",
523 pathLenConstraint);
524 if (result == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)
525 *pathLenConstraint = -1;
526 else if (result != GNUTLS_E_SUCCESS)
527 {
528 gnutls_assert ();
529 asn1_delete_structure (&ext);
530 return _gnutls_asn2err (result);
531 }
532 }
533
534 /* the default value of cA is false.
535 */
536 len = sizeof (str) - 1;
537 result = asn1_read_value (ext, "cA", str, &len);
538 if (result == ASN1_SUCCESS && strcmp (str, "TRUE") == 0)
539 *CA = 1;
540 else
541 *CA = 0;
542
543 asn1_delete_structure (&ext);
544
545 return 0;
546}
547
548/* generate the basicConstraints in a DER encoded extension
549 * Use 0 or 1 (TRUE) for CA.
550 * Use negative values for pathLenConstraint to indicate that the field
551 * should not be present, >= 0 to indicate set values.
552 */
553int
554_gnutls_x509_ext_gen_basicConstraints (int CA,
555 int pathLenConstraint,
556 gnutls_datum_t * der_ext)
557{
558 ASN1_TYPE ext = ASN1_TYPE_EMPTY;
559 const char *str;
560 int result;
561
562 if (CA == 0)
563 str = "FALSE";
564 else
565 str = "TRUE";
566
567 result =
568 asn1_create_element (_gnutls_get_pkix (), "PKIX1.BasicConstraints", &ext);
569 if (result != ASN1_SUCCESS)
570 {
571 gnutls_assert ();
572 return _gnutls_asn2err (result);
573 }
574
575 result = asn1_write_value (ext, "cA", str, 1);
576 if (result != ASN1_SUCCESS)
577 {
578 gnutls_assert ();
579 asn1_delete_structure (&ext);
580 return _gnutls_asn2err (result);
581 }
582
583 if (pathLenConstraint < 0)
584 {
585 result = asn1_write_value (ext, "pathLenConstraint", NULL, 0);
586 if (result < 0)
587 result = _gnutls_asn2err (result);
588 }
589 else
590 result = _gnutls_x509_write_uint32 (ext, "pathLenConstraint",
591 pathLenConstraint);
592 if (result < 0)
593 {
594 gnutls_assert ();
595 asn1_delete_structure (&ext);
596 return result;
597 }
598
599 result = _gnutls_x509_der_encode (ext, "", der_ext, 0);
600
601 asn1_delete_structure (&ext);
602
603 if (result < 0)
604 {
605 gnutls_assert ();
606 return result;
607 }
608
609 return 0;
610}
611
612/* generate the keyUsage in a DER encoded extension
613 * Use an ORed SEQUENCE of GNUTLS_KEY_* for usage.
614 */
615int
616_gnutls_x509_ext_gen_keyUsage (uint16_t usage, gnutls_datum_t * der_ext)
617{
618 ASN1_TYPE ext = ASN1_TYPE_EMPTY;
619 int result;
620 uint8_t str[2];
621
622 result = asn1_create_element (_gnutls_get_pkix (), "PKIX1.KeyUsage", &ext);
623 if (result != ASN1_SUCCESS)
624 {
625 gnutls_assert ();
626 return _gnutls_asn2err (result);
627 }
628
629 str[0] = usage & 0xff;
630 str[1] = usage >> 8;
631
632 result = asn1_write_value (ext, "", str, 9);
633 if (result != ASN1_SUCCESS)
634 {
635 gnutls_assert ();
636 asn1_delete_structure (&ext);
637 return _gnutls_asn2err (result);
638 }
639
640 result = _gnutls_x509_der_encode (ext, "", der_ext, 0);
641
642 asn1_delete_structure (&ext);
643
644 if (result < 0)
645 {
646 gnutls_assert ();
647 return result;
648 }
649
650 return 0;
651}
652
653static int
654write_new_general_name (ASN1_TYPE ext, const char *ext_name,
655 gnutls_x509_subject_alt_name_t type,
656 const char *data_string)
657{
658 const char *str;
659 int result;
660 char name[128];
661
662 result = asn1_write_value (ext, ext_name, "NEW", 1);
663 if (result != ASN1_SUCCESS)
664 {
665 gnutls_assert ();
666 return _gnutls_asn2err (result);
667 }
668
669 switch (type)
670 {
671 case GNUTLS_SAN_DNSNAME:
672 str = "dNSName";
673 break;
674 case GNUTLS_SAN_RFC822NAME:
675 str = "rfc822Name";
676 break;
677 case GNUTLS_SAN_URI:
678 str = "uniformResourceIdentifier";
679 break;
680 case GNUTLS_SAN_IPADDRESS:
681 str = "iPAddress";
682 break;
683 default:
684 gnutls_assert ();
685 return GNUTLS_E_INTERNAL_ERROR;
686 }
687
688 if (ext_name[0] == 0)
689 { /* no dot */
690 _gnutls_str_cpy (name, sizeof (name), "?LAST");
691 }
692 else
693 {
694 _gnutls_str_cpy (name, sizeof (name), ext_name);
695 _gnutls_str_cat (name, sizeof (name), ".?LAST");
696 }
697
698 result = asn1_write_value (ext, name, str, 1);
699 if (result != ASN1_SUCCESS)
700 {
701 gnutls_assert ();
702 return _gnutls_asn2err (result);
703 }
704
705 _gnutls_str_cat (name, sizeof (name), ".");
706 _gnutls_str_cat (name, sizeof (name), str);
707
708 result = asn1_write_value (ext, name, data_string, strlen (data_string));
709 if (result != ASN1_SUCCESS)
710 {
711 gnutls_assert ();
712 asn1_delete_structure (&ext);
713 return _gnutls_asn2err (result);
714 }
715
716 return 0;
717}
718
719/* Convert the given name to GeneralNames in a DER encoded extension.
720 * This is the same as subject alternative name.
721 */
722int
723_gnutls_x509_ext_gen_subject_alt_name (gnutls_x509_subject_alt_name_t
724 type, const char *data_string,
725 gnutls_datum_t * der_ext)
726{
727 ASN1_TYPE ext = ASN1_TYPE_EMPTY;
728 int result;
729
730 result =
731 asn1_create_element (_gnutls_get_pkix (), "PKIX1.GeneralNames", &ext);
732 if (result != ASN1_SUCCESS)
733 {
734 gnutls_assert ();
735 return _gnutls_asn2err (result);
736 }
737
738 result = write_new_general_name (ext, "", type, data_string);
739 if (result < 0)
740 {
741 gnutls_assert ();
742 asn1_delete_structure (&ext);
743 return result;
744 }
745
746 result = _gnutls_x509_der_encode (ext, "", der_ext, 0);
747
748 asn1_delete_structure (&ext);
749
750 if (result < 0)
751 {
752 gnutls_assert ();
753 return result;
754 }
755
756 return 0;
757}
758
759/* generate the SubjectKeyID in a DER encoded extension
760 */
761int
762_gnutls_x509_ext_gen_key_id (const void *id, size_t id_size,
763 gnutls_datum_t * der_ext)
764{
765 ASN1_TYPE ext = ASN1_TYPE_EMPTY;
766 int result;
767
768 result =
769 asn1_create_element (_gnutls_get_pkix (),
770 "PKIX1.SubjectKeyIdentifier", &ext);
771 if (result != ASN1_SUCCESS)
772 {
773 gnutls_assert ();
774 return _gnutls_asn2err (result);
775 }
776
777 result = asn1_write_value (ext, "", id, id_size);
778 if (result != ASN1_SUCCESS)
779 {
780 gnutls_assert ();
781 asn1_delete_structure (&ext);
782 return _gnutls_asn2err (result);
783 }
784
785 result = _gnutls_x509_der_encode (ext, "", der_ext, 0);
786
787 asn1_delete_structure (&ext);
788
789 if (result < 0)
790 {
791 gnutls_assert ();
792 return result;
793 }
794
795 return 0;
796}
797
798/* generate the AuthorityKeyID in a DER encoded extension
799 */
800int
801_gnutls_x509_ext_gen_auth_key_id (const void *id, size_t id_size,
802 gnutls_datum_t * der_ext)
803{
804 ASN1_TYPE ext = ASN1_TYPE_EMPTY;
805 int result;
806
807 result =
808 asn1_create_element (_gnutls_get_pkix (),
809 "PKIX1.AuthorityKeyIdentifier", &ext);
810 if (result != ASN1_SUCCESS)
811 {
812 gnutls_assert ();
813 return _gnutls_asn2err (result);
814 }
815
816 result = asn1_write_value (ext, "keyIdentifier", id, id_size);
817 if (result != ASN1_SUCCESS)
818 {
819 gnutls_assert ();
820 asn1_delete_structure (&ext);
821 return _gnutls_asn2err (result);
822 }
823
824 asn1_write_value (ext, "authorityCertIssuer", NULL, 0);
825 asn1_write_value (ext, "authorityCertSerialNumber", NULL, 0);
826
827 result = _gnutls_x509_der_encode (ext, "", der_ext, 0);
828
829 asn1_delete_structure (&ext);
830
831 if (result < 0)
832 {
833 gnutls_assert ();
834 return result;
835 }
836
837 return 0;
838}
839
840
841/* Creates and encodes the CRL Distribution points. data_string should be a name
842 * and type holds the type of the name.
843 * reason_flags should be an or'ed sequence of GNUTLS_CRL_REASON_*.
844 *
845 */
846int
847_gnutls_x509_ext_gen_crl_dist_points (gnutls_x509_subject_alt_name_t
848 type, const void *data_string,
849 unsigned int reason_flags,
850 gnutls_datum_t * der_ext)
851{
852 ASN1_TYPE ext = ASN1_TYPE_EMPTY;
853 gnutls_datum_t gnames = { NULL, 0 };
854 int result;
855 uint8_t reasons[2];
856
857 reasons[0] = reason_flags & 0xff;
858 reasons[1] = reason_flags >> 8;
859
860 result =
861 asn1_create_element (_gnutls_get_pkix (),
862 "PKIX1.CRLDistributionPoints", &ext);
863 if (result != ASN1_SUCCESS)
864 {
865 gnutls_assert ();
866 result = _gnutls_asn2err (result);
867 goto cleanup;
868 }
869
870 result = asn1_write_value (ext, "", "NEW", 1);
871 if (result != ASN1_SUCCESS)
872 {
873 gnutls_assert ();
874 result = _gnutls_asn2err (result);
875 goto cleanup;
876 }
877
878 if (reason_flags)
879 {
880 result = asn1_write_value (ext, "?LAST.reasons", reasons, 9);
881 if (result != ASN1_SUCCESS)
882 {
883 gnutls_assert ();
884 result = _gnutls_asn2err (result);
885 goto cleanup;
886 }
887 }
888 else
889 {
890 result = asn1_write_value (ext, "?LAST.reasons", NULL, 0);
891 if (result != ASN1_SUCCESS)
892 {
893 gnutls_assert ();
894 result = _gnutls_asn2err (result);
895 goto cleanup;
896 }
897 }
898
899 result = asn1_write_value (ext, "?LAST.cRLIssuer", NULL, 0);
900 if (result != ASN1_SUCCESS)
901 {
902 gnutls_assert ();
903 result = _gnutls_asn2err (result);
904 goto cleanup;
905 }
906
907 /* When used as type CHOICE.
908 */
909 result = asn1_write_value (ext, "?LAST.distributionPoint", "fullName", 1);
910 if (result != ASN1_SUCCESS)
911 {
912 gnutls_assert ();
913 result = _gnutls_asn2err (result);
914 goto cleanup;
915 }
916
917#if 0
918 /* only needed in old code (where defined as SEQUENCE OF) */
919 asn1_write_value (ext,
920 "?LAST.distributionPoint.nameRelativeToCRLIssuer",
921 NULL, 0);
922#endif
923
924 result =
925 write_new_general_name (ext, "?LAST.distributionPoint.fullName",
926 type, data_string);
927 if (result < 0)
928 {
929 gnutls_assert ();
930 goto cleanup;
931 }
932
933 result = _gnutls_x509_der_encode (ext, "", der_ext, 0);
934
935 if (result < 0)
936 {
937 gnutls_assert ();
938 goto cleanup;
939 }
940
941 result = 0;
942
943cleanup:
944 _gnutls_free_datum (&gnames);
945 asn1_delete_structure (&ext);
946
947 return result;
948}
949
950/* extract the proxyCertInfo from the DER encoded extension
951 */
952int
953_gnutls_x509_ext_extract_proxyCertInfo (int *pathLenConstraint,
954 char **policyLanguage,
955 char **policy,
956 size_t * sizeof_policy,
957 opaque * extnValue, int extnValueLen)
958{
959 ASN1_TYPE ext = ASN1_TYPE_EMPTY;
960 int result;
961 gnutls_datum_t value;
962
963 if ((result = asn1_create_element
964 (_gnutls_get_pkix (), "PKIX1.ProxyCertInfo", &ext)) != ASN1_SUCCESS)
965 {
966 gnutls_assert ();
967 return _gnutls_asn2err (result);
968 }
969
970 result = asn1_der_decoding (&ext, extnValue, extnValueLen, NULL);
971 if (result != ASN1_SUCCESS)
972 {
973 gnutls_assert ();
974 asn1_delete_structure (&ext);
975 return _gnutls_asn2err (result);
976 }
977
978 if (pathLenConstraint)
979 {
980 result = _gnutls_x509_read_uint (ext, "pCPathLenConstraint",
981 pathLenConstraint);
982 if (result == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)
983 *pathLenConstraint = -1;
984 else if (result != GNUTLS_E_SUCCESS)
985 {
986 asn1_delete_structure (&ext);
987 return _gnutls_asn2err (result);
988 }
989 }
990
991 result = _gnutls_x509_read_value (ext, "proxyPolicy.policyLanguage",
992 &value, 0);
993 if (result < 0)
994 {
995 gnutls_assert ();
996 asn1_delete_structure (&ext);
997 return result;
998 }
999
1000 if (policyLanguage)
1001 *policyLanguage = gnutls_strdup (value.data);
1002
1003 result = _gnutls_x509_read_value (ext, "proxyPolicy.policy", &value, 0);
1004 if (result == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)
1005 {
1006 if (policy)
1007 *policy = NULL;
1008 if (sizeof_policy)
1009 *sizeof_policy = 0;
1010 }
1011 else if (result < 0)
1012 {
1013 gnutls_assert ();
1014 asn1_delete_structure (&ext);
1015 return result;
1016 }
1017 else
1018 {
1019 if (policy)
1020 *policy = value.data;
1021 if (sizeof_policy)
1022 *sizeof_policy = value.size;
1023 }
1024
1025 asn1_delete_structure (&ext);
1026
1027 return 0;
1028}
1029
1030/* generate the proxyCertInfo in a DER encoded extension
1031 */
1032int
1033_gnutls_x509_ext_gen_proxyCertInfo (int pathLenConstraint,
1034 const char *policyLanguage,
1035 const char *policy,
1036 size_t sizeof_policy,
1037 gnutls_datum_t * der_ext)
1038{
1039 ASN1_TYPE ext = ASN1_TYPE_EMPTY;
1040 int result;
1041
1042 result = asn1_create_element (_gnutls_get_pkix (),
1043 "PKIX1.ProxyCertInfo", &ext);
1044 if (result != ASN1_SUCCESS)
1045 {
1046 gnutls_assert ();
1047 return _gnutls_asn2err (result);
1048 }
1049
1050 if (pathLenConstraint < 0)
1051 {
1052 result = asn1_write_value (ext, "pCPathLenConstraint", NULL, 0);
1053 if (result < 0)
1054 result = _gnutls_asn2err (result);
1055 }
1056 else
1057 result = _gnutls_x509_write_uint32 (ext, "pCPathLenConstraint",
1058 pathLenConstraint);
1059 if (result < 0)
1060 {
1061 gnutls_assert ();
1062 asn1_delete_structure (&ext);
1063 return result;
1064 }
1065
1066 result = asn1_write_value (ext, "proxyPolicy.policyLanguage",
1067 policyLanguage, 1);
1068 if (result < 0)
1069 {
1070 gnutls_assert ();
1071 asn1_delete_structure (&ext);
1072 return _gnutls_asn2err (result);
1073 }
1074
1075 result = asn1_write_value (ext, "proxyPolicy.policy",
1076 policy, sizeof_policy);
1077 if (result < 0)
1078 {
1079 gnutls_assert ();
1080 asn1_delete_structure (&ext);
1081 return _gnutls_asn2err (result);
1082 }
1083
1084 result = _gnutls_x509_der_encode (ext, "", der_ext, 0);
1085
1086 asn1_delete_structure (&ext);
1087
1088 if (result < 0)
1089 {
1090 gnutls_assert ();
1091 return result;
1092 }
1093
1094 return 0;
1095}
diff --git a/src/daemon/https/x509/extensions.h b/src/daemon/https/x509/extensions.h
new file mode 100644
index 00000000..fb758c90
--- /dev/null
+++ b/src/daemon/https/x509/extensions.h
@@ -0,0 +1,68 @@
1/*
2 * Copyright (C) 2003, 2004, 2005, 2006, 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
25int _gnutls_x509_crt_get_extension (gnutls_x509_crt_t cert,
26 const char *extension_id, int indx,
27 gnutls_datum_t * ret,
28 unsigned int *critical);
29
30int _gnutls_x509_crt_get_extension_oid (gnutls_x509_crt_t cert,
31 int indx, void *ret,
32 size_t * ret_size);
33int _gnutls_x509_ext_extract_keyUsage (uint16_t * keyUsage,
34 opaque * extnValue, int extnValueLen);
35int _gnutls_x509_ext_extract_basicConstraints (int *CA,
36 int *pathLenConstraint,
37 opaque * extnValue,
38 int extnValueLen);
39int _gnutls_x509_crt_set_extension (gnutls_x509_crt_t cert,
40 const char *extension_id,
41 const gnutls_datum_t * ext_data,
42 unsigned int critical);
43int _gnutls_x509_ext_gen_basicConstraints (int CA, int pathLenConstraint,
44 gnutls_datum_t * der_ext);
45int _gnutls_x509_ext_gen_keyUsage (uint16_t usage, gnutls_datum_t * der_ext);
46int _gnutls_x509_ext_gen_subject_alt_name (gnutls_x509_subject_alt_name_t
47 type, const char *data_string,
48 gnutls_datum_t * der_ext);
49int _gnutls_x509_ext_gen_crl_dist_points (gnutls_x509_subject_alt_name_t
50 type, const void *data_string,
51 unsigned int reason_flags,
52 gnutls_datum_t * der_ext);
53int _gnutls_x509_ext_gen_key_id (const void *id, size_t id_size,
54 gnutls_datum_t * der_data);
55int _gnutls_x509_ext_gen_auth_key_id (const void *id, size_t id_size,
56 gnutls_datum_t * der_data);
57
58int _gnutls_x509_ext_extract_proxyCertInfo (int *pathLenConstraint,
59 char **policyLanguage,
60 char **policy,
61 size_t *sizeof_policy,
62 opaque * extnValue,
63 int extnValueLen);
64int _gnutls_x509_ext_gen_proxyCertInfo (int pathLenConstraint,
65 const char *policyLanguage,
66 const char *policy,
67 size_t sizeof_policy,
68 gnutls_datum_t * der_ext);
diff --git a/src/daemon/https/x509/mpi.c b/src/daemon/https/x509/mpi.c
new file mode 100644
index 00000000..8cc43855
--- /dev/null
+++ b/src/daemon/https/x509/mpi.c
@@ -0,0 +1,576 @@
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 <gnutls_errors.h>
27#include <gnutls_global.h>
28#include <libtasn1.h>
29#include <gnutls_datum.h>
30#include "common.h"
31#include "x509.h"
32#include <gnutls_num.h>
33#include "mpi.h"
34
35/*
36 * some x509 certificate parsing functions that relate to MPI parameter
37 * extraction. This reads the BIT STRING subjectPublicKey.
38 * Returns 2 parameters (m,e).
39 */
40int
41_gnutls_x509_read_rsa_params (opaque * der, int dersize, mpi_t * params)
42{
43 int result;
44 ASN1_TYPE spk = ASN1_TYPE_EMPTY;
45
46 if ((result =
47 asn1_create_element (_gnutls_get_gnutls_asn (), "GNUTLS.RSAPublicKey",
48 &spk)) != ASN1_SUCCESS)
49 {
50 gnutls_assert ();
51 return _gnutls_asn2err (result);
52 }
53
54 result = asn1_der_decoding (&spk, der, dersize, NULL);
55
56 if (result != ASN1_SUCCESS)
57 {
58 gnutls_assert ();
59 asn1_delete_structure (&spk);
60 return _gnutls_asn2err (result);
61 }
62
63 if ((result = _gnutls_x509_read_int (spk, "modulus", &params[0])) < 0)
64 {
65 gnutls_assert ();
66 asn1_delete_structure (&spk);
67 return GNUTLS_E_ASN1_GENERIC_ERROR;
68 }
69
70 if ((result =
71 _gnutls_x509_read_int (spk, "publicExponent", &params[1])) < 0)
72 {
73 gnutls_assert ();
74 _gnutls_mpi_release (&params[0]);
75 asn1_delete_structure (&spk);
76 return GNUTLS_E_ASN1_GENERIC_ERROR;
77 }
78
79 asn1_delete_structure (&spk);
80
81 return 0;
82
83}
84
85/* reads p,q and g
86 * from the certificate (subjectPublicKey BIT STRING).
87 * params[0-2]
88 */
89int
90_gnutls_x509_read_dsa_params (opaque * der, int dersize, mpi_t * params)
91{
92 int result;
93 ASN1_TYPE spk = ASN1_TYPE_EMPTY;
94
95 if ((result =
96 asn1_create_element (_gnutls_get_pkix (), "PKIX1.Dss-Parms",
97 &spk)) != ASN1_SUCCESS)
98 {
99 gnutls_assert ();
100 return _gnutls_asn2err (result);
101 }
102
103 result = asn1_der_decoding (&spk, der, dersize, NULL);
104
105 if (result != ASN1_SUCCESS)
106 {
107 gnutls_assert ();
108 asn1_delete_structure (&spk);
109 return _gnutls_asn2err (result);
110 }
111
112 /* FIXME: If the parameters are not included in the certificate
113 * then the issuer's parameters should be used. This is not
114 * done yet.
115 */
116
117 /* Read p */
118
119 if ((result = _gnutls_x509_read_int (spk, "p", &params[0])) < 0)
120 {
121 gnutls_assert ();
122 asn1_delete_structure (&spk);
123 return GNUTLS_E_ASN1_GENERIC_ERROR;
124 }
125
126 /* Read q */
127
128 if ((result = _gnutls_x509_read_int (spk, "q", &params[1])) < 0)
129 {
130 gnutls_assert ();
131 asn1_delete_structure (&spk);
132 _gnutls_mpi_release (&params[0]);
133 return GNUTLS_E_ASN1_GENERIC_ERROR;
134 }
135
136 /* Read g */
137
138 if ((result = _gnutls_x509_read_int (spk, "g", &params[2])) < 0)
139 {
140 gnutls_assert ();
141 asn1_delete_structure (&spk);
142 _gnutls_mpi_release (&params[0]);
143 _gnutls_mpi_release (&params[1]);
144 return GNUTLS_E_ASN1_GENERIC_ERROR;
145 }
146
147 asn1_delete_structure (&spk);
148
149 return 0;
150
151}
152
153/* Reads an Integer from the DER encoded data
154 */
155
156int
157_gnutls_x509_read_der_int (opaque * der, int dersize, mpi_t * out)
158{
159 int result;
160 ASN1_TYPE spk = ASN1_TYPE_EMPTY;
161
162 /* == INTEGER */
163 if ((result =
164 asn1_create_element (_gnutls_get_gnutls_asn (), "GNUTLS.DSAPublicKey",
165 &spk)) != ASN1_SUCCESS)
166 {
167 gnutls_assert ();
168 return _gnutls_asn2err (result);
169 }
170
171 result = asn1_der_decoding (&spk, der, dersize, NULL);
172
173 if (result != ASN1_SUCCESS)
174 {
175 gnutls_assert ();
176 asn1_delete_structure (&spk);
177 return _gnutls_asn2err (result);
178 }
179
180 /* Read Y */
181
182 if ((result = _gnutls_x509_read_int (spk, "", out)) < 0)
183 {
184 gnutls_assert ();
185 asn1_delete_structure (&spk);
186 return _gnutls_asn2err (result);
187 }
188
189 asn1_delete_structure (&spk);
190
191 return 0;
192
193}
194
195/* reads DSA's Y
196 * from the certificate
197 * only sets params[3]
198 */
199int
200_gnutls_x509_read_dsa_pubkey (opaque * der, int dersize, mpi_t * params)
201{
202 return _gnutls_x509_read_der_int (der, dersize, &params[3]);
203}
204
205/* Extracts DSA and RSA parameters from a certificate.
206 */
207int
208_gnutls_x509_crt_get_mpis (gnutls_x509_crt_t cert,
209 mpi_t * params, int *params_size)
210{
211 int result;
212 int pk_algorithm;
213 gnutls_datum tmp = { NULL, 0 };
214
215 /* Read the algorithm's OID
216 */
217 pk_algorithm = gnutls_x509_crt_get_pk_algorithm (cert, NULL);
218
219 /* Read the algorithm's parameters
220 */
221 result
222 = _gnutls_x509_read_value (cert->cert,
223 "tbsCertificate.subjectPublicKeyInfo.subjectPublicKey",
224 &tmp, 2);
225
226 if (result < 0)
227 {
228 gnutls_assert ();
229 return result;
230 }
231
232 switch (pk_algorithm)
233 {
234 case GNUTLS_PK_RSA:
235 /* params[0] is the modulus,
236 * params[1] is the exponent
237 */
238 if (*params_size < RSA_PUBLIC_PARAMS)
239 {
240 gnutls_assert ();
241 /* internal error. Increase the mpi_ts in params */
242 result = GNUTLS_E_INTERNAL_ERROR;
243 goto error;
244 }
245
246 if ((result =
247 _gnutls_x509_read_rsa_params (tmp.data, tmp.size, params)) < 0)
248 {
249 gnutls_assert ();
250 goto error;
251 }
252 *params_size = RSA_PUBLIC_PARAMS;
253
254 break;
255 default:
256 /* other types like DH
257 * currently not supported
258 */
259 gnutls_assert ();
260 result = GNUTLS_E_X509_CERTIFICATE_ERROR;
261 goto error;
262 }
263
264 result = 0;
265
266error:_gnutls_free_datum (&tmp);
267 return result;
268}
269
270/*
271 * some x509 certificate functions that relate to MPI parameter
272 * setting. This writes the BIT STRING subjectPublicKey.
273 * Needs 2 parameters (m,e).
274 *
275 * Allocates the space used to store the DER data.
276 */
277int
278_gnutls_x509_write_rsa_params (mpi_t * params,
279 int params_size, gnutls_datum_t * der)
280{
281 int result;
282 ASN1_TYPE spk = ASN1_TYPE_EMPTY;
283
284 der->data = NULL;
285 der->size = 0;
286
287 if (params_size < 2)
288 {
289 gnutls_assert ();
290 result = GNUTLS_E_INVALID_REQUEST;
291 goto cleanup;
292 }
293
294 if ((result =
295 asn1_create_element (_gnutls_get_gnutls_asn (), "GNUTLS.RSAPublicKey",
296 &spk)) != ASN1_SUCCESS)
297 {
298 gnutls_assert ();
299 return _gnutls_asn2err (result);
300 }
301
302 result = _gnutls_x509_write_int (spk, "modulus", params[0], 0);
303 if (result < 0)
304 {
305 gnutls_assert ();
306 goto cleanup;
307 }
308
309 result = _gnutls_x509_write_int (spk, "publicExponent", params[1], 0);
310 if (result < 0)
311 {
312 gnutls_assert ();
313 goto cleanup;
314 }
315
316 result = _gnutls_x509_der_encode (spk, "", der, 0);
317 if (result < 0)
318 {
319 gnutls_assert ();
320 goto cleanup;
321 }
322
323 asn1_delete_structure (&spk);
324 return 0;
325
326cleanup:asn1_delete_structure (&spk);
327
328 return result;
329}
330
331/*
332 * This function writes and encodes the parameters for DSS or RSA keys.
333 * This is the "signatureAlgorithm" fields.
334 */
335int
336_gnutls_x509_write_sig_params (ASN1_TYPE dst,
337 const char *dst_name,
338 gnutls_pk_algorithm_t pk_algorithm,
339 gnutls_digest_algorithm_t dig,
340 mpi_t * params, int params_size)
341{
342 gnutls_datum_t der;
343 int result;
344 char name[128];
345 const char *pk;
346
347 _gnutls_str_cpy (name, sizeof (name), dst_name);
348 _gnutls_str_cat (name, sizeof (name), ".algorithm");
349
350 pk = _gnutls_x509_sign_to_oid (pk_algorithm, HASH2MAC (dig));
351 if (pk == NULL)
352 {
353 gnutls_assert ();
354 return GNUTLS_E_INVALID_REQUEST;
355 }
356
357 /* write the OID.
358 */
359 result = asn1_write_value (dst, name, pk, 1);
360 if (result != ASN1_SUCCESS)
361 {
362 gnutls_assert ();
363 return _gnutls_asn2err (result);
364 }
365
366 _gnutls_str_cpy (name, sizeof (name), dst_name);
367 _gnutls_str_cat (name, sizeof (name), ".parameters");
368
369 if (pk_algorithm == GNUTLS_PK_RSA)
370 { /* RSA */
371 result = asn1_write_value (dst, name, NULL, 0);
372
373 if (result != ASN1_SUCCESS && result != ASN1_ELEMENT_NOT_FOUND)
374 {
375 /* Here we ignore the element not found error, since this
376 * may have been disabled before.
377 */
378 gnutls_assert ();
379 return _gnutls_asn2err (result);
380 }
381 }
382
383 return 0;
384}
385
386/*
387 * This function writes the parameters for DSS keys.
388 * Needs 3 parameters (p,q,g).
389 *
390 * Allocates the space used to store the DER data.
391 */
392int
393_gnutls_x509_write_dsa_params (mpi_t * params,
394 int params_size, gnutls_datum_t * der)
395{
396 int result;
397 ASN1_TYPE spk = ASN1_TYPE_EMPTY;
398
399 der->data = NULL;
400 der->size = 0;
401
402 if (params_size < 3)
403 {
404 gnutls_assert ();
405 result = GNUTLS_E_INVALID_REQUEST;
406 goto cleanup;
407 }
408
409 if ((result =
410 asn1_create_element (_gnutls_get_gnutls_asn (), "GNUTLS.DSAParameters",
411 &spk)) != ASN1_SUCCESS)
412 {
413 gnutls_assert ();
414 return _gnutls_asn2err (result);
415 }
416
417 result = _gnutls_x509_write_int (spk, "p", params[0], 0);
418 if (result < 0)
419 {
420 gnutls_assert ();
421 goto cleanup;
422 }
423
424 result = _gnutls_x509_write_int (spk, "q", params[1], 0);
425 if (result < 0)
426 {
427 gnutls_assert ();
428 goto cleanup;
429 }
430
431 result = _gnutls_x509_write_int (spk, "g", params[2], 0);
432 if (result < 0)
433 {
434 gnutls_assert ();
435 goto cleanup;
436 }
437
438 result = _gnutls_x509_der_encode (spk, "", der, 0);
439 if (result < 0)
440 {
441 gnutls_assert ();
442 goto cleanup;
443 }
444
445 result = 0;
446
447cleanup:asn1_delete_structure (&spk);
448 return result;
449}
450
451/*
452 * This function writes the public parameters for DSS keys.
453 * Needs 1 parameter (y).
454 *
455 * Allocates the space used to store the DER data.
456 */
457int
458_gnutls_x509_write_dsa_public_key (mpi_t * params,
459 int params_size, gnutls_datum_t * der)
460{
461 int result;
462 ASN1_TYPE spk = ASN1_TYPE_EMPTY;
463
464 der->data = NULL;
465 der->size = 0;
466
467 if (params_size < 3)
468 {
469 gnutls_assert ();
470 result = GNUTLS_E_INVALID_REQUEST;
471 goto cleanup;
472 }
473
474 if ((result =
475 asn1_create_element (_gnutls_get_gnutls_asn (), "GNUTLS.DSAPublicKey",
476 &spk)) != ASN1_SUCCESS)
477 {
478 gnutls_assert ();
479 return _gnutls_asn2err (result);
480 }
481
482 result = _gnutls_x509_write_int (spk, "", params[3], 0);
483 if (result < 0)
484 {
485 gnutls_assert ();
486 goto cleanup;
487 }
488
489 result = _gnutls_x509_der_encode (spk, "", der, 0);
490 if (result < 0)
491 {
492 gnutls_assert ();
493 goto cleanup;
494 }
495
496 asn1_delete_structure (&spk);
497 return 0;
498
499cleanup:asn1_delete_structure (&spk);
500 return result;
501}
502
503/* this function reads a (small) unsigned integer
504 * from asn1 structs. Combines the read and the convertion
505 * steps.
506 */
507int
508_gnutls_x509_read_uint (ASN1_TYPE node, const char *value, unsigned int *ret)
509{
510 int len, result;
511 opaque *tmpstr;
512
513 len = 0;
514 result = asn1_read_value (node, value, NULL, &len);
515 if (result != ASN1_MEM_ERROR)
516 {
517 gnutls_assert ();
518 return _gnutls_asn2err (result);
519 }
520
521 tmpstr = gnutls_alloca (len);
522 if (tmpstr == NULL)
523 {
524 gnutls_assert ();
525 return GNUTLS_E_MEMORY_ERROR;
526 }
527
528 result = asn1_read_value (node, value, tmpstr, &len);
529
530 if (result != ASN1_SUCCESS)
531 {
532 gnutls_assert ();
533 gnutls_afree (tmpstr);
534 return _gnutls_asn2err (result);
535 }
536
537 if (len == 1)
538 *ret = tmpstr[0];
539 else if (len == 2)
540 *ret = _gnutls_read_uint16 (tmpstr);
541 else if (len == 3)
542 *ret = _gnutls_read_uint24 (tmpstr);
543 else if (len == 4)
544 *ret = _gnutls_read_uint32 (tmpstr);
545 else
546 {
547 gnutls_assert ();
548 gnutls_afree (tmpstr);
549 return GNUTLS_E_INTERNAL_ERROR;
550 }
551
552 gnutls_afree (tmpstr);
553
554 return 0;
555}
556
557/* Writes the specified integer into the specified node.
558 */
559int
560_gnutls_x509_write_uint32 (ASN1_TYPE node, const char *value, uint32_t num)
561{
562 opaque tmpstr[4];
563 int result;
564
565 _gnutls_write_uint32 (num, tmpstr);
566
567 result = asn1_write_value (node, value, tmpstr, 4);
568
569 if (result != ASN1_SUCCESS)
570 {
571 gnutls_assert ();
572 return _gnutls_asn2err (result);
573 }
574
575 return 0;
576}
diff --git a/src/daemon/https/x509/mpi.h b/src/daemon/https/x509/mpi.h
new file mode 100644
index 00000000..785d7e02
--- /dev/null
+++ b/src/daemon/https/x509/mpi.h
@@ -0,0 +1,57 @@
1/*
2 * Copyright (C) 2003, 2004, 2005 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 "x509.h"
27
28int _gnutls_x509_crt_get_mpis (gnutls_x509_crt_t cert,
29 mpi_t * params, int *params_size);
30int _gnutls_x509_read_rsa_params (opaque * der, int dersize, mpi_t * params);
31int _gnutls_x509_read_dsa_pubkey (opaque * der, int dersize, mpi_t * params);
32int _gnutls_x509_read_dsa_params (opaque * der, int dersize, mpi_t * params);
33
34int _gnutls_x509_write_rsa_params (mpi_t * params, int params_size,
35 gnutls_datum_t * der);
36int _gnutls_x509_write_dsa_params (mpi_t * params, int params_size,
37 gnutls_datum_t * der);
38int _gnutls_x509_write_dsa_public_key (mpi_t * params, int params_size,
39 gnutls_datum_t * der);
40
41int _gnutls_x509_read_uint (ASN1_TYPE node, const char *value,
42 unsigned int *ret);
43
44int
45_gnutls_x509_read_der_int (opaque * der, int dersize, mpi_t* out);
46
47int _gnutls_x509_read_int (ASN1_TYPE node, const char *value,
48 mpi_t * ret_mpi);
49int _gnutls_x509_write_int (ASN1_TYPE node, const char *value, mpi_t mpi,
50 int lz);
51int _gnutls_x509_write_uint32 (ASN1_TYPE node, const char *value,
52 uint32_t num);
53
54int _gnutls_x509_write_sig_params (ASN1_TYPE dst, const char *dst_name,
55 gnutls_pk_algorithm_t pk_algorithm,
56 gnutls_digest_algorithm_t, mpi_t * params,
57 int params_size);
diff --git a/src/daemon/https/x509/output.c b/src/daemon/https/x509/output.c
new file mode 100644
index 00000000..dcc87ab1
--- /dev/null
+++ b/src/daemon/https/x509/output.c
@@ -0,0 +1,1360 @@
1/*
2 * Copyright (C) 2007 Free Software Foundation
3 *
4 * Author: Simon Josefsson
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
21 * 02110-1301, USA
22 *
23 */
24
25/* Functions for printing X.509 Certificate structures
26 */
27
28#include <gnutls_int.h>
29#include <common.h>
30#include <gnutls_x509.h>
31#include <x509.h>
32#include <gnutls_errors.h>
33
34/* I18n of error codes. */
35#include "gettext.h"
36#define _(String) dgettext (PACKAGE, String)
37#define N_(String) gettext_noop (String)
38
39#define addf _gnutls_string_append_printf
40#define adds _gnutls_string_append_str
41
42static void
43hexdump (gnutls_string * str, const char *data, size_t len, const char *spc)
44{
45 size_t j;
46
47 if (spc)
48 adds (str, spc);
49 for (j = 0; j < len; j++)
50 {
51 if (((j + 1) % 16) == 0)
52 {
53 addf (str, "%.2x\n", (unsigned char) data[j]);
54 if (spc && j != (len - 1))
55 adds (str, spc);
56 }
57 else if (j == (len - 1))
58 addf (str, "%.2x", (unsigned char) data[j]);
59 else
60 addf (str, "%.2x:", (unsigned char) data[j]);
61 }
62 if ((j % 16) != 0)
63 adds (str, "\n");
64}
65
66static void
67hexprint (gnutls_string * str, const char *data, size_t len)
68{
69 size_t j;
70
71 if (len == 0)
72 adds (str, "00");
73 else
74 {
75 for (j = 0; j < len; j++)
76 addf (str, "%.2x", (unsigned char) data[j]);
77 }
78}
79
80
81static void
82asciiprint (gnutls_string * str, const char *data, size_t len)
83{
84 size_t j;
85
86 for (j = 0; j < len; j++)
87 if (isprint (data[j]))
88 addf (str, "%c", (unsigned char) data[j]);
89 else
90 addf (str, ".");
91}
92
93static void
94print_proxy (gnutls_string * str, gnutls_x509_crt_t cert)
95{
96 int pathlen;
97 char *policyLanguage;
98 char *policy;
99 size_t npolicy;
100 int err;
101
102 err = gnutls_x509_crt_get_proxy (cert, NULL,
103 &pathlen, &policyLanguage,
104 &policy, &npolicy);
105 if (err < 0)
106 {
107 addf (str, "error: get_proxy: %s\n", gnutls_strerror (err));
108 return;
109 }
110
111 if (pathlen >= 0)
112 addf (str, _("\t\t\tPath Length Constraint: %d\n"), pathlen);
113 addf (str, _("\t\t\tPolicy Language: %s"), policyLanguage);
114 if (strcmp (policyLanguage, "1.3.6.1.5.5.7.21.1") == 0)
115 adds (str, " (id-ppl-inheritALL)\n");
116 else if (strcmp (policyLanguage, "1.3.6.1.5.5.7.21.2") == 0)
117 adds (str, " (id-ppl-independent)\n");
118 else
119 adds (str, "\n");
120 if (npolicy)
121 {
122 adds (str, _("\t\t\tPolicy:\n\t\t\t\tASCII: "));
123 asciiprint (str, policy, npolicy);
124 adds (str, _("\n\t\t\t\tHexdump: "));
125 hexprint (str, policy, npolicy);
126 adds (str, "\n");
127 }
128}
129
130static void
131print_ski (gnutls_string * str, gnutls_x509_crt_t cert)
132{
133 char *buffer = NULL;
134 size_t size = 0;
135 int err;
136
137 err = gnutls_x509_crt_get_subject_key_id (cert, buffer, &size, NULL);
138 if (err != GNUTLS_E_SHORT_MEMORY_BUFFER)
139 {
140 addf (str, "error: get_subject_key_id: %s\n", gnutls_strerror (err));
141 return;
142 }
143
144 buffer = gnutls_malloc (size);
145 if (!buffer)
146 {
147 addf (str, "error: malloc: %s\n", gnutls_strerror (err));
148 return;
149 }
150
151 err = gnutls_x509_crt_get_subject_key_id (cert, buffer, &size, NULL);
152 if (err < 0)
153 {
154 gnutls_free (buffer);
155 addf (str, "error: get_subject_key_id2: %s\n", gnutls_strerror (err));
156 return;
157 }
158
159 adds (str, "\t\t\t");
160 hexprint (str, buffer, size);
161 adds (str, "\n");
162
163 gnutls_free (buffer);
164}
165
166static void
167print_aki (gnutls_string * str, gnutls_x509_crt_t cert)
168{
169 char *buffer = NULL;
170 size_t size = 0;
171 int err;
172
173 err = gnutls_x509_crt_get_authority_key_id (cert, buffer, &size, NULL);
174 if (err != GNUTLS_E_SHORT_MEMORY_BUFFER)
175 {
176 addf (str, "error: get_authority_key_id: %s\n", gnutls_strerror (err));
177 return;
178 }
179
180 buffer = gnutls_malloc (size);
181 if (!buffer)
182 {
183 addf (str, "error: malloc: %s\n", gnutls_strerror (err));
184 return;
185 }
186
187 err = gnutls_x509_crt_get_authority_key_id (cert, buffer, &size, NULL);
188 if (err < 0)
189 {
190 gnutls_free (buffer);
191 addf (str, "error: get_authority_key_id2: %s\n", gnutls_strerror (err));
192 return;
193 }
194
195 adds (str, "\t\t\t");
196 hexprint (str, buffer, size);
197 adds (str, "\n");
198
199 gnutls_free (buffer);
200}
201
202static void
203print_key_usage (gnutls_string * str, gnutls_x509_crt_t cert)
204{
205 unsigned int key_usage;
206 int err;
207
208 err = gnutls_x509_crt_get_key_usage (cert, &key_usage, NULL);
209 if (err < 0)
210 {
211 addf (str, "error: get_key_usage: %s\n", gnutls_strerror (err));
212 return;
213 }
214
215 if (key_usage & GNUTLS_KEY_DIGITAL_SIGNATURE)
216 addf (str, _("\t\t\tDigital signature.\n"));
217 if (key_usage & GNUTLS_KEY_NON_REPUDIATION)
218 addf (str, _("\t\t\tNon repudiation.\n"));
219 if (key_usage & GNUTLS_KEY_KEY_ENCIPHERMENT)
220 addf (str, _("\t\t\tKey encipherment.\n"));
221 if (key_usage & GNUTLS_KEY_DATA_ENCIPHERMENT)
222 addf (str, _("\t\t\tData encipherment.\n"));
223 if (key_usage & GNUTLS_KEY_KEY_AGREEMENT)
224 addf (str, _("\t\t\tKey agreement.\n"));
225 if (key_usage & GNUTLS_KEY_KEY_CERT_SIGN)
226 addf (str, _("\t\t\tCertificate signing.\n"));
227 if (key_usage & GNUTLS_KEY_CRL_SIGN)
228 addf (str, _("\t\t\tCRL signing.\n"));
229 if (key_usage & GNUTLS_KEY_ENCIPHER_ONLY)
230 addf (str, _("\t\t\tKey encipher only.\n"));
231 if (key_usage & GNUTLS_KEY_DECIPHER_ONLY)
232 addf (str, _("\t\t\tKey decipher only.\n"));
233}
234
235static void
236print_crldist (gnutls_string * str, gnutls_x509_crt_t cert)
237{
238 char *buffer = NULL;
239 size_t size;
240 int err;
241 int indx;
242
243 for (indx = 0;; indx++)
244 {
245 size = 0;
246 err = gnutls_x509_crt_get_crl_dist_points (cert, indx, buffer, &size,
247 NULL, NULL);
248 if (err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
249 return;
250 if (err != GNUTLS_E_SHORT_MEMORY_BUFFER)
251 {
252 addf (str, "error: get_crl_dist_points: %s\n",
253 gnutls_strerror (err));
254 return;
255 }
256
257 buffer = gnutls_malloc (size);
258 if (!buffer)
259 {
260 addf (str, "error: malloc: %s\n", gnutls_strerror (err));
261 return;
262 }
263
264 err = gnutls_x509_crt_get_crl_dist_points (cert, indx, buffer, &size,
265 NULL, NULL);
266 if (err < 0)
267 {
268 gnutls_free (buffer);
269 addf (str, "error: get_crl_dist_points2: %s\n",
270 gnutls_strerror (err));
271 return;
272 }
273
274 switch (err)
275 {
276 case GNUTLS_SAN_DNSNAME:
277 addf (str, "\t\t\tDNSname: %.*s\n", size, buffer);
278 break;
279
280 case GNUTLS_SAN_RFC822NAME:
281 addf (str, "\t\t\tRFC822name: %.*s\n", size, buffer);
282 break;
283
284 case GNUTLS_SAN_URI:
285 addf (str, "\t\t\tURI: %.*s\n", size, buffer);
286 break;
287
288 case GNUTLS_SAN_IPADDRESS:
289 addf (str, "\t\t\tIPAddress: %.*s\n", size, buffer);
290 break;
291
292 case GNUTLS_SAN_DN:
293 addf (str, "\t\t\tdirectoryName: %.*s\n", size, buffer);
294 break;
295
296 default:
297 addf (str, "error: unknown SAN\n");
298 break;
299 }
300 gnutls_free (buffer);
301 }
302}
303
304static void
305print_key_purpose (gnutls_string * str, gnutls_x509_crt_t cert)
306{
307 int indx;
308 char *buffer = NULL;
309 size_t size;
310 int err;
311
312 for (indx = 0;; indx++)
313 {
314 size = 0;
315 err = gnutls_x509_crt_get_key_purpose_oid (cert, indx, buffer,
316 &size, NULL);
317 if (err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
318 return;
319 if (err != GNUTLS_E_SHORT_MEMORY_BUFFER)
320 {
321 addf (str, "error: get_key_purpose_oid: %s\n",
322 gnutls_strerror (err));
323 return;
324 }
325
326 buffer = gnutls_malloc (size);
327 if (!buffer)
328 {
329 addf (str, "error: malloc: %s\n", gnutls_strerror (err));
330 return;
331 }
332
333 err = gnutls_x509_crt_get_key_purpose_oid (cert, indx, buffer,
334 &size, NULL);
335 if (err < 0)
336 {
337 gnutls_free (buffer);
338 addf (str, "error: get_key_purpose_oid2: %s\n",
339 gnutls_strerror (err));
340 return;
341 }
342
343 if (strcmp (buffer, GNUTLS_KP_TLS_WWW_SERVER) == 0)
344 addf (str, _("\t\t\tTLS WWW Server.\n"));
345 else if (strcmp (buffer, GNUTLS_KP_TLS_WWW_CLIENT) == 0)
346 addf (str, _("\t\t\tTLS WWW Client.\n"));
347 else if (strcmp (buffer, GNUTLS_KP_CODE_SIGNING) == 0)
348 addf (str, _("\t\t\tCode signing.\n"));
349 else if (strcmp (buffer, GNUTLS_KP_EMAIL_PROTECTION) == 0)
350 addf (str, _("\t\t\tEmail protection.\n"));
351 else if (strcmp (buffer, GNUTLS_KP_TIME_STAMPING) == 0)
352 addf (str, _("\t\t\tTime stamping.\n"));
353 else if (strcmp (buffer, GNUTLS_KP_OCSP_SIGNING) == 0)
354 addf (str, _("\t\t\tOCSP signing.\n"));
355 else if (strcmp (buffer, GNUTLS_KP_ANY) == 0)
356 addf (str, _("\t\t\tAny purpose.\n"));
357 else
358 addf (str, "\t\t\t%s\n", buffer);
359
360 gnutls_free (buffer);
361 }
362}
363
364static void
365print_basic (gnutls_string * str, gnutls_x509_crt_t cert)
366{
367 int pathlen;
368 int err;
369
370 err = gnutls_x509_crt_get_basic_constraints (cert, NULL, NULL, &pathlen);
371 if (err < 0)
372 {
373 addf (str, "error: get_basic_constraints: %s\n", gnutls_strerror (err));
374 return;
375 }
376
377 if (err == 0)
378 addf (str, _("\t\t\tCertificate Authority (CA): FALSE\n"));
379 else
380 addf (str, _("\t\t\tCertificate Authority (CA): TRUE\n"));
381
382 if (pathlen >= 0)
383 addf (str, _("\t\t\tPath Length Constraint: %d\n"), pathlen);
384}
385
386static void
387print_san (gnutls_string * str, gnutls_x509_crt_t cert)
388{
389 unsigned int san_idx;
390
391 for (san_idx = 0;; san_idx++)
392 {
393 char *buffer = NULL;
394 size_t size = 0;
395 int err;
396
397 err =
398 gnutls_x509_crt_get_subject_alt_name (cert, san_idx, buffer, &size,
399 NULL);
400 if (err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
401 break;
402 if (err != GNUTLS_E_SHORT_MEMORY_BUFFER)
403 {
404 addf (str, "error: get_subject_alt_name: %s\n",
405 gnutls_strerror (err));
406 return;
407 }
408
409 buffer = gnutls_malloc (size);
410 if (!buffer)
411 {
412 addf (str, "error: malloc: %s\n", gnutls_strerror (err));
413 return;
414 }
415
416 err = gnutls_x509_crt_get_subject_alt_name (cert, san_idx,
417 buffer, &size, NULL);
418 if (err < 0)
419 {
420 gnutls_free (buffer);
421 addf (str, "error: get_subject_alt_name2: %s\n",
422 gnutls_strerror (err));
423 return;
424 }
425
426 switch (err)
427 {
428 case GNUTLS_SAN_DNSNAME:
429 addf (str, "\t\t\tDNSname: %.*s\n", size, buffer);
430 break;
431
432 case GNUTLS_SAN_RFC822NAME:
433 addf (str, "\t\t\tRFC822name: %.*s\n", size, buffer);
434 break;
435
436 case GNUTLS_SAN_URI:
437 addf (str, "\t\t\tURI: %.*s\n", size, buffer);
438 break;
439
440 case GNUTLS_SAN_IPADDRESS:
441 addf (str, "\t\t\tIPAddress: %.*s\n", size, buffer);
442 break;
443
444 case GNUTLS_SAN_DN:
445 addf (str, "\t\t\tdirectoryName: %.*s\n", size, buffer);
446 break;
447
448 case GNUTLS_SAN_OTHERNAME:
449 {
450 char *oid = NULL;
451 size_t oidsize;
452
453 oidsize = 0;
454 err = gnutls_x509_crt_get_subject_alt_othername_oid
455 (cert, san_idx, oid, &oidsize);
456 if (err != GNUTLS_E_SHORT_MEMORY_BUFFER)
457 {
458 gnutls_free (buffer);
459 addf (str, "error: get_subject_alt_othername_oid: %s\n",
460 gnutls_strerror (err));
461 return;
462 }
463
464 oid = gnutls_malloc (oidsize);
465 if (!oid)
466 {
467 gnutls_free (buffer);
468 addf (str, "error: malloc: %s\n", gnutls_strerror (err));
469 return;
470 }
471
472 err = gnutls_x509_crt_get_subject_alt_othername_oid
473 (cert, san_idx, oid, &oidsize);
474 if (err < 0)
475 {
476 gnutls_free (buffer);
477 gnutls_free (oid);
478 addf (str, "error: get_subject_alt_othername_oid2: %s\n",
479 gnutls_strerror (err));
480 return;
481 }
482
483 if (err == GNUTLS_SAN_OTHERNAME_XMPP)
484 addf (str, _("\t\t\tXMPP Address: %.*s\n"), size, buffer);
485 else
486 {
487 addf (str, _("\t\t\totherName OID: %.*s\n"), oidsize, oid);
488 addf (str, _("\t\t\totherName DER: "));
489 hexprint (str, buffer, size);
490 addf (str, _("\n\t\t\totherName ASCII: "));
491 asciiprint (str, buffer, size);
492 addf (str, "\n");
493 }
494 gnutls_free (oid);
495 }
496 break;
497
498 default:
499 addf (str, "error: unknown SAN\n");
500 break;
501 }
502
503 gnutls_free (buffer);
504 }
505}
506
507static void
508print_cert (gnutls_string * str, gnutls_x509_crt_t cert, int notsigned)
509{
510 /* Version. */
511 {
512 int version = gnutls_x509_crt_get_version (cert);
513 if (version < 0)
514 addf (str, "error: get_version: %s\n", gnutls_strerror (version));
515 else
516 addf (str, _("\tVersion: %d\n"), version);
517 }
518
519 /* Serial. */
520 {
521 char serial[128];
522 size_t serial_size = sizeof (serial);
523 int err;
524
525 err = gnutls_x509_crt_get_serial (cert, serial, &serial_size);
526 if (err < 0)
527 addf (str, "error: get_serial: %s\n", gnutls_strerror (err));
528 else
529 {
530 addf (str, _("\tSerial Number (hex): "));
531 hexprint (str, serial, serial_size);
532 addf (str, "\n");
533 }
534 }
535
536 /* Issuer. */
537 if (!notsigned)
538 {
539 char dn[1024];
540 size_t dn_size = sizeof (dn);
541 int err;
542
543 err = gnutls_x509_crt_get_issuer_dn (cert, dn, &dn_size);
544 if (err < 0)
545 addf (str, "error: get_issuer_dn: %s\n", gnutls_strerror (err));
546 else
547 addf (str, _("\tIssuer: %s\n"), dn);
548 }
549
550 /* Validity. */
551 {
552 time_t tim;
553
554 addf (str, _("\tValidity:\n"));
555
556 tim = gnutls_x509_crt_get_activation_time (cert);
557 {
558 char s[42];
559 size_t max = sizeof (s);
560 struct tm t;
561
562 if (gmtime_r (&tim, &t) == NULL)
563 addf (str, "error: gmtime_r (%d)\n", t);
564 else if (strftime (s, max, "%a %b %e %H:%M:%S UTC %Y", &t) == 0)
565 addf (str, "error: strftime (%d)\n", t);
566 else
567 addf (str, _("\t\tNot Before: %s\n"), s);
568 }
569
570 tim = gnutls_x509_crt_get_expiration_time (cert);
571 {
572 char s[42];
573 size_t max = sizeof (s);
574 struct tm t;
575
576 if (gmtime_r (&tim, &t) == NULL)
577 addf (str, "error: gmtime_r (%d)\n", t);
578 else if (strftime (s, max, "%a %b %e %H:%M:%S UTC %Y", &t) == 0)
579 addf (str, "error: strftime (%d)\n", t);
580 else
581 addf (str, _("\t\tNot After: %s\n"), s);
582 }
583 }
584
585 /* Subject. */
586 {
587 char dn[1024];
588 size_t dn_size = sizeof (dn);
589 int err;
590
591 err = gnutls_x509_crt_get_dn (cert, dn, &dn_size);
592 if (err < 0)
593 addf (str, "error: get_dn: %s\n", gnutls_strerror (err));
594 else
595 addf (str, _("\tSubject: %s\n"), dn);
596 }
597
598 /* SubjectPublicKeyInfo. */
599 {
600 int err;
601 unsigned int bits;
602
603 err = gnutls_x509_crt_get_pk_algorithm (cert, &bits);
604 if (err < 0)
605 addf (str, "error: get_pk_algorithm: %s\n", gnutls_strerror (err));
606 else
607 {
608 const char *name = gnutls_pk_algorithm_get_name (err);
609 if (name == NULL)
610 name = "Unknown";
611
612 addf (str, _("\tSubject Public Key Algorithm: %s\n"), name);
613 switch (err)
614 {
615 case GNUTLS_PK_RSA:
616 {
617 gnutls_datum_t m, e;
618
619 err = gnutls_x509_crt_get_pk_rsa_raw (cert, &m, &e);
620 if (err < 0)
621 addf (str, "error: get_pk_rsa_raw: %s\n",
622 gnutls_strerror (err));
623 else
624 {
625 addf (str, _("\t\tModulus (bits %d):\n"), bits);
626 hexdump (str, m.data, m.size, "\t\t\t");
627 addf (str, _("\t\tExponent:\n"));
628 hexdump (str, e.data, e.size, "\t\t\t");
629 }
630
631 gnutls_free (m.data);
632 gnutls_free (e.data);
633 }
634 break;
635
636 case GNUTLS_PK_DSA:
637 {
638 gnutls_datum_t p, q, g, y;
639
640 err = gnutls_x509_crt_get_pk_dsa_raw (cert, &p, &q, &g, &y);
641 if (err < 0)
642 addf (str, "error: get_pk_dsa_raw: %s\n",
643 gnutls_strerror (err));
644 else
645 {
646 addf (str, _("\t\tPublic key (bits %d):\n"), bits);
647 hexdump (str, y.data, y.size, "\t\t\t");
648 addf (str, _("\t\tP:\n"));
649 hexdump (str, p.data, p.size, "\t\t\t");
650 addf (str, _("\t\tQ:\n"));
651 hexdump (str, q.data, q.size, "\t\t\t");
652 addf (str, _("\t\tG:\n"));
653 hexdump (str, g.data, g.size, "\t\t\t");
654 }
655 }
656 break;
657
658 default:
659 break;
660 }
661 }
662 }
663
664 /* Extensions. */
665 if (gnutls_x509_crt_get_version (cert) >= 3)
666 {
667 size_t i;
668 int err = 0;
669
670 for (i = 0;; i++)
671 {
672 char oid[128] = "";
673 size_t sizeof_oid = sizeof (oid);
674 int critical;
675 size_t san_idx = 0;
676 size_t proxy_idx = 0;
677 size_t basic_idx = 0;
678 size_t keyusage_idx = 0;
679 size_t keypurpose_idx = 0;
680 size_t ski_idx = 0;
681 size_t aki_idx = 0;
682 size_t crldist_idx = 0;
683
684 err = gnutls_x509_crt_get_extension_info (cert, i,
685 oid, &sizeof_oid,
686 &critical);
687 if (err < 0)
688 {
689 if (err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
690 break;
691 addf (str, "error: get_extension_info: %s\n",
692 gnutls_strerror (err));
693 continue;
694 }
695
696 if (i == 0)
697 addf (str, _("\tExtensions:\n"));
698
699 if (strcmp (oid, "2.5.29.19") == 0)
700 {
701 if (basic_idx)
702 {
703 addf (str, "error: more than one basic constraint\n");
704 continue;
705 }
706
707 addf (str, _("\t\tBasic Constraints (%s):\n"),
708 critical ? _("critical") : _("not critical"));
709
710 print_basic (str, cert);
711
712 basic_idx++;
713 }
714 else if (strcmp (oid, "2.5.29.14") == 0)
715 {
716 if (ski_idx)
717 {
718 addf (str, "error: more than one SKI extension\n");
719 continue;
720 }
721
722 addf (str, _("\t\tSubject Key Identifier (%s):\n"),
723 critical ? _("critical") : _("not critical"));
724
725 print_ski (str, cert);
726
727 ski_idx++;
728 }
729 else if (strcmp (oid, "2.5.29.35") == 0)
730 {
731 if (aki_idx)
732 {
733 addf (str, "error: more than one AKI extension\n");
734 continue;
735 }
736
737 addf (str, _("\t\tAuthority Key Identifier (%s):\n"),
738 critical ? _("critical") : _("not critical"));
739
740 print_aki (str, cert);
741
742 aki_idx++;
743 }
744 else if (strcmp (oid, "2.5.29.15") == 0)
745 {
746 if (keyusage_idx)
747 {
748 addf (str, "error: more than one key usage extension\n");
749 continue;
750 }
751
752 addf (str, _("\t\tKey Usage (%s):\n"),
753 critical ? _("critical") : _("not critical"));
754
755 print_key_usage (str, cert);
756
757 keyusage_idx++;
758 }
759 else if (strcmp (oid, "2.5.29.37") == 0)
760 {
761 if (keypurpose_idx)
762 {
763 addf (str, "error: more than one key purpose extension\n");
764 continue;
765 }
766
767 addf (str, _("\t\tKey Purpose (%s):\n"),
768 critical ? _("critical") : _("not critical"));
769
770 print_key_purpose (str, cert);
771
772 keypurpose_idx++;
773 }
774 else if (strcmp (oid, "2.5.29.17") == 0)
775 {
776 if (san_idx)
777 {
778 addf (str, "error: more than one SKI extension\n");
779 continue;
780 }
781
782 addf (str, _("\t\tSubject Alternative Name (%s):\n"),
783 critical ? _("critical") : _("not critical"));
784
785 print_san (str, cert);
786
787 san_idx++;
788 }
789 else if (strcmp (oid, "2.5.29.31") == 0)
790 {
791 if (crldist_idx)
792 {
793 addf (str, "error: more than one CRL distribution point\n");
794 continue;
795 }
796
797 addf (str, _("\t\tCRL Distribution points (%s):\n"),
798 critical ? _("critical") : _("not critical"));
799
800 print_crldist (str, cert);
801
802 crldist_idx++;
803 }
804 else if (strcmp (oid, "1.3.6.1.5.5.7.1.14") == 0)
805 {
806 if (proxy_idx)
807 {
808 addf (str, "error: more than one proxy extension\n");
809 continue;
810 }
811
812 addf (str, _("\t\tProxy Certificate Information (%s):\n"),
813 critical ? _("critical") : _("not critical"));
814
815 print_proxy (str, cert);
816
817 proxy_idx++;
818 }
819 else
820 {
821 char *buffer;
822 size_t extlen = 0;
823
824 addf (str, _("\t\tUnknown extension %s (%s):\n"), oid,
825 critical ? _("critical") : _("not critical"));
826
827 err = gnutls_x509_crt_get_extension_data (cert, i,
828 NULL, &extlen);
829 if (err < 0)
830 {
831 addf (str, "error: get_extension_data: %s\n",
832 gnutls_strerror (err));
833 continue;
834 }
835
836 buffer = gnutls_malloc (extlen);
837 if (!buffer)
838 {
839 addf (str, "error: malloc: %s\n", gnutls_strerror (err));
840 continue;
841 }
842
843 err = gnutls_x509_crt_get_extension_data (cert, i,
844 buffer, &extlen);
845 if (err < 0)
846 {
847 gnutls_free (buffer);
848 addf (str, "error: get_extension_data2: %s\n",
849 gnutls_strerror (err));
850 continue;
851 }
852
853 addf (str, _("\t\t\tASCII: "));
854 asciiprint (str, buffer, extlen);
855 addf (str, "\n");
856
857 addf (str, _("\t\t\tHexdump: "));
858 hexprint (str, buffer, extlen);
859 adds (str, "\n");
860
861 gnutls_free (buffer);
862 }
863 }
864 }
865
866 /* Signature. */
867 if (!notsigned)
868 {
869 int err;
870 size_t size = 0;
871 char *buffer = NULL;
872
873 err = gnutls_x509_crt_get_signature_algorithm (cert);
874 if (err < 0)
875 addf (str, "error: get_signature_algorithm: %s\n",
876 gnutls_strerror (err));
877 else
878 {
879 const char *name = gnutls_sign_algorithm_get_name (err);
880 if (name == NULL)
881 name = "Unknown";
882 addf (str, _("\tSignature Algorithm: %s\n"), name);
883 }
884 if (err == GNUTLS_SIGN_RSA_MD5 || err == GNUTLS_SIGN_RSA_MD2)
885 {
886 addf (str,
887 _
888 ("warning: signed using a broken signature algorithm that can be forged.\n"));
889 }
890
891 err = gnutls_x509_crt_get_signature (cert, buffer, &size);
892 if (err != GNUTLS_E_SHORT_MEMORY_BUFFER)
893 {
894 addf (str, "error: get_signature: %s\n", gnutls_strerror (err));
895 return;
896 }
897
898 buffer = gnutls_malloc (size);
899 if (!buffer)
900 {
901 addf (str, "error: malloc: %s\n", gnutls_strerror (err));
902 return;
903 }
904
905 err = gnutls_x509_crt_get_signature (cert, buffer, &size);
906 if (err < 0)
907 {
908 gnutls_free (buffer);
909 addf (str, "error: get_signature2: %s\n", gnutls_strerror (err));
910 return;
911 }
912
913 addf (str, _("\tSignature:\n"));
914 hexdump (str, buffer, size, "\t\t");
915
916 gnutls_free (buffer);
917 }
918}
919
920static void
921print_fingerprint (gnutls_string * str, gnutls_x509_crt_t cert,
922 gnutls_digest_algorithm_t algo)
923{
924 int err;
925 char buffer[MAX_HASH_SIZE];
926 size_t size = sizeof (buffer);
927
928 err = gnutls_x509_crt_get_fingerprint (cert, algo, buffer, &size);
929 if (err < 0)
930 {
931 addf (str, "error: get_fingerprint: %s\n", gnutls_strerror (err));
932 return;
933 }
934
935 if (algo == GNUTLS_DIG_MD5)
936 addf (str, _("\tMD5 fingerprint:\n\t\t"));
937 else
938 addf (str, _("\tSHA-1 fingerprint:\n\t\t"));
939 hexprint (str, buffer, size);
940 adds (str, "\n");
941}
942
943static void
944print_keyid (gnutls_string * str, gnutls_x509_crt_t cert)
945{
946 int err;
947 size_t size = 0;
948 char *buffer = NULL;
949
950 err = gnutls_x509_crt_get_key_id (cert, 0, buffer, &size);
951 if (err != GNUTLS_E_SHORT_MEMORY_BUFFER)
952 {
953 addf (str, "error: get_key_id: %s\n", gnutls_strerror (err));
954 return;
955 }
956
957 buffer = gnutls_malloc (size);
958 if (!buffer)
959 {
960 addf (str, "error: malloc: %s\n", gnutls_strerror (err));
961 return;
962 }
963
964 err = gnutls_x509_crt_get_key_id (cert, 0, buffer, &size);
965 if (err < 0)
966 {
967 gnutls_free (buffer);
968 addf (str, "error: get_key_id2: %s\n", gnutls_strerror (err));
969 return;
970 }
971
972 addf (str, _("\tPublic Key Id:\n\t\t"));
973 hexprint (str, buffer, size);
974 adds (str, "\n");
975
976 gnutls_free (buffer);
977}
978
979static void
980print_other (gnutls_string * str, gnutls_x509_crt_t cert, int notsigned)
981{
982 if (!notsigned)
983 {
984 print_fingerprint (str, cert, GNUTLS_DIG_MD5);
985 print_fingerprint (str, cert, GNUTLS_DIG_SHA1);
986 }
987 print_keyid (str, cert);
988}
989
990static void
991print_oneline (gnutls_string * str, gnutls_x509_crt_t cert)
992{
993
994 /* Subject. */
995 {
996 char dn[1024];
997 size_t dn_size = sizeof (dn);
998 int err;
999
1000 err = gnutls_x509_crt_get_dn (cert, dn, &dn_size);
1001 if (err < 0)
1002 addf (str, "unknown subject (%s), ", gnutls_strerror (err));
1003 else
1004 addf (str, "subject `%s', ", dn);
1005 }
1006
1007 /* Issuer. */
1008 {
1009 char dn[1024];
1010 size_t dn_size = sizeof (dn);
1011 int err;
1012
1013 err = gnutls_x509_crt_get_issuer_dn (cert, dn, &dn_size);
1014 if (err < 0)
1015 addf (str, "unknown issuer (%s), ", gnutls_strerror (err));
1016 else
1017 addf (str, "issuer `%s', ", dn);
1018 }
1019
1020 {
1021 int bits;
1022 const char *name = gnutls_pk_algorithm_get_name
1023 (gnutls_x509_crt_get_pk_algorithm (cert, &bits));
1024 if (name == NULL)
1025 name = "Unknown";
1026 addf (str, "%s key %d bits, ", name, bits);
1027 }
1028
1029 /* Validity. */
1030 {
1031 time_t tim;
1032
1033 tim = gnutls_x509_crt_get_activation_time (cert);
1034 {
1035 char s[42];
1036 size_t max = sizeof (s);
1037 struct tm t;
1038
1039 if (gmtime_r (&tim, &t) == NULL)
1040 addf (str, "unknown activation (%d), ", t);
1041 else if (strftime (s, max, "%Y-%m-%d %H:%M:%S UTC", &t) == 0)
1042 addf (str, "failed activation (%d), ", t);
1043 else
1044 addf (str, "activated `%s', ", s);
1045 }
1046
1047 tim = gnutls_x509_crt_get_expiration_time (cert);
1048 {
1049 char s[42];
1050 size_t max = sizeof (s);
1051 struct tm t;
1052
1053 if (gmtime_r (&tim, &t) == NULL)
1054 addf (str, "unknown expiry (%d), ", t);
1055 else if (strftime (s, max, "%Y-%m-%d %H:%M:%S UTC", &t) == 0)
1056 addf (str, "failed expiry (%d), ", t);
1057 else
1058 addf (str, "expires `%s', ", s);
1059 }
1060 }
1061
1062 {
1063 int pathlen;
1064 char *policyLanguage;
1065 int err;
1066
1067 err = gnutls_x509_crt_get_proxy (cert, NULL,
1068 &pathlen, &policyLanguage, NULL, NULL);
1069 if (err == 0)
1070 {
1071 addf (str, "proxy certificate (policy=");
1072 if (strcmp (policyLanguage, "1.3.6.1.5.5.7.21.1") == 0)
1073 addf (str, "id-ppl-inheritALL");
1074 else if (strcmp (policyLanguage, "1.3.6.1.5.5.7.21.2") == 0)
1075 addf (str, "id-ppl-independent");
1076 else
1077 addf (str, "%s", policyLanguage);
1078 if (pathlen >= 0)
1079 addf (str, ", pathlen=%d), ", pathlen);
1080 else
1081 addf (str, "), ");
1082 gnutls_free (policyLanguage);
1083 }
1084 }
1085
1086 {
1087 char buffer[20];
1088 size_t size = sizeof (buffer);
1089 int err;
1090
1091 err = gnutls_x509_crt_get_fingerprint (cert, GNUTLS_DIG_SHA1,
1092 buffer, &size);
1093 if (err < 0)
1094 {
1095 addf (str, "unknown fingerprint (%s)", gnutls_strerror (err));
1096 }
1097 else
1098 {
1099 addf (str, "SHA-1 fingerprint `");
1100 hexprint (str, buffer, size);
1101 adds (str, "'");
1102 }
1103 }
1104
1105}
1106
1107/**
1108 * gnutls_x509_crt_print - Pretty print X.509 certificates
1109 * @cert: The structure to be printed
1110 * @format: Indicate the format to use
1111 * @out: Newly allocated datum with zero terminated string.
1112 *
1113 * This function will pretty print a X.509 certificate, suitable for
1114 * display to a human.
1115 *
1116 * If the format is %GNUTLS_X509_CRT_FULL then all fields of the
1117 * certificate will be output, on multiple lines. The
1118 * %GNUTLS_X509_CRT_ONELINE format will generate one line with some
1119 * selected fields, which is useful for logging purposes.
1120 *
1121 * The output @out needs to be deallocate using gnutls_free().
1122 *
1123 * Returns 0 on success.
1124 **/
1125int
1126gnutls_x509_crt_print (gnutls_x509_crt_t cert,
1127 gnutls_certificate_print_formats_t format,
1128 gnutls_datum_t * out)
1129{
1130 gnutls_string str;
1131
1132 if (format == GNUTLS_X509_CRT_FULL
1133 || format == GNUTLS_X509_CRT_UNSIGNED_FULL)
1134 {
1135 _gnutls_string_init (&str, gnutls_malloc, gnutls_realloc, gnutls_free);
1136
1137 _gnutls_string_append_str (&str, _("X.509 Certificate Information:\n"));
1138
1139 print_cert (&str, cert, format == GNUTLS_X509_CRT_UNSIGNED_FULL);
1140
1141 _gnutls_string_append_str (&str, _("Other Information:\n"));
1142
1143 print_other (&str, cert, format == GNUTLS_X509_CRT_UNSIGNED_FULL);
1144
1145 _gnutls_string_append_data (&str, "\0", 1);
1146 out->data = str.data;
1147 out->size = strlen (str.data);
1148 }
1149 else if (format == GNUTLS_X509_CRT_ONELINE)
1150 {
1151 _gnutls_string_init (&str, gnutls_malloc, gnutls_realloc, gnutls_free);
1152
1153 print_oneline (&str, cert);
1154
1155 _gnutls_string_append_data (&str, "\0", 1);
1156 out->data = str.data;
1157 out->size = strlen (str.data);
1158 }
1159 else
1160 {
1161 gnutls_assert ();
1162 return GNUTLS_E_INVALID_REQUEST;
1163 }
1164
1165 return 0;
1166}
1167
1168static void
1169print_crl (gnutls_string * str, gnutls_x509_crl_t crl, int notsigned)
1170{
1171 /* Version. */
1172 {
1173 int version = gnutls_x509_crl_get_version (crl);
1174 if (version == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)
1175 addf (str, _("\tVersion: 1 (default)\n"));
1176 else if (version < 0)
1177 addf (str, "error: get_version: %s\n", gnutls_strerror (version));
1178 else
1179 addf (str, _("\tVersion: %d\n"), version);
1180 }
1181
1182 /* Issuer. */
1183 if (!notsigned)
1184 {
1185 char dn[1024];
1186 size_t dn_size = sizeof (dn);
1187 int err;
1188
1189 err = gnutls_x509_crl_get_issuer_dn (crl, dn, &dn_size);
1190 if (err < 0)
1191 addf (str, "error: get_issuer_dn: %s\n", gnutls_strerror (err));
1192 else
1193 addf (str, _("\tIssuer: %s\n"), dn);
1194 }
1195
1196 /* Validity. */
1197 {
1198 time_t tim;
1199
1200 addf (str, _("\tUpdate dates:\n"));
1201
1202 tim = gnutls_x509_crl_get_this_update (crl);
1203 {
1204 char s[42];
1205 size_t max = sizeof (s);
1206 struct tm t;
1207
1208 if (gmtime_r (&tim, &t) == NULL)
1209 addf (str, "error: gmtime_r (%d)\n", t);
1210 else if (strftime (s, max, "%a %b %e %H:%M:%S UTC %Y", &t) == 0)
1211 addf (str, "error: strftime (%d)\n", t);
1212 else
1213 addf (str, _("\t\tIssued: %s\n"), s);
1214 }
1215
1216 tim = gnutls_x509_crl_get_next_update (crl);
1217 {
1218 char s[42];
1219 size_t max = sizeof (s);
1220 struct tm t;
1221
1222 if (tim == -1)
1223 addf (str, "\t\tNo next update time.\n");
1224 else if (gmtime_r (&tim, &t) == NULL)
1225 addf (str, "error: gmtime_r (%d)\n", t);
1226 else if (strftime (s, max, "%a %b %e %H:%M:%S UTC %Y", &t) == 0)
1227 addf (str, "error: strftime (%d)\n", t);
1228 else
1229 addf (str, _("\t\tNext at: %s\n"), s);
1230 }
1231 }
1232
1233 /* Revoked certificates. */
1234 {
1235 int num = gnutls_x509_crl_get_crt_count (crl);
1236 int j;
1237
1238 if (num)
1239 addf (str, _("\tRevoked certificates (%d):\n"), num);
1240 else
1241 addf (str, _("\tNo revoked certificates.\n"));
1242
1243 for (j = 0; j < num; j++)
1244 {
1245 char serial[128];
1246 size_t serial_size = sizeof (serial);
1247 int err;
1248 time_t tim;
1249
1250 err = gnutls_x509_crl_get_crt_serial (crl, j, serial,
1251 &serial_size, &tim);
1252 if (err < 0)
1253 addf (str, "error: get_crt_serial: %s\n", gnutls_strerror (err));
1254 else
1255 {
1256 char s[42];
1257 size_t max = sizeof (s);
1258 struct tm t;
1259
1260 addf (str, _("\t\tSerial Number (hex): "));
1261 hexprint (str, serial, serial_size);
1262 adds (str, "\n");
1263
1264 if (gmtime_r (&tim, &t) == NULL)
1265 addf (str, "error: gmtime_r (%d)\n", t);
1266 else if (strftime (s, max, "%a %b %e %H:%M:%S UTC %Y", &t) == 0)
1267 addf (str, "error: strftime (%d)\n", t);
1268 else
1269 addf (str, _("\t\tRevoked at: %s\n"), s);
1270 }
1271 }
1272 }
1273
1274 /* Signature. */
1275 if (!notsigned)
1276 {
1277 int err;
1278 size_t size = 0;
1279 char *buffer = NULL;
1280
1281 err = gnutls_x509_crl_get_signature_algorithm (crl);
1282 if (err < 0)
1283 addf (str, "error: get_signature_algorithm: %s\n",
1284 gnutls_strerror (err));
1285 else
1286 {
1287 const char *name = gnutls_sign_algorithm_get_name (err);
1288 if (name == NULL)
1289 name = "Unknown";
1290 addf (str, _("\tSignature Algorithm: %s\n"), name);
1291 }
1292 if (err == GNUTLS_SIGN_RSA_MD5 || err == GNUTLS_SIGN_RSA_MD2)
1293 {
1294 addf (str,
1295 _
1296 ("warning: signed using a broken signature algorithm that can be forged.\n"));
1297 }
1298
1299 err = gnutls_x509_crl_get_signature (crl, buffer, &size);
1300 if (err != GNUTLS_E_SHORT_MEMORY_BUFFER)
1301 {
1302 addf (str, "error: get_signature: %s\n", gnutls_strerror (err));
1303 return;
1304 }
1305
1306 buffer = gnutls_malloc (size);
1307 if (!buffer)
1308 {
1309 addf (str, "error: malloc: %s\n", gnutls_strerror (err));
1310 return;
1311 }
1312
1313 err = gnutls_x509_crl_get_signature (crl, buffer, &size);
1314 if (err < 0)
1315 {
1316 gnutls_free (buffer);
1317 addf (str, "error: get_signature2: %s\n", gnutls_strerror (err));
1318 return;
1319 }
1320
1321 addf (str, _("\tSignature:\n"));
1322 hexdump (str, buffer, size, "\t\t");
1323
1324 gnutls_free (buffer);
1325 }
1326}
1327
1328/**
1329 * gnutls_x509_crl_print - Pretty print X.509 certificate revocation list
1330 * @crl: The structure to be printed
1331 * @format: Indicate the format to use
1332 * @out: Newly allocated datum with zero terminated string.
1333 *
1334 * This function will pretty print a X.509 certificate revocation
1335 * list, suitable for display to a human.
1336 *
1337 * The output @out needs to be deallocate using gnutls_free().
1338 *
1339 * Returns 0 on success.
1340 **/
1341int
1342gnutls_x509_crl_print (gnutls_x509_crl_t crl,
1343 gnutls_certificate_print_formats_t format,
1344 gnutls_datum_t * out)
1345{
1346 gnutls_string str;
1347
1348 _gnutls_string_init (&str, gnutls_malloc, gnutls_realloc, gnutls_free);
1349
1350 _gnutls_string_append_str
1351 (&str, _("X.509 Certificate Revocation List Information:\n"));
1352
1353 print_crl (&str, crl, format == GNUTLS_X509_CRT_UNSIGNED_FULL);
1354
1355 _gnutls_string_append_data (&str, "\0", 1);
1356 out->data = str.data;
1357 out->size = strlen (str.data);
1358
1359 return 0;
1360}
diff --git a/src/daemon/https/x509/pkcs12.c b/src/daemon/https/x509/pkcs12.c
new file mode 100644
index 00000000..40f7a243
--- /dev/null
+++ b/src/daemon/https/x509/pkcs12.c
@@ -0,0 +1,1325 @@
1/*
2 * Copyright (C) 2003, 2004, 2005 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/* Functions that relate on PKCS12 packet parsing.
26 */
27
28#include <gnutls_int.h>
29#include <libtasn1.h>
30
31#ifdef ENABLE_PKI
32
33#include <gnutls_datum.h>
34#include <gnutls_global.h>
35#include <gnutls_errors.h>
36#include <gnutls_num.h>
37#include <common.h>
38#include <x509_b64.h>
39#include <pkcs12.h>
40#include <dn.h>
41#include <mpi.h>
42#include <gc.h>
43
44
45/* Decodes the PKCS #12 auth_safe, and returns the allocated raw data,
46 * which holds them. Returns an ASN1_TYPE of authenticatedSafe.
47 */
48static int
49_decode_pkcs12_auth_safe (ASN1_TYPE pkcs12, ASN1_TYPE * authen_safe,
50 gnutls_datum_t * raw)
51{
52 char oid[128];
53 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
54 gnutls_datum_t auth_safe = { NULL, 0 };
55 int tmp_size, len, result;
56
57 len = sizeof (oid) - 1;
58 result = asn1_read_value (pkcs12, "authSafe.contentType", oid, &len);
59 if (result != ASN1_SUCCESS)
60 {
61 gnutls_assert ();
62 return _gnutls_asn2err (result);
63 }
64
65 if (strcmp (oid, DATA_OID) != 0)
66 {
67 gnutls_assert ();
68 _gnutls_x509_log ("Unknown PKCS12 Content OID '%s'\n", oid);
69 return GNUTLS_E_UNKNOWN_PKCS_CONTENT_TYPE;
70 }
71
72 /* Step 1. Read the content data
73 */
74
75 tmp_size = 0;
76 result =
77 _gnutls_x509_read_value (pkcs12, "authSafe.content", &auth_safe, 1);
78 if (result < 0)
79 {
80 gnutls_assert ();
81 goto cleanup;
82 }
83
84 /* Step 2. Extract the authenticatedSafe.
85 */
86
87 if ((result = asn1_create_element
88 (_gnutls_get_pkix (), "PKIX1.pkcs-12-AuthenticatedSafe",
89 &c2)) != ASN1_SUCCESS)
90 {
91 gnutls_assert ();
92 result = _gnutls_asn2err (result);
93 goto cleanup;
94 }
95
96 result = asn1_der_decoding (&c2, auth_safe.data, auth_safe.size, NULL);
97 if (result != ASN1_SUCCESS)
98 {
99 gnutls_assert ();
100 result = _gnutls_asn2err (result);
101 goto cleanup;
102 }
103
104 if (raw == NULL)
105 {
106 _gnutls_free_datum (&auth_safe);
107 }
108 else
109 {
110 raw->data = auth_safe.data;
111 raw->size = auth_safe.size;
112 }
113
114 if (authen_safe)
115 *authen_safe = c2;
116 else
117 asn1_delete_structure (&c2);
118
119 return 0;
120
121cleanup:
122 if (c2)
123 asn1_delete_structure (&c2);
124 _gnutls_free_datum (&auth_safe);
125 return result;
126}
127
128/**
129 * gnutls_pkcs12_init - This function initializes a gnutls_pkcs12_t structure
130 * @pkcs12: The structure to be initialized
131 *
132 * This function will initialize a PKCS12 structure. PKCS12 structures
133 * usually contain lists of X.509 Certificates and X.509 Certificate
134 * revocation lists.
135 *
136 * Returns 0 on success.
137 *
138 **/
139int
140gnutls_pkcs12_init (gnutls_pkcs12_t * pkcs12)
141{
142 *pkcs12 = gnutls_calloc (1, sizeof (gnutls_pkcs12_int));
143
144 if (*pkcs12)
145 {
146 int result = asn1_create_element (_gnutls_get_pkix (),
147 "PKIX1.pkcs-12-PFX",
148 &(*pkcs12)->pkcs12);
149 if (result != ASN1_SUCCESS)
150 {
151 gnutls_assert ();
152 gnutls_free (*pkcs12);
153 return _gnutls_asn2err (result);
154 }
155 return 0; /* success */
156 }
157 return GNUTLS_E_MEMORY_ERROR;
158}
159
160/**
161 * gnutls_pkcs12_deinit - This function deinitializes memory used by a gnutls_pkcs12_t structure
162 * @pkcs12: The structure to be initialized
163 *
164 * This function will deinitialize a PKCS12 structure.
165 *
166 **/
167void
168gnutls_pkcs12_deinit (gnutls_pkcs12_t pkcs12)
169{
170 if (!pkcs12)
171 return;
172
173 if (pkcs12->pkcs12)
174 asn1_delete_structure (&pkcs12->pkcs12);
175
176 gnutls_free (pkcs12);
177}
178
179/**
180 * gnutls_pkcs12_import - This function will import a DER or PEM encoded PKCS12 structure
181 * @pkcs12: The structure to store the parsed PKCS12.
182 * @data: The DER or PEM encoded PKCS12.
183 * @format: One of DER or PEM
184 * @flags: an ORed sequence of gnutls_privkey_pkcs8_flags
185 *
186 * This function will convert the given DER or PEM encoded PKCS12
187 * to the native gnutls_pkcs12_t format. The output will be stored in 'pkcs12'.
188 *
189 * If the PKCS12 is PEM encoded it should have a header of "PKCS12".
190 *
191 * Returns 0 on success.
192 *
193 **/
194int
195gnutls_pkcs12_import (gnutls_pkcs12_t pkcs12,
196 const gnutls_datum_t * data,
197 gnutls_x509_crt_fmt_t format, unsigned int flags)
198{
199 int result = 0, need_free = 0;
200 gnutls_datum_t _data;
201
202 _data.data = data->data;
203 _data.size = data->size;
204
205 if (pkcs12 == NULL)
206 {
207 gnutls_assert ();
208 return GNUTLS_E_INVALID_REQUEST;
209 }
210
211 /* If the PKCS12 is in PEM format then decode it
212 */
213 if (format == GNUTLS_X509_FMT_PEM)
214 {
215 opaque *out;
216
217 result = _gnutls_fbase64_decode (PEM_PKCS12, data->data, data->size,
218 &out);
219
220 if (result <= 0)
221 {
222 if (result == 0)
223 result = GNUTLS_E_INTERNAL_ERROR;
224 gnutls_assert ();
225 return result;
226 }
227
228 _data.data = out;
229 _data.size = result;
230
231 need_free = 1;
232 }
233
234 result = asn1_der_decoding (&pkcs12->pkcs12, _data.data, _data.size, NULL);
235 if (result != ASN1_SUCCESS)
236 {
237 result = _gnutls_asn2err (result);
238 gnutls_assert ();
239 goto cleanup;
240 }
241
242 if (need_free)
243 _gnutls_free_datum (&_data);
244
245 return 0;
246
247cleanup:
248 if (need_free)
249 _gnutls_free_datum (&_data);
250 return result;
251}
252
253
254/**
255 * gnutls_pkcs12_export - This function will export the pkcs12 structure
256 * @pkcs12: Holds the pkcs12 structure
257 * @format: the format of output params. One of PEM or DER.
258 * @output_data: will contain a structure PEM or DER encoded
259 * @output_data_size: holds the size of output_data (and will be
260 * replaced by the actual size of parameters)
261 *
262 * This function will export the pkcs12 structure to DER or PEM format.
263 *
264 * If the buffer provided is not long enough to hold the output, then
265 * *output_data_size will be updated and GNUTLS_E_SHORT_MEMORY_BUFFER
266 * will be returned.
267 *
268 * If the structure is PEM encoded, it will have a header
269 * of "BEGIN PKCS12".
270 *
271 * Return value: In case of failure a negative value will be
272 * returned, and 0 on success.
273 *
274 **/
275int
276gnutls_pkcs12_export (gnutls_pkcs12_t pkcs12,
277 gnutls_x509_crt_fmt_t format, void *output_data,
278 size_t * output_data_size)
279{
280 if (pkcs12 == NULL)
281 {
282 gnutls_assert ();
283 return GNUTLS_E_INVALID_REQUEST;
284 }
285
286 return _gnutls_x509_export_int (pkcs12->pkcs12, format, PEM_PKCS12,
287 output_data, output_data_size);
288}
289
290static int
291oid2bag (const char *oid)
292{
293 if (strcmp (oid, BAG_PKCS8_KEY) == 0)
294 return GNUTLS_BAG_PKCS8_KEY;
295 if (strcmp (oid, BAG_PKCS8_ENCRYPTED_KEY) == 0)
296 return GNUTLS_BAG_PKCS8_ENCRYPTED_KEY;
297 if (strcmp (oid, BAG_CERTIFICATE) == 0)
298 return GNUTLS_BAG_CERTIFICATE;
299 if (strcmp (oid, BAG_CRL) == 0)
300 return GNUTLS_BAG_CRL;
301
302 return GNUTLS_BAG_UNKNOWN;
303}
304
305static const char *
306bag_to_oid (int bag)
307{
308 switch (bag)
309 {
310 case GNUTLS_BAG_PKCS8_KEY:
311 return BAG_PKCS8_KEY;
312 case GNUTLS_BAG_PKCS8_ENCRYPTED_KEY:
313 return BAG_PKCS8_ENCRYPTED_KEY;
314 case GNUTLS_BAG_CERTIFICATE:
315 return BAG_CERTIFICATE;
316 case GNUTLS_BAG_CRL:
317 return BAG_CRL;
318 }
319 return NULL;
320}
321
322static inline char *
323ucs2_to_ascii (char *data, int size)
324{
325 int i, j;
326
327 for (i = 0; i < size / 2; i++)
328 {
329 j = 2 * i + 1;
330 if (isascii (data[j]))
331 data[i] = data[i * 2 + 1];
332 else
333 data[i] = '?';
334 }
335 data[i] = 0;
336
337 return data;
338}
339
340/* Decodes the SafeContents, and puts the output in
341 * the given bag.
342 */
343int
344_pkcs12_decode_safe_contents (const gnutls_datum_t * content,
345 gnutls_pkcs12_bag_t bag)
346{
347 char oid[128], root[MAX_NAME_SIZE];
348 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
349 int len, result;
350 int bag_type;
351 gnutls_datum_t attr_val;
352 int count = 0, i, attributes, j;
353 size_t size;
354
355 /* Step 1. Extract the SEQUENCE.
356 */
357
358 if ((result = asn1_create_element
359 (_gnutls_get_pkix (), "PKIX1.pkcs-12-SafeContents",
360 &c2)) != ASN1_SUCCESS)
361 {
362 gnutls_assert ();
363 result = _gnutls_asn2err (result);
364 goto cleanup;
365 }
366
367 result = asn1_der_decoding (&c2, content->data, content->size, NULL);
368 if (result != ASN1_SUCCESS)
369 {
370 gnutls_assert ();
371 result = _gnutls_asn2err (result);
372 goto cleanup;
373 }
374
375 /* Count the number of bags
376 */
377 result = asn1_number_of_elements (c2, "", &count);
378 if (result != ASN1_SUCCESS)
379 {
380 gnutls_assert ();
381 result = _gnutls_asn2err (result);
382 goto cleanup;
383 }
384
385 bag->bag_elements = MIN (MAX_BAG_ELEMENTS, count);
386
387 for (i = 0; i < bag->bag_elements; i++)
388 {
389
390 snprintf (root, sizeof (root), "?%u.bagId", i + 1);
391
392 len = sizeof (oid);
393 result = asn1_read_value (c2, root, oid, &len);
394 if (result != ASN1_SUCCESS)
395 {
396 gnutls_assert ();
397 result = _gnutls_asn2err (result);
398 goto cleanup;
399 }
400
401 /* Read the Bag type
402 */
403 bag_type = oid2bag (oid);
404
405 if (bag_type < 0)
406 {
407 gnutls_assert ();
408 goto cleanup;
409 }
410
411 /* Read the Bag Value
412 */
413
414 snprintf (root, sizeof (root), "?%u.bagValue", i + 1);
415
416 result = _gnutls_x509_read_value (c2, root, &bag->element[i].data, 0);
417 if (result < 0)
418 {
419 gnutls_assert ();
420 goto cleanup;
421 }
422
423 if (bag_type == GNUTLS_BAG_CERTIFICATE || bag_type == GNUTLS_BAG_CRL)
424 {
425 gnutls_datum_t tmp = bag->element[i].data;
426
427 result =
428 _pkcs12_decode_crt_bag (bag_type, &tmp, &bag->element[i].data);
429 if (result < 0)
430 {
431 gnutls_assert ();
432 goto cleanup;
433 }
434
435 _gnutls_free_datum (&tmp);
436 }
437
438 /* read the bag attributes
439 */
440 snprintf (root, sizeof (root), "?%u.bagAttributes", i + 1);
441
442 result = asn1_number_of_elements (c2, root, &attributes);
443 if (result != ASN1_SUCCESS && result != ASN1_ELEMENT_NOT_FOUND)
444 {
445 gnutls_assert ();
446 result = _gnutls_asn2err (result);
447 goto cleanup;
448 }
449
450 if (attributes < 0)
451 attributes = 1;
452
453 if (result != ASN1_ELEMENT_NOT_FOUND)
454 for (j = 0; j < attributes; j++)
455 {
456
457 snprintf (root, sizeof (root), "?%u.bagAttributes.?%u", i + 1,
458 j + 1);
459
460 result =
461 _gnutls_x509_decode_and_read_attribute (c2, root, oid,
462 sizeof (oid), &attr_val,
463 1, 0);
464
465 if (result < 0)
466 {
467 gnutls_assert ();
468 continue; /* continue in case we find some known attributes */
469 }
470
471 if (strcmp (oid, KEY_ID_OID) == 0)
472 {
473 size = attr_val.size;
474
475 result =
476 _gnutls_x509_decode_octet_string (NULL, attr_val.data, size,
477 attr_val.data, &size);
478 attr_val.size = size;
479 if (result < 0)
480 {
481 _gnutls_free_datum (&attr_val);
482 gnutls_assert ();
483 _gnutls_x509_log
484 ("Error decoding PKCS12 Bag Attribute OID '%s'\n", oid);
485 continue;
486 }
487 bag->element[i].local_key_id = attr_val;
488 }
489 else if (strcmp (oid, FRIENDLY_NAME_OID) == 0)
490 {
491 size = attr_val.size;
492 result =
493 _gnutls_x509_decode_octet_string ("BMPString",
494 attr_val.data, size,
495 attr_val.data, &size);
496 attr_val.size = size;
497 if (result < 0)
498 {
499 _gnutls_free_datum (&attr_val);
500 gnutls_assert ();
501 _gnutls_x509_log
502 ("Error decoding PKCS12 Bag Attribute OID '%s'\n", oid);
503 continue;
504 }
505 bag->element[i].friendly_name =
506 ucs2_to_ascii (attr_val.data, attr_val.size);
507 }
508 else
509 {
510 _gnutls_free_datum (&attr_val);
511 _gnutls_x509_log
512 ("Unknown PKCS12 Bag Attribute OID '%s'\n", oid);
513 }
514 }
515
516
517 bag->element[i].type = bag_type;
518
519 }
520
521 asn1_delete_structure (&c2);
522
523
524 return 0;
525
526cleanup:
527 if (c2)
528 asn1_delete_structure (&c2);
529 return result;
530
531}
532
533
534static int
535_parse_safe_contents (ASN1_TYPE sc, const char *sc_name,
536 gnutls_pkcs12_bag_t bag)
537{
538 gnutls_datum_t content = { NULL, 0 };
539 int result;
540
541 /* Step 1. Extract the content.
542 */
543
544 result = _gnutls_x509_read_value (sc, sc_name, &content, 1);
545 if (result < 0)
546 {
547 gnutls_assert ();
548 goto cleanup;
549 }
550
551 result = _pkcs12_decode_safe_contents (&content, bag);
552 if (result < 0)
553 {
554 gnutls_assert ();
555 goto cleanup;
556 }
557
558 _gnutls_free_datum (&content);
559
560 return 0;
561
562cleanup:
563 _gnutls_free_datum (&content);
564 return result;
565}
566
567
568/**
569 * gnutls_pkcs12_get_bag - This function returns a Bag from a PKCS12 structure
570 * @pkcs12: should contain a gnutls_pkcs12_t structure
571 * @indx: contains the index of the bag to extract
572 * @bag: An initialized bag, where the contents of the bag will be copied
573 *
574 * This function will return a Bag from the PKCS12 structure.
575 * Returns 0 on success.
576 *
577 * After the last Bag has been read GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
578 * will be returned.
579 *
580 **/
581int
582gnutls_pkcs12_get_bag (gnutls_pkcs12_t pkcs12,
583 int indx, gnutls_pkcs12_bag_t bag)
584{
585 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
586 int result, len;
587 char root2[MAX_NAME_SIZE];
588 char oid[128];
589
590 if (pkcs12 == NULL)
591 {
592 gnutls_assert ();
593 return GNUTLS_E_INVALID_REQUEST;
594 }
595
596 /* Step 1. decode the data.
597 */
598 result = _decode_pkcs12_auth_safe (pkcs12->pkcs12, &c2, NULL);
599 if (result < 0)
600 {
601 gnutls_assert ();
602 return result;
603 }
604
605 /* Step 2. Parse the AuthenticatedSafe
606 */
607
608 snprintf (root2, sizeof (root2), "?%u.contentType", indx + 1);
609
610 len = sizeof (oid) - 1;
611 result = asn1_read_value (c2, root2, oid, &len);
612
613 if (result == ASN1_ELEMENT_NOT_FOUND)
614 {
615 result = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
616 goto cleanup;
617 }
618
619 if (result != ASN1_SUCCESS)
620 {
621 gnutls_assert ();
622 result = _gnutls_asn2err (result);
623 goto cleanup;
624 }
625
626 /* Not encrypted Bag
627 */
628
629 snprintf (root2, sizeof (root2), "?%u.content", indx + 1);
630
631 if (strcmp (oid, DATA_OID) == 0)
632 {
633 result = _parse_safe_contents (c2, root2, bag);
634 goto cleanup;
635 }
636
637 /* ENC_DATA_OID needs decryption */
638
639 bag->element[0].type = GNUTLS_BAG_ENCRYPTED;
640 bag->bag_elements = 1;
641
642 result = _gnutls_x509_read_value (c2, root2, &bag->element[0].data, 0);
643 if (result < 0)
644 {
645 gnutls_assert ();
646 goto cleanup;
647 }
648
649 result = 0;
650
651cleanup:
652 if (c2)
653 asn1_delete_structure (&c2);
654 return result;
655}
656
657/* Creates an empty PFX structure for the PKCS12 structure.
658 */
659static int
660create_empty_pfx (ASN1_TYPE pkcs12)
661{
662 uint8_t three = 3;
663 int result;
664 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
665
666 /* Use version 3
667 */
668 result = asn1_write_value (pkcs12, "version", &three, 1);
669 if (result != ASN1_SUCCESS)
670 {
671 gnutls_assert ();
672 result = _gnutls_asn2err (result);
673 goto cleanup;
674 }
675
676 /* Write the content type of the data
677 */
678 result = asn1_write_value (pkcs12, "authSafe.contentType", DATA_OID, 1);
679 if (result != ASN1_SUCCESS)
680 {
681 gnutls_assert ();
682 result = _gnutls_asn2err (result);
683 goto cleanup;
684 }
685
686 /* Check if the authenticatedSafe content is empty, and encode a
687 * null one in that case.
688 */
689
690 if ((result = asn1_create_element
691 (_gnutls_get_pkix (), "PKIX1.pkcs-12-AuthenticatedSafe",
692 &c2)) != ASN1_SUCCESS)
693 {
694 gnutls_assert ();
695 result = _gnutls_asn2err (result);
696 goto cleanup;
697 }
698
699 result =
700 _gnutls_x509_der_encode_and_copy (c2, "", pkcs12, "authSafe.content", 1);
701 if (result < 0)
702 {
703 gnutls_assert ();
704 goto cleanup;
705 }
706 asn1_delete_structure (&c2);
707
708 return 0;
709
710cleanup:
711 asn1_delete_structure (&c2);
712 return result;
713
714}
715
716/**
717 * gnutls_pkcs12_set_bag - This function inserts a Bag into a PKCS12 structure
718 * @pkcs12: should contain a gnutls_pkcs12_t structure
719 * @bag: An initialized bag
720 *
721 * This function will insert a Bag into the PKCS12 structure.
722 * Returns 0 on success.
723 *
724 **/
725int
726gnutls_pkcs12_set_bag (gnutls_pkcs12_t pkcs12, gnutls_pkcs12_bag_t bag)
727{
728 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
729 ASN1_TYPE safe_cont = ASN1_TYPE_EMPTY;
730 int result;
731 int enc = 0, dum = 1;
732 char null;
733
734 if (pkcs12 == NULL)
735 {
736 gnutls_assert ();
737 return GNUTLS_E_INVALID_REQUEST;
738 }
739
740 /* Step 1. Check if the pkcs12 structure is empty. In that
741 * case generate an empty PFX.
742 */
743 result = asn1_read_value (pkcs12->pkcs12, "authSafe.content", &null, &dum);
744 if (result == ASN1_VALUE_NOT_FOUND)
745 {
746 result = create_empty_pfx (pkcs12->pkcs12);
747 if (result < 0)
748 {
749 gnutls_assert ();
750 return result;
751 }
752 }
753
754 /* Step 2. decode the authenticatedSafe.
755 */
756 result = _decode_pkcs12_auth_safe (pkcs12->pkcs12, &c2, NULL);
757 if (result < 0)
758 {
759 gnutls_assert ();
760 return result;
761 }
762
763 /* Step 3. Encode the bag elements into a SafeContents
764 * structure.
765 */
766 result = _pkcs12_encode_safe_contents (bag, &safe_cont, &enc);
767 if (result < 0)
768 {
769 gnutls_assert ();
770 return result;
771 }
772
773 /* Step 4. Insert the encoded SafeContents into the AuthenticatedSafe
774 * structure.
775 */
776 result = asn1_write_value (c2, "", "NEW", 1);
777 if (result != ASN1_SUCCESS)
778 {
779 gnutls_assert ();
780 result = _gnutls_asn2err (result);
781 goto cleanup;
782 }
783
784 if (enc)
785 result = asn1_write_value (c2, "?LAST.contentType", ENC_DATA_OID, 1);
786 else
787 result = asn1_write_value (c2, "?LAST.contentType", DATA_OID, 1);
788 if (result != ASN1_SUCCESS)
789 {
790 gnutls_assert ();
791 result = _gnutls_asn2err (result);
792 goto cleanup;
793 }
794
795 if (enc)
796 {
797 /* Encrypted packets are written directly.
798 */
799 result =
800 asn1_write_value (c2, "?LAST.content",
801 bag->element[0].data.data,
802 bag->element[0].data.size);
803 if (result != ASN1_SUCCESS)
804 {
805 gnutls_assert ();
806 result = _gnutls_asn2err (result);
807 goto cleanup;
808 }
809 }
810 else
811 {
812 result =
813 _gnutls_x509_der_encode_and_copy (safe_cont, "", c2,
814 "?LAST.content", 1);
815 if (result < 0)
816 {
817 gnutls_assert ();
818 goto cleanup;
819 }
820 }
821
822 asn1_delete_structure (&safe_cont);
823
824
825 /* Step 5. Reencode and copy the AuthenticatedSafe into the pkcs12
826 * structure.
827 */
828 result =
829 _gnutls_x509_der_encode_and_copy (c2, "", pkcs12->pkcs12,
830 "authSafe.content", 1);
831 if (result < 0)
832 {
833 gnutls_assert ();
834 goto cleanup;
835 }
836
837 asn1_delete_structure (&c2);
838
839 return 0;
840
841cleanup:
842 asn1_delete_structure (&c2);
843 asn1_delete_structure (&safe_cont);
844 return result;
845}
846
847/**
848 * gnutls_pkcs12_generate_mac - This function generates the MAC of the PKCS12 structure
849 * @pkcs12: should contain a gnutls_pkcs12_t structure
850 * @pass: The password for the MAC
851 *
852 * This function will generate a MAC for the PKCS12 structure.
853 * Returns 0 on success.
854 *
855 **/
856int
857gnutls_pkcs12_generate_mac (gnutls_pkcs12_t pkcs12, const char *pass)
858{
859 opaque salt[8], key[20];
860 int result;
861 const int iter = 1;
862 mac_hd_t td1 = NULL;
863 gnutls_datum_t tmp = { NULL, 0 };
864 opaque sha_mac[20];
865
866 if (pkcs12 == NULL)
867 {
868 gnutls_assert ();
869 return GNUTLS_E_INVALID_REQUEST;
870 }
871
872 /* Generate the salt.
873 */
874 if (gc_nonce (salt, sizeof (salt)) != GC_OK)
875 {
876 gnutls_assert ();
877 return GNUTLS_E_RANDOM_FAILED;
878 }
879
880 /* Write the salt into the structure.
881 */
882 result =
883 asn1_write_value (pkcs12->pkcs12, "macData.macSalt", salt, sizeof (salt));
884 if (result != ASN1_SUCCESS)
885 {
886 gnutls_assert ();
887 result = _gnutls_asn2err (result);
888 goto cleanup;
889 }
890
891 /* write the iterations
892 */
893
894 if (iter > 1)
895 {
896 result =
897 _gnutls_x509_write_uint32 (pkcs12->pkcs12, "macData.iterations",
898 iter);
899 if (result < 0)
900 {
901 gnutls_assert ();
902 goto cleanup;
903 }
904 }
905
906 /* Generate the key.
907 */
908 result = _pkcs12_string_to_key (3 /*MAC*/, salt, sizeof (salt),
909 iter, pass, sizeof (key), key);
910 if (result < 0)
911 {
912 gnutls_assert ();
913 goto cleanup;
914 }
915
916 /* Get the data to be MACed
917 */
918 result = _decode_pkcs12_auth_safe (pkcs12->pkcs12, NULL, &tmp);
919 if (result < 0)
920 {
921 gnutls_assert ();
922 goto cleanup;
923 }
924
925 /* MAC the data
926 */
927 td1 = _gnutls_hmac_init (GNUTLS_MAC_SHA1, key, sizeof (key));
928 if (td1 == GNUTLS_MAC_FAILED)
929 {
930 gnutls_assert ();
931 result = GNUTLS_E_INTERNAL_ERROR;
932 goto cleanup;
933 }
934
935 _gnutls_hmac (td1, tmp.data, tmp.size);
936 _gnutls_free_datum (&tmp);
937
938 _gnutls_hmac_deinit (td1, sha_mac);
939
940
941 result =
942 asn1_write_value (pkcs12->pkcs12, "macData.mac.digest", sha_mac,
943 sizeof (sha_mac));
944 if (result != ASN1_SUCCESS)
945 {
946 gnutls_assert ();
947 result = _gnutls_asn2err (result);
948 goto cleanup;
949 }
950
951 result =
952 asn1_write_value (pkcs12->pkcs12,
953 "macData.mac.digestAlgorithm.parameters", NULL, 0);
954 if (result != ASN1_SUCCESS)
955 {
956 gnutls_assert ();
957 result = _gnutls_asn2err (result);
958 goto cleanup;
959 }
960
961 result =
962 asn1_write_value (pkcs12->pkcs12,
963 "macData.mac.digestAlgorithm.algorithm", HASH_OID_SHA1,
964 1);
965 if (result != ASN1_SUCCESS)
966 {
967 gnutls_assert ();
968 result = _gnutls_asn2err (result);
969 goto cleanup;
970 }
971
972 return 0;
973
974cleanup:
975 _gnutls_free_datum (&tmp);
976 return result;
977}
978
979/**
980 * gnutls_pkcs12_verify_mac - This function verifies the MAC of the PKCS12 structure
981 * @pkcs12: should contain a gnutls_pkcs12_t structure
982 * @pass: The password for the MAC
983 *
984 * This function will verify the MAC for the PKCS12 structure.
985 * Returns 0 on success.
986 *
987 **/
988int
989gnutls_pkcs12_verify_mac (gnutls_pkcs12_t pkcs12, const char *pass)
990{
991 opaque key[20];
992 int result;
993 unsigned int iter;
994 int len;
995 mac_hd_t td1 = NULL;
996 gnutls_datum_t tmp = { NULL, 0 }, salt =
997 {
998 NULL, 0};
999 opaque sha_mac[20];
1000 opaque sha_mac_orig[20];
1001
1002 if (pkcs12 == NULL)
1003 {
1004 gnutls_assert ();
1005 return GNUTLS_E_INVALID_REQUEST;
1006 }
1007
1008 /* read the iterations
1009 */
1010
1011 result =
1012 _gnutls_x509_read_uint (pkcs12->pkcs12, "macData.iterations", &iter);
1013 if (result < 0)
1014 {
1015 iter = 1; /* the default */
1016 }
1017
1018
1019 /* Read the salt from the structure.
1020 */
1021 result =
1022 _gnutls_x509_read_value (pkcs12->pkcs12, "macData.macSalt", &salt, 0);
1023 if (result != ASN1_SUCCESS)
1024 {
1025 gnutls_assert ();
1026 result = _gnutls_asn2err (result);
1027 goto cleanup;
1028 }
1029
1030 /* Generate the key.
1031 */
1032 result = _pkcs12_string_to_key (3 /*MAC*/, salt.data, salt.size,
1033 iter, pass, sizeof (key), key);
1034 if (result < 0)
1035 {
1036 gnutls_assert ();
1037 goto cleanup;
1038 }
1039
1040 _gnutls_free_datum (&salt);
1041
1042 /* Get the data to be MACed
1043 */
1044 result = _decode_pkcs12_auth_safe (pkcs12->pkcs12, NULL, &tmp);
1045 if (result < 0)
1046 {
1047 gnutls_assert ();
1048 goto cleanup;
1049 }
1050
1051 /* MAC the data
1052 */
1053 td1 = _gnutls_hmac_init (GNUTLS_MAC_SHA1, key, sizeof (key));
1054 if (td1 == GNUTLS_MAC_FAILED)
1055 {
1056 gnutls_assert ();
1057 result = GNUTLS_E_INTERNAL_ERROR;
1058 goto cleanup;
1059 }
1060
1061 _gnutls_hmac (td1, tmp.data, tmp.size);
1062 _gnutls_free_datum (&tmp);
1063
1064 _gnutls_hmac_deinit (td1, sha_mac);
1065
1066 len = sizeof (sha_mac_orig);
1067 result =
1068 asn1_read_value (pkcs12->pkcs12, "macData.mac.digest", sha_mac_orig,
1069 &len);
1070 if (result != ASN1_SUCCESS)
1071 {
1072 gnutls_assert ();
1073 result = _gnutls_asn2err (result);
1074 goto cleanup;
1075 }
1076
1077 if (memcmp (sha_mac_orig, sha_mac, sizeof (sha_mac)) != 0)
1078 {
1079 gnutls_assert ();
1080 return GNUTLS_E_MAC_VERIFY_FAILED;
1081 }
1082
1083 return 0;
1084
1085cleanup:
1086 _gnutls_free_datum (&tmp);
1087 _gnutls_free_datum (&salt);
1088 return result;
1089}
1090
1091
1092static int
1093write_attributes (gnutls_pkcs12_bag_t bag, int elem,
1094 ASN1_TYPE c2, const char *where)
1095{
1096 int result;
1097 char root[128];
1098
1099 /* If the bag attributes are empty, then write
1100 * nothing to the attribute field.
1101 */
1102 if (bag->element[elem].friendly_name == NULL &&
1103 bag->element[elem].local_key_id.data == NULL)
1104 {
1105 /* no attributes
1106 */
1107 result = asn1_write_value (c2, where, NULL, 0);
1108 if (result != ASN1_SUCCESS)
1109 {
1110 gnutls_assert ();
1111 return _gnutls_asn2err (result);
1112 }
1113
1114 return 0;
1115 }
1116
1117 if (bag->element[elem].local_key_id.data != NULL)
1118 {
1119
1120 /* Add a new Attribute
1121 */
1122 result = asn1_write_value (c2, where, "NEW", 1);
1123 if (result != ASN1_SUCCESS)
1124 {
1125 gnutls_assert ();
1126 return _gnutls_asn2err (result);
1127 }
1128
1129 _gnutls_str_cpy (root, sizeof (root), where);
1130 _gnutls_str_cat (root, sizeof (root), ".?LAST");
1131
1132 result =
1133 _gnutls_x509_encode_and_write_attribute (KEY_ID_OID, c2, root,
1134 bag->element[elem].
1135 local_key_id.data,
1136 bag->element[elem].
1137 local_key_id.size, 1);
1138 if (result < 0)
1139 {
1140 gnutls_assert ();
1141 return result;
1142 }
1143 }
1144
1145 if (bag->element[elem].friendly_name != NULL)
1146 {
1147 opaque *name;
1148 int size, i;
1149 const char *p;
1150
1151 /* Add a new Attribute
1152 */
1153 result = asn1_write_value (c2, where, "NEW", 1);
1154 if (result != ASN1_SUCCESS)
1155 {
1156 gnutls_assert ();
1157 return _gnutls_asn2err (result);
1158 }
1159
1160 /* convert name to BMPString
1161 */
1162 size = strlen (bag->element[elem].friendly_name) * 2;
1163 name = gnutls_malloc (size);
1164
1165 if (name == NULL)
1166 {
1167 gnutls_assert ();
1168 return GNUTLS_E_MEMORY_ERROR;
1169 }
1170
1171 p = bag->element[elem].friendly_name;
1172 for (i = 0; i < size; i += 2)
1173 {
1174 name[i] = 0;
1175 name[i + 1] = *p;
1176 p++;
1177 }
1178
1179 _gnutls_str_cpy (root, sizeof (root), where);
1180 _gnutls_str_cat (root, sizeof (root), ".?LAST");
1181
1182 result =
1183 _gnutls_x509_encode_and_write_attribute (FRIENDLY_NAME_OID, c2,
1184 root, name, size, 1);
1185
1186 gnutls_free (name);
1187
1188 if (result < 0)
1189 {
1190 gnutls_assert ();
1191 return result;
1192 }
1193 }
1194
1195 return 0;
1196}
1197
1198
1199/* Encodes the bag into a SafeContents structure, and puts the output in
1200 * the given datum. Enc is set to non zero if the data are encrypted;
1201 */
1202int
1203_pkcs12_encode_safe_contents (gnutls_pkcs12_bag_t bag, ASN1_TYPE * contents,
1204 int *enc)
1205{
1206 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
1207 int result;
1208 int i;
1209 const char *oid;
1210
1211 if (bag->element[0].type == GNUTLS_BAG_ENCRYPTED && enc)
1212 {
1213 *enc = 1;
1214 return 0; /* ENCRYPTED BAG, do nothing. */
1215 }
1216 else if (enc)
1217 *enc = 0;
1218
1219 /* Step 1. Create the SEQUENCE.
1220 */
1221
1222 if ((result = asn1_create_element
1223 (_gnutls_get_pkix (), "PKIX1.pkcs-12-SafeContents",
1224 &c2)) != ASN1_SUCCESS)
1225 {
1226 gnutls_assert ();
1227 result = _gnutls_asn2err (result);
1228 goto cleanup;
1229 }
1230
1231 for (i = 0; i < bag->bag_elements; i++)
1232 {
1233
1234 oid = bag_to_oid (bag->element[i].type);
1235 if (oid == NULL)
1236 {
1237 gnutls_assert ();
1238 continue;
1239 }
1240
1241 result = asn1_write_value (c2, "", "NEW", 1);
1242 if (result != ASN1_SUCCESS)
1243 {
1244 gnutls_assert ();
1245 result = _gnutls_asn2err (result);
1246 goto cleanup;
1247 }
1248
1249 /* Copy the bag type.
1250 */
1251 result = asn1_write_value (c2, "?LAST.bagId", oid, 1);
1252 if (result != ASN1_SUCCESS)
1253 {
1254 gnutls_assert ();
1255 result = _gnutls_asn2err (result);
1256 goto cleanup;
1257 }
1258
1259 /* Set empty attributes
1260 */
1261 result = write_attributes (bag, i, c2, "?LAST.bagAttributes");
1262 if (result < 0)
1263 {
1264 gnutls_assert ();
1265 goto cleanup;
1266 }
1267
1268
1269 /* Copy the Bag Value
1270 */
1271
1272 if (bag->element[i].type == GNUTLS_BAG_CERTIFICATE ||
1273 bag->element[i].type == GNUTLS_BAG_CRL)
1274 {
1275 gnutls_datum_t tmp;
1276
1277 /* in that case encode it to a CertBag or
1278 * a CrlBag.
1279 */
1280
1281 result =
1282 _pkcs12_encode_crt_bag (bag->element[i].type,
1283 &bag->element[i].data, &tmp);
1284
1285 if (result < 0)
1286 {
1287 gnutls_assert ();
1288 goto cleanup;
1289 }
1290
1291 result = _gnutls_x509_write_value (c2, "?LAST.bagValue", &tmp, 0);
1292
1293 _gnutls_free_datum (&tmp);
1294
1295 }
1296 else
1297 {
1298
1299 result = _gnutls_x509_write_value (c2, "?LAST.bagValue",
1300 &bag->element[i].data, 0);
1301 }
1302
1303 if (result < 0)
1304 {
1305 gnutls_assert ();
1306 goto cleanup;
1307 }
1308
1309 }
1310
1311 /* Encode the data and copy them into the datum
1312 */
1313 *contents = c2;
1314
1315 return 0;
1316
1317cleanup:
1318 if (c2)
1319 asn1_delete_structure (&c2);
1320 return result;
1321
1322}
1323
1324
1325#endif /* ENABLE_PKI */
diff --git a/src/daemon/https/x509/pkcs12.h b/src/daemon/https/x509/pkcs12.h
new file mode 100644
index 00000000..566058fb
--- /dev/null
+++ b/src/daemon/https/x509/pkcs12.h
@@ -0,0 +1,208 @@
1/*
2 * Copyright (C) 2003, 2004, 2005 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// TODO clean
26
27#ifndef GNUTLS_PKCS12_H
28# define GNUTLS_PKCS12_H
29
30#ifdef __cplusplus
31extern "C"
32 {
33#endif
34
35#include <x509.h>
36
37#define MAX_BAG_ELEMENTS 32
38
39/* PKCS12 structures handling
40 */
41struct gnutls_pkcs12_int;
42
43struct gnutls_pkcs12_bag_int;
44typedef struct gnutls_pkcs12_int
45 {
46 ASN1_TYPE pkcs12;
47 } gnutls_pkcs12_int;
48
49typedef enum gnutls_pkcs12_bag_type_t
50 {
51 GNUTLS_BAG_EMPTY = 0,
52
53 GNUTLS_BAG_PKCS8_ENCRYPTED_KEY = 1,
54 GNUTLS_BAG_PKCS8_KEY,
55 GNUTLS_BAG_CERTIFICATE,
56 GNUTLS_BAG_CRL,
57 GNUTLS_BAG_ENCRYPTED = 10,
58 GNUTLS_BAG_UNKNOWN = 20
59 } gnutls_pkcs12_bag_type_t;
60
61struct bag_element
62 {
63 gnutls_datum_t data;
64 gnutls_pkcs12_bag_type_t type;
65 gnutls_datum_t local_key_id;
66 char *friendly_name;
67 };
68
69typedef struct gnutls_pkcs12_bag_int
70 {
71 struct bag_element element[MAX_BAG_ELEMENTS];
72 int bag_elements;
73 } gnutls_pkcs12_bag_int;
74
75/* Bag attributes */
76#define FRIENDLY_NAME_OID "1.2.840.113549.1.9.20"
77#define KEY_ID_OID "1.2.840.113549.1.9.21"
78
79typedef struct gnutls_pkcs12_int *gnutls_pkcs12_t;
80typedef struct gnutls_pkcs12_bag_int *gnutls_pkcs12_bag_t;
81
82int gnutls_pkcs12_init(gnutls_pkcs12_t * pkcs12);
83void gnutls_pkcs12_deinit(gnutls_pkcs12_t pkcs12);
84int gnutls_pkcs12_import(gnutls_pkcs12_t pkcs12,
85 const gnutls_datum_t * data,
86 gnutls_x509_crt_fmt_t format,
87 unsigned int flags);
88int gnutls_pkcs12_export(gnutls_pkcs12_t pkcs12,
89 gnutls_x509_crt_fmt_t format,
90 void *output_data,
91 size_t * output_data_size);
92
93int gnutls_pkcs12_get_bag(gnutls_pkcs12_t pkcs12,
94 int indx,
95 gnutls_pkcs12_bag_t bag);
96int gnutls_pkcs12_set_bag(gnutls_pkcs12_t pkcs12,
97 gnutls_pkcs12_bag_t bag);
98
99int gnutls_pkcs12_generate_mac(gnutls_pkcs12_t pkcs12,
100 const char *pass);
101int gnutls_pkcs12_verify_mac(gnutls_pkcs12_t pkcs12,
102 const char *pass);
103
104int gnutls_pkcs12_bag_decrypt(gnutls_pkcs12_bag_t bag,
105 const char *pass);
106int gnutls_pkcs12_bag_encrypt(gnutls_pkcs12_bag_t bag,
107 const char *pass,
108 unsigned int flags);
109
110gnutls_pkcs12_bag_type_t gnutls_pkcs12_bag_get_type(gnutls_pkcs12_bag_t
111 bag,
112 int indx);
113int gnutls_pkcs12_bag_get_data(gnutls_pkcs12_bag_t bag,
114 int indx,
115 gnutls_datum_t * data);
116int gnutls_pkcs12_bag_set_data(gnutls_pkcs12_bag_t bag,
117 gnutls_pkcs12_bag_type_t type,
118 const gnutls_datum_t * data);
119int gnutls_pkcs12_bag_set_crl(gnutls_pkcs12_bag_t bag,
120 gnutls_x509_crl_t crl);
121int gnutls_pkcs12_bag_set_crt(gnutls_pkcs12_bag_t bag,
122 gnutls_x509_crt_t crt);
123
124int gnutls_pkcs12_bag_init(gnutls_pkcs12_bag_t * bag);
125void gnutls_pkcs12_bag_deinit(gnutls_pkcs12_bag_t bag);
126int gnutls_pkcs12_bag_get_count(gnutls_pkcs12_bag_t bag);
127
128int gnutls_pkcs12_bag_get_key_id(gnutls_pkcs12_bag_t bag,
129 int indx,
130 gnutls_datum_t * id);
131int gnutls_pkcs12_bag_set_key_id(gnutls_pkcs12_bag_t bag,
132 int indx,
133 const gnutls_datum_t * id);
134
135int gnutls_pkcs12_bag_get_friendly_name(gnutls_pkcs12_bag_t bag,
136 int indx,
137 char **name);
138int gnutls_pkcs12_bag_set_friendly_name(gnutls_pkcs12_bag_t bag,
139 int indx,
140 const char *name);
141
142#ifdef __cplusplus
143}
144#endif
145
146#define BAG_PKCS8_KEY "1.2.840.113549.1.12.10.1.1"
147#define BAG_PKCS8_ENCRYPTED_KEY "1.2.840.113549.1.12.10.1.2"
148#define BAG_CERTIFICATE "1.2.840.113549.1.12.10.1.3"
149#define BAG_CRL "1.2.840.113549.1.12.10.1.4"
150
151/* PKCS #7
152 */
153#define DATA_OID "1.2.840.113549.1.7.1"
154#define ENC_DATA_OID "1.2.840.113549.1.7.6"
155
156int gnutls_pkcs12_init(gnutls_pkcs12_t * pkcs12);
157void gnutls_pkcs12_deinit(gnutls_pkcs12_t pkcs12);
158int gnutls_pkcs12_import(gnutls_pkcs12_t pkcs12,
159 const gnutls_datum_t * data,
160 gnutls_x509_crt_fmt_t format,
161 unsigned int flags);
162
163int gnutls_pkcs12_get_bag(gnutls_pkcs12_t pkcs12,
164 int indx,
165 gnutls_pkcs12_bag_t bag);
166
167int gnutls_pkcs12_bag_init(gnutls_pkcs12_bag_t * bag);
168void gnutls_pkcs12_bag_deinit(gnutls_pkcs12_bag_t bag);
169
170int _pkcs12_string_to_key(unsigned int id,
171 const opaque * salt,
172 unsigned int salt_size,
173 unsigned int iter,
174 const char *pw,
175 unsigned int req_keylen,
176 opaque * keybuf);
177
178int _gnutls_pkcs7_decrypt_data(const gnutls_datum_t * data,
179 const char *password,
180 gnutls_datum_t * dec);
181
182typedef enum schema_id
183 {
184 PBES2, /* the stuff in PKCS #5 */
185 PKCS12_3DES_SHA1, /* the fucking stuff in PKCS #12 */
186 PKCS12_ARCFOUR_SHA1,
187 PKCS12_RC2_40_SHA1
188 } schema_id;
189
190int _gnutls_pkcs7_encrypt_data(schema_id schema,
191 const gnutls_datum_t * data,
192 const char *password,
193 gnutls_datum_t * enc);
194int _pkcs12_decode_safe_contents(const gnutls_datum_t * content,
195 gnutls_pkcs12_bag_t bag);
196
197int _pkcs12_encode_safe_contents(gnutls_pkcs12_bag_t bag,
198 ASN1_TYPE * content,
199 int *enc);
200
201int _pkcs12_decode_crt_bag(gnutls_pkcs12_bag_type_t type,
202 const gnutls_datum_t * in,
203 gnutls_datum_t * out);
204int _pkcs12_encode_crt_bag(gnutls_pkcs12_bag_type_t type,
205 const gnutls_datum_t * raw,
206 gnutls_datum_t * out);
207
208#endif /* GNUTLS_PKCS12_H */
diff --git a/src/daemon/https/x509/pkcs12_bag.c b/src/daemon/https/x509/pkcs12_bag.c
new file mode 100644
index 00000000..c34ec757
--- /dev/null
+++ b/src/daemon/https/x509/pkcs12_bag.c
@@ -0,0 +1,770 @@
1/*
2 * Copyright (C) 2003, 2004, 2005 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/* Functions that relate on PKCS12 Bag packet parsing.
26 */
27
28#include <gnutls_int.h>
29
30#ifdef ENABLE_PKI
31
32#include <gnutls_datum.h>
33#include <gnutls_global.h>
34#include <gnutls_errors.h>
35#include <common.h>
36#include <pkcs12.h>
37#include <privkey.h>
38
39/**
40 * gnutls_pkcs12_bag_init - This function initializes a gnutls_pkcs12_bag_t structure
41 * @bag: The structure to be initialized
42 *
43 * This function will initialize a PKCS12 bag structure. PKCS12 Bags
44 * usually contain private keys, lists of X.509 Certificates and X.509 Certificate
45 * revocation lists.
46 *
47 * Returns 0 on success.
48 *
49 **/
50int
51gnutls_pkcs12_bag_init (gnutls_pkcs12_bag_t * bag)
52{
53 *bag = gnutls_calloc (1, sizeof (gnutls_pkcs12_bag_int));
54
55 if (*bag)
56 {
57 return 0; /* success */
58 }
59 return GNUTLS_E_MEMORY_ERROR;
60}
61
62static inline void
63_pkcs12_bag_free_data (gnutls_pkcs12_bag_t bag)
64{
65 int i;
66
67 for (i = 0; i < bag->bag_elements; i++)
68 {
69 _gnutls_free_datum (&bag->element[i].data);
70 _gnutls_free_datum (&bag->element[i].local_key_id);
71 gnutls_free (bag->element[i].friendly_name);
72 bag->element[i].friendly_name = NULL;
73 bag->element[i].type = 0;
74 }
75
76}
77
78
79/**
80 * gnutls_pkcs12_bag_deinit - This function deinitializes memory used by a gnutls_pkcs12_t structure
81 * @bag: The structure to be initialized
82 *
83 * This function will deinitialize a PKCS12 Bag structure.
84 *
85 **/
86void
87gnutls_pkcs12_bag_deinit (gnutls_pkcs12_bag_t bag)
88{
89 if (!bag)
90 return;
91
92 _pkcs12_bag_free_data (bag);
93
94 gnutls_free (bag);
95}
96
97/**
98 * gnutls_pkcs12_bag_get_type - This function returns the bag's type
99 * @bag: The bag
100 * @indx: The element of the bag to get the type
101 *
102 * This function will return the bag's type. One of the gnutls_pkcs12_bag_type_t
103 * enumerations.
104 *
105 **/
106gnutls_pkcs12_bag_type_t
107gnutls_pkcs12_bag_get_type (gnutls_pkcs12_bag_t bag, int indx)
108{
109 if (bag == NULL)
110 {
111 gnutls_assert ();
112 return GNUTLS_E_INVALID_REQUEST;
113 }
114
115 if (indx >= bag->bag_elements)
116 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
117 return bag->element[indx].type;
118}
119
120/**
121 * gnutls_pkcs12_bag_get_count - This function returns the bag's elements count
122 * @bag: The bag
123 *
124 * This function will return the number of the elements withing the bag.
125 *
126 **/
127int
128gnutls_pkcs12_bag_get_count (gnutls_pkcs12_bag_t bag)
129{
130 if (bag == NULL)
131 {
132 gnutls_assert ();
133 return GNUTLS_E_INVALID_REQUEST;
134 }
135
136 return bag->bag_elements;
137}
138
139/**
140 * gnutls_pkcs12_bag_get_data - This function returns the bag's data
141 * @bag: The bag
142 * @indx: The element of the bag to get the data from
143 * @data: where the bag's data will be. Should be treated as constant.
144 *
145 * This function will return the bag's data. The data is a constant
146 * that is stored into the bag. Should not be accessed after the bag
147 * is deleted.
148 *
149 * Returns 0 on success and a negative error code on error.
150 *
151 **/
152int
153gnutls_pkcs12_bag_get_data (gnutls_pkcs12_bag_t bag, int indx,
154 gnutls_datum_t * data)
155{
156 if (bag == NULL)
157 {
158 gnutls_assert ();
159 return GNUTLS_E_INVALID_REQUEST;
160 }
161
162 if (indx >= bag->bag_elements)
163 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
164
165 data->data = bag->element[indx].data.data;
166 data->size = bag->element[indx].data.size;
167
168 return 0;
169}
170
171#define X509_CERT_OID "1.2.840.113549.1.9.22.1"
172#define X509_CRL_OID "1.2.840.113549.1.9.23.1"
173
174int
175_pkcs12_decode_crt_bag (gnutls_pkcs12_bag_type_t type,
176 const gnutls_datum_t * in, gnutls_datum_t * out)
177{
178 int ret;
179 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
180
181 if (type == GNUTLS_BAG_CERTIFICATE)
182 {
183 if ((ret = asn1_create_element (_gnutls_get_pkix (),
184 "PKIX1.pkcs-12-CertBag",
185 &c2)) != ASN1_SUCCESS)
186 {
187 gnutls_assert ();
188 ret = _gnutls_asn2err (ret);
189 goto cleanup;
190 }
191
192 ret = asn1_der_decoding (&c2, in->data, in->size, NULL);
193 if (ret != ASN1_SUCCESS)
194 {
195 gnutls_assert ();
196 ret = _gnutls_asn2err (ret);
197 goto cleanup;
198 }
199
200 ret = _gnutls_x509_read_value (c2, "certValue", out, 1);
201 if (ret < 0)
202 {
203 gnutls_assert ();
204 goto cleanup;
205 }
206
207 }
208 else
209 { /* CRL */
210 if ((ret = asn1_create_element (_gnutls_get_pkix (),
211 "PKIX1.pkcs-12-CRLBag",
212 &c2)) != ASN1_SUCCESS)
213 {
214 gnutls_assert ();
215 ret = _gnutls_asn2err (ret);
216 goto cleanup;
217 }
218
219 ret = asn1_der_decoding (&c2, in->data, in->size, NULL);
220 if (ret != ASN1_SUCCESS)
221 {
222 gnutls_assert ();
223 ret = _gnutls_asn2err (ret);
224 goto cleanup;
225 }
226
227 ret = _gnutls_x509_read_value (c2, "crlValue", out, 1);
228 if (ret < 0)
229 {
230 gnutls_assert ();
231 goto cleanup;
232 }
233 }
234
235 asn1_delete_structure (&c2);
236
237 return 0;
238
239
240cleanup:
241
242 asn1_delete_structure (&c2);
243 return ret;
244}
245
246
247int
248_pkcs12_encode_crt_bag (gnutls_pkcs12_bag_type_t type,
249 const gnutls_datum_t * raw, gnutls_datum_t * out)
250{
251 int ret;
252 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
253
254 if (type == GNUTLS_BAG_CERTIFICATE)
255 {
256 if ((ret = asn1_create_element (_gnutls_get_pkix (),
257 "PKIX1.pkcs-12-CertBag",
258 &c2)) != ASN1_SUCCESS)
259 {
260 gnutls_assert ();
261 ret = _gnutls_asn2err (ret);
262 goto cleanup;
263 }
264
265 ret = asn1_write_value (c2, "certId", X509_CERT_OID, 1);
266 if (ret != ASN1_SUCCESS)
267 {
268 gnutls_assert ();
269 ret = _gnutls_asn2err (ret);
270 goto cleanup;
271 }
272
273 ret = _gnutls_x509_write_value (c2, "certValue", raw, 1);
274 if (ret < 0)
275 {
276 gnutls_assert ();
277 goto cleanup;
278 }
279
280 }
281 else
282 { /* CRL */
283 if ((ret = asn1_create_element (_gnutls_get_pkix (),
284 "PKIX1.pkcs-12-CRLBag",
285 &c2)) != ASN1_SUCCESS)
286 {
287 gnutls_assert ();
288 ret = _gnutls_asn2err (ret);
289 goto cleanup;
290 }
291
292 ret = asn1_write_value (c2, "crlId", X509_CRL_OID, 1);
293 if (ret != ASN1_SUCCESS)
294 {
295 gnutls_assert ();
296 ret = _gnutls_asn2err (ret);
297 goto cleanup;
298 }
299
300 ret = _gnutls_x509_write_value (c2, "crlValue", raw, 1);
301 if (ret < 0)
302 {
303 gnutls_assert ();
304 goto cleanup;
305 }
306 }
307
308 ret = _gnutls_x509_der_encode (c2, "", out, 0);
309
310 if (ret < 0)
311 {
312 gnutls_assert ();
313 goto cleanup;
314 }
315
316 asn1_delete_structure (&c2);
317
318 return 0;
319
320
321cleanup:
322
323 asn1_delete_structure (&c2);
324 return ret;
325}
326
327
328/**
329 * gnutls_pkcs12_bag_set_data - This function inserts data into the bag
330 * @bag: The bag
331 * @type: The data's type
332 * @data: the data to be copied.
333 *
334 * This function will insert the given data of the given type into the
335 * bag.
336 *
337 * Returns the index of the added bag on success, or a negative
338 * value on error.
339 *
340 **/
341int
342gnutls_pkcs12_bag_set_data (gnutls_pkcs12_bag_t bag,
343 gnutls_pkcs12_bag_type_t type,
344 const gnutls_datum_t * data)
345{
346 int ret;
347 if (bag == NULL)
348 {
349 gnutls_assert ();
350 return GNUTLS_E_INVALID_REQUEST;
351 }
352
353 if (bag->bag_elements == MAX_BAG_ELEMENTS - 1)
354 {
355 gnutls_assert ();
356 /* bag is full */
357 return GNUTLS_E_MEMORY_ERROR;
358 }
359
360 if (bag->bag_elements == 1)
361 {
362 /* A bag with a key or an encrypted bag, must have
363 * only one element.
364 */
365
366 if (bag->element[0].type == GNUTLS_BAG_PKCS8_KEY ||
367 bag->element[0].type == GNUTLS_BAG_PKCS8_ENCRYPTED_KEY ||
368 bag->element[0].type == GNUTLS_BAG_ENCRYPTED)
369 {
370 gnutls_assert ();
371 return GNUTLS_E_INVALID_REQUEST;
372 }
373 }
374
375 ret =
376 _gnutls_set_datum (&bag->element[bag->bag_elements].data,
377 data->data, data->size);
378
379 if (ret < 0)
380 {
381 gnutls_assert ();
382 return ret;
383 }
384
385 bag->element[bag->bag_elements].type = type;
386
387 bag->bag_elements++;
388
389 return bag->bag_elements - 1;
390}
391
392/**
393 * gnutls_pkcs12_bag_set_crt - This function inserts a certificate into the bag
394 * @bag: The bag
395 * @crt: the certificate to be copied.
396 *
397 * This function will insert the given certificate into the
398 * bag. This is just a wrapper over gnutls_pkcs12_bag_set_data().
399 *
400 * Returns the index of the added bag on success, or a negative
401 * value on failure.
402 *
403 **/
404int
405gnutls_pkcs12_bag_set_crt (gnutls_pkcs12_bag_t bag, gnutls_x509_crt_t crt)
406{
407 int ret;
408 gnutls_datum_t data;
409
410 if (bag == NULL)
411 {
412 gnutls_assert ();
413 return GNUTLS_E_INVALID_REQUEST;
414 }
415
416 ret = _gnutls_x509_der_encode (crt->cert, "", &data, 0);
417 if (ret < 0)
418 {
419 gnutls_assert ();
420 return ret;
421 }
422
423 ret = gnutls_pkcs12_bag_set_data (bag, GNUTLS_BAG_CERTIFICATE, &data);
424
425 _gnutls_free_datum (&data);
426
427 return ret;
428}
429
430/**
431 * gnutls_pkcs12_bag_set_crl - This function inserts the CRL into the bag
432 * @bag: The bag
433 * @crl: the CRL to be copied.
434 *
435 * This function will insert the given CRL into the
436 * bag. This is just a wrapper over gnutls_pkcs12_bag_set_data().
437 *
438 * Returns the index of the added bag on success, or a negative
439 * value on failure.
440 *
441 **/
442int
443gnutls_pkcs12_bag_set_crl (gnutls_pkcs12_bag_t bag, gnutls_x509_crl_t crl)
444{
445 int ret;
446 gnutls_datum_t data;
447
448
449 if (bag == NULL)
450 {
451 gnutls_assert ();
452 return GNUTLS_E_INVALID_REQUEST;
453 }
454
455 ret = _gnutls_x509_der_encode (crl->crl, "", &data, 0);
456 if (ret < 0)
457 {
458 gnutls_assert ();
459 return ret;
460 }
461
462 ret = gnutls_pkcs12_bag_set_data (bag, GNUTLS_BAG_CRL, &data);
463
464 _gnutls_free_datum (&data);
465
466 return ret;
467}
468
469/**
470 * gnutls_pkcs12_bag_set_key_id - This function sets a key ID into the bag element
471 * @bag: The bag
472 * @indx: The bag's element to add the id
473 * @id: the ID
474 *
475 * This function will add the given key ID, to the specified, by the index, bag
476 * element. The key ID will be encoded as a 'Local key identifier' bag attribute,
477 * which is usually used to distinguish the local private key and the certificate pair.
478 *
479 * Returns 0 on success, or a negative value on error.
480 *
481 **/
482int
483gnutls_pkcs12_bag_set_key_id (gnutls_pkcs12_bag_t bag, int indx,
484 const gnutls_datum_t * id)
485{
486 int ret;
487
488
489 if (bag == NULL)
490 {
491 gnutls_assert ();
492 return GNUTLS_E_INVALID_REQUEST;
493 }
494
495 if (indx > bag->bag_elements - 1)
496 {
497 gnutls_assert ();
498 return GNUTLS_E_INVALID_REQUEST;
499 }
500
501 ret = _gnutls_set_datum (&bag->element[indx].local_key_id,
502 id->data, id->size);
503
504 if (ret < 0)
505 {
506 gnutls_assert ();
507 return ret;
508 }
509
510 return 0;
511}
512
513/**
514 * gnutls_pkcs12_bag_get_key_id - This function gets the key ID from the bag element
515 * @bag: The bag
516 * @indx: The bag's element to add the id
517 * @id: where the ID will be copied (to be treated as const)
518 *
519 * This function will return the key ID, of the specified bag element.
520 * The key ID is usually used to distinguish the local private key and the certificate pair.
521 *
522 * Returns 0 on success, or a negative value on error.
523 *
524 **/
525int
526gnutls_pkcs12_bag_get_key_id (gnutls_pkcs12_bag_t bag, int indx,
527 gnutls_datum_t * id)
528{
529 if (bag == NULL)
530 {
531 gnutls_assert ();
532 return GNUTLS_E_INVALID_REQUEST;
533 }
534
535 if (indx > bag->bag_elements - 1)
536 {
537 gnutls_assert ();
538 return GNUTLS_E_INVALID_REQUEST;
539 }
540
541 id->data = bag->element[indx].local_key_id.data;
542 id->size = bag->element[indx].local_key_id.size;
543
544 return 0;
545}
546
547/**
548 * gnutls_pkcs12_bag_get_friendly_name - This function returns the friendly name of the bag element
549 * @bag: The bag
550 * @indx: The bag's element to add the id
551 * @name: will hold a pointer to the name (to be treated as const)
552 *
553 * This function will return the friendly name, of the specified bag element.
554 * The key ID is usually used to distinguish the local private key and the certificate pair.
555 *
556 * Returns 0 on success, or a negative value on error.
557 *
558 **/
559int
560gnutls_pkcs12_bag_get_friendly_name (gnutls_pkcs12_bag_t bag, int indx,
561 char **name)
562{
563 if (bag == NULL)
564 {
565 gnutls_assert ();
566 return GNUTLS_E_INVALID_REQUEST;
567 }
568
569 if (indx > bag->bag_elements - 1)
570 {
571 gnutls_assert ();
572 return GNUTLS_E_INVALID_REQUEST;
573 }
574
575 *name = bag->element[indx].friendly_name;
576
577 return 0;
578}
579
580
581/**
582 * gnutls_pkcs12_bag_set_friendly_name - This function sets a friendly name into the bag element
583 * @bag: The bag
584 * @indx: The bag's element to add the id
585 * @name: the name
586 *
587 * This function will add the given key friendly name, to the specified, by the index, bag
588 * element. The name will be encoded as a 'Friendly name' bag attribute,
589 * which is usually used to set a user name to the local private key and the certificate pair.
590 *
591 * Returns 0 on success, or a negative value on error.
592 *
593 **/
594int
595gnutls_pkcs12_bag_set_friendly_name (gnutls_pkcs12_bag_t bag, int indx,
596 const char *name)
597{
598 if (bag == NULL)
599 {
600 gnutls_assert ();
601 return GNUTLS_E_INVALID_REQUEST;
602 }
603
604 if (indx > bag->bag_elements - 1)
605 {
606 gnutls_assert ();
607 return GNUTLS_E_INVALID_REQUEST;
608 }
609
610 bag->element[indx].friendly_name = gnutls_strdup (name);
611
612 if (name == NULL)
613 {
614 gnutls_assert ();
615 return GNUTLS_E_MEMORY_ERROR;
616 }
617
618 return 0;
619}
620
621
622/**
623 * gnutls_pkcs12_bag_decrypt - This function will decrypt an encrypted bag
624 * @bag: The bag
625 * @pass: The password used for encryption. This can only be ASCII.
626 *
627 * This function will decrypt the given encrypted bag and return 0 on success.
628 *
629 **/
630int
631gnutls_pkcs12_bag_decrypt (gnutls_pkcs12_bag_t bag, const char *pass)
632{
633 int ret;
634 gnutls_datum_t dec;
635
636 if (bag == NULL)
637 {
638 gnutls_assert ();
639 return GNUTLS_E_INVALID_REQUEST;
640 }
641
642 if (bag->element[0].type != GNUTLS_BAG_ENCRYPTED)
643 {
644 gnutls_assert ();
645 return GNUTLS_E_INVALID_REQUEST;
646 }
647
648 ret = _gnutls_pkcs7_decrypt_data (&bag->element[0].data, pass, &dec);
649
650 if (ret < 0)
651 {
652 gnutls_assert ();
653 return ret;
654 }
655
656 /* decryption succeeded. Now decode the SafeContents
657 * stuff, and parse it.
658 */
659
660 _gnutls_free_datum (&bag->element[0].data);
661
662 ret = _pkcs12_decode_safe_contents (&dec, bag);
663
664 _gnutls_free_datum (&dec);
665
666 if (ret < 0)
667 {
668 gnutls_assert ();
669 return ret;
670 }
671
672 return 0;
673}
674
675/**
676 * gnutls_pkcs12_bag_encrypt - This function will encrypt a bag
677 * @bag: The bag
678 * @pass: The password used for encryption. This can only be ASCII.
679 * @flags: should be one of gnutls_pkcs_encrypt_flags_t elements bitwise or'd
680 *
681 * This function will encrypt the given bag and return 0 on success.
682 *
683 **/
684int
685gnutls_pkcs12_bag_encrypt (gnutls_pkcs12_bag_t bag, const char *pass,
686 unsigned int flags)
687{
688 int ret;
689 ASN1_TYPE safe_cont = ASN1_TYPE_EMPTY;
690 gnutls_datum_t der = { NULL, 0 };
691 gnutls_datum_t enc = { NULL, 0 };
692 schema_id id;
693
694 if (bag == NULL)
695 {
696 gnutls_assert ();
697 return GNUTLS_E_INVALID_REQUEST;
698 }
699
700 if (bag->element[0].type == GNUTLS_BAG_ENCRYPTED)
701 {
702 gnutls_assert ();
703 return GNUTLS_E_INVALID_REQUEST;
704 }
705
706 /* Encode the whole bag to a safe contents
707 * structure.
708 */
709 ret = _pkcs12_encode_safe_contents (bag, &safe_cont, NULL);
710 if (ret < 0)
711 {
712 gnutls_assert ();
713 return ret;
714 }
715
716 /* DER encode the SafeContents.
717 */
718 ret = _gnutls_x509_der_encode (safe_cont, "", &der, 0);
719
720 asn1_delete_structure (&safe_cont);
721
722 if (ret < 0)
723 {
724 gnutls_assert ();
725 return ret;
726 }
727
728 if (flags & GNUTLS_PKCS_PLAIN)
729 {
730 gnutls_assert ();
731 return GNUTLS_E_INVALID_REQUEST;
732 }
733
734 if (flags & GNUTLS_PKCS_USE_PKCS12_ARCFOUR)
735 id = PKCS12_ARCFOUR_SHA1;
736 else if (flags & GNUTLS_PKCS_USE_PKCS12_RC2_40)
737 id = PKCS12_RC2_40_SHA1;
738 else if (flags & GNUTLS_PKCS_USE_PBES2_3DES)
739 id = PBES2;
740 else
741 id = PKCS12_3DES_SHA1;
742
743 /* Now encrypt them.
744 */
745 ret = _gnutls_pkcs7_encrypt_data (id, &der, pass, &enc);
746
747 _gnutls_free_datum (&der);
748
749 if (ret < 0)
750 {
751 gnutls_assert ();
752 return ret;
753 }
754
755 /* encryption succeeded.
756 */
757
758 _pkcs12_bag_free_data (bag);
759
760 bag->element[0].type = GNUTLS_BAG_ENCRYPTED;
761 bag->element[0].data = enc;
762
763 bag->bag_elements = 1;
764
765
766 return 0;
767}
768
769
770#endif /* ENABLE_PKI */
diff --git a/src/daemon/https/x509/pkcs12_encr.c b/src/daemon/https/x509/pkcs12_encr.c
new file mode 100644
index 00000000..c80d23a3
--- /dev/null
+++ b/src/daemon/https/x509/pkcs12_encr.c
@@ -0,0 +1,169 @@
1/* minip12.c - A mini pkcs-12 implementation (modified for gnutls)
2 *
3 * Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
4 *
5 * This file is part of GNUTLS.
6 *
7 * The GNUTLS library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public License
9 * as published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
20 * USA
21 *
22 */
23
24#include <gnutls_int.h>
25
26#ifdef ENABLE_PKI
27
28#include <gcrypt.h>
29#include <gc.h>
30#include <gnutls_errors.h>
31
32/* Returns 0 if the password is ok, or a negative error
33 * code instead.
34 */
35static int
36_pkcs12_check_pass (const char *pass, size_t plen)
37{
38 const unsigned char *p = pass;
39 unsigned int i;
40
41 for (i = 0; i < plen; i++)
42 {
43 if (isascii (p[i]))
44 continue;
45 return GNUTLS_E_INVALID_PASSWORD;
46 }
47
48 return 0;
49}
50
51/* ID should be:
52 * 3 for MAC
53 * 2 for IV
54 * 1 for encryption key
55 */
56int
57_pkcs12_string_to_key (unsigned int id, const opaque * salt,
58 unsigned int salt_size, unsigned int iter,
59 const char *pw, unsigned int req_keylen,
60 opaque * keybuf)
61{
62 int rc;
63 unsigned int i, j;
64 gc_hash_handle md;
65 mpi_t num_b1 = NULL;
66 unsigned int pwlen;
67 opaque hash[20], buf_b[64], buf_i[128], *p;
68 size_t cur_keylen;
69 size_t n;
70
71 cur_keylen = 0;
72
73 if (pw == NULL)
74 pwlen = 0;
75 else
76 pwlen = strlen (pw);
77
78 if (pwlen > 63 / 2)
79 {
80 gnutls_assert ();
81 return GNUTLS_E_INVALID_REQUEST;
82 }
83
84 if ((rc = _pkcs12_check_pass (pw, pwlen)) < 0)
85 {
86 gnutls_assert ();
87 return rc;
88 }
89
90 /* Store salt and password in BUF_I */
91 p = buf_i;
92 for (i = 0; i < 64; i++)
93 *p++ = salt[i % salt_size];
94 if (pw)
95 {
96 for (i = j = 0; i < 64; i += 2)
97 {
98 *p++ = 0;
99 *p++ = pw[j];
100 if (++j > pwlen) /* Note, that we include the trailing zero */
101 j = 0;
102 }
103 }
104 else
105 memset (p, 0, 64);
106
107 for (;;)
108 {
109 rc = gc_hash_open (GC_SHA1, 0, &md);
110 if (rc)
111 {
112 gnutls_assert ();
113 return GNUTLS_E_DECRYPTION_FAILED;
114 }
115 for (i = 0; i < 64; i++)
116 {
117 unsigned char lid = id & 0xFF;
118 gc_hash_write (md, 1, &lid);
119 }
120 gc_hash_write (md, pw ? 128 : 64, buf_i);
121 memcpy (hash, gc_hash_read (md), 20);
122 gc_hash_close (md);
123 for (i = 1; i < iter; i++)
124 gc_hash_buffer (GC_SHA1, hash, 20, hash);
125 for (i = 0; i < 20 && cur_keylen < req_keylen; i++)
126 keybuf[cur_keylen++] = hash[i];
127 if (cur_keylen == req_keylen)
128 {
129 gcry_mpi_release (num_b1);
130 return 0; /* ready */
131 }
132
133 /* need more bytes. */
134 for (i = 0; i < 64; i++)
135 buf_b[i] = hash[i % 20];
136 n = 64;
137 rc = _gnutls_mpi_scan (&num_b1, buf_b, &n);
138 if (rc < 0)
139 {
140 gnutls_assert ();
141 return rc;
142 }
143 gcry_mpi_add_ui (num_b1, num_b1, 1);
144 for (i = 0; i < 128; i += 64)
145 {
146 mpi_t num_ij;
147
148 n = 64;
149 rc = _gnutls_mpi_scan (&num_ij, buf_i + i, &n);
150 if (rc < 0)
151 {
152 gnutls_assert ();
153 return rc;
154 }
155 gcry_mpi_add (num_ij, num_ij, num_b1);
156 gcry_mpi_clear_highbit (num_ij, 64 * 8);
157 n = 64;
158 rc = _gnutls_mpi_print (buf_i + i, &n, num_ij);
159 if (rc < 0)
160 {
161 gnutls_assert ();
162 return rc;
163 }
164 gcry_mpi_release (num_ij);
165 }
166 }
167}
168
169#endif /* ENABLE_PKI */
diff --git a/src/daemon/https/x509/pkcs7.c b/src/daemon/https/x509/pkcs7.c
new file mode 100644
index 00000000..35f21b12
--- /dev/null
+++ b/src/daemon/https/x509/pkcs7.c
@@ -0,0 +1,1023 @@
1/*
2 * Copyright (C) 2003, 2004, 2005 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/* Functions that relate on PKCS7 certificate lists parsing.
26 */
27
28#include <gnutls_int.h>
29#include <libtasn1.h>
30
31#ifdef ENABLE_PKI
32
33#include <gnutls_datum.h>
34#include <gnutls_global.h>
35#include <gnutls_errors.h>
36#include <common.h>
37#include <x509_b64.h>
38#include <pkcs7.h>
39#include <dn.h>
40
41#define SIGNED_DATA_OID "1.2.840.113549.1.7.2"
42
43/* Decodes the PKCS #7 signed data, and returns an ASN1_TYPE,
44 * which holds them. If raw is non null then the raw decoded
45 * data are copied (they are locally allocated) there.
46 */
47static int
48_decode_pkcs7_signed_data (ASN1_TYPE pkcs7, ASN1_TYPE * sdata,
49 gnutls_datum_t * raw)
50{
51 char oid[128];
52 ASN1_TYPE c2;
53 opaque *tmp = NULL;
54 int tmp_size, len, result;
55
56 len = sizeof (oid) - 1;
57 result = asn1_read_value (pkcs7, "contentType", oid, &len);
58 if (result != ASN1_SUCCESS)
59 {
60 gnutls_assert ();
61 return _gnutls_asn2err (result);
62 }
63
64 if (strcmp (oid, SIGNED_DATA_OID) != 0)
65 {
66 gnutls_assert ();
67 _gnutls_x509_log ("Unknown PKCS7 Content OID '%s'\n", oid);
68 return GNUTLS_E_UNKNOWN_PKCS_CONTENT_TYPE;
69 }
70
71 if ((result = asn1_create_element
72 (_gnutls_get_pkix (), "PKIX1.pkcs-7-SignedData", &c2)) != ASN1_SUCCESS)
73 {
74 gnutls_assert ();
75 return _gnutls_asn2err (result);
76 }
77
78 /* the Signed-data has been created, so
79 * decode them.
80 */
81 tmp_size = 0;
82 result = asn1_read_value (pkcs7, "content", NULL, &tmp_size);
83 if (result != ASN1_MEM_ERROR)
84 {
85 gnutls_assert ();
86 result = _gnutls_asn2err (result);
87 goto cleanup;
88 }
89
90 tmp = gnutls_malloc (tmp_size);
91 if (tmp == NULL)
92 {
93 gnutls_assert ();
94 result = GNUTLS_E_MEMORY_ERROR;
95 goto cleanup;
96 }
97
98 result = asn1_read_value (pkcs7, "content", tmp, &tmp_size);
99 if (result != ASN1_SUCCESS)
100 {
101 gnutls_assert ();
102 result = _gnutls_asn2err (result);
103 goto cleanup;
104 }
105
106 /* tmp, tmp_size hold the data and the size of the CertificateSet structure
107 * actually the ANY stuff.
108 */
109
110 /* Step 1. In case of a signed structure extract certificate set.
111 */
112
113 result = asn1_der_decoding (&c2, tmp, tmp_size, NULL);
114 if (result != ASN1_SUCCESS)
115 {
116 gnutls_assert ();
117 result = _gnutls_asn2err (result);
118 goto cleanup;
119 }
120
121 if (raw == NULL)
122 {
123 gnutls_free (tmp);
124 }
125 else
126 {
127 raw->data = tmp;
128 raw->size = tmp_size;
129 }
130
131 *sdata = c2;
132
133 return 0;
134
135cleanup:
136 if (c2)
137 asn1_delete_structure (&c2);
138 gnutls_free (tmp);
139 return result;
140}
141
142/**
143 * gnutls_pkcs7_init - This function initializes a gnutls_pkcs7_t structure
144 * @pkcs7: The structure to be initialized
145 *
146 * This function will initialize a PKCS7 structure. PKCS7 structures
147 * usually contain lists of X.509 Certificates and X.509 Certificate
148 * revocation lists.
149 *
150 * Returns 0 on success.
151 *
152 **/
153int
154gnutls_pkcs7_init (gnutls_pkcs7_t * pkcs7)
155{
156 *pkcs7 = gnutls_calloc (1, sizeof (gnutls_pkcs7_int));
157
158 if (*pkcs7)
159 {
160 int result = asn1_create_element (_gnutls_get_pkix (),
161 "PKIX1.pkcs-7-ContentInfo",
162 &(*pkcs7)->pkcs7);
163 if (result != ASN1_SUCCESS)
164 {
165 gnutls_assert ();
166 gnutls_free (*pkcs7);
167 return _gnutls_asn2err (result);
168 }
169 return 0; /* success */
170 }
171 return GNUTLS_E_MEMORY_ERROR;
172}
173
174/**
175 * gnutls_pkcs7_deinit - This function deinitializes memory used by a gnutls_pkcs7_t structure
176 * @pkcs7: The structure to be initialized
177 *
178 * This function will deinitialize a PKCS7 structure.
179 *
180 **/
181void
182gnutls_pkcs7_deinit (gnutls_pkcs7_t pkcs7)
183{
184 if (!pkcs7)
185 return;
186
187 if (pkcs7->pkcs7)
188 asn1_delete_structure (&pkcs7->pkcs7);
189
190 gnutls_free (pkcs7);
191}
192
193/**
194 * gnutls_pkcs7_import - This function will import a DER or PEM encoded PKCS7
195 * @pkcs7: The structure to store the parsed PKCS7.
196 * @data: The DER or PEM encoded PKCS7.
197 * @format: One of DER or PEM
198 *
199 * This function will convert the given DER or PEM encoded PKCS7
200 * to the native gnutls_pkcs7_t format. The output will be stored in 'pkcs7'.
201 *
202 * If the PKCS7 is PEM encoded it should have a header of "PKCS7".
203 *
204 * Returns 0 on success.
205 *
206 **/
207int
208gnutls_pkcs7_import (gnutls_pkcs7_t pkcs7, const gnutls_datum_t * data,
209 gnutls_x509_crt_fmt_t format)
210{
211 int result = 0, need_free = 0;
212 gnutls_datum_t _data;
213
214 if (pkcs7 == NULL)
215 return GNUTLS_E_INVALID_REQUEST;
216
217 _data.data = data->data;
218 _data.size = data->size;
219
220 /* If the PKCS7 is in PEM format then decode it
221 */
222 if (format == GNUTLS_X509_FMT_PEM)
223 {
224 opaque *out;
225
226 result = _gnutls_fbase64_decode (PEM_PKCS7, data->data, data->size,
227 &out);
228
229 if (result <= 0)
230 {
231 if (result == 0)
232 result = GNUTLS_E_INTERNAL_ERROR;
233 gnutls_assert ();
234 return result;
235 }
236
237 _data.data = out;
238 _data.size = result;
239
240 need_free = 1;
241 }
242
243
244 result = asn1_der_decoding (&pkcs7->pkcs7, _data.data, _data.size, NULL);
245 if (result != ASN1_SUCCESS)
246 {
247 result = _gnutls_asn2err (result);
248 gnutls_assert ();
249 goto cleanup;
250 }
251
252 if (need_free)
253 _gnutls_free_datum (&_data);
254
255 return 0;
256
257cleanup:
258 if (need_free)
259 _gnutls_free_datum (&_data);
260 return result;
261}
262
263/**
264 * gnutls_pkcs7_get_crt_raw - This function returns a certificate in a PKCS7 certificate set
265 * @pkcs7_struct: should contain a gnutls_pkcs7_t structure
266 * @indx: contains the index of the certificate to extract
267 * @certificate: the contents of the certificate will be copied there (may be null)
268 * @certificate_size: should hold the size of the certificate
269 *
270 * This function will return a certificate of the PKCS7 or RFC2630 certificate set.
271 * Returns 0 on success. If the provided buffer is not long enough,
272 * then @certificate_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER is returned.
273 *
274 * After the last certificate has been read GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
275 * will be returned.
276 *
277 **/
278int
279gnutls_pkcs7_get_crt_raw (gnutls_pkcs7_t pkcs7,
280 int indx, void *certificate,
281 size_t * certificate_size)
282{
283 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
284 int result, len;
285 char root2[MAX_NAME_SIZE];
286 char oid[128];
287 gnutls_datum_t tmp = { NULL, 0 };
288
289 if (certificate_size == NULL || pkcs7 == NULL)
290 return GNUTLS_E_INVALID_REQUEST;
291
292 /* Step 1. decode the signed data.
293 */
294 result = _decode_pkcs7_signed_data (pkcs7->pkcs7, &c2, &tmp);
295 if (result < 0)
296 {
297 gnutls_assert ();
298 return result;
299 }
300
301 /* Step 2. Parse the CertificateSet
302 */
303
304 snprintf (root2, sizeof (root2), "certificates.?%u", indx + 1);
305
306 len = sizeof (oid) - 1;
307
308 result = asn1_read_value (c2, root2, oid, &len);
309
310 if (result == ASN1_VALUE_NOT_FOUND)
311 {
312 result = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
313 goto cleanup;
314 }
315
316 if (result != ASN1_SUCCESS)
317 {
318 gnutls_assert ();
319 result = _gnutls_asn2err (result);
320 goto cleanup;
321 }
322
323 /* if 'Certificate' is the choice found:
324 */
325 if (strcmp (oid, "certificate") == 0)
326 {
327 int start, end;
328
329 result = asn1_der_decoding_startEnd (c2, tmp.data, tmp.size,
330 root2, &start, &end);
331
332 if (result != ASN1_SUCCESS)
333 {
334 gnutls_assert ();
335 result = _gnutls_asn2err (result);
336 goto cleanup;
337 }
338
339 end = end - start + 1;
340
341 if ((unsigned) end > *certificate_size)
342 {
343 *certificate_size = end;
344 result = GNUTLS_E_SHORT_MEMORY_BUFFER;
345 goto cleanup;
346 }
347
348 if (certificate)
349 memcpy (certificate, &tmp.data[start], end);
350
351 *certificate_size = end;
352
353 result = 0;
354
355 }
356 else
357 {
358 result = GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
359 }
360
361cleanup:
362 _gnutls_free_datum (&tmp);
363 if (c2)
364 asn1_delete_structure (&c2);
365 return result;
366}
367
368/**
369 * gnutls_pkcs7_get_crt_count - This function returns the number of certificates in a PKCS7 certificate set
370 * @pkcs7_struct: should contain a gnutls_pkcs7_t structure
371 *
372 * This function will return the number of certifcates in the PKCS7 or
373 * RFC2630 certificate set.
374 *
375 * Returns a negative value on failure.
376 *
377 **/
378int
379gnutls_pkcs7_get_crt_count (gnutls_pkcs7_t pkcs7)
380{
381 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
382 int result, count;
383
384 if (pkcs7 == NULL)
385 return GNUTLS_E_INVALID_REQUEST;
386
387 /* Step 1. decode the signed data.
388 */
389 result = _decode_pkcs7_signed_data (pkcs7->pkcs7, &c2, NULL);
390 if (result < 0)
391 {
392 gnutls_assert ();
393 return result;
394 }
395
396 /* Step 2. Count the CertificateSet */
397
398 result = asn1_number_of_elements (c2, "certificates", &count);
399
400 asn1_delete_structure (&c2);
401
402 if (result != ASN1_SUCCESS)
403 {
404 gnutls_assert ();
405 return 0; /* no certificates */
406 }
407
408 return count;
409
410}
411
412/**
413 * gnutls_pkcs7_export - This function will export the pkcs7 structure
414 * @pkcs7: Holds the pkcs7 structure
415 * @format: the format of output params. One of PEM or DER.
416 * @output_data: will contain a structure PEM or DER encoded
417 * @output_data_size: holds the size of output_data (and will be
418 * replaced by the actual size of parameters)
419 *
420 * This function will export the pkcs7 structure to DER or PEM format.
421 *
422 * If the buffer provided is not long enough to hold the output, then
423 * *output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
424 * be returned.
425 *
426 * If the structure is PEM encoded, it will have a header
427 * of "BEGIN PKCS7".
428 *
429 * Return value: In case of failure a negative value will be
430 * returned, and 0 on success.
431 *
432 **/
433int
434gnutls_pkcs7_export (gnutls_pkcs7_t pkcs7,
435 gnutls_x509_crt_fmt_t format, void *output_data,
436 size_t * output_data_size)
437{
438 if (pkcs7 == NULL)
439 return GNUTLS_E_INVALID_REQUEST;
440
441 return _gnutls_x509_export_int (pkcs7->pkcs7, format, PEM_PKCS7,
442 output_data, output_data_size);
443}
444
445/* Creates an empty signed data structure in the pkcs7
446 * structure and returns a handle to the signed data.
447 */
448static int
449create_empty_signed_data (ASN1_TYPE pkcs7, ASN1_TYPE * sdata)
450{
451 uint8_t one = 1;
452 int result;
453
454 *sdata = ASN1_TYPE_EMPTY;
455
456 if ((result = asn1_create_element
457 (_gnutls_get_pkix (), "PKIX1.pkcs-7-SignedData",
458 sdata)) != ASN1_SUCCESS)
459 {
460 gnutls_assert ();
461 result = _gnutls_asn2err (result);
462 goto cleanup;
463 }
464
465 /* Use version 1
466 */
467 result = asn1_write_value (*sdata, "version", &one, 1);
468 if (result != ASN1_SUCCESS)
469 {
470 gnutls_assert ();
471 result = _gnutls_asn2err (result);
472 goto cleanup;
473 }
474
475 /* Use no digest algorithms
476 */
477
478 /* id-data */
479 result =
480 asn1_write_value (*sdata, "encapContentInfo.eContentType",
481 "1.2.840.113549.1.7.5", 1);
482 if (result != ASN1_SUCCESS)
483 {
484 gnutls_assert ();
485 result = _gnutls_asn2err (result);
486 goto cleanup;
487 }
488
489 result = asn1_write_value (*sdata, "encapContentInfo.eContent", NULL, 0);
490 if (result != ASN1_SUCCESS)
491 {
492 gnutls_assert ();
493 result = _gnutls_asn2err (result);
494 goto cleanup;
495 }
496
497 /* Add no certificates.
498 */
499
500 /* Add no crls.
501 */
502
503 /* Add no signerInfos.
504 */
505
506 /* Write the content type of the signed data
507 */
508 result = asn1_write_value (pkcs7, "contentType", SIGNED_DATA_OID, 1);
509 if (result != ASN1_SUCCESS)
510 {
511 gnutls_assert ();
512 result = _gnutls_asn2err (result);
513 goto cleanup;
514 }
515
516 return 0;
517
518cleanup:
519 asn1_delete_structure (sdata);
520 return result;
521
522}
523
524/**
525 * gnutls_pkcs7_set_crt_raw - This function adds a certificate in a PKCS7 certificate set
526 * @pkcs7_struct: should contain a gnutls_pkcs7_t structure
527 * @crt: the DER encoded certificate to be added
528 *
529 * This function will add a certificate to the PKCS7 or RFC2630 certificate set.
530 * Returns 0 on success.
531 *
532 **/
533int
534gnutls_pkcs7_set_crt_raw (gnutls_pkcs7_t pkcs7, const gnutls_datum_t * crt)
535{
536 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
537 int result;
538
539 if (pkcs7 == NULL)
540 return GNUTLS_E_INVALID_REQUEST;
541
542 /* Step 1. decode the signed data.
543 */
544 result = _decode_pkcs7_signed_data (pkcs7->pkcs7, &c2, NULL);
545 if (result < 0 && result != GNUTLS_E_ASN1_VALUE_NOT_FOUND)
546 {
547 gnutls_assert ();
548 return result;
549 }
550
551 /* If the signed data are uninitialized
552 * then create them.
553 */
554 if (result == GNUTLS_E_ASN1_VALUE_NOT_FOUND)
555 {
556 /* The pkcs7 structure is new, so create the
557 * signedData.
558 */
559 result = create_empty_signed_data (pkcs7->pkcs7, &c2);
560 if (result < 0)
561 {
562 gnutls_assert ();
563 return result;
564 }
565 }
566
567 /* Step 2. Append the new certificate.
568 */
569
570 result = asn1_write_value (c2, "certificates", "NEW", 1);
571 if (result != ASN1_SUCCESS)
572 {
573 gnutls_assert ();
574 result = _gnutls_asn2err (result);
575 goto cleanup;
576 }
577
578 result = asn1_write_value (c2, "certificates.?LAST", "certificate", 1);
579 if (result != ASN1_SUCCESS)
580 {
581 gnutls_assert ();
582 result = _gnutls_asn2err (result);
583 goto cleanup;
584 }
585
586 result =
587 asn1_write_value (c2, "certificates.?LAST.certificate", crt->data,
588 crt->size);
589 if (result != ASN1_SUCCESS)
590 {
591 gnutls_assert ();
592 result = _gnutls_asn2err (result);
593 goto cleanup;
594 }
595
596 /* Step 3. Replace the old content with the new
597 */
598 result =
599 _gnutls_x509_der_encode_and_copy (c2, "", pkcs7->pkcs7, "content", 0);
600 if (result < 0)
601 {
602 gnutls_assert ();
603 goto cleanup;
604 }
605
606 asn1_delete_structure (&c2);
607
608 return 0;
609
610cleanup:
611 if (c2)
612 asn1_delete_structure (&c2);
613 return result;
614}
615
616/**
617 * gnutls_pkcs7_set_crt - This function adds a parsed certificate in a PKCS7 certificate set
618 * @pkcs7_struct: should contain a gnutls_pkcs7_t structure
619 * @crt: the certificate to be copied.
620 *
621 * This function will add a parsed certificate to the PKCS7 or RFC2630 certificate set.
622 * This is a wrapper function over gnutls_pkcs7_set_crt_raw() .
623 *
624 * Returns 0 on success.
625 *
626 **/
627int
628gnutls_pkcs7_set_crt (gnutls_pkcs7_t pkcs7, gnutls_x509_crt_t crt)
629{
630 int ret;
631 gnutls_datum_t data;
632
633 if (pkcs7 == NULL)
634 return GNUTLS_E_INVALID_REQUEST;
635
636 ret = _gnutls_x509_der_encode (crt->cert, "", &data, 0);
637 if (ret < 0)
638 {
639 gnutls_assert ();
640 return ret;
641 }
642
643 ret = gnutls_pkcs7_set_crt_raw (pkcs7, &data);
644
645 _gnutls_free_datum (&data);
646
647 if (ret < 0)
648 {
649 gnutls_assert ();
650 return ret;
651 }
652
653 return 0;
654}
655
656
657/**
658 * gnutls_pkcs7_delete_crt - This function deletes a certificate from a PKCS7 certificate set
659 * @pkcs7_struct: should contain a gnutls_pkcs7_t structure
660 * @indx: the index of the certificate to delete
661 *
662 * This function will delete a certificate from a PKCS7 or RFC2630 certificate set.
663 * Index starts from 0. Returns 0 on success.
664 *
665 **/
666int
667gnutls_pkcs7_delete_crt (gnutls_pkcs7_t pkcs7, int indx)
668{
669 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
670 int result;
671 char root2[MAX_NAME_SIZE];
672
673 if (pkcs7 == NULL)
674 return GNUTLS_E_INVALID_REQUEST;
675
676 /* Step 1. Decode the signed data.
677 */
678 result = _decode_pkcs7_signed_data (pkcs7->pkcs7, &c2, NULL);
679 if (result < 0)
680 {
681 gnutls_assert ();
682 return result;
683 }
684
685 /* Step 2. Delete the certificate.
686 */
687
688 snprintf (root2, sizeof (root2), "certificates.?%u", indx + 1);
689
690 result = asn1_write_value (c2, root2, NULL, 0);
691 if (result != ASN1_SUCCESS)
692 {
693 gnutls_assert ();
694 result = _gnutls_asn2err (result);
695 goto cleanup;
696 }
697
698 /* Step 3. Replace the old content with the new
699 */
700 result =
701 _gnutls_x509_der_encode_and_copy (c2, "", pkcs7->pkcs7, "content", 0);
702 if (result < 0)
703 {
704 gnutls_assert ();
705 goto cleanup;
706 }
707
708 asn1_delete_structure (&c2);
709
710 return 0;
711
712cleanup:
713 if (c2)
714 asn1_delete_structure (&c2);
715 return result;
716}
717
718/* Read and write CRLs
719 */
720
721/**
722 * gnutls_pkcs7_get_crl_raw - This function returns a crl in a PKCS7 crl set
723 * @pkcs7_struct: should contain a gnutls_pkcs7_t structure
724 * @indx: contains the index of the crl to extract
725 * @crl: the contents of the crl will be copied there (may be null)
726 * @crl_size: should hold the size of the crl
727 *
728 * This function will return a crl of the PKCS7 or RFC2630 crl set.
729 * Returns 0 on success. If the provided buffer is not long enough,
730 * then @crl_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER is returned.
731 *
732 * After the last crl has been read GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
733 * will be returned.
734 *
735 **/
736int
737gnutls_pkcs7_get_crl_raw (gnutls_pkcs7_t pkcs7,
738 int indx, void *crl, size_t * crl_size)
739{
740 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
741 int result;
742 char root2[MAX_NAME_SIZE];
743 gnutls_datum_t tmp = { NULL, 0 };
744 int start, end;
745
746 if (pkcs7 == NULL || crl_size == NULL)
747 return GNUTLS_E_INVALID_REQUEST;
748
749 /* Step 1. decode the signed data.
750 */
751 result = _decode_pkcs7_signed_data (pkcs7->pkcs7, &c2, &tmp);
752 if (result < 0)
753 {
754 gnutls_assert ();
755 return result;
756 }
757
758 /* Step 2. Parse the CertificateSet
759 */
760
761 snprintf (root2, sizeof (root2), "crls.?%u", indx + 1);
762
763 /* Get the raw CRL
764 */
765 result = asn1_der_decoding_startEnd (c2, tmp.data, tmp.size,
766 root2, &start, &end);
767
768 if (result != ASN1_SUCCESS)
769 {
770 gnutls_assert ();
771 result = _gnutls_asn2err (result);
772 goto cleanup;
773 }
774
775 end = end - start + 1;
776
777 if ((unsigned) end > *crl_size)
778 {
779 *crl_size = end;
780 result = GNUTLS_E_SHORT_MEMORY_BUFFER;
781 goto cleanup;
782 }
783
784 if (crl)
785 memcpy (crl, &tmp.data[start], end);
786
787 *crl_size = end;
788
789 result = 0;
790
791cleanup:
792 _gnutls_free_datum (&tmp);
793 if (c2)
794 asn1_delete_structure (&c2);
795 return result;
796}
797
798/**
799 * gnutls_pkcs7_get_crl_count - This function returns the number of crls in a PKCS7 crl set
800 * @pkcs7_struct: should contain a gnutls_pkcs7_t structure
801 *
802 * This function will return the number of certifcates in the PKCS7 or
803 * RFC2630 crl set.
804 *
805 * Returns a negative value on failure.
806 *
807 **/
808int
809gnutls_pkcs7_get_crl_count (gnutls_pkcs7_t pkcs7)
810{
811 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
812 int result, count;
813
814 if (pkcs7 == NULL)
815 return GNUTLS_E_INVALID_REQUEST;
816
817 /* Step 1. decode the signed data.
818 */
819 result = _decode_pkcs7_signed_data (pkcs7->pkcs7, &c2, NULL);
820 if (result < 0)
821 {
822 gnutls_assert ();
823 return result;
824 }
825
826 /* Step 2. Count the CertificateSet */
827
828 result = asn1_number_of_elements (c2, "crls", &count);
829
830 asn1_delete_structure (&c2);
831
832 if (result != ASN1_SUCCESS)
833 {
834 gnutls_assert ();
835 return 0; /* no crls */
836 }
837
838 return count;
839
840}
841
842/**
843 * gnutls_pkcs7_set_crl_raw - This function adds a crl in a PKCS7 crl set
844 * @pkcs7_struct: should contain a gnutls_pkcs7_t structure
845 * @crl: the DER encoded crl to be added
846 *
847 * This function will add a crl to the PKCS7 or RFC2630 crl set.
848 * Returns 0 on success.
849 *
850 **/
851int
852gnutls_pkcs7_set_crl_raw (gnutls_pkcs7_t pkcs7, const gnutls_datum_t * crl)
853{
854 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
855 int result;
856
857 if (pkcs7 == NULL)
858 return GNUTLS_E_INVALID_REQUEST;
859
860 /* Step 1. decode the signed data.
861 */
862 result = _decode_pkcs7_signed_data (pkcs7->pkcs7, &c2, NULL);
863 if (result < 0 && result != GNUTLS_E_ASN1_VALUE_NOT_FOUND)
864 {
865 gnutls_assert ();
866 return result;
867 }
868
869 /* If the signed data are uninitialized
870 * then create them.
871 */
872 if (result == GNUTLS_E_ASN1_VALUE_NOT_FOUND)
873 {
874 /* The pkcs7 structure is new, so create the
875 * signedData.
876 */
877 result = create_empty_signed_data (pkcs7->pkcs7, &c2);
878 if (result < 0)
879 {
880 gnutls_assert ();
881 return result;
882 }
883 }
884
885 /* Step 2. Append the new crl.
886 */
887
888 result = asn1_write_value (c2, "crls", "NEW", 1);
889 if (result != ASN1_SUCCESS)
890 {
891 gnutls_assert ();
892 result = _gnutls_asn2err (result);
893 goto cleanup;
894 }
895
896 result = asn1_write_value (c2, "crls.?LAST", crl->data, crl->size);
897 if (result != ASN1_SUCCESS)
898 {
899 gnutls_assert ();
900 result = _gnutls_asn2err (result);
901 goto cleanup;
902 }
903
904 /* Step 3. Replace the old content with the new
905 */
906 result =
907 _gnutls_x509_der_encode_and_copy (c2, "", pkcs7->pkcs7, "content", 0);
908 if (result < 0)
909 {
910 gnutls_assert ();
911 goto cleanup;
912 }
913
914 asn1_delete_structure (&c2);
915
916 return 0;
917
918cleanup:
919 if (c2)
920 asn1_delete_structure (&c2);
921 return result;
922}
923
924/**
925 * gnutls_pkcs7_set_crl - This function adds a parsed crl in a PKCS7 crl set
926 * @pkcs7_struct: should contain a gnutls_pkcs7_t structure
927 * @crl: the DER encoded crl to be added
928 *
929 * This function will add a parsed crl to the PKCS7 or RFC2630 crl set.
930 * Returns 0 on success.
931 *
932 **/
933int
934gnutls_pkcs7_set_crl (gnutls_pkcs7_t pkcs7, gnutls_x509_crl_t crl)
935{
936 int ret;
937 gnutls_datum_t data;
938
939 if (pkcs7 == NULL)
940 return GNUTLS_E_INVALID_REQUEST;
941
942 ret = _gnutls_x509_der_encode (crl->crl, "", &data, 0);
943 if (ret < 0)
944 {
945 gnutls_assert ();
946 return ret;
947 }
948
949 ret = gnutls_pkcs7_set_crl_raw (pkcs7, &data);
950
951 _gnutls_free_datum (&data);
952
953 if (ret < 0)
954 {
955 gnutls_assert ();
956 return ret;
957 }
958
959 return 0;
960}
961
962/**
963 * gnutls_pkcs7_delete_crl - This function deletes a crl from a PKCS7 crl set
964 * @pkcs7_struct: should contain a gnutls_pkcs7_t structure
965 * @indx: the index of the crl to delete
966 *
967 * This function will delete a crl from a PKCS7 or RFC2630 crl set.
968 * Index starts from 0. Returns 0 on success.
969 *
970 **/
971int
972gnutls_pkcs7_delete_crl (gnutls_pkcs7_t pkcs7, int indx)
973{
974 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
975 int result;
976 char root2[MAX_NAME_SIZE];
977
978 if (pkcs7 == NULL)
979 return GNUTLS_E_INVALID_REQUEST;
980
981 /* Step 1. Decode the signed data.
982 */
983 result = _decode_pkcs7_signed_data (pkcs7->pkcs7, &c2, NULL);
984 if (result < 0)
985 {
986 gnutls_assert ();
987 return result;
988 }
989
990 /* Step 2. Delete the crl.
991 */
992
993 snprintf (root2, sizeof (root2), "crls.?%u", indx + 1);
994
995 result = asn1_write_value (c2, root2, NULL, 0);
996 if (result != ASN1_SUCCESS)
997 {
998 gnutls_assert ();
999 result = _gnutls_asn2err (result);
1000 goto cleanup;
1001 }
1002
1003 /* Step 3. Replace the old content with the new
1004 */
1005 result =
1006 _gnutls_x509_der_encode_and_copy (c2, "", pkcs7->pkcs7, "content", 0);
1007 if (result < 0)
1008 {
1009 gnutls_assert ();
1010 goto cleanup;
1011 }
1012
1013 asn1_delete_structure (&c2);
1014
1015 return 0;
1016
1017cleanup:
1018 if (c2)
1019 asn1_delete_structure (&c2);
1020 return result;
1021}
1022
1023#endif /* ENABLE_PKI */
diff --git a/src/daemon/https/x509/pkcs7.h b/src/daemon/https/x509/pkcs7.h
new file mode 100644
index 00000000..ee1990c3
--- /dev/null
+++ b/src/daemon/https/x509/pkcs7.h
@@ -0,0 +1,30 @@
1/*
2 * Copyright (C) 2003, 2004, 2005 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 "x509.h"
26
27typedef struct gnutls_pkcs7_int
28{
29 ASN1_TYPE pkcs7;
30} gnutls_pkcs7_int;
diff --git a/src/daemon/https/x509/privkey.h b/src/daemon/https/x509/privkey.h
new file mode 100644
index 00000000..6e645b9d
--- /dev/null
+++ b/src/daemon/https/x509/privkey.h
@@ -0,0 +1,31 @@
1/*
2 * Copyright (C) 2003, 2004, 2005 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 "x509.h"
26
27ASN1_TYPE _gnutls_privkey_decode_pkcs1_rsa_key (const gnutls_datum_t *
28 raw_key,
29 gnutls_x509_privkey_t pkey);
30
31int _gnutls_asn1_encode_dsa (ASN1_TYPE * c2, mpi_t * params);
diff --git a/src/daemon/https/x509/privkey_pkcs8.c b/src/daemon/https/x509/privkey_pkcs8.c
new file mode 100644
index 00000000..2f1921bb
--- /dev/null
+++ b/src/daemon/https/x509/privkey_pkcs8.c
@@ -0,0 +1,2219 @@
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
27#ifdef ENABLE_PKI
28
29#include <gnutls_datum.h>
30#include <gnutls_global.h>
31#include <gnutls_errors.h>
32#include <gnutls_rsa_export.h>
33#include <common.h>
34#include <gnutls_x509.h>
35#include <x509_b64.h>
36#include <x509.h>
37#include <dn.h>
38#include <pkcs12.h>
39#include <privkey.h>
40#include <extensions.h>
41#include <mpi.h>
42#include <gnutls_algorithms.h>
43#include <gnutls_num.h>
44#include "gc.h"
45
46#define PBES2_OID "1.2.840.113549.1.5.13"
47#define PBKDF2_OID "1.2.840.113549.1.5.12"
48#define DES_EDE3_CBC_OID "1.2.840.113549.3.7"
49#define DES_CBC_OID "1.3.14.3.2.7"
50
51/* oid_pbeWithSHAAnd3_KeyTripleDES_CBC */
52#define PKCS12_PBE_3DES_SHA1_OID "1.2.840.113549.1.12.1.3"
53#define PKCS12_PBE_ARCFOUR_SHA1_OID "1.2.840.113549.1.12.1.1"
54#define PKCS12_PBE_RC2_40_SHA1_OID "1.2.840.113549.1.12.1.6"
55
56struct pbkdf2_params
57 {
58 opaque salt[32];
59 int salt_size;
60 unsigned int iter_count;
61 unsigned int key_size;
62 };
63
64struct pbe_enc_params
65 {
66 gnutls_cipher_algorithm_t cipher;
67 opaque iv[8];
68 int iv_size;
69 };
70
71static int generate_key (schema_id schema, const char *password,
72 struct pbkdf2_params *kdf_params,
73 struct pbe_enc_params *enc_params,
74 gnutls_datum_t * key);
75static int read_pbkdf2_params (ASN1_TYPE pbes2_asn,
76 const gnutls_datum_t * der,
77 struct pbkdf2_params *params);
78static int read_pbe_enc_params (ASN1_TYPE pbes2_asn,
79 const gnutls_datum_t * der,
80 struct pbe_enc_params *params);
81static int decrypt_data (schema_id, ASN1_TYPE pkcs8_asn, const char *root,
82 const char *password,
83 const struct pbkdf2_params *kdf_params,
84 const struct pbe_enc_params *enc_params,
85 gnutls_datum_t * decrypted_data);
86static int decode_private_key_info (const gnutls_datum_t * der,
87 gnutls_x509_privkey_t pkey);
88static int write_schema_params (schema_id schema, ASN1_TYPE pkcs8_asn,
89 const char *where,
90 const struct pbkdf2_params *kdf_params,
91 const struct pbe_enc_params *enc_params);
92static int encrypt_data (const gnutls_datum_t * plain,
93 const struct pbe_enc_params *enc_params,
94 gnutls_datum_t * key, gnutls_datum_t * encrypted);
95
96static int read_pkcs12_kdf_params (ASN1_TYPE pbes2_asn,
97 struct pbkdf2_params *params);
98static int write_pkcs12_kdf_params (ASN1_TYPE pbes2_asn,
99 const struct pbkdf2_params *params);
100
101#define PEM_PKCS8 "ENCRYPTED PRIVATE KEY"
102#define PEM_UNENCRYPTED_PKCS8 "PRIVATE KEY"
103
104/* Returns a negative error code if the encryption schema in
105 * the OID is not supported. The schema ID is returned.
106 */
107inline static int
108check_schema (const char *oid)
109 {
110
111 if (strcmp (oid, PBES2_OID) == 0)
112 return PBES2;
113
114 if (strcmp (oid, PKCS12_PBE_3DES_SHA1_OID) == 0)
115 return PKCS12_3DES_SHA1;
116
117 if (strcmp (oid, PKCS12_PBE_ARCFOUR_SHA1_OID) == 0)
118 return PKCS12_ARCFOUR_SHA1;
119
120 if (strcmp (oid, PKCS12_PBE_RC2_40_SHA1_OID) == 0)
121 return PKCS12_RC2_40_SHA1;
122
123 _gnutls_x509_log ("PKCS encryption schema OID '%s' is unsupported.\n", oid);
124
125 return GNUTLS_E_UNKNOWN_CIPHER_TYPE;
126 }
127
128/* Encodes a private key to the raw format PKCS #8 needs.
129 * For RSA it is a PKCS #1 DER private key and for DSA it is
130 * an ASN.1 INTEGER of the x value.
131 */
132inline static int
133_encode_privkey (gnutls_x509_privkey pkey, gnutls_datum * raw)
134 {
135 size_t size = 0;
136 opaque *data = NULL;
137 int ret;
138 ASN1_TYPE spk = ASN1_TYPE_EMPTY;
139
140 switch (pkey->pk_algorithm)
141 {
142 case GNUTLS_PK_RSA:
143 ret =
144 gnutls_x509_privkey_export (pkey, GNUTLS_X509_FMT_DER, NULL, &size);
145 if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
146 {
147 gnutls_assert ();
148 goto error;
149 }
150
151 data = gnutls_malloc (size);
152 if (data == NULL)
153 {
154 gnutls_assert ();
155 ret = GNUTLS_E_MEMORY_ERROR;
156 goto error;
157 }
158
159 ret =
160 gnutls_x509_privkey_export (pkey, GNUTLS_X509_FMT_DER, data, &size);
161 if (ret < 0)
162 {
163 gnutls_assert ();
164 goto error;
165 }
166
167 raw->data = data;
168 raw->size = size;
169 break;
170 default:
171 gnutls_assert ();
172 return GNUTLS_E_INVALID_REQUEST;
173 }
174
175 return 0;
176
177 error:
178 gnutls_free (data);
179 asn1_delete_structure (&spk);
180 return ret;
181
182 }
183
184/*
185 * Encodes a PKCS #1 private key to a PKCS #8 private key
186 * info. The output will be allocated and stored into der. Also
187 * the ASN1_TYPE of private key info will be returned.
188 */
189static int
190encode_to_private_key_info (gnutls_x509_privkey_t pkey,
191 gnutls_datum_t * der, ASN1_TYPE * pkey_info)
192 {
193 int result, len;
194 opaque null = 0;
195 const char *oid;
196 gnutls_datum algo_params =
197 { NULL, 0};
198 gnutls_datum algo_privkey =
199 { NULL, 0};
200
201 if (pkey->pk_algorithm == GNUTLS_PK_RSA)
202 {
203 oid = PK_PKIX1_RSA_OID;
204 /* parameters are null
205 */
206 }
207 else
208 {
209 oid = PK_DSA_OID;
210 result =
211 _gnutls_x509_write_dsa_params (pkey->params, pkey->params_size,
212 &algo_params);
213 if (result < 0)
214 {
215 gnutls_assert ();
216 return result;
217 }
218 }
219
220 if ((result =
221 asn1_create_element (_gnutls_get_pkix (),
222 "PKIX1.pkcs-8-PrivateKeyInfo",
223 pkey_info)) != ASN1_SUCCESS)
224 {
225 gnutls_assert ();
226 result = _gnutls_asn2err (result);
227 goto error;
228 }
229
230 /* Write the version.
231 */
232 result = asn1_write_value (*pkey_info, "version", &null, 1);
233 if (result != ASN1_SUCCESS)
234 {
235 gnutls_assert ();
236 result = _gnutls_asn2err (result);
237 goto error;
238 }
239
240 /* write the privateKeyAlgorithm
241 * fields. (OID+NULL data)
242 */
243 result =
244 asn1_write_value (*pkey_info, "privateKeyAlgorithm.algorithm", oid, 1);
245 if (result != ASN1_SUCCESS)
246 {
247 gnutls_assert ();
248 result = _gnutls_asn2err (result);
249 goto error;
250 }
251
252 result =
253 asn1_write_value (*pkey_info, "privateKeyAlgorithm.parameters",
254 algo_params.data, algo_params.size);
255 _gnutls_free_datum (&algo_params);
256 if (result != ASN1_SUCCESS)
257 {
258 gnutls_assert ();
259 result = _gnutls_asn2err (result);
260 goto error;
261 }
262
263 /* Write the raw private key
264 */
265 result = _encode_privkey (pkey, &algo_privkey);
266 if (result < 0)
267 {
268 gnutls_assert ();
269 goto error;
270 }
271
272 result =
273 asn1_write_value (*pkey_info, "privateKey", algo_privkey.data,
274 algo_privkey.size);
275 _gnutls_free_datum (&algo_privkey);
276
277 if (result != ASN1_SUCCESS)
278 {
279 gnutls_assert ();
280 result = _gnutls_asn2err (result);
281 goto error;
282 }
283
284 /* Append an empty Attributes field.
285 */
286 result = asn1_write_value (*pkey_info, "attributes", NULL, 0);
287 if (result != ASN1_SUCCESS)
288 {
289 gnutls_assert ();
290 result = _gnutls_asn2err (result);
291 goto error;
292 }
293
294 /* DER Encode the generated private key info.
295 */
296 len = 0;
297 result = asn1_der_coding (*pkey_info, "", NULL, &len, NULL);
298 if (result != ASN1_MEM_ERROR)
299 {
300 gnutls_assert ();
301 result = _gnutls_asn2err (result);
302 goto error;
303 }
304
305 /* allocate data for the der
306 */
307 der->size = len;
308 der->data = gnutls_malloc (len);
309 if (der->data == NULL)
310 {
311 gnutls_assert ();
312 return GNUTLS_E_MEMORY_ERROR;
313 }
314
315 result = asn1_der_coding (*pkey_info, "", der->data, &len, NULL);
316 if (result != ASN1_SUCCESS)
317 {
318 gnutls_assert ();
319 result = _gnutls_asn2err (result);
320 goto error;
321 }
322
323 return 0;
324
325 error:
326 asn1_delete_structure (pkey_info);
327 _gnutls_free_datum (&algo_params);
328 _gnutls_free_datum (&algo_privkey);
329 return result;
330
331 }
332
333/* Converts a PKCS #8 private key info to
334 * a PKCS #8 EncryptedPrivateKeyInfo.
335 */
336static int
337encode_to_pkcs8_key (schema_id schema, const gnutls_datum_t * der_key,
338 const char *password, ASN1_TYPE * out)
339 {
340 int result;
341 gnutls_datum_t key =
342 { NULL, 0};
343 gnutls_datum_t tmp =
344 { NULL, 0};
345 ASN1_TYPE pkcs8_asn = ASN1_TYPE_EMPTY;
346 struct pbkdf2_params kdf_params;
347 struct pbe_enc_params enc_params;
348
349 if ((result =
350 asn1_create_element (_gnutls_get_pkix (),
351 "PKIX1.pkcs-8-EncryptedPrivateKeyInfo",
352 &pkcs8_asn)) != ASN1_SUCCESS)
353 {
354 gnutls_assert ();
355 result = _gnutls_asn2err (result);
356 goto error;
357 }
358
359 /* Write the encryption schema OID
360 */
361 switch (schema)
362 {
363 case PBES2:
364 result =
365 asn1_write_value (pkcs8_asn, "encryptionAlgorithm.algorithm",
366 PBES2_OID, 1);
367 break;
368 case PKCS12_3DES_SHA1:
369 result =
370 asn1_write_value (pkcs8_asn, "encryptionAlgorithm.algorithm",
371 PKCS12_PBE_3DES_SHA1_OID, 1);
372 break;
373 case PKCS12_ARCFOUR_SHA1:
374 result =
375 asn1_write_value (pkcs8_asn, "encryptionAlgorithm.algorithm",
376 PKCS12_PBE_ARCFOUR_SHA1_OID, 1);
377 break;
378 case PKCS12_RC2_40_SHA1:
379 result =
380 asn1_write_value (pkcs8_asn, "encryptionAlgorithm.algorithm",
381 PKCS12_PBE_RC2_40_SHA1_OID, 1);
382 break;
383
384 }
385
386 if (result != ASN1_SUCCESS)
387 {
388 gnutls_assert ();
389 result = _gnutls_asn2err (result);
390 goto error;
391 }
392
393 /* Generate a symmetric key.
394 */
395
396 result = generate_key (schema, password, &kdf_params, &enc_params, &key);
397 if (result < 0)
398 {
399 gnutls_assert ();
400 goto error;
401 }
402
403 result =
404 write_schema_params (schema, pkcs8_asn,
405 "encryptionAlgorithm.parameters", &kdf_params,
406 &enc_params);
407 if (result < 0)
408 {
409 gnutls_assert ();
410 goto error;
411 }
412
413 /* Parameters have been encoded. Now
414 * encrypt the Data.
415 */
416 result = encrypt_data (der_key, &enc_params, &key, &tmp);
417 if (result < 0)
418 {
419 gnutls_assert ();
420 goto error;
421 }
422
423 /* write the encrypted data.
424 */
425 result = asn1_write_value (pkcs8_asn, "encryptedData", tmp.data, tmp.size);
426 if (result != ASN1_SUCCESS)
427 {
428 gnutls_assert ();
429 result = _gnutls_asn2err (result);
430 goto error;
431 }
432
433 _gnutls_free_datum (&tmp);
434 _gnutls_free_datum (&key);
435
436 *out = pkcs8_asn;
437
438 return 0;
439
440 error:
441 _gnutls_free_datum (&key);
442 _gnutls_free_datum (&tmp);
443 asn1_delete_structure (&pkcs8_asn);
444 return result;
445 }
446
447/**
448 * gnutls_x509_privkey_export_pkcs8 - This function will export the private key to PKCS8 format
449 * @key: Holds the key
450 * @format: the format of output params. One of PEM or DER.
451 * @password: the password that will be used to encrypt the key.
452 * @flags: an ORed sequence of gnutls_pkcs_encrypt_flags_t
453 * @output_data: will contain a private key PEM or DER encoded
454 * @output_data_size: holds the size of output_data (and will be
455 * replaced by the actual size of parameters)
456 *
457 * This function will export the private key to a PKCS8 structure.
458 * Both RSA and DSA keys can be exported. For DSA keys we use
459 * PKCS #11 definitions. If the flags do not specify the encryption
460 * cipher, then the default 3DES (PBES2) will be used.
461 *
462 * The @password can be either ASCII or UTF-8 in the default PBES2
463 * encryption schemas, or ASCII for the PKCS12 schemas.
464 *
465 * If the buffer provided is not long enough to hold the output, then
466 * *output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
467 * be returned.
468 *
469 * If the structure is PEM encoded, it will have a header
470 * of "BEGIN ENCRYPTED PRIVATE KEY" or "BEGIN PRIVATE KEY" if
471 * encryption is not used.
472 *
473 * Return value: In case of failure a negative value will be
474 * returned, and 0 on success.
475 *
476 **/
477int
478gnutls_x509_privkey_export_pkcs8 (gnutls_x509_privkey_t key,
479 gnutls_x509_crt_fmt_t format,
480 const char *password,
481 unsigned int flags,
482 void *output_data,
483 size_t * output_data_size)
484 {
485 ASN1_TYPE pkcs8_asn, pkey_info;
486 int ret;
487 gnutls_datum_t tmp;
488 schema_id schema;
489
490 if (key == NULL)
491 {
492 gnutls_assert ();
493 return GNUTLS_E_INVALID_REQUEST;
494 }
495
496 /* Get the private key info
497 * tmp holds the DER encoding.
498 */
499 ret = encode_to_private_key_info (key, &tmp, &pkey_info);
500 if (ret < 0)
501 {
502 gnutls_assert ();
503 return ret;
504 }
505
506 if (flags & GNUTLS_PKCS_USE_PKCS12_3DES)
507 schema = PKCS12_3DES_SHA1;
508 else if (flags & GNUTLS_PKCS_USE_PKCS12_ARCFOUR)
509 schema = PKCS12_ARCFOUR_SHA1;
510 else if (flags & GNUTLS_PKCS_USE_PKCS12_RC2_40)
511 schema = PKCS12_RC2_40_SHA1;
512 else
513 schema = PBES2;
514
515 if ((flags & GNUTLS_PKCS_PLAIN) || password == NULL)
516 {
517 _gnutls_free_datum (&tmp);
518
519 ret =
520 _gnutls_x509_export_int (pkey_info, format,
521 PEM_UNENCRYPTED_PKCS8,
522 output_data, output_data_size);
523
524 asn1_delete_structure (&pkey_info);
525 }
526 else
527 {
528 asn1_delete_structure (&pkey_info); /* we don't need it */
529
530 ret = encode_to_pkcs8_key (schema, &tmp, password, &pkcs8_asn);
531 _gnutls_free_datum (&tmp);
532
533 if (ret < 0)
534 {
535 gnutls_assert ();
536 return ret;
537 }
538
539 ret =
540 _gnutls_x509_export_int (pkcs8_asn, format, PEM_PKCS8,
541 output_data, output_data_size);
542
543 asn1_delete_structure (&pkcs8_asn);
544 }
545
546 return ret;
547 }
548
549/* Read the parameters cipher, IV, salt etc using the given
550 * schema ID.
551 */
552static int
553read_pkcs_schema_params (schema_id schema, const char *password,
554 const opaque * data, int data_size,
555 struct pbkdf2_params *kdf_params,
556 struct pbe_enc_params *enc_params)
557 {
558 ASN1_TYPE pbes2_asn = ASN1_TYPE_EMPTY;
559 int result;
560 gnutls_datum_t tmp;
561
562 switch (schema)
563 {
564
565 case PBES2:
566
567 /* Now check the key derivation and the encryption
568 * functions.
569 */
570 if ((result =
571 asn1_create_element (_gnutls_get_pkix (),
572 "PKIX1.pkcs-5-PBES2-params",
573 &pbes2_asn)) != ASN1_SUCCESS)
574 {
575 gnutls_assert ();
576 result = _gnutls_asn2err (result);
577 goto error;
578 }
579
580 /* Decode the parameters.
581 */
582 result = asn1_der_decoding (&pbes2_asn, data, data_size, NULL);
583 if (result != ASN1_SUCCESS)
584 {
585 gnutls_assert ();
586 result = _gnutls_asn2err (result);
587 goto error;
588 }
589
590 tmp.data = (opaque *) data;
591 tmp.size = data_size;
592
593 result = read_pbkdf2_params (pbes2_asn, &tmp, kdf_params);
594 if (result < 0)
595 {
596 gnutls_assert ();
597 result = _gnutls_asn2err (result);
598 goto error;
599 }
600
601 result = read_pbe_enc_params (pbes2_asn, &tmp, enc_params);
602 if (result < 0)
603 {
604 gnutls_assert ();
605 result = _gnutls_asn2err (result);
606 goto error;
607 }
608
609 asn1_delete_structure (&pbes2_asn);
610 return 0;
611 break;
612
613 case PKCS12_3DES_SHA1:
614 case PKCS12_ARCFOUR_SHA1:
615 case PKCS12_RC2_40_SHA1:
616
617 if ((schema) == PKCS12_3DES_SHA1)
618 {
619 enc_params->cipher = GNUTLS_CIPHER_3DES_CBC;
620 enc_params->iv_size = 8;
621 }
622 else if ((schema) == PKCS12_ARCFOUR_SHA1)
623 {
624 enc_params->cipher = GNUTLS_CIPHER_ARCFOUR_128;
625 enc_params->iv_size = 0;
626 }
627 else if ((schema) == PKCS12_RC2_40_SHA1)
628 {
629 enc_params->cipher = GNUTLS_CIPHER_RC2_40_CBC;
630 enc_params->iv_size = 8;
631 }
632
633 if ((result =
634 asn1_create_element (_gnutls_get_pkix (),
635 "PKIX1.pkcs-12-PbeParams",
636 &pbes2_asn)) != ASN1_SUCCESS)
637 {
638 gnutls_assert ();
639 result = _gnutls_asn2err (result);
640 goto error;
641 }
642
643 /* Decode the parameters.
644 */
645 result = asn1_der_decoding (&pbes2_asn, data, data_size, NULL);
646 if (result != ASN1_SUCCESS)
647 {
648 gnutls_assert ();
649 result = _gnutls_asn2err (result);
650 goto error;
651 }
652
653 result = read_pkcs12_kdf_params (pbes2_asn, kdf_params);
654 if (result < 0)
655 {
656 gnutls_assert ();
657 goto error;
658 }
659
660 if (enc_params->iv_size)
661 {
662 result =
663 _pkcs12_string_to_key (2 /*IV*/, kdf_params->salt,
664 kdf_params->salt_size,
665 kdf_params->iter_count, password,
666 enc_params->iv_size, enc_params->iv);
667 if (result < 0)
668 {
669 gnutls_assert ();
670 goto error;
671 }
672
673 }
674
675 asn1_delete_structure (&pbes2_asn);
676
677 return 0;
678 break;
679
680 } /* switch */
681
682 return GNUTLS_E_UNKNOWN_CIPHER_TYPE;
683
684 error:
685 asn1_delete_structure (&pbes2_asn);
686 return result;
687 }
688
689/* Converts a PKCS #8 key to
690 * an internal structure (gnutls_private_key)
691 * (normally a PKCS #1 encoded RSA key)
692 */
693static int
694decode_pkcs8_key (const gnutls_datum_t * raw_key,
695 const char *password, gnutls_x509_privkey_t pkey)
696 {
697 int result, len;
698 char enc_oid[64];
699 gnutls_datum_t tmp;
700 ASN1_TYPE pbes2_asn = ASN1_TYPE_EMPTY, pkcs8_asn = ASN1_TYPE_EMPTY;
701 int params_start, params_end, params_len;
702 struct pbkdf2_params kdf_params;
703 struct pbe_enc_params enc_params;
704 schema_id schema;
705
706 if ((result =
707 asn1_create_element (_gnutls_get_pkix (),
708 "PKIX1.pkcs-8-EncryptedPrivateKeyInfo",
709 &pkcs8_asn)) != ASN1_SUCCESS)
710 {
711 gnutls_assert ();
712 result = _gnutls_asn2err (result);
713 goto error;
714 }
715
716 result = asn1_der_decoding (&pkcs8_asn, raw_key->data, raw_key->size, NULL);
717 if (result != ASN1_SUCCESS)
718 {
719 gnutls_assert ();
720 result = _gnutls_asn2err (result);
721 goto error;
722 }
723
724 /* Check the encryption schema OID
725 */
726 len = sizeof (enc_oid);
727 result =
728 asn1_read_value (pkcs8_asn, "encryptionAlgorithm.algorithm",
729 enc_oid, &len);
730 if (result != ASN1_SUCCESS)
731 {
732 gnutls_assert ();
733 goto error;
734 }
735
736 if ((result = check_schema (enc_oid)) < 0)
737 {
738 gnutls_assert ();
739 goto error;
740 }
741
742 schema = result;
743
744 /* Get the DER encoding of the parameters.
745 */
746 result =
747 asn1_der_decoding_startEnd (pkcs8_asn, raw_key->data,
748 raw_key->size,
749 "encryptionAlgorithm.parameters",
750 &params_start, &params_end);
751 if (result != ASN1_SUCCESS)
752 {
753 gnutls_assert ();
754 result = _gnutls_asn2err (result);
755 goto error;
756 }
757 params_len = params_end - params_start + 1;
758
759 result =
760 read_pkcs_schema_params (schema, password,
761 &raw_key->data[params_start],
762 params_len, &kdf_params, &enc_params);
763
764 /* Parameters have been decoded. Now
765 * decrypt the EncryptedData.
766 */
767 result =
768 decrypt_data (schema, pkcs8_asn, "encryptedData", password,
769 &kdf_params, &enc_params, &tmp);
770 if (result < 0)
771 {
772 gnutls_assert ();
773 goto error;
774 }
775
776 asn1_delete_structure (&pkcs8_asn);
777
778 result = decode_private_key_info (&tmp, pkey);
779 _gnutls_free_datum (&tmp);
780
781 if (result < 0)
782 {
783 /* We've gotten this far. In the real world it's almost certain
784 * that we're dealing with a good file, but wrong password.
785 * Sadly like 90% of random data is somehow valid DER for the
786 * a first small number of bytes, so no easy way to guarantee. */
787 if (result == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND ||
788 result == GNUTLS_E_ASN1_IDENTIFIER_NOT_FOUND ||
789 result == GNUTLS_E_ASN1_DER_ERROR ||
790 result == GNUTLS_E_ASN1_VALUE_NOT_FOUND ||
791 result == GNUTLS_E_ASN1_GENERIC_ERROR ||
792 result == GNUTLS_E_ASN1_VALUE_NOT_VALID ||
793 result == GNUTLS_E_ASN1_TAG_ERROR ||
794 result == GNUTLS_E_ASN1_TAG_IMPLICIT ||
795 result == GNUTLS_E_ASN1_TYPE_ANY_ERROR ||
796 result == GNUTLS_E_ASN1_SYNTAX_ERROR ||
797 result == GNUTLS_E_ASN1_DER_OVERFLOW)
798 {
799 result = GNUTLS_E_DECRYPTION_FAILED;
800 }
801
802 gnutls_assert ();
803 goto error;
804 }
805
806 return 0;
807
808 error:
809 asn1_delete_structure (&pbes2_asn);
810 asn1_delete_structure (&pkcs8_asn);
811 return result;
812 }
813
814/* Decodes an RSA privateKey from a PKCS8 structure.
815 */
816static int
817_decode_pkcs8_rsa_key (ASN1_TYPE pkcs8_asn, gnutls_x509_privkey pkey)
818 {
819 int ret;
820 gnutls_datum tmp;
821
822 ret = _gnutls_x509_read_value (pkcs8_asn, "privateKey", &tmp, 0);
823 if (ret < 0)
824 {
825 gnutls_assert ();
826 goto error;
827 }
828
829 pkey->key = _gnutls_privkey_decode_pkcs1_rsa_key (&tmp, pkey);
830 _gnutls_free_datum (&tmp);
831 if (pkey->key == NULL)
832 {
833 gnutls_assert ();
834 goto error;
835 }
836
837 return 0;
838
839 error:
840 gnutls_x509_privkey_deinit (pkey);
841 return ret;
842 }
843
844/* Decodes an DSA privateKey and params from a PKCS8 structure.
845 */
846static int
847_decode_pkcs8_dsa_key (ASN1_TYPE pkcs8_asn, gnutls_x509_privkey pkey)
848 {
849 int ret;
850 gnutls_datum tmp;
851
852 ret = _gnutls_x509_read_value (pkcs8_asn, "privateKey", &tmp, 0);
853 if (ret < 0)
854 {
855 gnutls_assert ();
856 goto error;
857 }
858
859 ret = _gnutls_x509_read_der_int (tmp.data, tmp.size, &pkey->params[4]);
860 _gnutls_free_datum (&tmp);
861
862 if (ret < 0)
863 {
864 gnutls_assert ();
865 goto error;
866 }
867
868 ret =
869 _gnutls_x509_read_value (pkcs8_asn, "privateKeyAlgorithm.parameters",
870 &tmp, 0);
871 if (ret < 0)
872 {
873 gnutls_assert ();
874 goto error;
875 }
876
877 ret = _gnutls_x509_read_dsa_params (tmp.data, tmp.size, pkey->params);
878 _gnutls_free_datum (&tmp);
879 if (ret < 0)
880 {
881 gnutls_assert ();
882 goto error;
883 }
884
885 /* the public key can be generated as g^x mod p */
886 pkey->params[3] = _gnutls_mpi_alloc_like (pkey->params[0]);
887 if (pkey->params[3] == NULL)
888 {
889 gnutls_assert ();
890 goto error;
891 }
892
893 _gnutls_mpi_powm (pkey->params[3], pkey->params[2], pkey->params[4],
894 pkey->params[0]);
895
896 if (!pkey->crippled)
897 {
898 ret = _gnutls_asn1_encode_dsa (&pkey->key, pkey->params);
899 if (ret < 0)
900 {
901 gnutls_assert ();
902 goto error;
903 }
904 }
905
906 pkey->params_size = DSA_PRIVATE_PARAMS;
907
908 return 0;
909
910 error:
911 gnutls_x509_privkey_deinit (pkey);
912 return ret;
913 }
914
915static int
916decode_private_key_info (const gnutls_datum_t * der,
917 gnutls_x509_privkey_t pkey)
918 {
919 int result, len;
920 opaque oid[64];
921 ASN1_TYPE pkcs8_asn = ASN1_TYPE_EMPTY;
922
923 if ((result =
924 asn1_create_element (_gnutls_get_pkix (),
925 "PKIX1.pkcs-8-PrivateKeyInfo",
926 &pkcs8_asn)) != ASN1_SUCCESS)
927 {
928 gnutls_assert ();
929 result = _gnutls_asn2err (result);
930 goto error;
931 }
932
933 result = asn1_der_decoding (&pkcs8_asn, der->data, der->size, NULL);
934 if (result != ASN1_SUCCESS)
935 {
936 gnutls_assert ();
937 result = _gnutls_asn2err (result);
938 goto error;
939 }
940
941 /* Check the private key algorithm OID
942 */
943 len = sizeof (oid);
944 result =
945 asn1_read_value (pkcs8_asn, "privateKeyAlgorithm.algorithm", oid, &len);
946 if (result != ASN1_SUCCESS)
947 {
948 gnutls_assert ();
949 result = _gnutls_asn2err (result);
950 goto error;
951 }
952
953 /* we only support RSA and DSA private keys.
954 */
955 if (strcmp (oid, PK_PKIX1_RSA_OID) == 0)
956 pkey->pk_algorithm = GNUTLS_PK_RSA;
957 else
958 {
959 gnutls_assert ();
960 _gnutls_x509_log
961 ("PKCS #8 private key OID '%s' is unsupported.\n", oid);
962 result = GNUTLS_E_UNKNOWN_PK_ALGORITHM;
963 goto error;
964 }
965
966 /* Get the DER encoding of the actual private key.
967 */
968
969 if (pkey->pk_algorithm == GNUTLS_PK_RSA)
970 result = _decode_pkcs8_rsa_key (pkcs8_asn, pkey);
971 if (result < 0)
972 {
973 gnutls_assert ();
974 return result;
975 }
976
977 result = 0;
978
979 error:
980 asn1_delete_structure (&pkcs8_asn);
981
982 return result;
983
984 }
985
986/**
987 * gnutls_x509_privkey_import_pkcs8 - This function will import a DER or PEM PKCS8 encoded key
988 * @key: The structure to store the parsed key
989 * @data: The DER or PEM encoded key.
990 * @format: One of DER or PEM
991 * @password: the password to decrypt the key (if it is encrypted).
992 * @flags: 0 if encrypted or GNUTLS_PKCS_PLAIN if not encrypted.
993 *
994 * This function will convert the given DER or PEM encoded PKCS8 2.0 encrypted key
995 * to the native gnutls_x509_privkey_t format. The output will be stored in @key.
996 * Both RSA and DSA keys can be imported, and flags can only be used to indicate
997 * an unencrypted key.
998 *
999 * The @password can be either ASCII or UTF-8 in the default PBES2
1000 * encryption schemas, or ASCII for the PKCS12 schemas.
1001 *
1002 * If the Certificate is PEM encoded it should have a header of "ENCRYPTED PRIVATE KEY",
1003 * or "PRIVATE KEY". You only need to specify the flags if the key is DER encoded, since
1004 * in that case the encryption status cannot be auto-detected.
1005 *
1006 * Returns 0 on success.
1007 *
1008 **/
1009int
1010gnutls_x509_privkey_import_pkcs8 (gnutls_x509_privkey_t key,
1011 const gnutls_datum_t * data,
1012 gnutls_x509_crt_fmt_t format,
1013 const char *password, unsigned int flags)
1014 {
1015 int result = 0, need_free = 0;
1016 gnutls_datum_t _data;
1017
1018 if (key == NULL)
1019 {
1020 gnutls_assert ();
1021 return GNUTLS_E_INVALID_REQUEST;
1022 }
1023
1024 _data.data = data->data;
1025 _data.size = data->size;
1026
1027 key->pk_algorithm = GNUTLS_PK_UNKNOWN;
1028
1029 /* If the Certificate is in PEM format then decode it
1030 */
1031 if (format == GNUTLS_X509_FMT_PEM)
1032 {
1033 opaque *out;
1034
1035 /* Try the first header
1036 */
1037 result =
1038 _gnutls_fbase64_decode (PEM_UNENCRYPTED_PKCS8,
1039 data->data, data->size, &out);
1040
1041 if (result < 0)
1042 { /* Try the encrypted header
1043 */
1044 result =
1045 _gnutls_fbase64_decode (PEM_PKCS8, data->data, data->size, &out);
1046
1047 if (result <= 0)
1048 {
1049 if (result == 0)
1050 result = GNUTLS_E_INTERNAL_ERROR;
1051 gnutls_assert ();
1052 return result;
1053 }
1054 }
1055 else if (flags == 0)
1056 flags |= GNUTLS_PKCS_PLAIN;
1057
1058 _data.data = out;
1059 _data.size = result;
1060
1061 need_free = 1;
1062 }
1063
1064 if (flags & GNUTLS_PKCS_PLAIN)
1065 {
1066 result = decode_private_key_info (&_data, key);
1067 }
1068 else
1069 { /* encrypted. */
1070 result = decode_pkcs8_key (&_data, password, key);
1071 }
1072
1073 if (result < 0)
1074 {
1075 gnutls_assert ();
1076 goto cleanup;
1077 }
1078
1079 if (need_free)
1080 _gnutls_free_datum (&_data);
1081
1082 /* The key has now been decoded.
1083 */
1084
1085 return 0;
1086
1087 cleanup:
1088 key->pk_algorithm = GNUTLS_PK_UNKNOWN;
1089 if (need_free)
1090 _gnutls_free_datum (&_data);
1091 return result;
1092 }
1093
1094/* Reads the PBKDF2 parameters.
1095 */
1096static int
1097read_pbkdf2_params (ASN1_TYPE pbes2_asn,
1098 const gnutls_datum_t * der, struct pbkdf2_params *params)
1099 {
1100 int params_start, params_end;
1101 int params_len, len, result;
1102 ASN1_TYPE pbkdf2_asn = ASN1_TYPE_EMPTY;
1103 char oid[64];
1104
1105 memset (params, 0, sizeof (params));
1106
1107 /* Check the key derivation algorithm
1108 */
1109 len = sizeof (oid);
1110 result =
1111 asn1_read_value (pbes2_asn, "keyDerivationFunc.algorithm", oid, &len);
1112 if (result != ASN1_SUCCESS)
1113 {
1114 gnutls_assert ();
1115 return _gnutls_asn2err (result);
1116 }
1117 _gnutls_hard_log ("keyDerivationFunc.algorithm: %s\n", oid);
1118
1119 if (strcmp (oid, PBKDF2_OID) != 0)
1120 {
1121 gnutls_assert ();
1122 _gnutls_x509_log
1123 ("PKCS #8 key derivation OID '%s' is unsupported.\n", oid);
1124 return _gnutls_asn2err (result);
1125 }
1126
1127 result =
1128 asn1_der_decoding_startEnd (pbes2_asn, der->data, der->size,
1129 "keyDerivationFunc.parameters",
1130 &params_start, &params_end);
1131 if (result != ASN1_SUCCESS)
1132 {
1133 gnutls_assert ();
1134 return _gnutls_asn2err (result);
1135 }
1136 params_len = params_end - params_start + 1;
1137
1138 /* Now check the key derivation and the encryption
1139 * functions.
1140 */
1141 if ((result =
1142 asn1_create_element (_gnutls_get_pkix (),
1143 "PKIX1.pkcs-5-PBKDF2-params",
1144 &pbkdf2_asn)) != ASN1_SUCCESS)
1145 {
1146 gnutls_assert ();
1147 return _gnutls_asn2err (result);
1148 }
1149
1150 result =
1151 asn1_der_decoding (&pbkdf2_asn, &der->data[params_start],
1152 params_len, NULL);
1153 if (result != ASN1_SUCCESS)
1154 {
1155 gnutls_assert ();
1156 result = _gnutls_asn2err (result);
1157 goto error;
1158 }
1159
1160 /* read the salt */
1161 params->salt_size = sizeof (params->salt);
1162 result =
1163 asn1_read_value (pbkdf2_asn, "salt.specified", params->salt,
1164 &params->salt_size);
1165 if (result != ASN1_SUCCESS)
1166 {
1167 gnutls_assert ();
1168 result = _gnutls_asn2err (result);
1169 goto error;
1170 }
1171 _gnutls_hard_log ("salt.specified.size: %d\n", params->salt_size);
1172
1173 /* read the iteration count
1174 */
1175 result =
1176 _gnutls_x509_read_uint (pbkdf2_asn, "iterationCount",
1177 &params->iter_count);
1178 if (result != ASN1_SUCCESS)
1179 {
1180 gnutls_assert ();
1181 goto error;
1182 }
1183 _gnutls_hard_log ("iterationCount: %d\n", params->iter_count);
1184
1185 /* read the keylength, if it is set.
1186 */
1187 result =
1188 _gnutls_x509_read_uint (pbkdf2_asn, "keyLength", &params->key_size);
1189 if (result < 0)
1190 {
1191 params->key_size = 0;
1192 }
1193 _gnutls_hard_log ("keyLength: %d\n", params->key_size);
1194
1195 /* We don't read the PRF. We only use the default.
1196 */
1197
1198 return 0;
1199
1200 error:
1201 asn1_delete_structure (&pbkdf2_asn);
1202 return result;
1203
1204 }
1205
1206/* Reads the PBE parameters from PKCS-12 schemas (*&#%*&#% RSA).
1207 */
1208static int
1209read_pkcs12_kdf_params (ASN1_TYPE pbes2_asn, struct pbkdf2_params *params)
1210 {
1211 int result;
1212
1213 memset (params, 0, sizeof (params));
1214
1215 /* read the salt */
1216 params->salt_size = sizeof (params->salt);
1217 result =
1218 asn1_read_value (pbes2_asn, "salt", params->salt, &params->salt_size);
1219 if (result != ASN1_SUCCESS)
1220 {
1221 gnutls_assert ();
1222 result = _gnutls_asn2err (result);
1223 goto error;
1224 }
1225 _gnutls_hard_log ("salt.size: %d\n", params->salt_size);
1226
1227 /* read the iteration count
1228 */
1229 result =
1230 _gnutls_x509_read_uint (pbes2_asn, "iterations", &params->iter_count);
1231 if (result != ASN1_SUCCESS)
1232 {
1233 gnutls_assert ();
1234 goto error;
1235 }
1236 _gnutls_hard_log ("iterationCount: %d\n", params->iter_count);
1237
1238 params->key_size = 0;
1239
1240 return 0;
1241
1242 error:
1243 return result;
1244
1245 }
1246
1247/* Writes the PBE parameters for PKCS-12 schemas.
1248 */
1249static int
1250write_pkcs12_kdf_params (ASN1_TYPE pbes2_asn,
1251 const struct pbkdf2_params *kdf_params)
1252 {
1253 int result;
1254
1255 /* write the salt
1256 */
1257 result =
1258 asn1_write_value (pbes2_asn, "salt",
1259 kdf_params->salt, kdf_params->salt_size);
1260 if (result != ASN1_SUCCESS)
1261 {
1262 gnutls_assert ();
1263 result = _gnutls_asn2err (result);
1264 goto error;
1265 }
1266 _gnutls_hard_log ("salt.size: %d\n", kdf_params->salt_size);
1267
1268 /* write the iteration count
1269 */
1270 result =
1271 _gnutls_x509_write_uint32 (pbes2_asn, "iterations",
1272 kdf_params->iter_count);
1273 if (result < 0)
1274 {
1275 gnutls_assert ();
1276 goto error;
1277 }
1278 _gnutls_hard_log ("iterationCount: %d\n", kdf_params->iter_count);
1279
1280 return 0;
1281
1282 error:
1283 return result;
1284
1285 }
1286
1287/* Converts an OID to a gnutls cipher type.
1288 */
1289inline static int
1290oid2cipher (const char *oid, gnutls_cipher_algorithm_t * algo)
1291 {
1292
1293 *algo = 0;
1294
1295 if (strcmp (oid, DES_EDE3_CBC_OID) == 0)
1296 {
1297 *algo = GNUTLS_CIPHER_3DES_CBC;
1298 return 0;
1299 }
1300
1301 if (strcmp (oid, DES_CBC_OID) == 0)
1302 {
1303 *algo = GNUTLS_CIPHER_DES_CBC;
1304 return 0;
1305 }
1306
1307 _gnutls_x509_log ("PKCS #8 encryption OID '%s' is unsupported.\n", oid);
1308 return GNUTLS_E_UNKNOWN_CIPHER_TYPE;
1309 }
1310
1311static int
1312read_pbe_enc_params (ASN1_TYPE pbes2_asn,
1313 const gnutls_datum_t * der,
1314 struct pbe_enc_params *params)
1315 {
1316 int params_start, params_end;
1317 int params_len, len, result;
1318 ASN1_TYPE pbe_asn = ASN1_TYPE_EMPTY;
1319 char oid[64];
1320
1321 memset (params, 0, sizeof (params));
1322
1323 /* Check the encryption algorithm
1324 */
1325 len = sizeof (oid);
1326 result =
1327 asn1_read_value (pbes2_asn, "encryptionScheme.algorithm", oid, &len);
1328 if (result != ASN1_SUCCESS)
1329 {
1330 gnutls_assert ();
1331 goto error;
1332 }
1333 _gnutls_hard_log ("encryptionScheme.algorithm: %s\n", oid);
1334
1335 if ((result = oid2cipher (oid, &params->cipher)) < 0)
1336 {
1337 gnutls_assert ();
1338 goto error;
1339 }
1340
1341 result =
1342 asn1_der_decoding_startEnd (pbes2_asn, der->data, der->size,
1343 "encryptionScheme.parameters",
1344 &params_start, &params_end);
1345 if (result != ASN1_SUCCESS)
1346 {
1347 gnutls_assert ();
1348 return _gnutls_asn2err (result);
1349 }
1350 params_len = params_end - params_start + 1;
1351
1352 /* Now check the encryption parameters.
1353 */
1354 if ((result =
1355 asn1_create_element (_gnutls_get_pkix (),
1356 "PKIX1.pkcs-5-des-EDE3-CBC-params",
1357 &pbe_asn)) != ASN1_SUCCESS)
1358 {
1359 gnutls_assert ();
1360 return _gnutls_asn2err (result);
1361 }
1362
1363 result =
1364 asn1_der_decoding (&pbe_asn, &der->data[params_start], params_len, NULL);
1365 if (result != ASN1_SUCCESS)
1366 {
1367 gnutls_assert ();
1368 result = _gnutls_asn2err (result);
1369 goto error;
1370 }
1371
1372 /* read the IV */
1373 params->iv_size = sizeof (params->iv);
1374 result = asn1_read_value (pbe_asn, "", params->iv, &params->iv_size);
1375 if (result != ASN1_SUCCESS)
1376 {
1377 gnutls_assert ();
1378 result = _gnutls_asn2err (result);
1379 goto error;
1380 }
1381 _gnutls_hard_log ("IV.size: %d\n", params->iv_size);
1382
1383 return 0;
1384
1385 error:
1386 asn1_delete_structure (&pbe_asn);
1387 return result;
1388
1389 }
1390
1391static int
1392decrypt_data (schema_id schema, ASN1_TYPE pkcs8_asn,
1393 const char *root, const char *password,
1394 const struct pbkdf2_params *kdf_params,
1395 const struct pbe_enc_params *enc_params,
1396 gnutls_datum_t * decrypted_data)
1397 {
1398 int result;
1399 int data_size;
1400 opaque *data = NULL, *key = NULL;
1401 gnutls_datum_t dkey, d_iv;
1402 cipher_hd_t ch = NULL;
1403 int key_size;
1404
1405 data_size = 0;
1406 result = asn1_read_value (pkcs8_asn, root, NULL, &data_size);
1407 if (result != ASN1_MEM_ERROR)
1408 {
1409 gnutls_assert ();
1410 return _gnutls_asn2err (result);
1411 }
1412
1413 data = gnutls_malloc (data_size);
1414 if (data == NULL)
1415 {
1416 gnutls_assert ();
1417 return GNUTLS_E_MEMORY_ERROR;
1418 }
1419
1420 result = asn1_read_value (pkcs8_asn, root, data, &data_size);
1421 if (result != ASN1_SUCCESS)
1422 {
1423 gnutls_assert ();
1424 result = _gnutls_asn2err (result);
1425 goto error;
1426 }
1427
1428 if (kdf_params->key_size == 0)
1429 {
1430 key_size = gnutls_cipher_get_key_size (enc_params->cipher);
1431 }
1432 else
1433 key_size = kdf_params->key_size;
1434
1435 key = gnutls_alloca (key_size);
1436 if (key == NULL)
1437 {
1438 gnutls_assert ();
1439 result = GNUTLS_E_MEMORY_ERROR;
1440 goto error;
1441 }
1442
1443 /* generate the key
1444 */
1445 if (schema == PBES2)
1446 {
1447 result = gc_pbkdf2_sha1 (password, strlen (password),
1448 kdf_params->salt, kdf_params->salt_size,
1449 kdf_params->iter_count, key, key_size);
1450
1451 if (result != GC_OK)
1452 {
1453 gnutls_assert ();
1454 result = GNUTLS_E_DECRYPTION_FAILED;
1455 goto error;
1456 }
1457 }
1458 else
1459 {
1460 result =
1461 _pkcs12_string_to_key (1 /*KEY*/, kdf_params->salt,
1462 kdf_params->salt_size,
1463 kdf_params->iter_count, password,
1464 key_size, key);
1465
1466 if (result < 0)
1467 {
1468 gnutls_assert ();
1469 goto error;
1470 }
1471 }
1472
1473 /* do the decryption.
1474 */
1475 dkey.data = key;
1476 dkey.size = key_size;
1477
1478 d_iv.data = (opaque *) enc_params->iv;
1479 d_iv.size = enc_params->iv_size;
1480 ch = _gnutls_cipher_init (enc_params->cipher, &dkey, &d_iv);
1481
1482 gnutls_afree (key);
1483 key = NULL;
1484
1485 if (ch == NULL)
1486 {
1487 gnutls_assert ();
1488 result = GNUTLS_E_DECRYPTION_FAILED;
1489 goto error;
1490 }
1491
1492 result = _gnutls_cipher_decrypt (ch, data, data_size);
1493 if (result < 0)
1494 {
1495 gnutls_assert ();
1496 goto error;
1497 }
1498
1499 decrypted_data->data = data;
1500
1501 if (_gnutls_cipher_get_block_size (enc_params->cipher) != 1)
1502 decrypted_data->size = data_size - data[data_size - 1];
1503 else
1504 decrypted_data->size = data_size;
1505
1506 _gnutls_cipher_deinit (ch);
1507
1508 return 0;
1509
1510 error:
1511 gnutls_free (data);
1512 gnutls_afree (key);
1513 if (ch != NULL)
1514 _gnutls_cipher_deinit (ch);
1515 return result;
1516 }
1517
1518/* Writes the PBKDF2 parameters.
1519 */
1520static int
1521write_pbkdf2_params (ASN1_TYPE pbes2_asn,
1522 const struct pbkdf2_params *kdf_params)
1523 {
1524 int result;
1525 ASN1_TYPE pbkdf2_asn = ASN1_TYPE_EMPTY;
1526 opaque tmp[64];
1527
1528 /* Write the key derivation algorithm
1529 */
1530 result =
1531 asn1_write_value (pbes2_asn, "keyDerivationFunc.algorithm",
1532 PBKDF2_OID, 1);
1533 if (result != ASN1_SUCCESS)
1534 {
1535 gnutls_assert ();
1536 return _gnutls_asn2err (result);
1537 }
1538
1539 /* Now write the key derivation and the encryption
1540 * functions.
1541 */
1542 if ((result =
1543 asn1_create_element (_gnutls_get_pkix (),
1544 "PKIX1.pkcs-5-PBKDF2-params",
1545 &pbkdf2_asn)) != ASN1_SUCCESS)
1546 {
1547 gnutls_assert ();
1548 return _gnutls_asn2err (result);
1549 }
1550
1551 result = asn1_write_value (pbkdf2_asn, "salt", "specified", 1);
1552 if (result != ASN1_SUCCESS)
1553 {
1554 gnutls_assert ();
1555 result = _gnutls_asn2err (result);
1556 goto error;
1557 }
1558
1559 /* write the salt
1560 */
1561 result =
1562 asn1_write_value (pbkdf2_asn, "salt.specified",
1563 kdf_params->salt, kdf_params->salt_size);
1564 if (result != ASN1_SUCCESS)
1565 {
1566 gnutls_assert ();
1567 result = _gnutls_asn2err (result);
1568 goto error;
1569 }
1570 _gnutls_hard_log ("salt.specified.size: %d\n", kdf_params->salt_size);
1571
1572 /* write the iteration count
1573 */
1574 _gnutls_write_uint32 (kdf_params->iter_count, tmp);
1575
1576 result = asn1_write_value (pbkdf2_asn, "iterationCount", tmp, 4);
1577 if (result != ASN1_SUCCESS)
1578 {
1579 gnutls_assert ();
1580 result = _gnutls_asn2err (result);
1581 goto error;
1582 }
1583 _gnutls_hard_log ("iterationCount: %d\n", kdf_params->iter_count);
1584
1585 /* write the keylength, if it is set.
1586 */
1587 result = asn1_write_value (pbkdf2_asn, "keyLength", NULL, 0);
1588 if (result != ASN1_SUCCESS)
1589 {
1590 gnutls_assert ();
1591 result = _gnutls_asn2err (result);
1592 goto error;
1593 }
1594
1595 /* We write an emptry prf.
1596 */
1597 result = asn1_write_value (pbkdf2_asn, "prf", NULL, 0);
1598 if (result != ASN1_SUCCESS)
1599 {
1600 gnutls_assert ();
1601 result = _gnutls_asn2err (result);
1602 goto error;
1603 }
1604
1605 /* now encode them an put the DER output
1606 * in the keyDerivationFunc.parameters
1607 */
1608 result = _gnutls_x509_der_encode_and_copy (pbkdf2_asn, "",
1609 pbes2_asn,
1610 "keyDerivationFunc.parameters",
1611 0);
1612 if (result < 0)
1613 {
1614 gnutls_assert ();
1615 goto error;
1616 }
1617
1618 return 0;
1619
1620 error:
1621 asn1_delete_structure (&pbkdf2_asn);
1622 return result;
1623
1624 }
1625
1626static int
1627write_pbe_enc_params (ASN1_TYPE pbes2_asn,
1628 const struct pbe_enc_params *params)
1629 {
1630 int result;
1631 ASN1_TYPE pbe_asn = ASN1_TYPE_EMPTY;
1632
1633 /* Write the encryption algorithm
1634 */
1635 result =
1636 asn1_write_value (pbes2_asn, "encryptionScheme.algorithm",
1637 DES_EDE3_CBC_OID, 1);
1638 if (result != ASN1_SUCCESS)
1639 {
1640 gnutls_assert ();
1641 goto error;
1642 }
1643 _gnutls_hard_log ("encryptionScheme.algorithm: %s\n", DES_EDE3_CBC_OID);
1644
1645 /* Now check the encryption parameters.
1646 */
1647 if ((result =
1648 asn1_create_element (_gnutls_get_pkix (),
1649 "PKIX1.pkcs-5-des-EDE3-CBC-params",
1650 &pbe_asn)) != ASN1_SUCCESS)
1651 {
1652 gnutls_assert ();
1653 return _gnutls_asn2err (result);
1654 }
1655
1656 /* read the salt */
1657 result = asn1_write_value (pbe_asn, "", params->iv, params->iv_size);
1658 if (result != ASN1_SUCCESS)
1659 {
1660 gnutls_assert ();
1661 result = _gnutls_asn2err (result);
1662 goto error;
1663 }
1664 _gnutls_hard_log ("IV.size: %d\n", params->iv_size);
1665
1666 /* now encode them an put the DER output
1667 * in the encryptionScheme.parameters
1668 */
1669 result = _gnutls_x509_der_encode_and_copy (pbe_asn, "",
1670 pbes2_asn,
1671 "encryptionScheme.parameters",
1672 0);
1673 if (result < 0)
1674 {
1675 gnutls_assert ();
1676 goto error;
1677 }
1678
1679 return 0;
1680
1681 error:
1682 asn1_delete_structure (&pbe_asn);
1683 return result;
1684
1685 }
1686
1687/* Generates a key and also stores the key parameters.
1688 */
1689static int
1690generate_key (schema_id schema,
1691 const char *password,
1692 struct pbkdf2_params *kdf_params,
1693 struct pbe_enc_params *enc_params, gnutls_datum_t * key)
1694 {
1695 opaque rnd[2];
1696 int ret;
1697
1698 /* We should use the flags here to use different
1699 * encryption algorithms etc.
1700 */
1701
1702 if (schema == PKCS12_ARCFOUR_SHA1)
1703 enc_params->cipher = GNUTLS_CIPHER_ARCFOUR_128;
1704 else if (schema == PKCS12_3DES_SHA1)
1705 enc_params->cipher = GNUTLS_CIPHER_3DES_CBC;
1706 else if (schema == PKCS12_RC2_40_SHA1)
1707 enc_params->cipher = GNUTLS_CIPHER_RC2_40_CBC;
1708
1709 if (gc_pseudo_random (rnd, 2) != GC_OK)
1710 {
1711 gnutls_assert ();
1712 return GNUTLS_E_RANDOM_FAILED;
1713 }
1714
1715 /* generate salt */
1716
1717 if (schema == PBES2)
1718 {
1719 kdf_params->salt_size = MIN (sizeof (kdf_params->salt), (unsigned) (10 + (rnd[1] % 10)));
1720 }
1721 else
1722 kdf_params->salt_size = 8;
1723
1724 if (gc_pseudo_random (kdf_params->salt, kdf_params->salt_size) != GC_OK)
1725 {
1726 gnutls_assert ();
1727 return GNUTLS_E_RANDOM_FAILED;
1728 }
1729
1730 kdf_params->iter_count = 256 + rnd[0];
1731 key->size = kdf_params->key_size =
1732 gnutls_cipher_get_key_size (enc_params->cipher);
1733
1734 enc_params->iv_size = _gnutls_cipher_get_iv_size (enc_params->cipher);
1735
1736 key->data = gnutls_secure_malloc (key->size);
1737 if (key->data == NULL)
1738 {
1739 gnutls_assert ();
1740 return GNUTLS_E_MEMORY_ERROR;
1741 }
1742
1743 /* now generate the key.
1744 */
1745
1746 if (schema == PBES2)
1747 {
1748
1749 ret = gc_pbkdf2_sha1 (password, strlen (password),
1750 kdf_params->salt, kdf_params->salt_size,
1751 kdf_params->iter_count,
1752 key->data, kdf_params->key_size);
1753 if (ret != GC_OK)
1754 {
1755 gnutls_assert ();
1756 return GNUTLS_E_ENCRYPTION_FAILED;
1757 }
1758
1759 if (enc_params->iv_size &&
1760 gc_nonce (enc_params->iv, enc_params->iv_size) != GC_OK)
1761 {
1762 gnutls_assert ();
1763 return GNUTLS_E_RANDOM_FAILED;
1764 }
1765 }
1766 else
1767 { /* PKCS12 schemas */
1768 ret =
1769 _pkcs12_string_to_key (1 /*KEY*/, kdf_params->salt,
1770 kdf_params->salt_size,
1771 kdf_params->iter_count, password,
1772 kdf_params->key_size, key->data);
1773 if (ret < 0)
1774 {
1775 gnutls_assert ();
1776 return ret;
1777 }
1778
1779 /* Now generate the IV
1780 */
1781 if (enc_params->iv_size)
1782 {
1783 ret =
1784 _pkcs12_string_to_key (2 /*IV*/, kdf_params->salt,
1785 kdf_params->salt_size,
1786 kdf_params->iter_count, password,
1787 enc_params->iv_size, enc_params->iv);
1788 if (ret < 0)
1789 {
1790 gnutls_assert ();
1791 return ret;
1792 }
1793 }
1794 }
1795
1796 return 0;
1797 }
1798
1799/* Encodes the parameters to be written in the encryptionAlgorithm.parameters
1800 * part.
1801 */
1802static int
1803write_schema_params (schema_id schema, ASN1_TYPE pkcs8_asn,
1804 const char *where,
1805 const struct pbkdf2_params *kdf_params,
1806 const struct pbe_enc_params *enc_params)
1807 {
1808 int result;
1809 ASN1_TYPE pbes2_asn = ASN1_TYPE_EMPTY;
1810
1811 if (schema == PBES2)
1812 {
1813 if ((result =
1814 asn1_create_element (_gnutls_get_pkix (),
1815 "PKIX1.pkcs-5-PBES2-params",
1816 &pbes2_asn)) != ASN1_SUCCESS)
1817 {
1818 gnutls_assert ();
1819 return _gnutls_asn2err (result);
1820 }
1821
1822 result = write_pbkdf2_params (pbes2_asn, kdf_params);
1823 if (result < 0)
1824 {
1825 gnutls_assert ();
1826 goto error;
1827 }
1828
1829 result = write_pbe_enc_params (pbes2_asn, enc_params);
1830 if (result < 0)
1831 {
1832 gnutls_assert ();
1833 goto error;
1834 }
1835
1836 result = _gnutls_x509_der_encode_and_copy (pbes2_asn, "",
1837 pkcs8_asn, where, 0);
1838 if (result < 0)
1839 {
1840 gnutls_assert ();
1841 goto error;
1842 }
1843
1844 asn1_delete_structure (&pbes2_asn);
1845 }
1846 else
1847 { /* PKCS12 schemas */
1848
1849 if ((result =
1850 asn1_create_element (_gnutls_get_pkix (),
1851 "PKIX1.pkcs-12-PbeParams",
1852 &pbes2_asn)) != ASN1_SUCCESS)
1853 {
1854 gnutls_assert ();
1855 result = _gnutls_asn2err (result);
1856 goto error;
1857 }
1858
1859 result = write_pkcs12_kdf_params (pbes2_asn, kdf_params);
1860 if (result < 0)
1861 {
1862 gnutls_assert ();
1863 goto error;
1864 }
1865
1866 result = _gnutls_x509_der_encode_and_copy (pbes2_asn, "",
1867 pkcs8_asn, where, 0);
1868 if (result < 0)
1869 {
1870 gnutls_assert ();
1871 goto error;
1872 }
1873
1874 asn1_delete_structure (&pbes2_asn);
1875
1876 }
1877
1878 return 0;
1879
1880 error:
1881 asn1_delete_structure (&pbes2_asn);
1882 return result;
1883
1884 }
1885
1886static int
1887encrypt_data (const gnutls_datum_t * plain,
1888 const struct pbe_enc_params *enc_params,
1889 gnutls_datum_t * key, gnutls_datum_t * encrypted)
1890 {
1891 int result;
1892 int data_size;
1893 opaque *data = NULL;
1894 gnutls_datum_t d_iv;
1895 cipher_hd_t ch = NULL;
1896 opaque pad, pad_size;
1897
1898 pad_size = _gnutls_cipher_get_block_size (enc_params->cipher);
1899
1900 if (pad_size == 1) /* stream */
1901 pad_size = 0;
1902
1903 data = gnutls_malloc (plain->size + pad_size);
1904 if (data == NULL)
1905 {
1906 gnutls_assert ();
1907 return GNUTLS_E_MEMORY_ERROR;
1908 }
1909
1910 memcpy (data, plain->data, plain->size);
1911
1912 if (pad_size> 0)
1913 {
1914 pad = pad_size - (plain->size % pad_size);
1915 if (pad == 0)
1916 pad = pad_size;
1917 memset (&data[plain->size], pad, pad);
1918 }
1919 else
1920 pad = 0;
1921
1922 data_size = plain->size + pad;
1923
1924 d_iv.data = (opaque *) enc_params->iv;
1925 d_iv.size = enc_params->iv_size;
1926 ch = _gnutls_cipher_init (enc_params->cipher, key, &d_iv);
1927
1928 if (ch == GNUTLS_CIPHER_FAILED)
1929 {
1930 gnutls_assert ();
1931 result = GNUTLS_E_ENCRYPTION_FAILED;
1932 goto error;
1933 }
1934
1935 result = _gnutls_cipher_encrypt (ch, data, data_size);
1936 if (result < 0)
1937 {
1938 gnutls_assert ();
1939 goto error;
1940 }
1941
1942 encrypted->data = data;
1943 encrypted->size = data_size;
1944
1945 _gnutls_cipher_deinit (ch);
1946
1947 return 0;
1948
1949 error:
1950 gnutls_free (data);
1951 if (ch != NULL)
1952 _gnutls_cipher_deinit (ch);
1953 return result;
1954 }
1955
1956/* Decrypts a PKCS #7 encryptedData. The output is allocated
1957 * and stored in dec.
1958 */
1959int
1960_gnutls_pkcs7_decrypt_data (const gnutls_datum_t * data,
1961 const char *password, gnutls_datum_t * dec)
1962 {
1963 int result, len;
1964 char enc_oid[64];
1965 gnutls_datum_t tmp;
1966 ASN1_TYPE pbes2_asn = ASN1_TYPE_EMPTY, pkcs7_asn = ASN1_TYPE_EMPTY;
1967 int params_start, params_end, params_len;
1968 struct pbkdf2_params kdf_params;
1969 struct pbe_enc_params enc_params;
1970 schema_id schema;
1971
1972 if ((result =
1973 asn1_create_element (_gnutls_get_pkix (),
1974 "PKIX1.pkcs-7-EncryptedData",
1975 &pkcs7_asn)) != ASN1_SUCCESS)
1976 {
1977 gnutls_assert ();
1978 result = _gnutls_asn2err (result);
1979 goto error;
1980 }
1981
1982 result = asn1_der_decoding (&pkcs7_asn, data->data, data->size, NULL);
1983 if (result != ASN1_SUCCESS)
1984 {
1985 gnutls_assert ();
1986 result = _gnutls_asn2err (result);
1987 goto error;
1988 }
1989
1990 /* Check the encryption schema OID
1991 */
1992 len = sizeof (enc_oid);
1993 result =
1994 asn1_read_value (pkcs7_asn,
1995 "encryptedContentInfo.contentEncryptionAlgorithm.algorithm",
1996 enc_oid, &len);
1997 if (result != ASN1_SUCCESS)
1998 {
1999 gnutls_assert ();
2000 result = _gnutls_asn2err (result);
2001 goto error;
2002 }
2003
2004 if ((result = check_schema (enc_oid)) < 0)
2005 {
2006 gnutls_assert ();
2007 goto error;
2008 }
2009 schema = result;
2010
2011 /* Get the DER encoding of the parameters.
2012 */
2013 result =
2014 asn1_der_decoding_startEnd (pkcs7_asn, data->data, data->size,
2015 "encryptedContentInfo.contentEncryptionAlgorithm.parameters",
2016 &params_start, &params_end);
2017 if (result != ASN1_SUCCESS)
2018 {
2019 gnutls_assert ();
2020 result = _gnutls_asn2err (result);
2021 goto error;
2022 }
2023 params_len = params_end - params_start + 1;
2024
2025 result =
2026 read_pkcs_schema_params (schema, password,
2027 &data->data[params_start],
2028 params_len, &kdf_params, &enc_params);
2029 if (result < ASN1_SUCCESS)
2030 {
2031 gnutls_assert ();
2032 result = _gnutls_asn2err (result);
2033 goto error;
2034 }
2035
2036 /* Parameters have been decoded. Now
2037 * decrypt the EncryptedData.
2038 */
2039
2040 result =
2041 decrypt_data (schema, pkcs7_asn,
2042 "encryptedContentInfo.encryptedContent", password,
2043 &kdf_params, &enc_params, &tmp);
2044 if (result < 0)
2045 {
2046 gnutls_assert ();
2047 goto error;
2048 }
2049
2050 asn1_delete_structure (&pkcs7_asn);
2051
2052 *dec = tmp;
2053
2054 return 0;
2055
2056 error:
2057 asn1_delete_structure (&pbes2_asn);
2058 asn1_delete_structure (&pkcs7_asn);
2059 return result;
2060 }
2061
2062/* Encrypts to a PKCS #7 encryptedData. The output is allocated
2063 * and stored in enc.
2064 */
2065int
2066_gnutls_pkcs7_encrypt_data (schema_id schema,
2067 const gnutls_datum_t * data,
2068 const char *password, gnutls_datum_t * enc)
2069 {
2070 int result;
2071 gnutls_datum_t key =
2072 { NULL, 0};
2073 gnutls_datum_t tmp =
2074 { NULL, 0};
2075 ASN1_TYPE pkcs7_asn = ASN1_TYPE_EMPTY;
2076 struct pbkdf2_params kdf_params;
2077 struct pbe_enc_params enc_params;
2078
2079 if ((result =
2080 asn1_create_element (_gnutls_get_pkix (),
2081 "PKIX1.pkcs-7-EncryptedData",
2082 &pkcs7_asn)) != ASN1_SUCCESS)
2083 {
2084 gnutls_assert ();
2085 result = _gnutls_asn2err (result);
2086 goto error;
2087 }
2088
2089 /* Write the encryption schema OID
2090 */
2091 switch (schema)
2092 {
2093 case PBES2:
2094 result =
2095 asn1_write_value (pkcs7_asn,
2096 "encryptedContentInfo.contentEncryptionAlgorithm.algorithm",
2097 PBES2_OID, 1);
2098 break;
2099 case PKCS12_3DES_SHA1:
2100 result =
2101 asn1_write_value (pkcs7_asn,
2102 "encryptedContentInfo.contentEncryptionAlgorithm.algorithm",
2103 PKCS12_PBE_3DES_SHA1_OID, 1);
2104 break;
2105 case PKCS12_ARCFOUR_SHA1:
2106 result =
2107 asn1_write_value (pkcs7_asn,
2108 "encryptedContentInfo.contentEncryptionAlgorithm.algorithm",
2109 PKCS12_PBE_ARCFOUR_SHA1_OID, 1);
2110 break;
2111 case PKCS12_RC2_40_SHA1:
2112 result =
2113 asn1_write_value (pkcs7_asn,
2114 "encryptedContentInfo.contentEncryptionAlgorithm.algorithm",
2115 PKCS12_PBE_RC2_40_SHA1_OID, 1);
2116 break;
2117
2118 }
2119
2120 if (result != ASN1_SUCCESS)
2121 {
2122 gnutls_assert ();
2123 result = _gnutls_asn2err (result);
2124 goto error;
2125 }
2126
2127 /* Generate a symmetric key.
2128 */
2129
2130 result = generate_key (schema, password, &kdf_params, &enc_params, &key);
2131 if (result < 0)
2132 {
2133 gnutls_assert ();
2134 goto error;
2135 }
2136
2137 result = write_schema_params (schema, pkcs7_asn,
2138 "encryptedContentInfo.contentEncryptionAlgorithm.parameters",
2139 &kdf_params, &enc_params);
2140 if (result < 0)
2141 {
2142 gnutls_assert ();
2143 goto error;
2144 }
2145
2146 /* Parameters have been encoded. Now
2147 * encrypt the Data.
2148 */
2149 result = encrypt_data (data, &enc_params, &key, &tmp);
2150 if (result < 0)
2151 {
2152 gnutls_assert ();
2153 goto error;
2154 }
2155
2156 /* write the encrypted data.
2157 */
2158 result =
2159 asn1_write_value (pkcs7_asn,
2160 "encryptedContentInfo.encryptedContent", tmp.data,
2161 tmp.size);
2162 if (result != ASN1_SUCCESS)
2163 {
2164 gnutls_assert ();
2165 result = _gnutls_asn2err (result);
2166 goto error;
2167 }
2168
2169 _gnutls_free_datum (&tmp);
2170 _gnutls_free_datum (&key);
2171
2172 /* Now write the rest of the pkcs-7 stuff.
2173 */
2174
2175 result = _gnutls_x509_write_uint32 (pkcs7_asn, "version", 0);
2176 if (result < 0)
2177 {
2178 gnutls_assert ();
2179 goto error;
2180 }
2181
2182 result =
2183 asn1_write_value (pkcs7_asn, "encryptedContentInfo.contentType",
2184 DATA_OID, 1);
2185 if (result != ASN1_SUCCESS)
2186 {
2187 gnutls_assert ();
2188 result = _gnutls_asn2err (result);
2189 goto error;
2190 }
2191
2192 result = asn1_write_value (pkcs7_asn, "unprotectedAttrs", NULL, 0);
2193 if (result != ASN1_SUCCESS)
2194 {
2195 gnutls_assert ();
2196 result = _gnutls_asn2err (result);
2197 goto error;
2198 }
2199
2200 /* Now encode and copy the DER stuff.
2201 */
2202 result = _gnutls_x509_der_encode (pkcs7_asn, "", enc, 0);
2203
2204 asn1_delete_structure (&pkcs7_asn);
2205
2206 if (result < 0)
2207 {
2208 gnutls_assert ();
2209 goto error;
2210 }
2211
2212 error:
2213 _gnutls_free_datum (&key);
2214 _gnutls_free_datum (&tmp);
2215 asn1_delete_structure (&pkcs7_asn);
2216 return result;
2217 }
2218
2219#endif
diff --git a/src/daemon/https/x509/rfc2818.h b/src/daemon/https/x509/rfc2818.h
new file mode 100644
index 00000000..c3399145
--- /dev/null
+++ b/src/daemon/https/x509/rfc2818.h
@@ -0,0 +1,26 @@
1/*
2 * Copyright (C) 2003, 2004, 2005 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
25int _gnutls_hostname_compare (const char *certname, const char *hostname);
26#define MAX_CN 256
diff --git a/src/daemon/https/x509/rfc2818_hostname.c b/src/daemon/https/x509/rfc2818_hostname.c
new file mode 100644
index 00000000..93a96589
--- /dev/null
+++ b/src/daemon/https/x509/rfc2818_hostname.c
@@ -0,0 +1,160 @@
1/*
2 * Copyright (C) 2003, 2004, 2005, 2007 Free Software Foundation
3 * Copyright (C) 2002 Andrew McDonald
4 *
5 * This file is part of GNUTLS.
6 *
7 * The GNUTLS library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public License
9 * as published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
20 * USA
21 *
22 */
23
24#include <gnutls_int.h>
25#include <x509.h>
26#include <dn.h>
27#include <common.h>
28#include <rfc2818.h>
29#include <gnutls_errors.h>
30
31/* compare hostname against certificate, taking account of wildcards
32 * return 1 on success or 0 on error
33 */
34int
35_gnutls_hostname_compare (const char *certname, const char *hostname)
36{
37 const char *cmpstr1, *cmpstr2;
38
39 if (strlen (certname) == 0 || strlen (hostname) == 0)
40 return 0;
41
42 if (strlen (certname) > 2 && strncmp (certname, "*.", 2) == 0)
43 {
44 /* a wildcard certificate */
45
46 cmpstr1 = certname + 1;
47
48 /* find the first dot in hostname, compare from there on */
49 cmpstr2 = strchr (hostname, '.');
50
51 if (cmpstr2 == NULL)
52 {
53 /* error, the hostname we're connecting to is only a local part */
54 return 0;
55 }
56
57 if (strcasecmp (cmpstr1, cmpstr2) == 0)
58 {
59 return 1;
60 }
61
62 return 0;
63 }
64
65 if (strcasecmp (certname, hostname) == 0)
66 {
67 return 1;
68 }
69
70 return 0;
71}
72
73/**
74 * gnutls_x509_crt_check_hostname - This function compares the given hostname with the hostname in the certificate
75 * @cert: should contain an gnutls_x509_crt_t structure
76 * @hostname: A null terminated string that contains a DNS name
77 *
78 * This function will check if the given certificate's subject
79 * matches the given hostname. This is a basic implementation of the
80 * matching described in RFC2818 (HTTPS), which takes into account
81 * wildcards, and the DNSName/IPAddress subject alternative name PKIX
82 * extension.
83 *
84 * Returns non zero for a successful match, and zero on failure.
85 **/
86int
87gnutls_x509_crt_check_hostname (gnutls_x509_crt_t cert, const char *hostname)
88{
89
90 char dnsname[MAX_CN];
91 size_t dnsnamesize;
92 int found_dnsname = 0;
93 int ret = 0;
94 int i = 0;
95
96 /* try matching against:
97 * 1) a DNS name as an alternative name (subjectAltName) extension
98 * in the certificate
99 * 2) the common name (CN) in the certificate
100 *
101 * either of these may be of the form: *.domain.tld
102 *
103 * only try (2) if there is no subjectAltName extension of
104 * type dNSName
105 */
106
107 /* Check through all included subjectAltName extensions, comparing
108 * against all those of type dNSName.
109 */
110 for (i = 0; !(ret < 0); i++)
111 {
112
113 dnsnamesize = sizeof (dnsname);
114 ret = gnutls_x509_crt_get_subject_alt_name (cert, i,
115 dnsname, &dnsnamesize,
116 NULL);
117
118 if (ret == GNUTLS_SAN_DNSNAME)
119 {
120 found_dnsname = 1;
121 if (_gnutls_hostname_compare (dnsname, hostname))
122 {
123 return 1;
124 }
125 }
126 else if (ret == GNUTLS_SAN_IPADDRESS)
127 {
128 found_dnsname = 1; /* RFC 2818 is unclear whether the CN
129 should be compared for IP addresses
130 too, but we won't do it. */
131 if (_gnutls_hostname_compare (dnsname, hostname))
132 {
133 return 1;
134 }
135 }
136 }
137
138 if (!found_dnsname)
139 {
140 /* not got the necessary extension, use CN instead
141 */
142 dnsnamesize = sizeof (dnsname);
143 if (gnutls_x509_crt_get_dn_by_oid (cert, OID_X520_COMMON_NAME, 0,
144 0, dnsname, &dnsnamesize) < 0)
145 {
146 /* got an error, can't find a name
147 */
148 return 0;
149 }
150
151 if (_gnutls_hostname_compare (dnsname, hostname))
152 {
153 return 1;
154 }
155 }
156
157 /* not found a matching name
158 */
159 return 0;
160}
diff --git a/src/daemon/https/x509/sign.c b/src/daemon/https/x509/sign.c
new file mode 100644
index 00000000..275fc3f7
--- /dev/null
+++ b/src/daemon/https/x509/sign.c
@@ -0,0 +1,346 @@
1/*
2 * Copyright (C) 2003, 2004, 2005, 2006, 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/* All functions which relate to X.509 certificate signing stuff are
26 * included here
27 */
28
29#include <gnutls_int.h>
30
31#ifdef ENABLE_PKI
32
33#include <gnutls_errors.h>
34#include <gnutls_cert.h>
35#include <libtasn1.h>
36#include <gnutls_global.h>
37#include <gnutls_num.h> /* MAX */
38#include <gnutls_sig.h>
39#include <gnutls_str.h>
40#include <gnutls_datum.h>
41#include <dn.h>
42#include <x509.h>
43#include <mpi.h>
44#include <sign.h>
45#include <common.h>
46#include <verify.h>
47
48/* Writes the digest information and the digest in a DER encoded
49 * structure. The digest info is allocated and stored into the info structure.
50 */
51static int
52encode_ber_digest_info (gnutls_digest_algorithm_t hash,
53 const gnutls_datum_t * digest, gnutls_datum_t * info)
54{
55 ASN1_TYPE dinfo = ASN1_TYPE_EMPTY;
56 int result;
57 const char *algo;
58
59 algo = _gnutls_x509_mac_to_oid ((gnutls_mac_algorithm_t) hash);
60 if (algo == NULL)
61 {
62 gnutls_assert ();
63 _gnutls_x509_log ("Hash algorithm: %d\n", hash);
64 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
65 }
66
67 if ((result = asn1_create_element (_gnutls_get_gnutls_asn (),
68 "GNUTLS.DigestInfo",
69 &dinfo)) != ASN1_SUCCESS)
70 {
71 gnutls_assert ();
72 return _gnutls_asn2err (result);
73 }
74
75 result = asn1_write_value (dinfo, "digestAlgorithm.algorithm", algo, 1);
76 if (result != ASN1_SUCCESS)
77 {
78 gnutls_assert ();
79 asn1_delete_structure (&dinfo);
80 return _gnutls_asn2err (result);
81 }
82
83 /* Write an ASN.1 NULL in the parameters field. This matches RFC
84 3279 and RFC 4055, although is arguable incorrect from a historic
85 perspective (see those documents for more information).
86 Regardless of what is correct, this appears to be what most
87 implementations do. */
88 result = asn1_write_value (dinfo, "digestAlgorithm.parameters",
89 "\x05\x00", 2);
90 if (result != ASN1_SUCCESS)
91 {
92 gnutls_assert ();
93 asn1_delete_structure (&dinfo);
94 return _gnutls_asn2err (result);
95 }
96
97 result = asn1_write_value (dinfo, "digest", digest->data, digest->size);
98 if (result != ASN1_SUCCESS)
99 {
100 gnutls_assert ();
101 asn1_delete_structure (&dinfo);
102 return _gnutls_asn2err (result);
103 }
104
105 info->size = 0;
106 asn1_der_coding (dinfo, "", NULL, &info->size, NULL);
107
108 info->data = gnutls_malloc (info->size);
109 if (info->data == NULL)
110 {
111 gnutls_assert ();
112 asn1_delete_structure (&dinfo);
113 return GNUTLS_E_MEMORY_ERROR;
114 }
115
116 result = asn1_der_coding (dinfo, "", info->data, &info->size, NULL);
117 if (result != ASN1_SUCCESS)
118 {
119 gnutls_assert ();
120 asn1_delete_structure (&dinfo);
121 return _gnutls_asn2err (result);
122 }
123
124 asn1_delete_structure (&dinfo);
125
126 return 0;
127}
128
129/* if hash==MD5 then we do RSA-MD5
130 * if hash==SHA then we do RSA-SHA
131 * params[0] is modulus
132 * params[1] is public key
133 */
134static int
135pkcs1_rsa_sign (gnutls_digest_algorithm_t hash, const gnutls_datum_t * text,
136 mpi_t * params, int params_len, gnutls_datum_t * signature)
137{
138 int ret;
139 opaque _digest[MAX_HASH_SIZE];
140 GNUTLS_HASH_HANDLE hd;
141 gnutls_datum_t digest, info;
142
143 hd = _gnutls_hash_init (HASH2MAC (hash));
144 if (hd == NULL)
145 {
146 gnutls_assert ();
147 return GNUTLS_E_HASH_FAILED;
148 }
149
150 _gnutls_hash (hd, text->data, text->size);
151 _gnutls_hash_deinit (hd, _digest);
152
153 digest.data = _digest;
154 digest.size = _gnutls_hash_get_algo_len (HASH2MAC (hash));
155
156 /* Encode the digest as a DigestInfo
157 */
158 if ((ret = encode_ber_digest_info (hash, &digest, &info)) != 0)
159 {
160 gnutls_assert ();
161 return ret;
162 }
163
164 if ((ret =
165 _gnutls_sign (GNUTLS_PK_RSA, params, params_len, &info,
166 signature)) < 0)
167 {
168 gnutls_assert ();
169 _gnutls_free_datum (&info);
170 return ret;
171 }
172
173 _gnutls_free_datum (&info);
174
175 return 0;
176}
177
178/* Signs the given data using the parameters from the signer's
179 * private key.
180 *
181 * returns 0 on success.
182 *
183 * 'tbs' is the data to be signed
184 * 'signature' will hold the signature!
185 * 'hash' is only used in PKCS1 RSA signing.
186 */
187int
188_gnutls_x509_sign (const gnutls_datum_t * tbs,
189 gnutls_digest_algorithm_t hash,
190 gnutls_x509_privkey_t signer, gnutls_datum_t * signature)
191{
192 int ret;
193
194 switch (signer->pk_algorithm)
195 {
196 case GNUTLS_PK_RSA:
197 ret =
198 pkcs1_rsa_sign (hash, tbs, signer->params, signer->params_size,
199 signature);
200 if (ret < 0)
201 {
202 gnutls_assert ();
203 return ret;
204 }
205 return 0;
206 break;
207 default:
208 gnutls_assert ();
209 return GNUTLS_E_INTERNAL_ERROR;
210 }
211
212}
213
214/* This is the same as the _gnutls_x509_sign, but this one will decode
215 * the ASN1_TYPE given, and sign the DER data. Actually used to get the DER
216 * of the TBS and sign it on the fly.
217 */
218int
219_gnutls_x509_sign_tbs (ASN1_TYPE cert, const char *tbs_name,
220 gnutls_digest_algorithm_t hash,
221 gnutls_x509_privkey_t signer,
222 gnutls_datum_t * signature)
223{
224 int result;
225 opaque *buf;
226 int buf_size;
227 gnutls_datum_t tbs;
228
229 buf_size = 0;
230 asn1_der_coding (cert, tbs_name, NULL, &buf_size, NULL);
231
232 buf = gnutls_alloca (buf_size);
233 if (buf == NULL)
234 {
235 gnutls_assert ();
236 return GNUTLS_E_MEMORY_ERROR;
237 }
238
239 result = asn1_der_coding (cert, tbs_name, buf, &buf_size, NULL);
240
241 if (result != ASN1_SUCCESS)
242 {
243 gnutls_assert ();
244 gnutls_afree (buf);
245 return _gnutls_asn2err (result);
246 }
247
248 tbs.data = buf;
249 tbs.size = buf_size;
250
251 result = _gnutls_x509_sign (&tbs, hash, signer, signature);
252 gnutls_afree (buf);
253
254 return result;
255}
256
257/*-
258 * _gnutls_x509_pkix_sign - This function will sign a CRL or a certificate with a key
259 * @src: should contain an ASN1_TYPE
260 * @issuer: is the certificate of the certificate issuer
261 * @issuer_key: holds the issuer's private key
262 *
263 * This function will sign a CRL or a certificate with the issuer's private key, and
264 * will copy the issuer's information into the CRL or certificate.
265 *
266 * Returns 0 on success.
267 *
268 -*/
269int
270_gnutls_x509_pkix_sign (ASN1_TYPE src, const char *src_name,
271 gnutls_digest_algorithm_t dig,
272 gnutls_x509_crt_t issuer,
273 gnutls_x509_privkey_t issuer_key)
274{
275 int result;
276 gnutls_datum_t signature;
277 char name[128];
278
279 /* Step 1. Copy the issuer's name into the certificate.
280 */
281 _gnutls_str_cpy (name, sizeof (name), src_name);
282 _gnutls_str_cat (name, sizeof (name), ".issuer");
283
284 result = asn1_copy_node (src, name, issuer->cert, "tbsCertificate.subject");
285 if (result != ASN1_SUCCESS)
286 {
287 gnutls_assert ();
288 return _gnutls_asn2err (result);
289 }
290
291 /* Step 1.5. Write the signature stuff in the tbsCertificate.
292 */
293 _gnutls_str_cpy (name, sizeof (name), src_name);
294 _gnutls_str_cat (name, sizeof (name), ".signature");
295
296 result = _gnutls_x509_write_sig_params (src, name,
297 issuer_key->pk_algorithm, dig,
298 issuer_key->params,
299 issuer_key->params_size);
300 if (result < 0)
301 {
302 gnutls_assert ();
303 return result;
304 }
305
306 /* Step 2. Sign the certificate.
307 */
308 result = _gnutls_x509_sign_tbs (src, src_name, dig, issuer_key, &signature);
309
310 if (result < 0)
311 {
312 gnutls_assert ();
313 return result;
314 }
315
316 /* write the signature (bits)
317 */
318 result =
319 asn1_write_value (src, "signature", signature.data, signature.size * 8);
320
321 _gnutls_free_datum (&signature);
322
323 if (result != ASN1_SUCCESS)
324 {
325 gnutls_assert ();
326 return _gnutls_asn2err (result);
327 }
328
329 /* Step 3. Move up and write the AlgorithmIdentifier, which is also
330 * the same.
331 */
332
333 result = _gnutls_x509_write_sig_params (src, "signatureAlgorithm",
334 issuer_key->pk_algorithm, dig,
335 issuer_key->params,
336 issuer_key->params_size);
337 if (result < 0)
338 {
339 gnutls_assert ();
340 return result;
341 }
342
343 return 0;
344}
345
346#endif
diff --git a/src/daemon/https/x509/sign.h b/src/daemon/https/x509/sign.h
new file mode 100644
index 00000000..e1bf46d4
--- /dev/null
+++ b/src/daemon/https/x509/sign.h
@@ -0,0 +1,36 @@
1/*
2 * Copyright (C) 2003, 2004, 2005 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
25int _gnutls_x509_sign (const gnutls_datum_t * tbs,
26 gnutls_digest_algorithm_t hash,
27 gnutls_x509_privkey_t signer,
28 gnutls_datum_t * signature);
29int _gnutls_x509_sign_tbs (ASN1_TYPE cert, const char *tbs_name,
30 gnutls_digest_algorithm_t hash,
31 gnutls_x509_privkey_t signer,
32 gnutls_datum_t * signature);
33int _gnutls_x509_pkix_sign (ASN1_TYPE src, const char *src_name,
34 gnutls_digest_algorithm_t,
35 gnutls_x509_crt_t issuer,
36 gnutls_x509_privkey_t issuer_key);
diff --git a/src/daemon/https/x509/verify.h b/src/daemon/https/x509/verify.h
new file mode 100644
index 00000000..d7ca5151
--- /dev/null
+++ b/src/daemon/https/x509/verify.h
@@ -0,0 +1,34 @@
1/*
2 * Copyright (C) 2003, 2004, 2005 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 "x509.h"
26
27int gnutls_x509_crt_is_issuer (gnutls_x509_crt_t cert,
28 gnutls_x509_crt_t issuer);
29int _gnutls_x509_verify_signature (const gnutls_datum_t * tbs,
30 const gnutls_datum_t * signature,
31 gnutls_x509_crt_t issuer);
32int _gnutls_x509_privkey_verify_signature (const gnutls_datum_t * tbs,
33 const gnutls_datum_t * signature,
34 gnutls_x509_privkey_t issuer);
diff --git a/src/daemon/https/x509/x509-api.texi b/src/daemon/https/x509/x509-api.texi
new file mode 100644
index 00000000..f4dd35b9
--- /dev/null
+++ b/src/daemon/https/x509/x509-api.texi
@@ -0,0 +1,2943 @@
1
2@subheading gnutls_x509_crl_init
3@anchor{gnutls_x509_crl_init}
4@deftypefun {int} {gnutls_x509_crl_init} (gnutls_x509_crl_t * @var{crl})
5@var{crl}: The structure to be initialized
6
7This function will initialize a CRL structure. CRL stands for
8Certificate Revocation List. A revocation list usually contains
9lists of certificate serial numbers that have been revoked
10by an Authority. The revocation lists are always signed with
11the authority's private key.
12
13Returns 0 on success.
14@end deftypefun
15
16@subheading gnutls_x509_crl_deinit
17@anchor{gnutls_x509_crl_deinit}
18@deftypefun {void} {gnutls_x509_crl_deinit} (gnutls_x509_crl_t @var{crl})
19@var{crl}: The structure to be initialized
20
21This function will deinitialize a CRL structure.
22@end deftypefun
23
24@subheading gnutls_x509_crl_import
25@anchor{gnutls_x509_crl_import}
26@deftypefun {int} {gnutls_x509_crl_import} (gnutls_x509_crl_t @var{crl}, const gnutls_datum_t * @var{data}, gnutls_x509_crt_fmt_t @var{format})
27@var{crl}: The structure to store the parsed CRL.
28
29@var{data}: The DER or PEM encoded CRL.
30
31@var{format}: One of DER or PEM
32
33This function will convert the given DER or PEM encoded CRL
34to the native gnutls_x509_crl_t format. The output will be stored in 'crl'.
35
36If the CRL is PEM encoded it should have a header of "X509 CRL".
37
38Returns 0 on success.
39@end deftypefun
40
41@subheading gnutls_x509_crl_get_issuer_dn
42@anchor{gnutls_x509_crl_get_issuer_dn}
43@deftypefun {int} {gnutls_x509_crl_get_issuer_dn} (const gnutls_x509_crl_t @var{crl}, char * @var{buf}, size_t * @var{sizeof_buf})
44@var{crl}: should contain a gnutls_x509_crl_t structure
45
46@var{buf}: a pointer to a structure to hold the peer's name (may be null)
47
48@var{sizeof_buf}: initially holds the size of @code{buf}
49
50This function will copy the name of the CRL issuer in the provided buffer. The name
51will be in the form "C=xxxx,O=yyyy,CN=zzzz" as described in RFC2253. The output
52string will be ASCII or UTF-8 encoded, depending on the certificate data.
53
54If buf is null then only the size will be filled.
55
56Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not long enough, and
57in that case the sizeof_buf will be updated with the required size, and
580 on success.
59@end deftypefun
60
61@subheading gnutls_x509_crl_get_issuer_dn_by_oid
62@anchor{gnutls_x509_crl_get_issuer_dn_by_oid}
63@deftypefun {int} {gnutls_x509_crl_get_issuer_dn_by_oid} (gnutls_x509_crl_t @var{crl}, const char * @var{oid}, int @var{indx}, unsigned int @var{raw_flag}, void * @var{buf}, size_t * @var{sizeof_buf})
64@var{crl}: should contain a gnutls_x509_crl_t structure
65
66@var{oid}: holds an Object Identified in null terminated string
67
68@var{indx}: In case multiple same OIDs exist in the RDN, this specifies which to send. Use zero to get the first one.
69
70@var{raw_flag}: If non zero returns the raw DER data of the DN part.
71
72@var{buf}: a pointer to a structure to hold the peer's name (may be null)
73
74@var{sizeof_buf}: initially holds the size of @code{buf}
75
76This function will extract the part of the name of the CRL issuer specified
77by the given OID. The output will be encoded as described in RFC2253. The output
78string will be ASCII or UTF-8 encoded, depending on the certificate data.
79
80Some helper macros with popular OIDs can be found in gnutls/x509.h
81If raw flag is zero, this function will only return known OIDs as text. Other OIDs
82will be DER encoded, as described in RFC2253 -- in hex format with a '\#' prefix.
83You can check about known OIDs using @code{gnutls_x509_dn_oid_known()}.
84
85If buf is null then only the size will be filled.
86
87Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not long enough, and
88in that case the sizeof_buf will be updated with the required size,
89and 0 on success.
90@end deftypefun
91
92@subheading gnutls_x509_crl_get_dn_oid
93@anchor{gnutls_x509_crl_get_dn_oid}
94@deftypefun {int} {gnutls_x509_crl_get_dn_oid} (gnutls_x509_crl_t @var{crl}, int @var{indx}, void * @var{oid}, size_t * @var{sizeof_oid})
95@var{crl}: should contain a gnutls_x509_crl_t structure
96
97@var{indx}: Specifies which DN OID to send. Use zero to get the first one.
98
99@var{oid}: a pointer to a structure to hold the name (may be null)
100
101@var{sizeof_oid}: initially holds the size of 'oid'
102
103This function will extract the requested OID of the name of the CRL issuer, specified
104by the given index.
105
106If oid is null then only the size will be filled.
107
108Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not long enough, and
109in that case the sizeof_oid will be updated with the required size.
110On success 0 is returned.
111@end deftypefun
112
113@subheading gnutls_x509_crl_get_signature_algorithm
114@anchor{gnutls_x509_crl_get_signature_algorithm}
115@deftypefun {int} {gnutls_x509_crl_get_signature_algorithm} (gnutls_x509_crl_t @var{crl})
116@var{crl}: should contain a gnutls_x509_crl_t structure
117
118This function will return a value of the gnutls_sign_algorithm_t enumeration that
119is the signature algorithm.
120
121Returns a negative value on error.
122@end deftypefun
123
124@subheading gnutls_x509_crl_get_signature
125@anchor{gnutls_x509_crl_get_signature}
126@deftypefun {int} {gnutls_x509_crl_get_signature} (gnutls_x509_crl_t @var{crl}, char * @var{sig}, size_t * @var{sizeof_sig})
127@var{crl}: should contain a gnutls_x509_crl_t structure
128
129@var{sig}: a pointer where the signature part will be copied (may be null).
130
131@var{sizeof_sig}: initially holds the size of @code{sig}
132
133This function will extract the signature field of a CRL.
134
135Returns 0 on success, and a negative value on error.
136@end deftypefun
137
138@subheading gnutls_x509_crl_get_version
139@anchor{gnutls_x509_crl_get_version}
140@deftypefun {int} {gnutls_x509_crl_get_version} (gnutls_x509_crl_t @var{crl})
141@var{crl}: should contain a gnutls_x509_crl_t structure
142
143This function will return the version of the specified CRL.
144
145Returns a negative value on error.
146@end deftypefun
147
148@subheading gnutls_x509_crl_get_this_update
149@anchor{gnutls_x509_crl_get_this_update}
150@deftypefun {time_t} {gnutls_x509_crl_get_this_update} (gnutls_x509_crl_t @var{crl})
151@var{crl}: should contain a gnutls_x509_crl_t structure
152
153This function will return the time this CRL was issued.
154
155Returns (time_t)-1 on error.
156@end deftypefun
157
158@subheading gnutls_x509_crl_get_next_update
159@anchor{gnutls_x509_crl_get_next_update}
160@deftypefun {time_t} {gnutls_x509_crl_get_next_update} (gnutls_x509_crl_t @var{crl})
161@var{crl}: should contain a gnutls_x509_crl_t structure
162
163This function will return the time the next CRL will be issued.
164This field is optional in a CRL so it might be normal to get
165an error instead.
166
167Returns (time_t)-1 on error.
168@end deftypefun
169
170@subheading gnutls_x509_crl_get_crt_count
171@anchor{gnutls_x509_crl_get_crt_count}
172@deftypefun {int} {gnutls_x509_crl_get_crt_count} (gnutls_x509_crl_t @var{crl})
173@var{crl}: should contain a gnutls_x509_crl_t structure
174
175This function will return the number of revoked certificates in the
176given CRL.
177
178Returns a negative value on failure.
179@end deftypefun
180
181@subheading gnutls_x509_crl_get_crt_serial
182@anchor{gnutls_x509_crl_get_crt_serial}
183@deftypefun {int} {gnutls_x509_crl_get_crt_serial} (gnutls_x509_crl_t @var{crl}, int @var{indx}, unsigned char * @var{serial}, size_t * @var{serial_size}, time_t * @var{t})
184@var{crl}: should contain a gnutls_x509_crl_t structure
185
186@var{indx}: the index of the certificate to extract (starting from 0)
187
188@var{serial}: where the serial number will be copied
189
190@var{serial_size}: initially holds the size of serial
191
192@var{t}: if non null, will hold the time this certificate was revoked
193
194This function will return the serial number of the specified, by
195the index, revoked certificate.
196
197Returns a negative value on failure.
198@end deftypefun
199
200@subheading gnutls_x509_crl_export
201@anchor{gnutls_x509_crl_export}
202@deftypefun {int} {gnutls_x509_crl_export} (gnutls_x509_crl_t @var{crl}, gnutls_x509_crt_fmt_t @var{format}, void * @var{output_data}, size_t * @var{output_data_size})
203@var{crl}: Holds the revocation list
204
205@var{format}: the format of output params. One of PEM or DER.
206
207@var{output_data}: will contain a private key PEM or DER encoded
208
209@var{output_data_size}: holds the size of output_data (and will be replaced by the actual size of parameters)
210
211This function will export the revocation list to DER or PEM format.
212
213If the buffer provided is not long enough to hold the output, then
214GNUTLS_E_SHORT_MEMORY_BUFFER will be returned.
215
216If the structure is PEM encoded, it will have a header
217of "BEGIN X509 CRL".
218
219Returns 0 on success, and a negative value on failure.
220@end deftypefun
221
222@subheading gnutls_x509_rdn_get
223@anchor{gnutls_x509_rdn_get}
224@deftypefun {int} {gnutls_x509_rdn_get} (const gnutls_datum_t * @var{idn}, char * @var{buf}, size_t * @var{sizeof_buf})
225@var{idn}: should contain a DER encoded RDN sequence
226
227@var{buf}: a pointer to a structure to hold the peer's name
228
229@var{sizeof_buf}: holds the size of @code{buf}
230
231This function will return the name of the given RDN sequence. The
232name will be in the form "C=xxxx,O=yyyy,CN=zzzz" as described in
233RFC2253.
234
235If the provided buffer is not long enough, returns
236GNUTLS_E_SHORT_MEMORY_BUFFER and *sizeof_buf will be updated. On
237success 0 is returned.
238@end deftypefun
239
240@subheading gnutls_x509_rdn_get_by_oid
241@anchor{gnutls_x509_rdn_get_by_oid}
242@deftypefun {int} {gnutls_x509_rdn_get_by_oid} (const gnutls_datum_t * @var{idn}, const char * @var{oid}, int @var{indx}, unsigned int @var{raw_flag}, void * @var{buf}, size_t * @var{sizeof_buf})
243@var{idn}: should contain a DER encoded RDN sequence
244
245@var{oid}: an Object Identifier
246
247@var{indx}: In case multiple same OIDs exist in the RDN indicates which
248to send. Use 0 for the first one.
249
250@var{raw_flag}: If non zero then the raw DER data are returned.
251
252@var{buf}: a pointer to a structure to hold the peer's name
253
254@var{sizeof_buf}: holds the size of @code{buf}
255
256This function will return the name of the given Object identifier,
257of the RDN sequence. The name will be encoded using the rules
258from RFC2253.
259
260Returns GNUTLS_E_SHORT_MEMORY_BUFFER and updates *sizeof_buf if
261the provided buffer is not long enough, and 0 on success.
262@end deftypefun
263
264@subheading gnutls_x509_rdn_get_oid
265@anchor{gnutls_x509_rdn_get_oid}
266@deftypefun {int} {gnutls_x509_rdn_get_oid} (const gnutls_datum_t * @var{idn}, int @var{indx}, void * @var{buf}, size_t * @var{sizeof_buf})
267@var{idn}: should contain a DER encoded RDN sequence
268
269@var{indx}: Indicates which OID to return. Use 0 for the first one.
270
271This function will return the specified Object identifier, of the
272RDN sequence.
273
274Returns GNUTLS_E_SHORT_MEMORY_BUFFER and updates *sizeof_buf if
275the provided buffer is not long enough, and 0 on success.
276@end deftypefun
277
278@subheading gnutls_x509_dn_oid_known
279@anchor{gnutls_x509_dn_oid_known}
280@deftypefun {int} {gnutls_x509_dn_oid_known} (const char * @var{oid})
281@var{oid}: holds an Object Identifier in a null terminated string
282
283This function will inform about known DN OIDs. This is useful since functions
284like @code{gnutls_x509_crt_set_dn_by_oid()} use the information on known
285OIDs to properly encode their input. Object Identifiers that are not
286known are not encoded by these functions, and their input is stored directly
287into the ASN.1 structure. In that case of unknown OIDs, you have
288the responsibility of DER encoding your data.
289
290Returns 1 on known OIDs and 0 otherwise.
291@end deftypefun
292
293@subheading gnutls_x509_crt_init
294@anchor{gnutls_x509_crt_init}
295@deftypefun {int} {gnutls_x509_crt_init} (gnutls_x509_crt_t * @var{cert})
296@var{cert}: The structure to be initialized
297
298This function will initialize an X.509 certificate structure.
299
300Returns 0 on success.
301@end deftypefun
302
303@subheading gnutls_x509_crt_deinit
304@anchor{gnutls_x509_crt_deinit}
305@deftypefun {void} {gnutls_x509_crt_deinit} (gnutls_x509_crt_t @var{cert})
306@var{cert}: The structure to be initialized
307
308This function will deinitialize a CRL structure.
309@end deftypefun
310
311@subheading gnutls_x509_crt_import
312@anchor{gnutls_x509_crt_import}
313@deftypefun {int} {gnutls_x509_crt_import} (gnutls_x509_crt_t @var{cert}, const gnutls_datum_t * @var{data}, gnutls_x509_crt_fmt_t @var{format})
314@var{cert}: The structure to store the parsed certificate.
315
316@var{data}: The DER or PEM encoded certificate.
317
318@var{format}: One of DER or PEM
319
320This function will convert the given DER or PEM encoded Certificate
321to the native gnutls_x509_crt_t format. The output will be stored in @code{cert}.
322
323If the Certificate is PEM encoded it should have a header of "X509 CERTIFICATE", or
324"CERTIFICATE".
325
326Returns 0 on success.
327@end deftypefun
328
329@subheading gnutls_x509_crt_get_issuer_dn
330@anchor{gnutls_x509_crt_get_issuer_dn}
331@deftypefun {int} {gnutls_x509_crt_get_issuer_dn} (gnutls_x509_crt_t @var{cert}, char * @var{buf}, size_t * @var{sizeof_buf})
332@var{cert}: should contain a gnutls_x509_crt_t structure
333
334@var{buf}: a pointer to a structure to hold the name (may be null)
335
336@var{sizeof_buf}: initially holds the size of @code{buf}
337
338This function will copy the name of the Certificate issuer in the
339provided buffer. The name will be in the form
340"C=xxxx,O=yyyy,CN=zzzz" as described in RFC2253. The output string
341will be ASCII or UTF-8 encoded, depending on the certificate data.
342
343If @code{buf} is null then only the size will be filled.
344
345Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
346long enough, and in that case the *sizeof_buf will be updated with
347the required size. On success 0 is returned.
348@end deftypefun
349
350@subheading gnutls_x509_crt_get_issuer_dn_by_oid
351@anchor{gnutls_x509_crt_get_issuer_dn_by_oid}
352@deftypefun {int} {gnutls_x509_crt_get_issuer_dn_by_oid} (gnutls_x509_crt_t @var{cert}, const char * @var{oid}, int @var{indx}, unsigned int @var{raw_flag}, void * @var{buf}, size_t * @var{sizeof_buf})
353@var{cert}: should contain a gnutls_x509_crt_t structure
354
355@var{oid}: holds an Object Identified in null terminated string
356
357@var{indx}: In case multiple same OIDs exist in the RDN, this specifies which to send. Use zero to get the first one.
358
359@var{raw_flag}: If non zero returns the raw DER data of the DN part.
360
361@var{buf}: a pointer to a structure to hold the name (may be null)
362
363@var{sizeof_buf}: initially holds the size of @code{buf}
364
365This function will extract the part of the name of the Certificate
366issuer specified by the given OID. The output, if the raw flag is not
367used, will be encoded as described in RFC2253. Thus a string that is
368ASCII or UTF-8 encoded, depending on the certificate data.
369
370Some helper macros with popular OIDs can be found in gnutls/x509.h
371If raw flag is zero, this function will only return known OIDs as
372text. Other OIDs will be DER encoded, as described in RFC2253 --
373in hex format with a '\#' prefix. You can check about known OIDs
374using @code{gnutls_x509_dn_oid_known()}.
375
376If @code{buf} is null then only the size will be filled.
377
378Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
379long enough, and in that case the *sizeof_buf will be updated with
380the required size. On success 0 is returned.
381@end deftypefun
382
383@subheading gnutls_x509_crt_get_issuer_dn_oid
384@anchor{gnutls_x509_crt_get_issuer_dn_oid}
385@deftypefun {int} {gnutls_x509_crt_get_issuer_dn_oid} (gnutls_x509_crt_t @var{cert}, int @var{indx}, void * @var{oid}, size_t * @var{sizeof_oid})
386@var{cert}: should contain a gnutls_x509_crt_t structure
387
388@var{indx}: This specifies which OID to return. Use zero to get the first one.
389
390@var{oid}: a pointer to a buffer to hold the OID (may be null)
391
392@var{sizeof_oid}: initially holds the size of @code{oid}
393
394This function will extract the OIDs of the name of the Certificate
395issuer specified by the given index.
396
397If @code{oid} is null then only the size will be filled.
398
399Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
400long enough, and in that case the *sizeof_oid will be updated with
401the required size. On success 0 is returned.
402@end deftypefun
403
404@subheading gnutls_x509_crt_get_dn
405@anchor{gnutls_x509_crt_get_dn}
406@deftypefun {int} {gnutls_x509_crt_get_dn} (gnutls_x509_crt_t @var{cert}, char * @var{buf}, size_t * @var{sizeof_buf})
407@var{cert}: should contain a gnutls_x509_crt_t structure
408
409@var{buf}: a pointer to a structure to hold the name (may be null)
410
411@var{sizeof_buf}: initially holds the size of @code{buf}
412
413This function will copy the name of the Certificate in the
414provided buffer. The name will be in the form
415"C=xxxx,O=yyyy,CN=zzzz" as described in RFC2253. The output string
416will be ASCII or UTF-8 encoded, depending on the certificate data.
417
418If @code{buf} is null then only the size will be filled.
419
420Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
421long enough, and in that case the *sizeof_buf will be updated with
422the required size. On success 0 is returned.
423@end deftypefun
424
425@subheading gnutls_x509_crt_get_dn_by_oid
426@anchor{gnutls_x509_crt_get_dn_by_oid}
427@deftypefun {int} {gnutls_x509_crt_get_dn_by_oid} (gnutls_x509_crt_t @var{cert}, const char * @var{oid}, int @var{indx}, unsigned int @var{raw_flag}, void * @var{buf}, size_t * @var{sizeof_buf})
428@var{cert}: should contain a gnutls_x509_crt_t structure
429
430@var{oid}: holds an Object Identified in null terminated string
431
432@var{indx}: In case multiple same OIDs exist in the RDN, this specifies which to send. Use zero to get the first one.
433
434@var{raw_flag}: If non zero returns the raw DER data of the DN part.
435
436@var{buf}: a pointer where the DN part will be copied (may be null).
437
438@var{sizeof_buf}: initially holds the size of @code{buf}
439
440This function will extract the part of the name of the Certificate
441subject specified by the given OID. The output, if the raw flag is not
442used, will be encoded as described in RFC2253. Thus a string that is
443ASCII or UTF-8 encoded, depending on the certificate data.
444
445Some helper macros with popular OIDs can be found in gnutls/x509.h
446If raw flag is zero, this function will only return known OIDs as
447text. Other OIDs will be DER encoded, as described in RFC2253 --
448in hex format with a '\#' prefix. You can check about known OIDs
449using @code{gnutls_x509_dn_oid_known()}.
450
451If @code{buf} is null then only the size will be filled.
452
453Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
454long enough, and in that case the *sizeof_buf will be updated with
455the required size. On success 0 is returned.
456@end deftypefun
457
458@subheading gnutls_x509_crt_get_dn_oid
459@anchor{gnutls_x509_crt_get_dn_oid}
460@deftypefun {int} {gnutls_x509_crt_get_dn_oid} (gnutls_x509_crt_t @var{cert}, int @var{indx}, void * @var{oid}, size_t * @var{sizeof_oid})
461@var{cert}: should contain a gnutls_x509_crt_t structure
462
463@var{indx}: This specifies which OID to return. Use zero to get the first one.
464
465@var{oid}: a pointer to a buffer to hold the OID (may be null)
466
467@var{sizeof_oid}: initially holds the size of @code{oid}
468
469This function will extract the OIDs of the name of the Certificate
470subject specified by the given index.
471
472If oid is null then only the size will be filled.
473
474Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
475long enough, and in that case the *sizeof_oid will be updated with
476the required size. On success 0 is returned.
477@end deftypefun
478
479@subheading gnutls_x509_crt_get_signature_algorithm
480@anchor{gnutls_x509_crt_get_signature_algorithm}
481@deftypefun {int} {gnutls_x509_crt_get_signature_algorithm} (gnutls_x509_crt_t @var{cert})
482@var{cert}: should contain a gnutls_x509_crt_t structure
483
484This function will return a value of the gnutls_sign_algorithm_t enumeration that
485is the signature algorithm.
486
487Returns a negative value on error.
488@end deftypefun
489
490@subheading gnutls_x509_crt_get_signature
491@anchor{gnutls_x509_crt_get_signature}
492@deftypefun {int} {gnutls_x509_crt_get_signature} (gnutls_x509_crt_t @var{cert}, char * @var{sig}, size_t * @var{sizeof_sig})
493@var{cert}: should contain a gnutls_x509_crt_t structure
494
495@var{sig}: a pointer where the signature part will be copied (may be null).
496
497@var{sizeof_sig}: initially holds the size of @code{sig}
498
499This function will extract the signature field of a certificate.
500
501Returns 0 on success, and a negative value on error.
502@end deftypefun
503
504@subheading gnutls_x509_crt_get_version
505@anchor{gnutls_x509_crt_get_version}
506@deftypefun {int} {gnutls_x509_crt_get_version} (gnutls_x509_crt_t @var{cert})
507@var{cert}: should contain a gnutls_x509_crt_t structure
508
509This function will return the version of the specified Certificate.
510
511Returns a negative value on error.
512@end deftypefun
513
514@subheading gnutls_x509_crt_get_activation_time
515@anchor{gnutls_x509_crt_get_activation_time}
516@deftypefun {time_t} {gnutls_x509_crt_get_activation_time} (gnutls_x509_crt_t @var{cert})
517@var{cert}: should contain a gnutls_x509_crt_t structure
518
519This function will return the time this Certificate was or will be activated.
520
521Returns (time_t)-1 on error.
522@end deftypefun
523
524@subheading gnutls_x509_crt_get_expiration_time
525@anchor{gnutls_x509_crt_get_expiration_time}
526@deftypefun {time_t} {gnutls_x509_crt_get_expiration_time} (gnutls_x509_crt_t @var{cert})
527@var{cert}: should contain a gnutls_x509_crt_t structure
528
529This function will return the time this Certificate was or will be expired.
530
531Returns (time_t)-1 on error.
532@end deftypefun
533
534@subheading gnutls_x509_crt_get_serial
535@anchor{gnutls_x509_crt_get_serial}
536@deftypefun {int} {gnutls_x509_crt_get_serial} (gnutls_x509_crt_t @var{cert}, void * @var{result}, size_t * @var{result_size})
537@var{cert}: should contain a gnutls_x509_crt_t structure
538
539@var{result}: The place where the serial number will be copied
540
541@var{result_size}: Holds the size of the result field.
542
543This function will return the X.509 certificate's serial number.
544This is obtained by the X509 Certificate serialNumber
545field. Serial is not always a 32 or 64bit number. Some CAs use
546large serial numbers, thus it may be wise to handle it as something
547opaque.
548
549Returns 0 on success and a negative value in case of an error.
550@end deftypefun
551
552@subheading gnutls_x509_crt_get_subject_key_id
553@anchor{gnutls_x509_crt_get_subject_key_id}
554@deftypefun {int} {gnutls_x509_crt_get_subject_key_id} (gnutls_x509_crt_t @var{cert}, void * @var{ret}, size_t * @var{ret_size}, unsigned int * @var{critical})
555@var{cert}: should contain a gnutls_x509_crt_t structure
556
557@var{ret}: The place where the identifier will be copied
558
559@var{ret_size}: Holds the size of the result field.
560
561@var{critical}: will be non zero if the extension is marked as critical (may be null)
562
563This function will return the X.509v3 certificate's subject key identifier.
564This is obtained by the X.509 Subject Key identifier extension
565field (2.5.29.14).
566
567Returns 0 on success and a negative value in case of an error.
568@end deftypefun
569
570@subheading gnutls_x509_crt_get_authority_key_id
571@anchor{gnutls_x509_crt_get_authority_key_id}
572@deftypefun {int} {gnutls_x509_crt_get_authority_key_id} (gnutls_x509_crt_t @var{cert}, void * @var{ret}, size_t * @var{ret_size}, unsigned int * @var{critical})
573@var{cert}: should contain a gnutls_x509_crt_t structure
574
575@var{critical}: will be non zero if the extension is marked as critical (may be null)
576
577This function will return the X.509v3 certificate authority's key identifier.
578This is obtained by the X.509 Authority Key identifier extension
579field (2.5.29.35). Note that this function only returns the keyIdentifier
580field of the extension.
581
582Returns 0 on success and a negative value in case of an error.
583@end deftypefun
584
585@subheading gnutls_x509_crt_get_pk_algorithm
586@anchor{gnutls_x509_crt_get_pk_algorithm}
587@deftypefun {int} {gnutls_x509_crt_get_pk_algorithm} (gnutls_x509_crt_t @var{cert}, unsigned int * @var{bits})
588@var{cert}: should contain a gnutls_x509_crt_t structure
589
590@var{bits}: if bits is non null it will hold the size of the parameters' in bits
591
592This function will return the public key algorithm of an X.509
593certificate.
594
595If bits is non null, it should have enough size to hold the parameters
596size in bits. For RSA the bits returned is the modulus.
597For DSA the bits returned are of the public
598exponent.
599
600Returns a member of the gnutls_pk_algorithm_t enumeration on success,
601or a negative value on error.
602@end deftypefun
603
604@subheading gnutls_x509_crt_get_subject_alt_name
605@anchor{gnutls_x509_crt_get_subject_alt_name}
606@deftypefun {int} {gnutls_x509_crt_get_subject_alt_name} (gnutls_x509_crt_t @var{cert}, unsigned int @var{seq}, void * @var{ret}, size_t * @var{ret_size}, unsigned int * @var{critical})
607@var{cert}: should contain a gnutls_x509_crt_t structure
608
609@var{seq}: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
610
611@var{ret}: is the place where the alternative name will be copied to
612
613@var{ret_size}: holds the size of ret.
614
615@var{critical}: will be non zero if the extension is marked as critical (may be null)
616
617This function will return the alternative names, contained in the
618given certificate.
619
620This is specified in X509v3 Certificate Extensions. GNUTLS will
621return the Alternative name (2.5.29.17), or a negative error code.
622
623When the SAN type is otherName, it will extract the data in the
624otherName's value field, and @code{GNUTLS_SAN_OTHERNAME} is returned.
625You may use @code{gnutls_x509_crt_get_subject_alt_othername_oid()} to get
626the corresponding OID and the "virtual" SAN types (e.g.,
627@code{GNUTLS_SAN_OTHERNAME_XMPP}).
628
629If an otherName OID is known, the data will be decoded. Otherwise
630the returned data will be DER encoded, and you will have to decode
631it yourself. Currently, only the RFC 3920 id-on-xmppAddr SAN is
632recognized.
633
634Returns the alternative subject name type on success. The type is
635one of the enumerated gnutls_x509_subject_alt_name_t. It will
636return @code{GNUTLS_E_SHORT_MEMORY_BUFFER} if @code{ret_size} is not large
637enough to hold the value. In that case @code{ret_size} will be updated
638with the required size. If the certificate does not have an
639Alternative name with the specified sequence number then
640@code{GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE} is returned.
641@end deftypefun
642
643@subheading gnutls_x509_crt_get_subject_alt_name2
644@anchor{gnutls_x509_crt_get_subject_alt_name2}
645@deftypefun {int} {gnutls_x509_crt_get_subject_alt_name2} (gnutls_x509_crt_t @var{cert}, unsigned int @var{seq}, void * @var{ret}, size_t * @var{ret_size}, unsigned int* @var{ret_type}, unsigned int * @var{critical})
646@var{cert}: should contain a gnutls_x509_crt_t structure
647
648@var{seq}: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
649
650@var{ret}: is the place where the alternative name will be copied to
651
652@var{ret_size}: holds the size of ret.
653
654@var{ret_type}: holds the type of the alternative name (one of gnutls_x509_subject_alt_name_t).
655
656@var{critical}: will be non zero if the extension is marked as critical (may be null)
657
658This function will return the alternative names, contained in the
659given certificate. It is the same as @code{gnutls_x509_crt_get_subject_alt_name()}
660except for the fact that it will return the type of the alternative
661name in @code{ret_type} even if the function fails for some reason (i.e.
662the buffer provided is not enough).
663
664The return values are the same as with @code{gnutls_x509_crt_get_subject_alt_name()}.
665@end deftypefun
666
667@subheading gnutls_x509_crt_get_subject_alt_othername_oid
668@anchor{gnutls_x509_crt_get_subject_alt_othername_oid}
669@deftypefun {int} {gnutls_x509_crt_get_subject_alt_othername_oid} (gnutls_x509_crt_t @var{cert}, unsigned int @var{seq}, void * @var{ret}, size_t * @var{ret_size})
670@var{cert}: should contain a gnutls_x509_crt_t structure
671
672@var{seq}: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
673
674@var{ret}: is the place where the otherName OID will be copied to
675
676@var{ret_size}: holds the size of ret.
677
678This function will extract the type OID of an otherName Subject
679Alternative Name, contained in the given certificate, and return
680the type as an enumerated element.
681
682This function is only useful if
683@code{gnutls_x509_crt_get_subject_alt_name()} returned
684@code{GNUTLS_SAN_OTHERNAME}.
685
686Returns the alternative subject name type on success. The type is
687one of the enumerated gnutls_x509_subject_alt_name_t. For
688supported OIDs, it will return one of the virtual
689(GNUTLS_SAN_OTHERNAME_*) types, e.g. @code{GNUTLS_SAN_OTHERNAME_XMPP},
690and @code{GNUTLS_SAN_OTHERNAME} for unknown OIDs. It will return
691@code{GNUTLS_E_SHORT_MEMORY_BUFFER} if @code{ret_size} is not large enough to
692hold the value. In that case @code{ret_size} will be updated with the
693required size. If the certificate does not have an Alternative
694name with the specified sequence number and with the otherName type
695then @code{GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE} is returned.
696@end deftypefun
697
698@subheading gnutls_x509_crt_get_basic_constraints
699@anchor{gnutls_x509_crt_get_basic_constraints}
700@deftypefun {int} {gnutls_x509_crt_get_basic_constraints} (gnutls_x509_crt_t @var{cert}, unsigned int * @var{critical}, int * @var{ca}, int * @var{pathlen})
701@var{cert}: should contain a gnutls_x509_crt_t structure
702
703@var{critical}: will be non zero if the extension is marked as critical
704
705@var{ca}: pointer to output integer indicating CA status, may be NULL,
706value is 1 if the certificate CA flag is set, 0 otherwise.
707
708@var{pathlen}: pointer to output integer indicating path length (may be
709NULL), non-negative values indicate a present pathLenConstraint
710field and the actual value, -1 indicate that the field is absent.
711
712This function will read the certificate's basic constraints, and
713return the certificates CA status. It reads the basicConstraints
714X.509 extension (2.5.29.19).
715
716@strong{Return value:} If the certificate is a CA a positive value will be
717returned, or zero if the certificate does not have CA flag set. A
718negative value may be returned in case of errors. If the
719certificate does not contain the basicConstraints extension
720GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
721@end deftypefun
722
723@subheading gnutls_x509_crt_get_ca_status
724@anchor{gnutls_x509_crt_get_ca_status}
725@deftypefun {int} {gnutls_x509_crt_get_ca_status} (gnutls_x509_crt_t @var{cert}, unsigned int * @var{critical})
726@var{cert}: should contain a gnutls_x509_crt_t structure
727
728@var{critical}: will be non zero if the extension is marked as critical
729
730This function will return certificates CA status, by reading the
731basicConstraints X.509 extension (2.5.29.19). If the certificate is
732a CA a positive value will be returned, or zero if the certificate
733does not have CA flag set.
734
735Use @code{gnutls_x509_crt_get_basic_constraints()} if you want to read the
736pathLenConstraint field too.
737
738A negative value may be returned in case of parsing error.
739If the certificate does not contain the basicConstraints extension
740GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
741@end deftypefun
742
743@subheading gnutls_x509_crt_get_key_usage
744@anchor{gnutls_x509_crt_get_key_usage}
745@deftypefun {int} {gnutls_x509_crt_get_key_usage} (gnutls_x509_crt_t @var{cert}, unsigned int * @var{key_usage}, unsigned int * @var{critical})
746@var{cert}: should contain a gnutls_x509_crt_t structure
747
748@var{key_usage}: where the key usage bits will be stored
749
750@var{critical}: will be non zero if the extension is marked as critical
751
752This function will return certificate's key usage, by reading the
753keyUsage X.509 extension (2.5.29.15). The key usage value will ORed values of the:
754GNUTLS_KEY_DIGITAL_SIGNATURE, GNUTLS_KEY_NON_REPUDIATION,
755GNUTLS_KEY_KEY_ENCIPHERMENT, GNUTLS_KEY_DATA_ENCIPHERMENT,
756GNUTLS_KEY_KEY_AGREEMENT, GNUTLS_KEY_KEY_CERT_SIGN,
757GNUTLS_KEY_CRL_SIGN, GNUTLS_KEY_ENCIPHER_ONLY,
758GNUTLS_KEY_DECIPHER_ONLY.
759
760A negative value may be returned in case of parsing error.
761If the certificate does not contain the keyUsage extension
762GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
763@end deftypefun
764
765@subheading gnutls_x509_crt_get_proxy
766@anchor{gnutls_x509_crt_get_proxy}
767@deftypefun {int} {gnutls_x509_crt_get_proxy} (gnutls_x509_crt_t @var{cert}, unsigned int * @var{critical}, int * @var{pathlen}, char ** @var{policyLanguage}, char ** @var{policy}, size_t * @var{sizeof_policy})
768@var{cert}: should contain a gnutls_x509_crt_t structure
769
770@var{critical}: will be non zero if the extension is marked as critical
771
772@var{pathlen}: pointer to output integer indicating path length (may be
773NULL), non-negative values indicate a present pCPathLenConstraint
774field and the actual value, -1 indicate that the field is absent.
775
776This function will read the certificate's basic constraints, and
777return the certificates CA status. It reads the basicConstraints
778X.509 extension (2.5.29.19).
779
780@strong{Return value:} If the certificate is a CA a positive value will be
781returned, or zero if the certificate does not have CA flag set. A
782negative value may be returned in case of errors. If the
783certificate does not contain the basicConstraints extension
784GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
785@end deftypefun
786
787@subheading gnutls_x509_crt_get_extension_by_oid
788@anchor{gnutls_x509_crt_get_extension_by_oid}
789@deftypefun {int} {gnutls_x509_crt_get_extension_by_oid} (gnutls_x509_crt_t @var{cert}, const char * @var{oid}, int @var{indx}, void * @var{buf}, size_t * @var{sizeof_buf}, unsigned int * @var{critical})
790@var{cert}: should contain a gnutls_x509_crt_t structure
791
792@var{oid}: holds an Object Identified in null terminated string
793
794@var{indx}: In case multiple same OIDs exist in the extensions, this specifies which to send. Use zero to get the first one.
795
796@var{buf}: a pointer to a structure to hold the name (may be null)
797
798@var{sizeof_buf}: initially holds the size of @code{buf}
799
800@var{critical}: will be non zero if the extension is marked as critical
801
802This function will return the extension specified by the OID in the certificate.
803The extensions will be returned as binary data DER encoded, in the provided
804buffer.
805
806A negative value may be returned in case of parsing error.
807If the certificate does not contain the specified extension
808GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
809@end deftypefun
810
811@subheading gnutls_x509_crt_get_extension_oid
812@anchor{gnutls_x509_crt_get_extension_oid}
813@deftypefun {int} {gnutls_x509_crt_get_extension_oid} (gnutls_x509_crt_t @var{cert}, int @var{indx}, void * @var{oid}, size_t * @var{sizeof_oid})
814@var{cert}: should contain a gnutls_x509_crt_t structure
815
816@var{indx}: Specifies which extension OID to send. Use zero to get the first one.
817
818@var{oid}: a pointer to a structure to hold the OID (may be null)
819
820@var{sizeof_oid}: initially holds the size of @code{oid}
821
822This function will return the requested extension OID in the certificate.
823The extension OID will be stored as a string in the provided buffer.
824
825A negative value may be returned in case of parsing error.
826If your have reached the last extension available
827GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
828@end deftypefun
829
830@subheading gnutls_x509_crt_get_extension_info
831@anchor{gnutls_x509_crt_get_extension_info}
832@deftypefun {int} {gnutls_x509_crt_get_extension_info} (gnutls_x509_crt_t @var{cert}, int @var{indx}, void * @var{oid}, size_t * @var{sizeof_oid}, int * @var{critical})
833@var{cert}: should contain a gnutls_x509_crt_t structure
834
835@var{indx}: Specifies which extension OID to send. Use zero to get the first one.
836
837@var{oid}: a pointer to a structure to hold the OID
838
839@var{sizeof_oid}: initially holds the size of @code{oid}
840
841@var{critical}: output variable with critical flag, may be NULL.
842
843This function will return the requested extension OID in the
844certificate, and the critical flag for it. The extension OID will
845be stored as a string in the provided buffer. Use
846@code{gnutls_x509_crt_get_extension_data()} to extract the data.
847
848Return 0 on success. A negative value may be returned in case of
849parsing error. If you have reached the last extension available
850GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
851@end deftypefun
852
853@subheading gnutls_x509_crt_get_extension_data
854@anchor{gnutls_x509_crt_get_extension_data}
855@deftypefun {int} {gnutls_x509_crt_get_extension_data} (gnutls_x509_crt_t @var{cert}, int @var{indx}, void * @var{data}, size_t * @var{sizeof_data})
856@var{cert}: should contain a gnutls_x509_crt_t structure
857
858@var{indx}: Specifies which extension OID to send. Use zero to get the first one.
859
860@var{data}: a pointer to a structure to hold the data (may be null)
861
862@var{sizeof_data}: initially holds the size of @code{oid}
863
864This function will return the requested extension data in the
865certificate. The extension data will be stored as a string in the
866provided buffer.
867
868Use @code{gnutls_x509_crt_get_extension_info()} to extract the OID and
869critical flag. Use @code{gnutls_x509_crt_get_extension_by_oid()} instead,
870if you want to get data indexed by the extension OID rather than
871sequence.
872
873Return 0 on success. A negative value may be returned in case of
874parsing error. If you have reached the last extension available
875GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
876@end deftypefun
877
878@subheading gnutls_x509_crt_get_raw_issuer_dn
879@anchor{gnutls_x509_crt_get_raw_issuer_dn}
880@deftypefun {int} {gnutls_x509_crt_get_raw_issuer_dn} (gnutls_x509_crt_t @var{cert}, gnutls_datum_t * @var{start})
881@var{cert}: should contain a gnutls_x509_crt_t structure
882
883@var{start}: will hold the starting point of the DN
884
885This function will return a pointer to the DER encoded DN structure
886and the length.
887
888Returns 0 on success or a negative value on error.
889@end deftypefun
890
891@subheading gnutls_x509_crt_get_raw_dn
892@anchor{gnutls_x509_crt_get_raw_dn}
893@deftypefun {int} {gnutls_x509_crt_get_raw_dn} (gnutls_x509_crt_t @var{cert}, gnutls_datum_t * @var{start})
894@var{cert}: should contain a gnutls_x509_crt_t structure
895
896@var{start}: will hold the starting point of the DN
897
898This function will return a pointer to the DER encoded DN structure and
899the length.
900
901Returns 0 on success, or a negative value on error.
902@end deftypefun
903
904@subheading gnutls_x509_crt_get_subject
905@anchor{gnutls_x509_crt_get_subject}
906@deftypefun {int} {gnutls_x509_crt_get_subject} (gnutls_x509_crt_t @var{cert}, gnutls_x509_dn_t * @var{dn})
907@var{cert}: should contain a gnutls_x509_crt_t structure
908
909@var{dn}: output variable with pointer to opaque DN.
910
911Return the Certificate's Subject DN as an opaque data type. You
912may use @code{gnutls_x509_dn_get_rdn_ava()} to decode the DN.
913
914@strong{Returns:} Returns 0 on success, or an error code.
915@end deftypefun
916
917@subheading gnutls_x509_crt_get_issuer
918@anchor{gnutls_x509_crt_get_issuer}
919@deftypefun {int} {gnutls_x509_crt_get_issuer} (gnutls_x509_crt_t @var{cert}, gnutls_x509_dn_t * @var{dn})
920@var{cert}: should contain a gnutls_x509_crt_t structure
921
922@var{dn}: output variable with pointer to opaque DN
923
924Return the Certificate's Issuer DN as an opaque data type. You may
925use @code{gnutls_x509_dn_get_rdn_ava()} to decode the DN.
926
927Note that @code{dn} points into the @code{cert} object, and thus you may not
928deallocate @code{cert} and continue to access @code{dn}.
929
930@strong{Returns:} Returns 0 on success, or an error code.
931@end deftypefun
932
933@subheading gnutls_x509_dn_get_rdn_ava
934@anchor{gnutls_x509_dn_get_rdn_ava}
935@deftypefun {int} {gnutls_x509_dn_get_rdn_ava} (gnutls_x509_dn_t @var{dn}, int @var{irdn}, int @var{iava}, gnutls_x509_ava_st * @var{ava})
936@var{dn}: input variable with opaque DN pointer
937
938@var{irdn}: index of RDN
939
940@var{iava}: index of AVA.
941
942@var{ava}: Pointer to structure which will hold output information.
943
944Get pointers to data within the DN.
945
946Note that @code{ava} will contain pointers into the @code{dn} structure, so you
947should not modify any data or deallocate it. Note also that the DN
948in turn points into the original certificate structure, and thus
949you may not deallocate the certificate and continue to access @code{dn}.
950
951@strong{Returns:} Returns 0 on success, or an error code.
952@end deftypefun
953
954@subheading gnutls_x509_crt_get_fingerprint
955@anchor{gnutls_x509_crt_get_fingerprint}
956@deftypefun {int} {gnutls_x509_crt_get_fingerprint} (gnutls_x509_crt_t @var{cert}, gnutls_digest_algorithm_t @var{algo}, void * @var{buf}, size_t * @var{sizeof_buf})
957@var{cert}: should contain a gnutls_x509_crt_t structure
958
959@var{algo}: is a digest algorithm
960
961@var{buf}: a pointer to a structure to hold the fingerprint (may be null)
962
963@var{sizeof_buf}: initially holds the size of @code{buf}
964
965This function will calculate and copy the certificate's fingerprint
966in the provided buffer.
967
968If the buffer is null then only the size will be filled.
969
970@strong{Returns:} @code{GNUTLS_E_SHORT_MEMORY_BUFFER} if the provided buffer is
971not long enough, and in that case the *sizeof_buf will be updated
972with the required size. On success 0 is returned.
973@end deftypefun
974
975@subheading gnutls_x509_crt_export
976@anchor{gnutls_x509_crt_export}
977@deftypefun {int} {gnutls_x509_crt_export} (gnutls_x509_crt_t @var{cert}, gnutls_x509_crt_fmt_t @var{format}, void * @var{output_data}, size_t * @var{output_data_size})
978@var{cert}: Holds the certificate
979
980@var{format}: the format of output params. One of PEM or DER.
981
982@var{output_data}: will contain a certificate PEM or DER encoded
983
984@var{output_data_size}: holds the size of output_data (and will be
985replaced by the actual size of parameters)
986
987This function will export the certificate to DER or PEM format.
988
989If the buffer provided is not long enough to hold the output, then
990*output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
991be returned.
992
993If the structure is PEM encoded, it will have a header
994of "BEGIN CERTIFICATE".
995
996@strong{Return value:} In case of failure a negative value will be
997returned, and 0 on success.
998@end deftypefun
999
1000@subheading gnutls_x509_crt_get_key_id
1001@anchor{gnutls_x509_crt_get_key_id}
1002@deftypefun {int} {gnutls_x509_crt_get_key_id} (gnutls_x509_crt_t @var{crt}, unsigned int @var{flags}, unsigned char * @var{output_data}, size_t * @var{output_data_size})
1003@var{crt}: Holds the certificate
1004
1005@var{flags}: should be 0 for now
1006
1007@var{output_data}: will contain the key ID
1008
1009@var{output_data_size}: holds the size of output_data (and will be
1010replaced by the actual size of parameters)
1011
1012This function will return a unique ID the depends on the public
1013key parameters. This ID can be used in checking whether a
1014certificate corresponds to the given private key.
1015
1016If the buffer provided is not long enough to hold the output, then
1017*output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
1018be returned. The output will normally be a SHA-1 hash output,
1019which is 20 bytes.
1020
1021@strong{Return value:} In case of failure a negative value will be
1022returned, and 0 on success.
1023@end deftypefun
1024
1025@subheading gnutls_x509_crt_check_revocation
1026@anchor{gnutls_x509_crt_check_revocation}
1027@deftypefun {int} {gnutls_x509_crt_check_revocation} (gnutls_x509_crt_t @var{cert}, const gnutls_x509_crl_t * @var{crl_list}, int @var{crl_list_length})
1028@var{cert}: should contain a gnutls_x509_crt_t structure
1029
1030@var{crl_list}: should contain a list of gnutls_x509_crl_t structures
1031
1032@var{crl_list_length}: the length of the crl_list
1033
1034This function will return check if the given certificate is
1035revoked. It is assumed that the CRLs have been verified before.
1036
1037@strong{Returns:} 0 if the certificate is NOT revoked, and 1 if it is. A
1038negative value is returned on error.
1039@end deftypefun
1040
1041@subheading gnutls_x509_crt_verify_data
1042@anchor{gnutls_x509_crt_verify_data}
1043@deftypefun {int} {gnutls_x509_crt_verify_data} (gnutls_x509_crt_t @var{crt}, unsigned int @var{flags}, const gnutls_datum_t * @var{data}, const gnutls_datum_t * @var{signature})
1044@var{crt}: Holds the certificate
1045
1046@var{flags}: should be 0 for now
1047
1048@var{data}: holds the data to be signed
1049
1050@var{signature}: contains the signature
1051
1052This function will verify the given signed data, using the
1053parameters from the certificate.
1054
1055@strong{Returns:} In case of a verification failure 0 is returned, and 1 on
1056success.
1057@end deftypefun
1058
1059@subheading gnutls_x509_crt_get_crl_dist_points
1060@anchor{gnutls_x509_crt_get_crl_dist_points}
1061@deftypefun {int} {gnutls_x509_crt_get_crl_dist_points} (gnutls_x509_crt_t @var{cert}, unsigned int @var{seq}, void * @var{ret}, size_t * @var{ret_size}, unsigned int * @var{reason_flags}, unsigned int * @var{critical})
1062@var{cert}: should contain a gnutls_x509_crt_t structure
1063
1064@var{seq}: specifies the sequence number of the distribution point (0 for the first one, 1 for the second etc.)
1065
1066@var{ret}: is the place where the distribution point will be copied to
1067
1068@var{ret_size}: holds the size of ret.
1069
1070@var{reason_flags}: Revocation reasons flags.
1071
1072@var{critical}: will be non zero if the extension is marked as critical (may be null)
1073
1074This function will return the CRL distribution points (2.5.29.31),
1075contained in the given certificate.
1076
1077@code{reason_flags} should be an ORed sequence of
1078GNUTLS_CRL_REASON_UNUSED, GNUTLS_CRL_REASON_KEY_COMPROMISE,
1079GNUTLS_CRL_REASON_CA_COMPROMISE,
1080GNUTLS_CRL_REASON_AFFILIATION_CHANGED,
1081GNUTLS_CRL_REASON_SUPERSEEDED,
1082GNUTLS_CRL_REASON_CESSATION_OF_OPERATION,
1083GNUTLS_CRL_REASON_CERTIFICATE_HOLD,
1084GNUTLS_CRL_REASON_PRIVILEGE_WITHDRAWN,
1085GNUTLS_CRL_REASON_AA_COMPROMISE, or zero for all possible reasons.
1086
1087This is specified in X509v3 Certificate Extensions. GNUTLS will
1088return the distribution point type, or a negative error code on
1089error.
1090
1091Returns @code{GNUTLS_E_SHORT_MEMORY_BUFFER} and updates &@code{ret_size} if
1092&@code{ret_size} is not enough to hold the distribution point, or the
1093type of the distribution point if everything was ok. The type is
1094one of the enumerated @code{gnutls_x509_subject_alt_name_t}. If the
1095certificate does not have an Alternative name with the specified
1096sequence number then @code{GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE} is
1097returned.
1098@end deftypefun
1099
1100@subheading gnutls_x509_crt_get_key_purpose_oid
1101@anchor{gnutls_x509_crt_get_key_purpose_oid}
1102@deftypefun {int} {gnutls_x509_crt_get_key_purpose_oid} (gnutls_x509_crt_t @var{cert}, int @var{indx}, void * @var{oid}, size_t * @var{sizeof_oid}, unsigned int * @var{critical})
1103@var{cert}: should contain a gnutls_x509_crt_t structure
1104
1105@var{indx}: This specifies which OID to return. Use zero to get the first one.
1106
1107@var{oid}: a pointer to a buffer to hold the OID (may be null)
1108
1109@var{sizeof_oid}: initially holds the size of @code{oid}
1110
1111This function will extract the key purpose OIDs of the Certificate
1112specified by the given index. These are stored in the Extended Key
1113Usage extension (2.5.29.37) See the GNUTLS_KP_* definitions for
1114human readable names.
1115
1116If @code{oid} is null then only the size will be filled.
1117
1118@strong{Returns:} @code{GNUTLS_E_SHORT_MEMORY_BUFFER} if the provided buffer is
1119not long enough, and in that case the *sizeof_oid will be updated
1120with the required size. On success 0 is returned.
1121@end deftypefun
1122
1123@subheading gnutls_x509_crt_get_pk_rsa_raw
1124@anchor{gnutls_x509_crt_get_pk_rsa_raw}
1125@deftypefun {int} {gnutls_x509_crt_get_pk_rsa_raw} (gnutls_x509_crt_t @var{crt}, gnutls_datum_t * @var{m}, gnutls_datum_t * @var{e})
1126@var{crt}: Holds the certificate
1127
1128@var{m}: will hold the modulus
1129
1130@var{e}: will hold the public exponent
1131
1132This function will export the RSA public key's parameters found in
1133the given structure. The new parameters will be allocated using
1134@code{gnutls_malloc()} and will be stored in the appropriate datum.
1135
1136@strong{Returns:} @code{GNUTLS_E_SUCCESS} on success, otherwise an error.
1137@end deftypefun
1138
1139@subheading gnutls_x509_crt_get_pk_dsa_raw
1140@anchor{gnutls_x509_crt_get_pk_dsa_raw}
1141@deftypefun {int} {gnutls_x509_crt_get_pk_dsa_raw} (gnutls_x509_crt_t @var{crt}, gnutls_datum_t * @var{p}, gnutls_datum_t * @var{q}, gnutls_datum_t * @var{g}, gnutls_datum_t * @var{y})
1142@var{crt}: Holds the certificate
1143
1144@var{p}: will hold the p
1145
1146@var{q}: will hold the q
1147
1148@var{g}: will hold the g
1149
1150@var{y}: will hold the y
1151
1152This function will export the DSA public key's parameters found in
1153the given certificate. The new parameters will be allocated using
1154@code{gnutls_malloc()} and will be stored in the appropriate datum.
1155
1156@strong{Returns:} @code{GNUTLS_E_SUCCESS} on success, otherwise an error.
1157@end deftypefun
1158
1159@subheading gnutls_x509_crt_list_import
1160@anchor{gnutls_x509_crt_list_import}
1161@deftypefun {int} {gnutls_x509_crt_list_import} (gnutls_x509_crt_t * @var{certs}, unsigned int * @var{cert_max}, const gnutls_datum_t * @var{data}, gnutls_x509_crt_fmt_t @var{format}, unsigned int @var{flags})
1162@var{certs}: The structures to store the parsed certificate. Must not be initialized.
1163
1164@var{cert_max}: Initially must hold the maximum number of certs. It will be updated with the number of certs available.
1165
1166@var{data}: The PEM encoded certificate.
1167
1168@var{format}: One of DER or PEM.
1169
1170@var{flags}: must be zero or an OR'd sequence of gnutls_certificate_import_flags.
1171
1172This function will convert the given PEM encoded certificate list
1173to the native gnutls_x509_crt_t format. The output will be stored
1174in @code{certs}. They will be automatically initialized.
1175
1176If the Certificate is PEM encoded it should have a header of "X509
1177CERTIFICATE", or "CERTIFICATE".
1178
1179@strong{Returns:} the number of certificates read or a negative error value.
1180@end deftypefun
1181
1182@subheading gnutls_x509_crt_check_hostname
1183@anchor{gnutls_x509_crt_check_hostname}
1184@deftypefun {int} {gnutls_x509_crt_check_hostname} (gnutls_x509_crt_t @var{cert}, const char * @var{hostname})
1185@var{cert}: should contain an gnutls_x509_crt_t structure
1186
1187@var{hostname}: A null terminated string that contains a DNS name
1188
1189This function will check if the given certificate's subject
1190matches the given hostname. This is a basic implementation of the
1191matching described in RFC2818 (HTTPS), which takes into account
1192wildcards, and the DNSName/IPAddress subject alternative name PKIX
1193extension.
1194
1195Returns non zero for a successful match, and zero on failure.
1196@end deftypefun
1197
1198@subheading gnutls_x509_crt_check_issuer
1199@anchor{gnutls_x509_crt_check_issuer}
1200@deftypefun {int} {gnutls_x509_crt_check_issuer} (gnutls_x509_crt_t @var{cert}, gnutls_x509_crt_t @var{issuer})
1201@var{cert}: is the certificate to be checked
1202
1203@var{issuer}: is the certificate of a possible issuer
1204
1205This function will check if the given certificate was issued by the
1206given issuer. It will return true (1) if the given certificate is issued
1207by the given issuer, and false (0) if not.
1208
1209A negative value is returned in case of an error.
1210@end deftypefun
1211
1212@subheading gnutls_x509_crt_list_verify
1213@anchor{gnutls_x509_crt_list_verify}
1214@deftypefun {int} {gnutls_x509_crt_list_verify} (const gnutls_x509_crt_t * @var{cert_list}, int @var{cert_list_length}, const gnutls_x509_crt_t * @var{CA_list}, int @var{CA_list_length}, const gnutls_x509_crl_t * @var{CRL_list}, int @var{CRL_list_length}, unsigned int @var{flags}, unsigned int * @var{verify})
1215@var{cert_list}: is the certificate list to be verified
1216
1217@var{cert_list_length}: holds the number of certificate in cert_list
1218
1219@var{CA_list}: is the CA list which will be used in verification
1220
1221@var{CA_list_length}: holds the number of CA certificate in CA_list
1222
1223@var{CRL_list}: holds a list of CRLs.
1224
1225@var{CRL_list_length}: the length of CRL list.
1226
1227@var{flags}: Flags that may be used to change the verification algorithm. Use OR of the gnutls_certificate_verify_flags enumerations.
1228
1229@var{verify}: will hold the certificate verification output.
1230
1231This function will try to verify the given certificate list and return its status.
1232Note that expiration and activation dates are not checked
1233by this function, you should check them using the appropriate functions.
1234
1235If no flags are specified (0), this function will use the
1236basicConstraints (2.5.29.19) PKIX extension. This means that only a certificate
1237authority is allowed to sign a certificate.
1238
1239You must also check the peer's name in order to check if the verified
1240certificate belongs to the actual peer.
1241
1242The certificate verification output will be put in @code{verify} and will be
1243one or more of the gnutls_certificate_status_t enumerated elements bitwise or'd.
1244For a more detailed verification status use @code{gnutls_x509_crt_verify()} per list
1245element.
1246
1247@strong{GNUTLS_CERT_INVALID:} the certificate chain is not valid.
1248
1249@strong{GNUTLS_CERT_REVOKED:} a certificate in the chain has been revoked.
1250
1251Returns 0 on success and a negative value in case of an error.
1252@end deftypefun
1253
1254@subheading gnutls_x509_crt_verify
1255@anchor{gnutls_x509_crt_verify}
1256@deftypefun {int} {gnutls_x509_crt_verify} (gnutls_x509_crt_t @var{cert}, const gnutls_x509_crt_t * @var{CA_list}, int @var{CA_list_length}, unsigned int @var{flags}, unsigned int * @var{verify})
1257@var{cert}: is the certificate to be verified
1258
1259@var{CA_list}: is one certificate that is considered to be trusted one
1260
1261@var{CA_list_length}: holds the number of CA certificate in CA_list
1262
1263@var{flags}: Flags that may be used to change the verification algorithm. Use OR of the gnutls_certificate_verify_flags enumerations.
1264
1265@var{verify}: will hold the certificate verification output.
1266
1267This function will try to verify the given certificate and return its status.
1268The verification output in this functions cannot be GNUTLS_CERT_NOT_VALID.
1269
1270Returns 0 on success and a negative value in case of an error.
1271@end deftypefun
1272
1273@subheading gnutls_x509_crl_check_issuer
1274@anchor{gnutls_x509_crl_check_issuer}
1275@deftypefun {int} {gnutls_x509_crl_check_issuer} (gnutls_x509_crl_t @var{cert}, gnutls_x509_crt_t @var{issuer})
1276@var{issuer}: is the certificate of a possible issuer
1277
1278This function will check if the given CRL was issued by the
1279given issuer certificate. It will return true (1) if the given CRL was issued
1280by the given issuer, and false (0) if not.
1281
1282A negative value is returned in case of an error.
1283@end deftypefun
1284
1285@subheading gnutls_x509_crl_verify
1286@anchor{gnutls_x509_crl_verify}
1287@deftypefun {int} {gnutls_x509_crl_verify} (gnutls_x509_crl_t @var{crl}, const gnutls_x509_crt_t * @var{CA_list}, int @var{CA_list_length}, unsigned int @var{flags}, unsigned int * @var{verify})
1288@var{crl}: is the crl to be verified
1289
1290@var{CA_list}: is a certificate list that is considered to be trusted one
1291
1292@var{CA_list_length}: holds the number of CA certificates in CA_list
1293
1294@var{flags}: Flags that may be used to change the verification algorithm. Use OR of the gnutls_certificate_verify_flags enumerations.
1295
1296@var{verify}: will hold the crl verification output.
1297
1298This function will try to verify the given crl and return its status.
1299See @code{gnutls_x509_crt_list_verify()} for a detailed description of
1300return values.
1301
1302Returns 0 on success and a negative value in case of an error.
1303@end deftypefun
1304
1305@subheading gnutls_x509_privkey_init
1306@anchor{gnutls_x509_privkey_init}
1307@deftypefun {int} {gnutls_x509_privkey_init} (gnutls_x509_privkey_t * @var{key})
1308@var{key}: The structure to be initialized
1309
1310This function will initialize an private key structure.
1311
1312Returns 0 on success.
1313@end deftypefun
1314
1315@subheading gnutls_x509_privkey_deinit
1316@anchor{gnutls_x509_privkey_deinit}
1317@deftypefun {void} {gnutls_x509_privkey_deinit} (gnutls_x509_privkey_t @var{key})
1318@var{key}: The structure to be initialized
1319
1320This function will deinitialize a private key structure.
1321@end deftypefun
1322
1323@subheading gnutls_x509_privkey_cpy
1324@anchor{gnutls_x509_privkey_cpy}
1325@deftypefun {int} {gnutls_x509_privkey_cpy} (gnutls_x509_privkey_t @var{dst}, gnutls_x509_privkey_t @var{src})
1326@var{dst}: The destination key, which should be initialized.
1327
1328@var{src}: The source key
1329
1330This function will copy a private key from source to destination key.
1331@end deftypefun
1332
1333@subheading gnutls_x509_privkey_import
1334@anchor{gnutls_x509_privkey_import}
1335@deftypefun {int} {gnutls_x509_privkey_import} (gnutls_x509_privkey_t @var{key}, const gnutls_datum_t * @var{data}, gnutls_x509_crt_fmt_t @var{format})
1336@var{key}: The structure to store the parsed key
1337
1338@var{data}: The DER or PEM encoded certificate.
1339
1340@var{format}: One of DER or PEM
1341
1342This function will convert the given DER or PEM encoded key
1343to the native gnutls_x509_privkey_t format. The output will be stored in @code{key} .
1344
1345If the key is PEM encoded it should have a header of "RSA PRIVATE KEY", or
1346"DSA PRIVATE KEY".
1347
1348Returns 0 on success.
1349@end deftypefun
1350
1351@subheading gnutls_x509_privkey_import_rsa_raw
1352@anchor{gnutls_x509_privkey_import_rsa_raw}
1353@deftypefun {int} {gnutls_x509_privkey_import_rsa_raw} (gnutls_x509_privkey_t @var{key}, const gnutls_datum_t * @var{m}, const gnutls_datum_t * @var{e}, const gnutls_datum_t * @var{d}, const gnutls_datum_t * @var{p}, const gnutls_datum_t * @var{q}, const gnutls_datum_t * @var{u})
1354@var{key}: The structure to store the parsed key
1355
1356@var{m}: holds the modulus
1357
1358@var{e}: holds the public exponent
1359
1360@var{d}: holds the private exponent
1361
1362@var{p}: holds the first prime (p)
1363
1364@var{q}: holds the second prime (q)
1365
1366@var{u}: holds the coefficient
1367
1368This function will convert the given RSA raw parameters
1369to the native gnutls_x509_privkey_t format. The output will be stored in @code{key}.
1370@end deftypefun
1371
1372@subheading gnutls_x509_privkey_import_dsa_raw
1373@anchor{gnutls_x509_privkey_import_dsa_raw}
1374@deftypefun {int} {gnutls_x509_privkey_import_dsa_raw} (gnutls_x509_privkey_t @var{key}, const gnutls_datum_t * @var{p}, const gnutls_datum_t * @var{q}, const gnutls_datum_t * @var{g}, const gnutls_datum_t * @var{y}, const gnutls_datum_t * @var{x})
1375@var{key}: The structure to store the parsed key
1376
1377@var{p}: holds the p
1378
1379@var{q}: holds the q
1380
1381@var{g}: holds the g
1382
1383@var{y}: holds the y
1384
1385@var{x}: holds the x
1386
1387This function will convert the given DSA raw parameters
1388to the native gnutls_x509_privkey_t format. The output will be stored in @code{key}.
1389@end deftypefun
1390
1391@subheading gnutls_x509_privkey_get_pk_algorithm
1392@anchor{gnutls_x509_privkey_get_pk_algorithm}
1393@deftypefun {int} {gnutls_x509_privkey_get_pk_algorithm} (gnutls_x509_privkey_t @var{key})
1394@var{key}: should contain a gnutls_x509_privkey_t structure
1395
1396This function will return the public key algorithm of a private
1397key.
1398
1399Returns a member of the gnutls_pk_algorithm_t enumeration on success,
1400or a negative value on error.
1401@end deftypefun
1402
1403@subheading gnutls_x509_privkey_export
1404@anchor{gnutls_x509_privkey_export}
1405@deftypefun {int} {gnutls_x509_privkey_export} (gnutls_x509_privkey_t @var{key}, gnutls_x509_crt_fmt_t @var{format}, void * @var{output_data}, size_t * @var{output_data_size})
1406@var{key}: Holds the key
1407
1408@var{format}: the format of output params. One of PEM or DER.
1409
1410@var{output_data}: will contain a private key PEM or DER encoded
1411
1412@var{output_data_size}: holds the size of output_data (and will be
1413replaced by the actual size of parameters)
1414
1415This function will export the private key to a PKCS1 structure for
1416RSA keys, or an integer sequence for DSA keys. The DSA keys are in
1417the same format with the parameters used by openssl.
1418
1419If the buffer provided is not long enough to hold the output, then
1420*output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
1421be returned.
1422
1423If the structure is PEM encoded, it will have a header
1424of "BEGIN RSA PRIVATE KEY".
1425
1426@strong{Return value:} In case of failure a negative value will be
1427returned, and 0 on success.
1428@end deftypefun
1429
1430@subheading gnutls_x509_privkey_export_rsa_raw
1431@anchor{gnutls_x509_privkey_export_rsa_raw}
1432@deftypefun {int} {gnutls_x509_privkey_export_rsa_raw} (gnutls_x509_privkey_t @var{key}, gnutls_datum_t * @var{m}, gnutls_datum_t * @var{e}, gnutls_datum_t * @var{d}, gnutls_datum_t * @var{p}, gnutls_datum_t * @var{q}, gnutls_datum_t * @var{u})
1433@var{key}: a structure that holds the rsa parameters
1434
1435@var{m}: will hold the modulus
1436
1437@var{e}: will hold the public exponent
1438
1439@var{d}: will hold the private exponent
1440
1441@var{p}: will hold the first prime (p)
1442
1443@var{q}: will hold the second prime (q)
1444
1445@var{u}: will hold the coefficient
1446
1447This function will export the RSA private key's parameters found in the given
1448structure. The new parameters will be allocated using
1449@code{gnutls_malloc()} and will be stored in the appropriate datum.
1450@end deftypefun
1451
1452@subheading gnutls_x509_privkey_export_dsa_raw
1453@anchor{gnutls_x509_privkey_export_dsa_raw}
1454@deftypefun {int} {gnutls_x509_privkey_export_dsa_raw} (gnutls_x509_privkey_t @var{key}, gnutls_datum_t * @var{p}, gnutls_datum_t * @var{q}, gnutls_datum_t * @var{g}, gnutls_datum_t * @var{y}, gnutls_datum_t * @var{x})
1455@var{p}: will hold the p
1456
1457@var{q}: will hold the q
1458
1459@var{g}: will hold the g
1460
1461@var{y}: will hold the y
1462
1463@var{x}: will hold the x
1464
1465This function will export the DSA private key's parameters found in the given
1466structure. The new parameters will be allocated using
1467@code{gnutls_malloc()} and will be stored in the appropriate datum.
1468@end deftypefun
1469
1470@subheading gnutls_x509_privkey_generate
1471@anchor{gnutls_x509_privkey_generate}
1472@deftypefun {int} {gnutls_x509_privkey_generate} (gnutls_x509_privkey_t @var{key}, gnutls_pk_algorithm_t @var{algo}, unsigned int @var{bits}, unsigned int @var{flags})
1473@var{key}: should contain a gnutls_x509_privkey_t structure
1474
1475@var{algo}: is one of RSA or DSA.
1476
1477@var{bits}: the size of the modulus
1478
1479@var{flags}: unused for now. Must be 0.
1480
1481This function will generate a random private key. Note that
1482this function must be called on an empty private key.
1483
1484Returns 0 on success or a negative value on error.
1485@end deftypefun
1486
1487@subheading gnutls_x509_privkey_get_key_id
1488@anchor{gnutls_x509_privkey_get_key_id}
1489@deftypefun {int} {gnutls_x509_privkey_get_key_id} (gnutls_x509_privkey_t @var{key}, unsigned int @var{flags}, unsigned char * @var{output_data}, size_t * @var{output_data_size})
1490@var{key}: Holds the key
1491
1492@var{flags}: should be 0 for now
1493
1494@var{output_data}: will contain the key ID
1495
1496@var{output_data_size}: holds the size of output_data (and will be
1497replaced by the actual size of parameters)
1498
1499This function will return a unique ID the depends on the public key
1500parameters. This ID can be used in checking whether a certificate
1501corresponds to the given key.
1502
1503If the buffer provided is not long enough to hold the output, then
1504*output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
1505be returned. The output will normally be a SHA-1 hash output,
1506which is 20 bytes.
1507
1508@strong{Return value:} In case of failure a negative value will be
1509returned, and 0 on success.
1510@end deftypefun
1511
1512@subheading gnutls_x509_privkey_sign_data
1513@anchor{gnutls_x509_privkey_sign_data}
1514@deftypefun {int} {gnutls_x509_privkey_sign_data} (gnutls_x509_privkey_t @var{key}, gnutls_digest_algorithm_t @var{digest}, unsigned int @var{flags}, const gnutls_datum_t * @var{data}, void * @var{signature}, size_t * @var{signature_size})
1515@var{key}: Holds the key
1516
1517@var{digest}: should be MD5 or SHA1
1518
1519@var{flags}: should be 0 for now
1520
1521@var{data}: holds the data to be signed
1522
1523@var{signature}: will contain the signature
1524
1525@var{signature_size}: holds the size of signature (and will be replaced
1526by the new size)
1527
1528This function will sign the given data using a signature algorithm
1529supported by the private key. Signature algorithms are always used
1530together with a hash functions. Different hash functions may be
1531used for the RSA algorithm, but only SHA-1 for the DSA keys.
1532
1533If the buffer provided is not long enough to hold the output, then
1534*signature_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
1535be returned.
1536
1537In case of failure a negative value will be returned, and
15380 on success.
1539@end deftypefun
1540
1541@subheading gnutls_x509_privkey_sign_hash
1542@anchor{gnutls_x509_privkey_sign_hash}
1543@deftypefun {int} {gnutls_x509_privkey_sign_hash} (gnutls_x509_privkey_t @var{key}, const gnutls_datum_t * @var{hash}, gnutls_datum_t * @var{signature})
1544@var{key}: Holds the key
1545
1546@var{hash}: holds the data to be signed
1547
1548@var{signature}: will contain newly allocated signature
1549
1550This function will sign the given hash using the private key.
1551
1552@strong{Return value:} In case of failure a negative value will be returned,
1553and 0 on success.
1554@end deftypefun
1555
1556@subheading gnutls_x509_privkey_verify_data
1557@anchor{gnutls_x509_privkey_verify_data}
1558@deftypefun {int} {gnutls_x509_privkey_verify_data} (gnutls_x509_privkey_t @var{key}, unsigned int @var{flags}, const gnutls_datum_t * @var{data}, const gnutls_datum_t * @var{signature})
1559@var{key}: Holds the key
1560
1561@var{flags}: should be 0 for now
1562
1563@var{data}: holds the data to be signed
1564
1565@var{signature}: contains the signature
1566
1567This function will verify the given signed data, using the parameters in the
1568private key.
1569
1570In case of a verification failure 0 is returned, and
15711 on success.
1572@end deftypefun
1573
1574@subheading gnutls_x509_privkey_fix
1575@anchor{gnutls_x509_privkey_fix}
1576@deftypefun {int} {gnutls_x509_privkey_fix} (gnutls_x509_privkey_t @var{key})
1577@var{key}: Holds the key
1578
1579This function will recalculate the secondary parameters in a key.
1580In RSA keys, this can be the coefficient and exponent1,2.
1581
1582@strong{Return value:} In case of failure a negative value will be
1583returned, and 0 on success.
1584@end deftypefun
1585
1586@subheading gnutls_pkcs7_init
1587@anchor{gnutls_pkcs7_init}
1588@deftypefun {int} {gnutls_pkcs7_init} (gnutls_pkcs7_t * @var{pkcs7})
1589@var{pkcs7}: The structure to be initialized
1590
1591This function will initialize a PKCS7 structure. PKCS7 structures
1592usually contain lists of X.509 Certificates and X.509 Certificate
1593revocation lists.
1594
1595Returns 0 on success.
1596@end deftypefun
1597
1598@subheading gnutls_pkcs7_deinit
1599@anchor{gnutls_pkcs7_deinit}
1600@deftypefun {void} {gnutls_pkcs7_deinit} (gnutls_pkcs7_t @var{pkcs7})
1601@var{pkcs7}: The structure to be initialized
1602
1603This function will deinitialize a PKCS7 structure.
1604@end deftypefun
1605
1606@subheading gnutls_pkcs7_import
1607@anchor{gnutls_pkcs7_import}
1608@deftypefun {int} {gnutls_pkcs7_import} (gnutls_pkcs7_t @var{pkcs7}, const gnutls_datum_t * @var{data}, gnutls_x509_crt_fmt_t @var{format})
1609@var{pkcs7}: The structure to store the parsed PKCS7.
1610
1611@var{data}: The DER or PEM encoded PKCS7.
1612
1613@var{format}: One of DER or PEM
1614
1615This function will convert the given DER or PEM encoded PKCS7
1616to the native gnutls_pkcs7_t format. The output will be stored in 'pkcs7'.
1617
1618If the PKCS7 is PEM encoded it should have a header of "PKCS7".
1619
1620Returns 0 on success.
1621@end deftypefun
1622
1623@subheading gnutls_pkcs7_get_crt_raw
1624@anchor{gnutls_pkcs7_get_crt_raw}
1625@deftypefun {int} {gnutls_pkcs7_get_crt_raw} (gnutls_pkcs7_t @var{pkcs7}, int @var{indx}, void * @var{certificate}, size_t * @var{certificate_size})
1626@var{indx}: contains the index of the certificate to extract
1627
1628@var{certificate}: the contents of the certificate will be copied there (may be null)
1629
1630@var{certificate_size}: should hold the size of the certificate
1631
1632This function will return a certificate of the PKCS7 or RFC2630 certificate set.
1633Returns 0 on success. If the provided buffer is not long enough,
1634then @code{certificate_size} is updated and GNUTLS_E_SHORT_MEMORY_BUFFER is returned.
1635
1636After the last certificate has been read GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1637will be returned.
1638@end deftypefun
1639
1640@subheading gnutls_pkcs7_get_crt_count
1641@anchor{gnutls_pkcs7_get_crt_count}
1642@deftypefun {int} {gnutls_pkcs7_get_crt_count} (gnutls_pkcs7_t @var{pkcs7})
1643This function will return the number of certifcates in the PKCS7 or
1644RFC2630 certificate set.
1645
1646Returns a negative value on failure.
1647@end deftypefun
1648
1649@subheading gnutls_pkcs7_export
1650@anchor{gnutls_pkcs7_export}
1651@deftypefun {int} {gnutls_pkcs7_export} (gnutls_pkcs7_t @var{pkcs7}, gnutls_x509_crt_fmt_t @var{format}, void * @var{output_data}, size_t * @var{output_data_size})
1652@var{pkcs7}: Holds the pkcs7 structure
1653
1654@var{format}: the format of output params. One of PEM or DER.
1655
1656@var{output_data}: will contain a structure PEM or DER encoded
1657
1658@var{output_data_size}: holds the size of output_data (and will be
1659replaced by the actual size of parameters)
1660
1661This function will export the pkcs7 structure to DER or PEM format.
1662
1663If the buffer provided is not long enough to hold the output, then
1664*output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
1665be returned.
1666
1667If the structure is PEM encoded, it will have a header
1668of "BEGIN PKCS7".
1669
1670@strong{Return value:} In case of failure a negative value will be
1671returned, and 0 on success.
1672@end deftypefun
1673
1674@subheading gnutls_pkcs7_set_crt_raw
1675@anchor{gnutls_pkcs7_set_crt_raw}
1676@deftypefun {int} {gnutls_pkcs7_set_crt_raw} (gnutls_pkcs7_t @var{pkcs7}, const gnutls_datum_t * @var{crt})
1677@var{crt}: the DER encoded certificate to be added
1678
1679This function will add a certificate to the PKCS7 or RFC2630 certificate set.
1680Returns 0 on success.
1681@end deftypefun
1682
1683@subheading gnutls_pkcs7_set_crt
1684@anchor{gnutls_pkcs7_set_crt}
1685@deftypefun {int} {gnutls_pkcs7_set_crt} (gnutls_pkcs7_t @var{pkcs7}, gnutls_x509_crt_t @var{crt})
1686@var{crt}: the certificate to be copied.
1687
1688This function will add a parsed certificate to the PKCS7 or RFC2630 certificate set.
1689This is a wrapper function over @code{gnutls_pkcs7_set_crt_raw()} .
1690
1691Returns 0 on success.
1692@end deftypefun
1693
1694@subheading gnutls_pkcs7_delete_crt
1695@anchor{gnutls_pkcs7_delete_crt}
1696@deftypefun {int} {gnutls_pkcs7_delete_crt} (gnutls_pkcs7_t @var{pkcs7}, int @var{indx})
1697@var{indx}: the index of the certificate to delete
1698
1699This function will delete a certificate from a PKCS7 or RFC2630 certificate set.
1700Index starts from 0. Returns 0 on success.
1701@end deftypefun
1702
1703@subheading gnutls_pkcs7_get_crl_raw
1704@anchor{gnutls_pkcs7_get_crl_raw}
1705@deftypefun {int} {gnutls_pkcs7_get_crl_raw} (gnutls_pkcs7_t @var{pkcs7}, int @var{indx}, void * @var{crl}, size_t * @var{crl_size})
1706@var{indx}: contains the index of the crl to extract
1707
1708@var{crl}: the contents of the crl will be copied there (may be null)
1709
1710@var{crl_size}: should hold the size of the crl
1711
1712This function will return a crl of the PKCS7 or RFC2630 crl set.
1713Returns 0 on success. If the provided buffer is not long enough,
1714then @code{crl_size} is updated and GNUTLS_E_SHORT_MEMORY_BUFFER is returned.
1715
1716After the last crl has been read GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1717will be returned.
1718@end deftypefun
1719
1720@subheading gnutls_pkcs7_get_crl_count
1721@anchor{gnutls_pkcs7_get_crl_count}
1722@deftypefun {int} {gnutls_pkcs7_get_crl_count} (gnutls_pkcs7_t @var{pkcs7})
1723This function will return the number of certifcates in the PKCS7 or
1724RFC2630 crl set.
1725
1726Returns a negative value on failure.
1727@end deftypefun
1728
1729@subheading gnutls_pkcs7_set_crl_raw
1730@anchor{gnutls_pkcs7_set_crl_raw}
1731@deftypefun {int} {gnutls_pkcs7_set_crl_raw} (gnutls_pkcs7_t @var{pkcs7}, const gnutls_datum_t * @var{crl})
1732@var{crl}: the DER encoded crl to be added
1733
1734This function will add a crl to the PKCS7 or RFC2630 crl set.
1735Returns 0 on success.
1736@end deftypefun
1737
1738@subheading gnutls_pkcs7_set_crl
1739@anchor{gnutls_pkcs7_set_crl}
1740@deftypefun {int} {gnutls_pkcs7_set_crl} (gnutls_pkcs7_t @var{pkcs7}, gnutls_x509_crl_t @var{crl})
1741@var{crl}: the DER encoded crl to be added
1742
1743This function will add a parsed crl to the PKCS7 or RFC2630 crl set.
1744Returns 0 on success.
1745@end deftypefun
1746
1747@subheading gnutls_pkcs7_delete_crl
1748@anchor{gnutls_pkcs7_delete_crl}
1749@deftypefun {int} {gnutls_pkcs7_delete_crl} (gnutls_pkcs7_t @var{pkcs7}, int @var{indx})
1750@var{indx}: the index of the crl to delete
1751
1752This function will delete a crl from a PKCS7 or RFC2630 crl set.
1753Index starts from 0. Returns 0 on success.
1754@end deftypefun
1755
1756@subheading gnutls_x509_crq_init
1757@anchor{gnutls_x509_crq_init}
1758@deftypefun {int} {gnutls_x509_crq_init} (gnutls_x509_crq_t * @var{crq})
1759@var{crq}: The structure to be initialized
1760
1761This function will initialize a PKCS10 certificate request structure.
1762
1763Returns 0 on success.
1764@end deftypefun
1765
1766@subheading gnutls_x509_crq_deinit
1767@anchor{gnutls_x509_crq_deinit}
1768@deftypefun {void} {gnutls_x509_crq_deinit} (gnutls_x509_crq_t @var{crq})
1769@var{crq}: The structure to be initialized
1770
1771This function will deinitialize a CRL structure.
1772@end deftypefun
1773
1774@subheading gnutls_x509_crq_import
1775@anchor{gnutls_x509_crq_import}
1776@deftypefun {int} {gnutls_x509_crq_import} (gnutls_x509_crq_t @var{crq}, const gnutls_datum_t * @var{data}, gnutls_x509_crt_fmt_t @var{format})
1777@var{crq}: The structure to store the parsed certificate request.
1778
1779@var{data}: The DER or PEM encoded certificate.
1780
1781@var{format}: One of DER or PEM
1782
1783This function will convert the given DER or PEM encoded Certificate
1784to the native gnutls_x509_crq_t format. The output will be stored in @code{cert}.
1785
1786If the Certificate is PEM encoded it should have a header of "NEW CERTIFICATE REQUEST".
1787
1788Returns 0 on success.
1789@end deftypefun
1790
1791@subheading gnutls_x509_crq_get_dn
1792@anchor{gnutls_x509_crq_get_dn}
1793@deftypefun {int} {gnutls_x509_crq_get_dn} (gnutls_x509_crq_t @var{crq}, char * @var{buf}, size_t * @var{sizeof_buf})
1794@var{crq}: should contain a gnutls_x509_crq_t structure
1795
1796@var{buf}: a pointer to a structure to hold the name (may be null)
1797
1798@var{sizeof_buf}: initially holds the size of @code{buf}
1799
1800This function will copy the name of the Certificate request
1801subject in the provided buffer. The name will be in the form
1802"C=xxxx,O=yyyy,CN=zzzz" as described in RFC2253. The output string
1803will be ASCII or UTF-8 encoded, depending on the certificate data.
1804
1805If @code{buf} is null then only the size will be filled.
1806
1807Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
1808long enough, and in that case the *sizeof_buf will be updated with
1809the required size. On success 0 is returned.
1810@end deftypefun
1811
1812@subheading gnutls_x509_crq_get_dn_by_oid
1813@anchor{gnutls_x509_crq_get_dn_by_oid}
1814@deftypefun {int} {gnutls_x509_crq_get_dn_by_oid} (gnutls_x509_crq_t @var{crq}, const char * @var{oid}, int @var{indx}, unsigned int @var{raw_flag}, void * @var{buf}, size_t * @var{sizeof_buf})
1815@var{crq}: should contain a gnutls_x509_crq_t structure
1816
1817@var{oid}: holds an Object Identified in null terminated string
1818
1819@var{indx}: In case multiple same OIDs exist in the RDN, this specifies
1820which to send. Use zero to get the first one.
1821
1822@var{raw_flag}: If non zero returns the raw DER data of the DN part.
1823
1824@var{buf}: a pointer to a structure to hold the name (may be null)
1825
1826@var{sizeof_buf}: initially holds the size of @code{buf}
1827
1828This function will extract the part of the name of the Certificate
1829request subject, specified by the given OID. The output will be
1830encoded as described in RFC2253. The output string will be ASCII
1831or UTF-8 encoded, depending on the certificate data.
1832
1833Some helper macros with popular OIDs can be found in gnutls/x509.h
1834If raw flag is zero, this function will only return known OIDs as
1835text. Other OIDs will be DER encoded, as described in RFC2253 --
1836in hex format with a '\#' prefix. You can check about known OIDs
1837using @code{gnutls_x509_dn_oid_known()}.
1838
1839If @code{buf} is null then only the size will be filled.
1840
1841Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
1842long enough, and in that case the *sizeof_buf will be updated with
1843the required size. On success 0 is returned.
1844@end deftypefun
1845
1846@subheading gnutls_x509_crq_get_dn_oid
1847@anchor{gnutls_x509_crq_get_dn_oid}
1848@deftypefun {int} {gnutls_x509_crq_get_dn_oid} (gnutls_x509_crq_t @var{crq}, int @var{indx}, void * @var{oid}, size_t * @var{sizeof_oid})
1849@var{crq}: should contain a gnutls_x509_crq_t structure
1850
1851@var{indx}: Specifies which DN OID to send. Use zero to get the first one.
1852
1853@var{oid}: a pointer to a structure to hold the name (may be null)
1854
1855@var{sizeof_oid}: initially holds the size of @code{oid}
1856
1857This function will extract the requested OID of the name of the
1858Certificate request subject, specified by the given index.
1859
1860If oid is null then only the size will be filled.
1861
1862Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
1863long enough, and in that case the *sizeof_oid will be updated with
1864the required size. On success 0 is returned.
1865@end deftypefun
1866
1867@subheading gnutls_x509_crq_get_challenge_password
1868@anchor{gnutls_x509_crq_get_challenge_password}
1869@deftypefun {int} {gnutls_x509_crq_get_challenge_password} (gnutls_x509_crq_t @var{crq}, char * @var{pass}, size_t * @var{sizeof_pass})
1870@var{crq}: should contain a gnutls_x509_crq_t structure
1871
1872@var{pass}: will hold a null terminated password
1873
1874@var{sizeof_pass}: Initially holds the size of @code{pass}.
1875
1876This function will return the challenge password in the
1877request.
1878
1879Returns 0 on success.
1880@end deftypefun
1881
1882@subheading gnutls_x509_crq_set_attribute_by_oid
1883@anchor{gnutls_x509_crq_set_attribute_by_oid}
1884@deftypefun {int} {gnutls_x509_crq_set_attribute_by_oid} (gnutls_x509_crq_t @var{crq}, const char * @var{oid}, void * @var{buf}, size_t @var{sizeof_buf})
1885@var{crq}: should contain a gnutls_x509_crq_t structure
1886
1887@var{oid}: holds an Object Identified in null terminated string
1888
1889@var{buf}: a pointer to a structure that holds the attribute data
1890
1891@var{sizeof_buf}: holds the size of @code{buf}
1892
1893This function will set the attribute in the certificate request specified
1894by the given Object ID. The attribute must be be DER encoded.
1895
1896Returns 0 on success.
1897@end deftypefun
1898
1899@subheading gnutls_x509_crq_get_attribute_by_oid
1900@anchor{gnutls_x509_crq_get_attribute_by_oid}
1901@deftypefun {int} {gnutls_x509_crq_get_attribute_by_oid} (gnutls_x509_crq_t @var{crq}, const char * @var{oid}, int @var{indx}, void * @var{buf}, size_t * @var{sizeof_buf})
1902@var{crq}: should contain a gnutls_x509_crq_t structure
1903
1904@var{oid}: holds an Object Identified in null terminated string
1905
1906@var{indx}: In case multiple same OIDs exist in the attribute list, this specifies
1907which to send. Use zero to get the first one.
1908
1909@var{buf}: a pointer to a structure to hold the attribute data (may be null)
1910
1911@var{sizeof_buf}: initially holds the size of @code{buf}
1912
1913This function will return the attribute in the certificate request specified
1914by the given Object ID. The attribute will be DER encoded.
1915
1916Returns 0 on success.
1917@end deftypefun
1918
1919@subheading gnutls_x509_crq_set_dn_by_oid
1920@anchor{gnutls_x509_crq_set_dn_by_oid}
1921@deftypefun {int} {gnutls_x509_crq_set_dn_by_oid} (gnutls_x509_crq_t @var{crq}, const char * @var{oid}, unsigned int @var{raw_flag}, const void * @var{data}, unsigned int @var{sizeof_data})
1922@var{crq}: should contain a gnutls_x509_crq_t structure
1923
1924@var{oid}: holds an Object Identifier in a null terminated string
1925
1926@var{raw_flag}: must be 0, or 1 if the data are DER encoded
1927
1928@var{data}: a pointer to the input data
1929
1930@var{sizeof_data}: holds the size of @code{data}
1931
1932This function will set the part of the name of the Certificate request subject, specified
1933by the given OID. The input string should be ASCII or UTF-8 encoded.
1934
1935Some helper macros with popular OIDs can be found in gnutls/x509.h
1936With this function you can only set the known OIDs. You can test
1937for known OIDs using @code{gnutls_x509_dn_oid_known()}. For OIDs that are
1938not known (by gnutls) you should properly DER encode your data, and
1939call this function with raw_flag set.
1940
1941Returns 0 on success.
1942@end deftypefun
1943
1944@subheading gnutls_x509_crq_set_version
1945@anchor{gnutls_x509_crq_set_version}
1946@deftypefun {int} {gnutls_x509_crq_set_version} (gnutls_x509_crq_t @var{crq}, unsigned int @var{version})
1947@var{crq}: should contain a gnutls_x509_crq_t structure
1948
1949@var{version}: holds the version number. For v1 Requests must be 1.
1950
1951This function will set the version of the certificate request. For
1952version 1 requests this must be one.
1953
1954Returns 0 on success.
1955@end deftypefun
1956
1957@subheading gnutls_x509_crq_get_version
1958@anchor{gnutls_x509_crq_get_version}
1959@deftypefun {int} {gnutls_x509_crq_get_version} (gnutls_x509_crq_t @var{crq})
1960@var{crq}: should contain a gnutls_x509_crq_t structure
1961
1962This function will return the version of the specified Certificate request.
1963
1964Returns a negative value on error.
1965@end deftypefun
1966
1967@subheading gnutls_x509_crq_set_key
1968@anchor{gnutls_x509_crq_set_key}
1969@deftypefun {int} {gnutls_x509_crq_set_key} (gnutls_x509_crq_t @var{crq}, gnutls_x509_privkey_t @var{key})
1970@var{crq}: should contain a gnutls_x509_crq_t structure
1971
1972@var{key}: holds a private key
1973
1974This function will set the public parameters from the given private key to the
1975request. Only RSA keys are currently supported.
1976
1977Returns 0 on success.
1978@end deftypefun
1979
1980@subheading gnutls_x509_crq_set_challenge_password
1981@anchor{gnutls_x509_crq_set_challenge_password}
1982@deftypefun {int} {gnutls_x509_crq_set_challenge_password} (gnutls_x509_crq_t @var{crq}, const char * @var{pass})
1983@var{crq}: should contain a gnutls_x509_crq_t structure
1984
1985@var{pass}: holds a null terminated password
1986
1987This function will set a challenge password to be used when revoking the request.
1988
1989Returns 0 on success.
1990@end deftypefun
1991
1992@subheading gnutls_x509_crq_sign2
1993@anchor{gnutls_x509_crq_sign2}
1994@deftypefun {int} {gnutls_x509_crq_sign2} (gnutls_x509_crq_t @var{crq}, gnutls_x509_privkey_t @var{key}, gnutls_digest_algorithm_t @var{dig}, unsigned int @var{flags})
1995@var{crq}: should contain a gnutls_x509_crq_t structure
1996
1997@var{key}: holds a private key
1998
1999@var{dig}: The message digest to use. GNUTLS_DIG_SHA1 is the safe choice unless you know what you're doing.
2000
2001@var{flags}: must be 0
2002
2003This function will sign the certificate request with a private key.
2004This must be the same key as the one used in @code{gnutls_x509_crt_set_key()} since a
2005certificate request is self signed.
2006
2007This must be the last step in a certificate request generation since all
2008the previously set parameters are now signed.
2009
2010Returns 0 on success.
2011@end deftypefun
2012
2013@subheading gnutls_x509_crq_sign
2014@anchor{gnutls_x509_crq_sign}
2015@deftypefun {int} {gnutls_x509_crq_sign} (gnutls_x509_crq_t @var{crq}, gnutls_x509_privkey_t @var{key})
2016@var{crq}: should contain a gnutls_x509_crq_t structure
2017
2018@var{key}: holds a private key
2019
2020This function is the same a @code{gnutls_x509_crq_sign2()} with no flags, and
2021SHA1 as the hash algorithm.
2022
2023Returns 0 on success.
2024@end deftypefun
2025
2026@subheading gnutls_x509_crq_export
2027@anchor{gnutls_x509_crq_export}
2028@deftypefun {int} {gnutls_x509_crq_export} (gnutls_x509_crq_t @var{crq}, gnutls_x509_crt_fmt_t @var{format}, void * @var{output_data}, size_t * @var{output_data_size})
2029@var{crq}: Holds the request
2030
2031@var{format}: the format of output params. One of PEM or DER.
2032
2033@var{output_data}: will contain a certificate request PEM or DER encoded
2034
2035@var{output_data_size}: holds the size of output_data (and will be
2036replaced by the actual size of parameters)
2037
2038This function will export the certificate request to a PKCS10
2039
2040If the buffer provided is not long enough to hold the output, then
2041GNUTLS_E_SHORT_MEMORY_BUFFER will be returned and
2042*output_data_size will be updated.
2043
2044If the structure is PEM encoded, it will have a header of "BEGIN
2045NEW CERTIFICATE REQUEST".
2046
2047@strong{Return value:} In case of failure a negative value will be
2048returned, and 0 on success.
2049@end deftypefun
2050
2051@subheading gnutls_x509_crq_get_pk_algorithm
2052@anchor{gnutls_x509_crq_get_pk_algorithm}
2053@deftypefun {int} {gnutls_x509_crq_get_pk_algorithm} (gnutls_x509_crq_t @var{crq}, unsigned int * @var{bits})
2054@var{crq}: should contain a gnutls_x509_crq_t structure
2055
2056@var{bits}: if bits is non null it will hold the size of the parameters' in bits
2057
2058This function will return the public key algorithm of a PKCS \@code{10}
2059certificate request.
2060
2061If bits is non null, it should have enough size to hold the parameters
2062size in bits. For RSA the bits returned is the modulus.
2063For DSA the bits returned are of the public
2064exponent.
2065
2066Returns a member of the gnutls_pk_algorithm_t enumeration on success,
2067or a negative value on error.
2068@end deftypefun
2069
2070@subheading gnutls_x509_privkey_export_pkcs8
2071@anchor{gnutls_x509_privkey_export_pkcs8}
2072@deftypefun {int} {gnutls_x509_privkey_export_pkcs8} (gnutls_x509_privkey_t @var{key}, gnutls_x509_crt_fmt_t @var{format}, const char * @var{password}, unsigned int @var{flags}, void * @var{output_data}, size_t * @var{output_data_size})
2073@var{key}: Holds the key
2074
2075@var{format}: the format of output params. One of PEM or DER.
2076
2077@var{password}: the password that will be used to encrypt the key.
2078
2079@var{flags}: an ORed sequence of gnutls_pkcs_encrypt_flags_t
2080
2081@var{output_data}: will contain a private key PEM or DER encoded
2082
2083@var{output_data_size}: holds the size of output_data (and will be
2084replaced by the actual size of parameters)
2085
2086This function will export the private key to a PKCS8 structure.
2087Both RSA and DSA keys can be exported. For DSA keys we use
2088PKCS @code{11} definitions. If the flags do not specify the encryption
2089cipher, then the default 3DES (PBES2) will be used.
2090
2091The @code{password} can be either ASCII or UTF-8 in the default PBES2
2092encryption schemas, or ASCII for the PKCS12 schemas.
2093
2094If the buffer provided is not long enough to hold the output, then
2095*output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
2096be returned.
2097
2098If the structure is PEM encoded, it will have a header
2099of "BEGIN ENCRYPTED PRIVATE KEY" or "BEGIN PRIVATE KEY" if
2100encryption is not used.
2101
2102@strong{Return value:} In case of failure a negative value will be
2103returned, and 0 on success.
2104@end deftypefun
2105
2106@subheading gnutls_x509_privkey_import_pkcs8
2107@anchor{gnutls_x509_privkey_import_pkcs8}
2108@deftypefun {int} {gnutls_x509_privkey_import_pkcs8} (gnutls_x509_privkey_t @var{key}, const gnutls_datum_t * @var{data}, gnutls_x509_crt_fmt_t @var{format}, const char * @var{password}, unsigned int @var{flags})
2109@var{key}: The structure to store the parsed key
2110
2111@var{data}: The DER or PEM encoded key.
2112
2113@var{format}: One of DER or PEM
2114
2115@var{password}: the password to decrypt the key (if it is encrypted).
2116
2117@var{flags}: 0 if encrypted or GNUTLS_PKCS_PLAIN if not encrypted.
2118
2119This function will convert the given DER or PEM encoded PKCS8 2.0 encrypted key
2120to the native gnutls_x509_privkey_t format. The output will be stored in @code{key}.
2121Both RSA and DSA keys can be imported, and flags can only be used to indicate
2122an unencrypted key.
2123
2124The @code{password} can be either ASCII or UTF-8 in the default PBES2
2125encryption schemas, or ASCII for the PKCS12 schemas.
2126
2127If the Certificate is PEM encoded it should have a header of "ENCRYPTED PRIVATE KEY",
2128or "PRIVATE KEY". You only need to specify the flags if the key is DER encoded, since
2129in that case the encryption status cannot be auto-detected.
2130
2131Returns 0 on success.
2132@end deftypefun
2133
2134@subheading gnutls_pkcs12_init
2135@anchor{gnutls_pkcs12_init}
2136@deftypefun {int} {gnutls_pkcs12_init} (gnutls_pkcs12_t * @var{pkcs12})
2137@var{pkcs12}: The structure to be initialized
2138
2139This function will initialize a PKCS12 structure. PKCS12 structures
2140usually contain lists of X.509 Certificates and X.509 Certificate
2141revocation lists.
2142
2143Returns 0 on success.
2144@end deftypefun
2145
2146@subheading gnutls_pkcs12_deinit
2147@anchor{gnutls_pkcs12_deinit}
2148@deftypefun {void} {gnutls_pkcs12_deinit} (gnutls_pkcs12_t @var{pkcs12})
2149@var{pkcs12}: The structure to be initialized
2150
2151This function will deinitialize a PKCS12 structure.
2152@end deftypefun
2153
2154@subheading gnutls_pkcs12_import
2155@anchor{gnutls_pkcs12_import}
2156@deftypefun {int} {gnutls_pkcs12_import} (gnutls_pkcs12_t @var{pkcs12}, const gnutls_datum_t * @var{data}, gnutls_x509_crt_fmt_t @var{format}, unsigned int @var{flags})
2157@var{pkcs12}: The structure to store the parsed PKCS12.
2158
2159@var{data}: The DER or PEM encoded PKCS12.
2160
2161@var{format}: One of DER or PEM
2162
2163@var{flags}: an ORed sequence of gnutls_privkey_pkcs8_flags
2164
2165This function will convert the given DER or PEM encoded PKCS12
2166to the native gnutls_pkcs12_t format. The output will be stored in 'pkcs12'.
2167
2168If the PKCS12 is PEM encoded it should have a header of "PKCS12".
2169
2170Returns 0 on success.
2171@end deftypefun
2172
2173@subheading gnutls_pkcs12_export
2174@anchor{gnutls_pkcs12_export}
2175@deftypefun {int} {gnutls_pkcs12_export} (gnutls_pkcs12_t @var{pkcs12}, gnutls_x509_crt_fmt_t @var{format}, void * @var{output_data}, size_t * @var{output_data_size})
2176@var{pkcs12}: Holds the pkcs12 structure
2177
2178@var{format}: the format of output params. One of PEM or DER.
2179
2180@var{output_data}: will contain a structure PEM or DER encoded
2181
2182@var{output_data_size}: holds the size of output_data (and will be
2183replaced by the actual size of parameters)
2184
2185This function will export the pkcs12 structure to DER or PEM format.
2186
2187If the buffer provided is not long enough to hold the output, then
2188*output_data_size will be updated and GNUTLS_E_SHORT_MEMORY_BUFFER
2189will be returned.
2190
2191If the structure is PEM encoded, it will have a header
2192of "BEGIN PKCS12".
2193
2194@strong{Return value:} In case of failure a negative value will be
2195returned, and 0 on success.
2196@end deftypefun
2197
2198@subheading gnutls_pkcs12_get_bag
2199@anchor{gnutls_pkcs12_get_bag}
2200@deftypefun {int} {gnutls_pkcs12_get_bag} (gnutls_pkcs12_t @var{pkcs12}, int @var{indx}, gnutls_pkcs12_bag_t @var{bag})
2201@var{pkcs12}: should contain a gnutls_pkcs12_t structure
2202
2203@var{indx}: contains the index of the bag to extract
2204
2205@var{bag}: An initialized bag, where the contents of the bag will be copied
2206
2207This function will return a Bag from the PKCS12 structure.
2208Returns 0 on success.
2209
2210After the last Bag has been read GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
2211will be returned.
2212@end deftypefun
2213
2214@subheading gnutls_pkcs12_set_bag
2215@anchor{gnutls_pkcs12_set_bag}
2216@deftypefun {int} {gnutls_pkcs12_set_bag} (gnutls_pkcs12_t @var{pkcs12}, gnutls_pkcs12_bag_t @var{bag})
2217@var{pkcs12}: should contain a gnutls_pkcs12_t structure
2218
2219@var{bag}: An initialized bag
2220
2221This function will insert a Bag into the PKCS12 structure.
2222Returns 0 on success.
2223@end deftypefun
2224
2225@subheading gnutls_pkcs12_generate_mac
2226@anchor{gnutls_pkcs12_generate_mac}
2227@deftypefun {int} {gnutls_pkcs12_generate_mac} (gnutls_pkcs12_t @var{pkcs12}, const char * @var{pass})
2228@var{pkcs12}: should contain a gnutls_pkcs12_t structure
2229
2230@var{pass}: The password for the MAC
2231
2232This function will generate a MAC for the PKCS12 structure.
2233Returns 0 on success.
2234@end deftypefun
2235
2236@subheading gnutls_pkcs12_verify_mac
2237@anchor{gnutls_pkcs12_verify_mac}
2238@deftypefun {int} {gnutls_pkcs12_verify_mac} (gnutls_pkcs12_t @var{pkcs12}, const char * @var{pass})
2239@var{pkcs12}: should contain a gnutls_pkcs12_t structure
2240
2241@var{pass}: The password for the MAC
2242
2243This function will verify the MAC for the PKCS12 structure.
2244Returns 0 on success.
2245@end deftypefun
2246
2247@subheading gnutls_pkcs12_bag_init
2248@anchor{gnutls_pkcs12_bag_init}
2249@deftypefun {int} {gnutls_pkcs12_bag_init} (gnutls_pkcs12_bag_t * @var{bag})
2250@var{bag}: The structure to be initialized
2251
2252This function will initialize a PKCS12 bag structure. PKCS12 Bags
2253usually contain private keys, lists of X.509 Certificates and X.509 Certificate
2254revocation lists.
2255
2256Returns 0 on success.
2257@end deftypefun
2258
2259@subheading gnutls_pkcs12_bag_deinit
2260@anchor{gnutls_pkcs12_bag_deinit}
2261@deftypefun {void} {gnutls_pkcs12_bag_deinit} (gnutls_pkcs12_bag_t @var{bag})
2262@var{bag}: The structure to be initialized
2263
2264This function will deinitialize a PKCS12 Bag structure.
2265@end deftypefun
2266
2267@subheading gnutls_pkcs12_bag_get_type
2268@anchor{gnutls_pkcs12_bag_get_type}
2269@deftypefun {gnutls_pkcs12_bag_type_t} {gnutls_pkcs12_bag_get_type} (gnutls_pkcs12_bag_t @var{bag}, int @var{indx})
2270@var{bag}: The bag
2271
2272@var{indx}: The element of the bag to get the type
2273
2274This function will return the bag's type. One of the gnutls_pkcs12_bag_type_t
2275enumerations.
2276@end deftypefun
2277
2278@subheading gnutls_pkcs12_bag_get_count
2279@anchor{gnutls_pkcs12_bag_get_count}
2280@deftypefun {int} {gnutls_pkcs12_bag_get_count} (gnutls_pkcs12_bag_t @var{bag})
2281@var{bag}: The bag
2282
2283This function will return the number of the elements withing the bag.
2284@end deftypefun
2285
2286@subheading gnutls_pkcs12_bag_get_data
2287@anchor{gnutls_pkcs12_bag_get_data}
2288@deftypefun {int} {gnutls_pkcs12_bag_get_data} (gnutls_pkcs12_bag_t @var{bag}, int @var{indx}, gnutls_datum_t * @var{data})
2289@var{bag}: The bag
2290
2291@var{indx}: The element of the bag to get the data from
2292
2293@var{data}: where the bag's data will be. Should be treated as constant.
2294
2295This function will return the bag's data. The data is a constant
2296that is stored into the bag. Should not be accessed after the bag
2297is deleted.
2298
2299Returns 0 on success and a negative error code on error.
2300@end deftypefun
2301
2302@subheading gnutls_pkcs12_bag_set_data
2303@anchor{gnutls_pkcs12_bag_set_data}
2304@deftypefun {int} {gnutls_pkcs12_bag_set_data} (gnutls_pkcs12_bag_t @var{bag}, gnutls_pkcs12_bag_type_t @var{type}, const gnutls_datum_t * @var{data})
2305@var{bag}: The bag
2306
2307@var{type}: The data's type
2308
2309@var{data}: the data to be copied.
2310
2311This function will insert the given data of the given type into the
2312bag.
2313
2314Returns the index of the added bag on success, or a negative
2315value on error.
2316@end deftypefun
2317
2318@subheading gnutls_pkcs12_bag_set_crt
2319@anchor{gnutls_pkcs12_bag_set_crt}
2320@deftypefun {int} {gnutls_pkcs12_bag_set_crt} (gnutls_pkcs12_bag_t @var{bag}, gnutls_x509_crt_t @var{crt})
2321@var{bag}: The bag
2322
2323@var{crt}: the certificate to be copied.
2324
2325This function will insert the given certificate into the
2326bag. This is just a wrapper over @code{gnutls_pkcs12_bag_set_data()}.
2327
2328Returns the index of the added bag on success, or a negative
2329value on failure.
2330@end deftypefun
2331
2332@subheading gnutls_pkcs12_bag_set_crl
2333@anchor{gnutls_pkcs12_bag_set_crl}
2334@deftypefun {int} {gnutls_pkcs12_bag_set_crl} (gnutls_pkcs12_bag_t @var{bag}, gnutls_x509_crl_t @var{crl})
2335@var{bag}: The bag
2336
2337@var{crl}: the CRL to be copied.
2338
2339This function will insert the given CRL into the
2340bag. This is just a wrapper over @code{gnutls_pkcs12_bag_set_data()}.
2341
2342Returns the index of the added bag on success, or a negative
2343value on failure.
2344@end deftypefun
2345
2346@subheading gnutls_pkcs12_bag_set_key_id
2347@anchor{gnutls_pkcs12_bag_set_key_id}
2348@deftypefun {int} {gnutls_pkcs12_bag_set_key_id} (gnutls_pkcs12_bag_t @var{bag}, int @var{indx}, const gnutls_datum_t * @var{id})
2349@var{bag}: The bag
2350
2351@var{indx}: The bag's element to add the id
2352
2353@var{id}: the ID
2354
2355This function will add the given key ID, to the specified, by the index, bag
2356element. The key ID will be encoded as a 'Local key identifier' bag attribute,
2357which is usually used to distinguish the local private key and the certificate pair.
2358
2359Returns 0 on success, or a negative value on error.
2360@end deftypefun
2361
2362@subheading gnutls_pkcs12_bag_get_key_id
2363@anchor{gnutls_pkcs12_bag_get_key_id}
2364@deftypefun {int} {gnutls_pkcs12_bag_get_key_id} (gnutls_pkcs12_bag_t @var{bag}, int @var{indx}, gnutls_datum_t * @var{id})
2365@var{bag}: The bag
2366
2367@var{indx}: The bag's element to add the id
2368
2369@var{id}: where the ID will be copied (to be treated as const)
2370
2371This function will return the key ID, of the specified bag element.
2372The key ID is usually used to distinguish the local private key and the certificate pair.
2373
2374Returns 0 on success, or a negative value on error.
2375@end deftypefun
2376
2377@subheading gnutls_pkcs12_bag_get_friendly_name
2378@anchor{gnutls_pkcs12_bag_get_friendly_name}
2379@deftypefun {int} {gnutls_pkcs12_bag_get_friendly_name} (gnutls_pkcs12_bag_t @var{bag}, int @var{indx}, char ** @var{name})
2380@var{bag}: The bag
2381
2382@var{indx}: The bag's element to add the id
2383
2384@var{name}: will hold a pointer to the name (to be treated as const)
2385
2386This function will return the friendly name, of the specified bag element.
2387The key ID is usually used to distinguish the local private key and the certificate pair.
2388
2389Returns 0 on success, or a negative value on error.
2390@end deftypefun
2391
2392@subheading gnutls_pkcs12_bag_set_friendly_name
2393@anchor{gnutls_pkcs12_bag_set_friendly_name}
2394@deftypefun {int} {gnutls_pkcs12_bag_set_friendly_name} (gnutls_pkcs12_bag_t @var{bag}, int @var{indx}, const char * @var{name})
2395@var{bag}: The bag
2396
2397@var{indx}: The bag's element to add the id
2398
2399@var{name}: the name
2400
2401This function will add the given key friendly name, to the specified, by the index, bag
2402element. The name will be encoded as a 'Friendly name' bag attribute,
2403which is usually used to set a user name to the local private key and the certificate pair.
2404
2405Returns 0 on success, or a negative value on error.
2406@end deftypefun
2407
2408@subheading gnutls_pkcs12_bag_decrypt
2409@anchor{gnutls_pkcs12_bag_decrypt}
2410@deftypefun {int} {gnutls_pkcs12_bag_decrypt} (gnutls_pkcs12_bag_t @var{bag}, const char * @var{pass})
2411@var{bag}: The bag
2412
2413@var{pass}: The password used for encryption. This can only be ASCII.
2414
2415This function will decrypt the given encrypted bag and return 0 on success.
2416@end deftypefun
2417
2418@subheading gnutls_pkcs12_bag_encrypt
2419@anchor{gnutls_pkcs12_bag_encrypt}
2420@deftypefun {int} {gnutls_pkcs12_bag_encrypt} (gnutls_pkcs12_bag_t @var{bag}, const char * @var{pass}, unsigned int @var{flags})
2421@var{bag}: The bag
2422
2423@var{pass}: The password used for encryption. This can only be ASCII.
2424
2425@var{flags}: should be one of gnutls_pkcs_encrypt_flags_t elements bitwise or'd
2426
2427This function will encrypt the given bag and return 0 on success.
2428@end deftypefun
2429
2430@subheading gnutls_x509_crt_set_dn_by_oid
2431@anchor{gnutls_x509_crt_set_dn_by_oid}
2432@deftypefun {int} {gnutls_x509_crt_set_dn_by_oid} (gnutls_x509_crt_t @var{crt}, const char * @var{oid}, unsigned int @var{raw_flag}, const void * @var{name}, unsigned int @var{sizeof_name})
2433@var{crt}: should contain a gnutls_x509_crt_t structure
2434
2435@var{oid}: holds an Object Identifier in a null terminated string
2436
2437@var{raw_flag}: must be 0, or 1 if the data are DER encoded
2438
2439@var{name}: a pointer to the name
2440
2441@var{sizeof_name}: holds the size of @code{name}
2442
2443This function will set the part of the name of the Certificate subject, specified
2444by the given OID. The input string should be ASCII or UTF-8 encoded.
2445
2446Some helper macros with popular OIDs can be found in gnutls/x509.h
2447With this function you can only set the known OIDs. You can test
2448for known OIDs using @code{gnutls_x509_dn_oid_known()}. For OIDs that are
2449not known (by gnutls) you should properly DER encode your data, and
2450call this function with raw_flag set.
2451
2452Returns 0 on success.
2453@end deftypefun
2454
2455@subheading gnutls_x509_crt_set_issuer_dn_by_oid
2456@anchor{gnutls_x509_crt_set_issuer_dn_by_oid}
2457@deftypefun {int} {gnutls_x509_crt_set_issuer_dn_by_oid} (gnutls_x509_crt_t @var{crt}, const char * @var{oid}, unsigned int @var{raw_flag}, const void * @var{name}, unsigned int @var{sizeof_name})
2458@var{crt}: should contain a gnutls_x509_crt_t structure
2459
2460@var{oid}: holds an Object Identifier in a null terminated string
2461
2462@var{raw_flag}: must be 0, or 1 if the data are DER encoded
2463
2464@var{name}: a pointer to the name
2465
2466@var{sizeof_name}: holds the size of @code{name}
2467
2468This function will set the part of the name of the Certificate issuer, specified
2469by the given OID. The input string should be ASCII or UTF-8 encoded.
2470
2471Some helper macros with popular OIDs can be found in gnutls/x509.h
2472With this function you can only set the known OIDs. You can test
2473for known OIDs using @code{gnutls_x509_dn_oid_known()}. For OIDs that are
2474not known (by gnutls) you should properly DER encode your data, and
2475call this function with raw_flag set.
2476
2477Normally you do not need to call this function, since the signing
2478operation will copy the signer's name as the issuer of the certificate.
2479
2480Returns 0 on success.
2481@end deftypefun
2482
2483@subheading gnutls_x509_crt_set_proxy_dn
2484@anchor{gnutls_x509_crt_set_proxy_dn}
2485@deftypefun {int} {gnutls_x509_crt_set_proxy_dn} (gnutls_x509_crt_t @var{crt}, gnutls_x509_crt_t @var{eecrt}, unsigned int @var{raw_flag}, const void * @var{name}, unsigned int @var{sizeof_name})
2486@var{crt}: a gnutls_x509_crt_t structure with the new proxy cert
2487
2488@var{eecrt}: the end entity certificate that will be issuing the proxy
2489
2490@var{raw_flag}: must be 0, or 1 if the CN is DER encoded
2491
2492@var{name}: a pointer to the CN name, may be NULL (but MUST then be added later)
2493
2494@var{sizeof_name}: holds the size of @code{name}
2495
2496This function will set the subject in @code{crt} to the end entity's
2497@code{eecrt} subject name, and add a single Common Name component @code{name}
2498of size @code{sizeof_name}. This corresponds to the required proxy
2499certificate naming style. Note that if @code{name} is @code{NULL}, you MUST
2500set it later by using @code{gnutls_x509_crt_set_dn_by_oid()} or similar.
2501
2502Returns 0 on success.
2503@end deftypefun
2504
2505@subheading gnutls_x509_crt_set_version
2506@anchor{gnutls_x509_crt_set_version}
2507@deftypefun {int} {gnutls_x509_crt_set_version} (gnutls_x509_crt_t @var{crt}, unsigned int @var{version})
2508@var{crt}: should contain a gnutls_x509_crt_t structure
2509
2510@var{version}: holds the version number. For X.509v1 certificates must be 1.
2511
2512This function will set the version of the certificate. This must
2513be one for X.509 version 1, and so on. Plain certificates without
2514extensions must have version set to one.
2515
2516To create well-formed certificates, you must specify version 3 if
2517you use any certificate extensions. Extensions are created by
2518functions such as gnutls_x509_crt_set_subject_alternative_name or
2519gnutls_x509_crt_set_key_usage.
2520
2521Returns 0 on success.
2522@end deftypefun
2523
2524@subheading gnutls_x509_crt_set_key
2525@anchor{gnutls_x509_crt_set_key}
2526@deftypefun {int} {gnutls_x509_crt_set_key} (gnutls_x509_crt_t @var{crt}, gnutls_x509_privkey_t @var{key})
2527@var{crt}: should contain a gnutls_x509_crt_t structure
2528
2529@var{key}: holds a private key
2530
2531This function will set the public parameters from the given private key to the
2532certificate. Only RSA keys are currently supported.
2533
2534Returns 0 on success.
2535@end deftypefun
2536
2537@subheading gnutls_x509_crt_set_crq
2538@anchor{gnutls_x509_crt_set_crq}
2539@deftypefun {int} {gnutls_x509_crt_set_crq} (gnutls_x509_crt_t @var{crt}, gnutls_x509_crq_t @var{crq})
2540@var{crt}: should contain a gnutls_x509_crt_t structure
2541
2542@var{crq}: holds a certificate request
2543
2544This function will set the name and public parameters from the given certificate request to the
2545certificate. Only RSA keys are currently supported.
2546
2547Returns 0 on success.
2548@end deftypefun
2549
2550@subheading gnutls_x509_crt_set_extension_by_oid
2551@anchor{gnutls_x509_crt_set_extension_by_oid}
2552@deftypefun {int} {gnutls_x509_crt_set_extension_by_oid} (gnutls_x509_crt_t @var{crt}, const char * @var{oid}, const void * @var{buf}, size_t @var{sizeof_buf}, unsigned int @var{critical})
2553@var{crt}: should contain a gnutls_x509_crt_t structure
2554
2555@var{oid}: holds an Object Identified in null terminated string
2556
2557@var{buf}: a pointer to a DER encoded data
2558
2559@var{sizeof_buf}: holds the size of @code{buf}
2560
2561@var{critical}: should be non zero if the extension is to be marked as critical
2562
2563This function will set an the extension, by the specified OID, in the certificate.
2564The extension data should be binary data DER encoded.
2565
2566Returns 0 on success and a negative value in case of an error.
2567@end deftypefun
2568
2569@subheading gnutls_x509_crt_set_basic_constraints
2570@anchor{gnutls_x509_crt_set_basic_constraints}
2571@deftypefun {int} {gnutls_x509_crt_set_basic_constraints} (gnutls_x509_crt_t @var{crt}, unsigned int @var{ca}, int @var{pathLenConstraint})
2572@var{crt}: should contain a gnutls_x509_crt_t structure
2573
2574@var{ca}: true(1) or false(0). Depending on the Certificate authority status.
2575
2576@var{pathLenConstraint}: non-negative values indicate maximum length of path,
2577and negative values indicate that the pathLenConstraints field should
2578not be present.
2579
2580This function will set the basicConstraints certificate extension.
2581
2582Returns 0 on success.
2583@end deftypefun
2584
2585@subheading gnutls_x509_crt_set_ca_status
2586@anchor{gnutls_x509_crt_set_ca_status}
2587@deftypefun {int} {gnutls_x509_crt_set_ca_status} (gnutls_x509_crt_t @var{crt}, unsigned int @var{ca})
2588@var{crt}: should contain a gnutls_x509_crt_t structure
2589
2590@var{ca}: true(1) or false(0). Depending on the Certificate authority status.
2591
2592This function will set the basicConstraints certificate extension.
2593Use @code{gnutls_x509_crt_set_basic_constraints()} if you want to control
2594the pathLenConstraint field too.
2595
2596Returns 0 on success.
2597@end deftypefun
2598
2599@subheading gnutls_x509_crt_set_key_usage
2600@anchor{gnutls_x509_crt_set_key_usage}
2601@deftypefun {int} {gnutls_x509_crt_set_key_usage} (gnutls_x509_crt_t @var{crt}, unsigned int @var{usage})
2602@var{crt}: should contain a gnutls_x509_crt_t structure
2603
2604@var{usage}: an ORed sequence of the GNUTLS_KEY_* elements.
2605
2606This function will set the keyUsage certificate extension.
2607
2608Returns 0 on success.
2609@end deftypefun
2610
2611@subheading gnutls_x509_crt_set_subject_alternative_name
2612@anchor{gnutls_x509_crt_set_subject_alternative_name}
2613@deftypefun {int} {gnutls_x509_crt_set_subject_alternative_name} (gnutls_x509_crt_t @var{crt}, gnutls_x509_subject_alt_name_t @var{type}, const char * @var{data_string})
2614@var{crt}: should contain a gnutls_x509_crt_t structure
2615
2616@var{type}: is one of the gnutls_x509_subject_alt_name_t enumerations
2617
2618@var{data_string}: The data to be set
2619
2620This function will set the subject alternative name certificate extension.
2621
2622Returns 0 on success.
2623@end deftypefun
2624
2625@subheading gnutls_x509_crt_set_proxy
2626@anchor{gnutls_x509_crt_set_proxy}
2627@deftypefun {int} {gnutls_x509_crt_set_proxy} (gnutls_x509_crt_t @var{crt}, int @var{pathLenConstraint}, const char * @var{policyLanguage}, const char * @var{policy}, size_t @var{sizeof_policy})
2628@var{crt}: should contain a gnutls_x509_crt_t structure
2629
2630@var{pathLenConstraint}: non-negative values indicate maximum length of path,
2631and negative values indicate that the pathLenConstraints field should
2632not be present.
2633
2634@var{policyLanguage}: OID describing the language of @code{policy}.
2635
2636@var{policy}: opaque byte array with policy language, can be @code{NULL}
2637
2638@var{sizeof_policy}: size of @code{policy}.
2639
2640This function will set the proxyCertInfo extension.
2641
2642Returns 0 on success.
2643@end deftypefun
2644
2645@subheading gnutls_x509_crt_sign2
2646@anchor{gnutls_x509_crt_sign2}
2647@deftypefun {int} {gnutls_x509_crt_sign2} (gnutls_x509_crt_t @var{crt}, gnutls_x509_crt_t @var{issuer}, gnutls_x509_privkey_t @var{issuer_key}, gnutls_digest_algorithm_t @var{dig}, unsigned int @var{flags})
2648@var{crt}: should contain a gnutls_x509_crt_t structure
2649
2650@var{issuer}: is the certificate of the certificate issuer
2651
2652@var{issuer_key}: holds the issuer's private key
2653
2654@var{dig}: The message digest to use. GNUTLS_DIG_SHA1 is the safe choice unless you know what you're doing.
2655
2656@var{flags}: must be 0
2657
2658This function will sign the certificate with the issuer's private key, and
2659will copy the issuer's information into the certificate.
2660
2661This must be the last step in a certificate generation since all
2662the previously set parameters are now signed.
2663
2664Returns 0 on success.
2665@end deftypefun
2666
2667@subheading gnutls_x509_crt_sign
2668@anchor{gnutls_x509_crt_sign}
2669@deftypefun {int} {gnutls_x509_crt_sign} (gnutls_x509_crt_t @var{crt}, gnutls_x509_crt_t @var{issuer}, gnutls_x509_privkey_t @var{issuer_key})
2670@var{crt}: should contain a gnutls_x509_crt_t structure
2671
2672@var{issuer}: is the certificate of the certificate issuer
2673
2674@var{issuer_key}: holds the issuer's private key
2675
2676This function is the same a @code{gnutls_x509_crt_sign2()} with no flags, and
2677SHA1 as the hash algorithm.
2678
2679Returns 0 on success.
2680@end deftypefun
2681
2682@subheading gnutls_x509_crt_set_activation_time
2683@anchor{gnutls_x509_crt_set_activation_time}
2684@deftypefun {int} {gnutls_x509_crt_set_activation_time} (gnutls_x509_crt_t @var{cert}, time_t @var{act_time})
2685@var{cert}: should contain a gnutls_x509_crt_t structure
2686
2687@var{act_time}: The actual time
2688
2689This function will set the time this Certificate was or will be activated.
2690
2691Returns 0 on success, or a negative value in case of an error.
2692@end deftypefun
2693
2694@subheading gnutls_x509_crt_set_expiration_time
2695@anchor{gnutls_x509_crt_set_expiration_time}
2696@deftypefun {int} {gnutls_x509_crt_set_expiration_time} (gnutls_x509_crt_t @var{cert}, time_t @var{exp_time})
2697@var{cert}: should contain a gnutls_x509_crt_t structure
2698
2699@var{exp_time}: The actual time
2700
2701This function will set the time this Certificate will expire.
2702
2703Returns 0 on success, or a negative value in case of an error.
2704@end deftypefun
2705
2706@subheading gnutls_x509_crt_set_serial
2707@anchor{gnutls_x509_crt_set_serial}
2708@deftypefun {int} {gnutls_x509_crt_set_serial} (gnutls_x509_crt_t @var{cert}, const void * @var{serial}, size_t @var{serial_size})
2709@var{cert}: should contain a gnutls_x509_crt_t structure
2710
2711@var{serial}: The serial number
2712
2713@var{serial_size}: Holds the size of the serial field.
2714
2715This function will set the X.509 certificate's serial number.
2716Serial is not always a 32 or 64bit number. Some CAs use
2717large serial numbers, thus it may be wise to handle it as something
2718opaque.
2719
2720Returns 0 on success, or a negative value in case of an error.
2721@end deftypefun
2722
2723@subheading gnutls_x509_crt_set_crl_dist_points
2724@anchor{gnutls_x509_crt_set_crl_dist_points}
2725@deftypefun {int} {gnutls_x509_crt_set_crl_dist_points} (gnutls_x509_crt_t @var{crt}, gnutls_x509_subject_alt_name_t @var{type}, const void * @var{data_string}, unsigned int @var{reason_flags})
2726@var{crt}: should contain a gnutls_x509_crt_t structure
2727
2728@var{type}: is one of the gnutls_x509_subject_alt_name_t enumerations
2729
2730@var{data_string}: The data to be set
2731
2732@var{reason_flags}: revocation reasons
2733
2734This function will set the CRL distribution points certificate extension.
2735
2736Returns 0 on success.
2737@end deftypefun
2738
2739@subheading gnutls_x509_crt_cpy_crl_dist_points
2740@anchor{gnutls_x509_crt_cpy_crl_dist_points}
2741@deftypefun {int} {gnutls_x509_crt_cpy_crl_dist_points} (gnutls_x509_crt_t @var{dst}, gnutls_x509_crt_t @var{src})
2742@var{dst}: should contain a gnutls_x509_crt_t structure
2743
2744@var{src}: the certificate where the dist points will be copied from
2745
2746This function will copy the CRL distribution points certificate
2747extension, from the source to the destination certificate.
2748This may be useful to copy from a CA certificate to issued ones.
2749
2750Returns 0 on success.
2751@end deftypefun
2752
2753@subheading gnutls_x509_crt_set_subject_key_id
2754@anchor{gnutls_x509_crt_set_subject_key_id}
2755@deftypefun {int} {gnutls_x509_crt_set_subject_key_id} (gnutls_x509_crt_t @var{cert}, const void * @var{id}, size_t @var{id_size})
2756@var{cert}: should contain a gnutls_x509_crt_t structure
2757
2758@var{id}: The key ID
2759
2760@var{id_size}: Holds the size of the serial field.
2761
2762This function will set the X.509 certificate's subject key ID extension.
2763
2764Returns 0 on success, or a negative value in case of an error.
2765@end deftypefun
2766
2767@subheading gnutls_x509_crt_set_authority_key_id
2768@anchor{gnutls_x509_crt_set_authority_key_id}
2769@deftypefun {int} {gnutls_x509_crt_set_authority_key_id} (gnutls_x509_crt_t @var{cert}, const void * @var{id}, size_t @var{id_size})
2770@var{cert}: should contain a gnutls_x509_crt_t structure
2771
2772@var{id}: The key ID
2773
2774@var{id_size}: Holds the size of the serial field.
2775
2776This function will set the X.509 certificate's authority key ID extension.
2777Only the keyIdentifier field can be set with this function.
2778
2779Returns 0 on success, or a negative value in case of an error.
2780@end deftypefun
2781
2782@subheading gnutls_x509_crt_set_key_purpose_oid
2783@anchor{gnutls_x509_crt_set_key_purpose_oid}
2784@deftypefun {int} {gnutls_x509_crt_set_key_purpose_oid} (gnutls_x509_crt_t @var{cert}, const void * @var{oid}, unsigned int @var{critical})
2785@var{cert}: should contain a gnutls_x509_crt_t structure
2786
2787@var{oid}: a pointer to a null terminated string that holds the OID
2788
2789@var{critical}: Whether this extension will be critical or not
2790
2791This function will set the key purpose OIDs of the Certificate.
2792These are stored in the Extended Key Usage extension (2.5.29.37)
2793See the GNUTLS_KP_* definitions for human readable names.
2794
2795Subsequent calls to this function will append OIDs to the OID list.
2796
2797On success 0 is returned.
2798@end deftypefun
2799
2800@subheading gnutls_x509_crl_set_version
2801@anchor{gnutls_x509_crl_set_version}
2802@deftypefun {int} {gnutls_x509_crl_set_version} (gnutls_x509_crl_t @var{crl}, unsigned int @var{version})
2803@var{crl}: should contain a gnutls_x509_crl_t structure
2804
2805@var{version}: holds the version number. For CRLv1 crls must be 1.
2806
2807This function will set the version of the CRL. This
2808must be one for CRL version 1, and so on. The CRLs generated
2809by gnutls should have a version number of 2.
2810
2811Returns 0 on success.
2812@end deftypefun
2813
2814@subheading gnutls_x509_crl_sign2
2815@anchor{gnutls_x509_crl_sign2}
2816@deftypefun {int} {gnutls_x509_crl_sign2} (gnutls_x509_crl_t @var{crl}, gnutls_x509_crt_t @var{issuer}, gnutls_x509_privkey_t @var{issuer_key}, gnutls_digest_algorithm_t @var{dig}, unsigned int @var{flags})
2817@var{crl}: should contain a gnutls_x509_crl_t structure
2818
2819@var{issuer}: is the certificate of the certificate issuer
2820
2821@var{issuer_key}: holds the issuer's private key
2822
2823@var{dig}: The message digest to use. GNUTLS_DIG_SHA1 is the safe choice unless you know what you're doing.
2824
2825@var{flags}: must be 0
2826
2827This function will sign the CRL with the issuer's private key, and
2828will copy the issuer's information into the CRL.
2829
2830This must be the last step in a certificate CRL since all
2831the previously set parameters are now signed.
2832
2833Returns 0 on success.
2834@end deftypefun
2835
2836@subheading gnutls_x509_crl_sign
2837@anchor{gnutls_x509_crl_sign}
2838@deftypefun {int} {gnutls_x509_crl_sign} (gnutls_x509_crl_t @var{crl}, gnutls_x509_crt_t @var{issuer}, gnutls_x509_privkey_t @var{issuer_key})
2839@var{crl}: should contain a gnutls_x509_crl_t structure
2840
2841@var{issuer}: is the certificate of the certificate issuer
2842
2843@var{issuer_key}: holds the issuer's private key
2844
2845This function is the same a @code{gnutls_x509_crl_sign2()} with no flags, and
2846SHA1 as the hash algorithm.
2847
2848Returns 0 on success.
2849@end deftypefun
2850
2851@subheading gnutls_x509_crl_set_this_update
2852@anchor{gnutls_x509_crl_set_this_update}
2853@deftypefun {int} {gnutls_x509_crl_set_this_update} (gnutls_x509_crl_t @var{crl}, time_t @var{act_time})
2854@var{crl}: should contain a gnutls_x509_crl_t structure
2855
2856@var{act_time}: The actual time
2857
2858This function will set the time this CRL was issued.
2859
2860Returns 0 on success, or a negative value in case of an error.
2861@end deftypefun
2862
2863@subheading gnutls_x509_crl_set_next_update
2864@anchor{gnutls_x509_crl_set_next_update}
2865@deftypefun {int} {gnutls_x509_crl_set_next_update} (gnutls_x509_crl_t @var{crl}, time_t @var{exp_time})
2866@var{crl}: should contain a gnutls_x509_crl_t structure
2867
2868@var{exp_time}: The actual time
2869
2870This function will set the time this CRL will be updated.
2871
2872Returns 0 on success, or a negative value in case of an error.
2873@end deftypefun
2874
2875@subheading gnutls_x509_crl_set_crt_serial
2876@anchor{gnutls_x509_crl_set_crt_serial}
2877@deftypefun {int} {gnutls_x509_crl_set_crt_serial} (gnutls_x509_crl_t @var{crl}, const void * @var{serial}, size_t @var{serial_size}, time_t @var{revocation_time})
2878@var{crl}: should contain a gnutls_x509_crl_t structure
2879
2880@var{serial}: The revoked certificate's serial number
2881
2882@var{serial_size}: Holds the size of the serial field.
2883
2884@var{revocation_time}: The time this certificate was revoked
2885
2886This function will set a revoked certificate's serial number to the CRL.
2887
2888Returns 0 on success, or a negative value in case of an error.
2889@end deftypefun
2890
2891@subheading gnutls_x509_crl_set_crt
2892@anchor{gnutls_x509_crl_set_crt}
2893@deftypefun {int} {gnutls_x509_crl_set_crt} (gnutls_x509_crl_t @var{crl}, gnutls_x509_crt_t @var{crt}, time_t @var{revocation_time})
2894@var{crl}: should contain a gnutls_x509_crl_t structure
2895
2896@var{crt}: should contain a gnutls_x509_crt_t structure with the revoked certificate
2897
2898@var{revocation_time}: The time this certificate was revoked
2899
2900This function will set a revoked certificate's serial number to the CRL.
2901
2902Returns 0 on success, or a negative value in case of an error.
2903@end deftypefun
2904
2905@subheading gnutls_x509_crt_print
2906@anchor{gnutls_x509_crt_print}
2907@deftypefun {int} {gnutls_x509_crt_print} (gnutls_x509_crt_t @var{cert}, gnutls_certificate_print_formats_t @var{format}, gnutls_datum_t * @var{out})
2908@var{cert}: The structure to be printed
2909
2910@var{format}: Indicate the format to use
2911
2912@var{out}: Newly allocated datum with zero terminated string.
2913
2914This function will pretty print a X.509 certificate, suitable for
2915display to a human.
2916
2917If the format is @code{GNUTLS_X509_CRT_FULL} then all fields of the
2918certificate will be output, on multiple lines. The
2919@code{GNUTLS_X509_CRT_ONELINE} format will generate one line with some
2920selected fields, which is useful for logging purposes.
2921
2922The output @code{out} needs to be deallocate using @code{gnutls_free()}.
2923
2924Returns 0 on success.
2925@end deftypefun
2926
2927@subheading gnutls_x509_crl_print
2928@anchor{gnutls_x509_crl_print}
2929@deftypefun {int} {gnutls_x509_crl_print} (gnutls_x509_crl_t @var{crl}, gnutls_certificate_print_formats_t @var{format}, gnutls_datum_t * @var{out})
2930@var{crl}: The structure to be printed
2931
2932@var{format}: Indicate the format to use
2933
2934@var{out}: Newly allocated datum with zero terminated string.
2935
2936This function will pretty print a X.509 certificate revocation
2937list, suitable for display to a human.
2938
2939The output @code{out} needs to be deallocate using @code{gnutls_free()}.
2940
2941Returns 0 on success.
2942@end deftypefun
2943
diff --git a/src/daemon/https/x509/x509.c b/src/daemon/https/x509/x509.c
new file mode 100644
index 00000000..96999d27
--- /dev/null
+++ b/src/daemon/https/x509/x509.c
@@ -0,0 +1,2851 @@
1/*
2 * Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation
3 * Author: Nikos Mavrogiannopoulos, Simon Josefsson, Howard Chu
4 *
5 * This file is part of GNUTLS.
6 *
7 * The GNUTLS library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public License
9 * as published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
20 * USA
21 *
22 */
23
24/* Functions on X.509 Certificate parsing
25 */
26
27#include <gnutls_int.h>
28#include <gnutls_datum.h>
29#include <gnutls_global.h>
30#include <gnutls_errors.h>
31#include <common.h>
32#include <gnutls_x509.h>
33#include <x509_b64.h>
34#include <x509.h>
35#include <dn.h>
36#include <extensions.h>
37#include <libtasn1.h>
38#include <mpi.h>
39#include <privkey.h>
40#include <verify.h>
41
42/**
43 * gnutls_x509_crt_init - This function initializes a gnutls_x509_crt_t structure
44 * @cert: The structure to be initialized
45 *
46 * This function will initialize an X.509 certificate structure.
47 *
48 * Returns 0 on success.
49 *
50 **/
51int
52gnutls_x509_crt_init (gnutls_x509_crt_t * cert)
53{
54 gnutls_x509_crt_t tmp = gnutls_calloc (1, sizeof (gnutls_x509_crt_int));
55 int result;
56
57 if (!tmp)
58 return GNUTLS_E_MEMORY_ERROR;
59
60 result = asn1_create_element (_gnutls_get_pkix (),
61 "PKIX1.Certificate", &tmp->cert);
62 if (result != ASN1_SUCCESS)
63 {
64 gnutls_assert ();
65 gnutls_free (tmp);
66 return _gnutls_asn2err (result);
67 }
68
69 *cert = tmp;
70
71 return 0; /* success */
72}
73
74/*-
75 * _gnutls_x509_crt_cpy - This function copies a gnutls_x509_crt_t structure
76 * @dest: The structure where to copy
77 * @src: The structure to be copied
78 *
79 * This function will copy an X.509 certificate structure.
80 *
81 * Returns 0 on success.
82 *
83 -*/
84int
85_gnutls_x509_crt_cpy (gnutls_x509_crt_t dest, gnutls_x509_crt_t src)
86{
87 int ret;
88 size_t der_size;
89 opaque *der;
90 gnutls_datum_t tmp;
91
92 ret = gnutls_x509_crt_export (src, GNUTLS_X509_FMT_DER, NULL, &der_size);
93 if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
94 {
95 gnutls_assert ();
96 return ret;
97 }
98
99 der = gnutls_alloca (der_size);
100 if (der == NULL)
101 {
102 gnutls_assert ();
103 return GNUTLS_E_MEMORY_ERROR;
104 }
105
106 ret = gnutls_x509_crt_export (src, GNUTLS_X509_FMT_DER, der, &der_size);
107 if (ret < 0)
108 {
109 gnutls_assert ();
110 gnutls_afree (der);
111 return ret;
112 }
113
114 tmp.data = der;
115 tmp.size = der_size;
116 ret = gnutls_x509_crt_import (dest, &tmp, GNUTLS_X509_FMT_DER);
117
118 gnutls_afree (der);
119
120 if (ret < 0)
121 {
122 gnutls_assert ();
123 return ret;
124 }
125
126 return 0;
127
128}
129
130/**
131 * gnutls_x509_crt_deinit - This function deinitializes memory used by a gnutls_x509_crt_t structure
132 * @cert: The structure to be initialized
133 *
134 * This function will deinitialize a CRL structure.
135 *
136 **/
137void
138gnutls_x509_crt_deinit (gnutls_x509_crt_t cert)
139{
140 if (!cert)
141 return;
142
143 if (cert->cert)
144 asn1_delete_structure (&cert->cert);
145
146 gnutls_free (cert);
147}
148
149/**
150 * gnutls_x509_crt_import - This function will import a DER or PEM encoded Certificate
151 * @cert: The structure to store the parsed certificate.
152 * @data: The DER or PEM encoded certificate.
153 * @format: One of DER or PEM
154 *
155 * This function will convert the given DER or PEM encoded Certificate
156 * to the native gnutls_x509_crt_t format. The output will be stored in @cert.
157 *
158 * If the Certificate is PEM encoded it should have a header of "X509 CERTIFICATE", or
159 * "CERTIFICATE".
160 *
161 * Returns 0 on success.
162 *
163 **/
164int
165gnutls_x509_crt_import (gnutls_x509_crt_t cert,
166 const gnutls_datum_t * data,
167 gnutls_x509_crt_fmt_t format)
168{
169 int result = 0, need_free = 0;
170 gnutls_datum_t _data;
171 opaque *signature = NULL;
172
173 if (cert == NULL)
174 {
175 gnutls_assert ();
176 return GNUTLS_E_INVALID_REQUEST;
177 }
178
179 _data.data = data->data;
180 _data.size = data->size;
181
182 /* If the Certificate is in PEM format then decode it
183 */
184 if (format == GNUTLS_X509_FMT_PEM)
185 {
186 opaque *out;
187
188 /* Try the first header */
189 result = _gnutls_fbase64_decode (PEM_X509_CERT2, data->data, data->size,
190 &out);
191
192 if (result <= 0)
193 {
194 /* try for the second header */
195 result = _gnutls_fbase64_decode (PEM_X509_CERT, data->data,
196 data->size, &out);
197
198 if (result <= 0)
199 {
200 if (result == 0)
201 result = GNUTLS_E_INTERNAL_ERROR;
202 gnutls_assert ();
203 return result;
204 }
205 }
206
207 _data.data = out;
208 _data.size = result;
209
210 need_free = 1;
211 }
212
213 result = asn1_der_decoding (&cert->cert, _data.data, _data.size, NULL);
214 if (result != ASN1_SUCCESS)
215 {
216 result = _gnutls_asn2err (result);
217 gnutls_assert ();
218 goto cleanup;
219 }
220
221 /* Since we do not want to disable any extension
222 */
223 cert->use_extensions = 1;
224 if (need_free)
225 _gnutls_free_datum (&_data);
226
227 return 0;
228
229cleanup:gnutls_free (signature);
230 if (need_free)
231 _gnutls_free_datum (&_data);
232 return result;
233}
234
235/**
236 * gnutls_x509_crt_get_issuer_dn - This function returns the Certificate's issuer distinguished name
237 * @cert: should contain a gnutls_x509_crt_t structure
238 * @buf: a pointer to a structure to hold the name (may be null)
239 * @sizeof_buf: initially holds the size of @buf
240 *
241 * This function will copy the name of the Certificate issuer in the
242 * provided buffer. The name will be in the form
243 * "C=xxxx,O=yyyy,CN=zzzz" as described in RFC2253. The output string
244 * will be ASCII or UTF-8 encoded, depending on the certificate data.
245 *
246 * If @buf is null then only the size will be filled.
247 *
248 * Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
249 * long enough, and in that case the *sizeof_buf will be updated with
250 * the required size. On success 0 is returned.
251 *
252 **/
253int
254gnutls_x509_crt_get_issuer_dn (gnutls_x509_crt_t cert,
255 char *buf, size_t * sizeof_buf)
256{
257 if (cert == NULL)
258 {
259 gnutls_assert ();
260 return GNUTLS_E_INVALID_REQUEST;
261 }
262
263 return _gnutls_x509_parse_dn (cert->cert,
264 "tbsCertificate.issuer.rdnSequence", buf,
265 sizeof_buf);
266}
267
268/**
269 * gnutls_x509_crt_get_issuer_dn_by_oid - This function returns the Certificate's issuer distinguished name
270 * @cert: should contain a gnutls_x509_crt_t structure
271 * @oid: holds an Object Identified in null terminated string
272 * @indx: In case multiple same OIDs exist in the RDN, this specifies which to send. Use zero to get the first one.
273 * @raw_flag: If non zero returns the raw DER data of the DN part.
274 * @buf: a pointer to a structure to hold the name (may be null)
275 * @sizeof_buf: initially holds the size of @buf
276 *
277 * This function will extract the part of the name of the Certificate
278 * issuer specified by the given OID. The output, if the raw flag is not
279 * used, will be encoded as described in RFC2253. Thus a string that is
280 * ASCII or UTF-8 encoded, depending on the certificate data.
281 *
282 * Some helper macros with popular OIDs can be found in gnutls/x509.h
283 * If raw flag is zero, this function will only return known OIDs as
284 * text. Other OIDs will be DER encoded, as described in RFC2253 --
285 * in hex format with a '\#' prefix. You can check about known OIDs
286 * using gnutls_x509_dn_oid_known().
287 *
288 * If @buf is null then only the size will be filled.
289 *
290 * Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
291 * long enough, and in that case the *sizeof_buf will be updated with
292 * the required size. On success 0 is returned.
293 *
294 **/
295int
296gnutls_x509_crt_get_issuer_dn_by_oid (gnutls_x509_crt_t cert,
297 const char *oid,
298 int indx,
299 unsigned int raw_flag,
300 void *buf, size_t * sizeof_buf)
301{
302 if (cert == NULL)
303 {
304 gnutls_assert ();
305 return GNUTLS_E_INVALID_REQUEST;
306 }
307
308 return _gnutls_x509_parse_dn_oid (cert->cert,
309 "tbsCertificate.issuer.rdnSequence", oid,
310 indx, raw_flag, buf, sizeof_buf);
311}
312
313/**
314 * gnutls_x509_crt_get_issuer_dn_oid - This function returns the Certificate's issuer distinguished name OIDs
315 * @cert: should contain a gnutls_x509_crt_t structure
316 * @indx: This specifies which OID to return. Use zero to get the first one.
317 * @oid: a pointer to a buffer to hold the OID (may be null)
318 * @sizeof_oid: initially holds the size of @oid
319 *
320 * This function will extract the OIDs of the name of the Certificate
321 * issuer specified by the given index.
322 *
323 * If @oid is null then only the size will be filled.
324 *
325 * Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
326 * long enough, and in that case the *sizeof_oid will be updated with
327 * the required size. On success 0 is returned.
328 *
329 **/
330int
331gnutls_x509_crt_get_issuer_dn_oid (gnutls_x509_crt_t cert,
332 int indx, void *oid, size_t * sizeof_oid)
333{
334 if (cert == NULL)
335 {
336 gnutls_assert ();
337 return GNUTLS_E_INVALID_REQUEST;
338 }
339
340 return _gnutls_x509_get_dn_oid (cert->cert,
341 "tbsCertificate.issuer.rdnSequence", indx,
342 oid, sizeof_oid);
343}
344
345/**
346 * gnutls_x509_crt_get_dn - This function returns the Certificate's distinguished name
347 * @cert: should contain a gnutls_x509_crt_t structure
348 * @buf: a pointer to a structure to hold the name (may be null)
349 * @sizeof_buf: initially holds the size of @buf
350 *
351 * This function will copy the name of the Certificate in the
352 * provided buffer. The name will be in the form
353 * "C=xxxx,O=yyyy,CN=zzzz" as described in RFC2253. The output string
354 * will be ASCII or UTF-8 encoded, depending on the certificate data.
355 *
356 * If @buf is null then only the size will be filled.
357 *
358 * Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
359 * long enough, and in that case the *sizeof_buf will be updated with
360 * the required size. On success 0 is returned.
361 *
362 **/
363int
364gnutls_x509_crt_get_dn (gnutls_x509_crt_t cert,
365 char *buf, size_t * sizeof_buf)
366{
367 if (cert == NULL)
368 {
369 gnutls_assert ();
370 return GNUTLS_E_INVALID_REQUEST;
371 }
372
373 return _gnutls_x509_parse_dn (cert->cert,
374 "tbsCertificate.subject.rdnSequence", buf,
375 sizeof_buf);
376}
377
378/**
379 * gnutls_x509_crt_get_dn_by_oid - This function returns the Certificate's distinguished name
380 * @cert: should contain a gnutls_x509_crt_t structure
381 * @oid: holds an Object Identified in null terminated string
382 * @indx: In case multiple same OIDs exist in the RDN, this specifies which to send. Use zero to get the first one.
383 * @raw_flag: If non zero returns the raw DER data of the DN part.
384 * @buf: a pointer where the DN part will be copied (may be null).
385 * @sizeof_buf: initially holds the size of @buf
386 *
387 * This function will extract the part of the name of the Certificate
388 * subject specified by the given OID. The output, if the raw flag is not
389 * used, will be encoded as described in RFC2253. Thus a string that is
390 * ASCII or UTF-8 encoded, depending on the certificate data.
391 *
392 * Some helper macros with popular OIDs can be found in gnutls/x509.h
393 * If raw flag is zero, this function will only return known OIDs as
394 * text. Other OIDs will be DER encoded, as described in RFC2253 --
395 * in hex format with a '\#' prefix. You can check about known OIDs
396 * using gnutls_x509_dn_oid_known().
397 *
398 * If @buf is null then only the size will be filled.
399 *
400 * Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
401 * long enough, and in that case the *sizeof_buf will be updated with
402 * the required size. On success 0 is returned.
403 *
404 **/
405int
406gnutls_x509_crt_get_dn_by_oid (gnutls_x509_crt_t cert,
407 const char *oid,
408 int indx,
409 unsigned int raw_flag,
410 void *buf, size_t * sizeof_buf)
411{
412 if (cert == NULL)
413 {
414 gnutls_assert ();
415 return GNUTLS_E_INVALID_REQUEST;
416 }
417
418 return _gnutls_x509_parse_dn_oid (cert->cert,
419 "tbsCertificate.subject.rdnSequence", oid,
420 indx, raw_flag, buf, sizeof_buf);
421}
422
423/**
424 * gnutls_x509_crt_get_dn_oid - This function returns the Certificate's subject distinguished name OIDs
425 * @cert: should contain a gnutls_x509_crt_t structure
426 * @indx: This specifies which OID to return. Use zero to get the first one.
427 * @oid: a pointer to a buffer to hold the OID (may be null)
428 * @sizeof_oid: initially holds the size of @oid
429 *
430 * This function will extract the OIDs of the name of the Certificate
431 * subject specified by the given index.
432 *
433 * If oid is null then only the size will be filled.
434 *
435 * Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
436 * long enough, and in that case the *sizeof_oid will be updated with
437 * the required size. On success 0 is returned.
438 *
439 **/
440int
441gnutls_x509_crt_get_dn_oid (gnutls_x509_crt_t cert,
442 int indx, void *oid, size_t * sizeof_oid)
443{
444 if (cert == NULL)
445 {
446 gnutls_assert ();
447 return GNUTLS_E_INVALID_REQUEST;
448 }
449
450 return _gnutls_x509_get_dn_oid (cert->cert,
451 "tbsCertificate.subject.rdnSequence", indx,
452 oid, sizeof_oid);
453}
454
455/**
456 * gnutls_x509_crt_get_signature_algorithm - This function returns the Certificate's signature algorithm
457 * @cert: should contain a gnutls_x509_crt_t structure
458 *
459 * This function will return a value of the gnutls_sign_algorithm_t enumeration that
460 * is the signature algorithm.
461 *
462 * Returns a negative value on error.
463 *
464 **/
465int
466gnutls_x509_crt_get_signature_algorithm (gnutls_x509_crt_t cert)
467{
468 int result;
469 gnutls_datum_t sa;
470
471 if (cert == NULL)
472 {
473 gnutls_assert ();
474 return GNUTLS_E_INVALID_REQUEST;
475 }
476
477 /* Read the signature algorithm. Note that parameters are not
478 * read. They will be read from the issuer's certificate if needed.
479 */
480 result =
481 _gnutls_x509_read_value (cert->cert, "signatureAlgorithm.algorithm", &sa,
482 0);
483
484 if (result < 0)
485 {
486 gnutls_assert ();
487 return result;
488 }
489
490 result = _gnutls_x509_oid2sign_algorithm (sa.data);
491
492 _gnutls_free_datum (&sa);
493
494 return result;
495}
496
497/**
498 * gnutls_x509_crt_get_signature - Returns the Certificate's signature
499 * @cert: should contain a gnutls_x509_crt_t structure
500 * @sig: a pointer where the signature part will be copied (may be null).
501 * @sizeof_sig: initially holds the size of @sig
502 *
503 * This function will extract the signature field of a certificate.
504 *
505 * Returns 0 on success, and a negative value on error.
506 **/
507int
508gnutls_x509_crt_get_signature (gnutls_x509_crt_t cert,
509 char *sig, size_t * sizeof_sig)
510{
511 int result;
512 int bits, len;
513
514 if (cert == NULL)
515 {
516 gnutls_assert ();
517 return GNUTLS_E_INVALID_REQUEST;
518 }
519
520 bits = 0;
521 result = asn1_read_value (cert->cert, "signature", NULL, &bits);
522 if (result != ASN1_MEM_ERROR)
523 {
524 gnutls_assert ();
525 return _gnutls_asn2err (result);
526 }
527
528 if (bits % 8 != 0)
529 {
530 gnutls_assert ();
531 return GNUTLS_E_CERTIFICATE_ERROR;
532 }
533
534 len = bits / 8;
535
536 if (*sizeof_sig < len)
537 {
538 *sizeof_sig = bits / 8;
539 return GNUTLS_E_SHORT_MEMORY_BUFFER;
540 }
541
542 result = asn1_read_value (cert->cert, "signature", sig, &len);
543 if (result != ASN1_SUCCESS)
544 {
545 gnutls_assert ();
546 return _gnutls_asn2err (result);
547 }
548
549 return 0;
550}
551
552/**
553 * gnutls_x509_crt_get_version - This function returns the Certificate's version number
554 * @cert: should contain a gnutls_x509_crt_t structure
555 *
556 * This function will return the version of the specified Certificate.
557 *
558 * Returns a negative value on error.
559 *
560 **/
561int
562gnutls_x509_crt_get_version (gnutls_x509_crt_t cert)
563{
564 opaque version[5];
565 int len, result;
566
567 if (cert == NULL)
568 {
569 gnutls_assert ();
570 return GNUTLS_E_INVALID_REQUEST;
571 }
572
573 len = sizeof (version);
574 if ((result =
575 asn1_read_value (cert->cert, "tbsCertificate.version", version,
576 &len)) != ASN1_SUCCESS)
577 {
578
579 if (result == ASN1_ELEMENT_NOT_FOUND)
580 return 1; /* the DEFAULT version */
581 gnutls_assert ();
582 return _gnutls_asn2err (result);
583 }
584
585 return (int) version[0] + 1;
586}
587
588/**
589 * gnutls_x509_crt_get_activation_time - This function returns the Certificate's activation time
590 * @cert: should contain a gnutls_x509_crt_t structure
591 *
592 * This function will return the time this Certificate was or will be activated.
593 *
594 * Returns (time_t)-1 on error.
595 *
596 **/
597time_t
598gnutls_x509_crt_get_activation_time (gnutls_x509_crt_t cert)
599{
600 if (cert == NULL)
601 {
602 gnutls_assert ();
603 return (time_t) - 1;
604 }
605
606 return _gnutls_x509_get_time (cert->cert,
607 "tbsCertificate.validity.notBefore");
608}
609
610/**
611 * gnutls_x509_crt_get_expiration_time - This function returns the Certificate's expiration time
612 * @cert: should contain a gnutls_x509_crt_t structure
613 *
614 * This function will return the time this Certificate was or will be expired.
615 *
616 * Returns (time_t)-1 on error.
617 *
618 **/
619time_t
620gnutls_x509_crt_get_expiration_time (gnutls_x509_crt_t cert)
621{
622 if (cert == NULL)
623 {
624 gnutls_assert ();
625 return (time_t) - 1;
626 }
627
628 return _gnutls_x509_get_time (cert->cert,
629 "tbsCertificate.validity.notAfter");
630}
631
632/**
633 * gnutls_x509_crt_get_serial - This function returns the certificate's serial number
634 * @cert: should contain a gnutls_x509_crt_t structure
635 * @result: The place where the serial number will be copied
636 * @result_size: Holds the size of the result field.
637 *
638 * This function will return the X.509 certificate's serial number.
639 * This is obtained by the X509 Certificate serialNumber
640 * field. Serial is not always a 32 or 64bit number. Some CAs use
641 * large serial numbers, thus it may be wise to handle it as something
642 * opaque.
643 *
644 * Returns 0 on success and a negative value in case of an error.
645 *
646 **/
647int
648gnutls_x509_crt_get_serial (gnutls_x509_crt_t cert,
649 void *result, size_t * result_size)
650{
651 int ret, len;
652
653 if (cert == NULL)
654 {
655 gnutls_assert ();
656 return GNUTLS_E_INVALID_REQUEST;
657 }
658
659 len = *result_size;
660 ret
661 =
662 asn1_read_value (cert->cert, "tbsCertificate.serialNumber", result, &len);
663 *result_size = len;
664
665 if (ret != ASN1_SUCCESS)
666 {
667 gnutls_assert ();
668 return _gnutls_asn2err (ret);
669 }
670
671 return 0;
672}
673
674/**
675 * gnutls_x509_crt_get_subject_key_id - This function returns the certificate's key identifier
676 * @cert: should contain a gnutls_x509_crt_t structure
677 * @ret: The place where the identifier will be copied
678 * @ret_size: Holds the size of the result field.
679 * @critical: will be non zero if the extension is marked as critical (may be null)
680 *
681 * This function will return the X.509v3 certificate's subject key identifier.
682 * This is obtained by the X.509 Subject Key identifier extension
683 * field (2.5.29.14).
684 *
685 * Returns 0 on success and a negative value in case of an error.
686 *
687 **/
688int
689gnutls_x509_crt_get_subject_key_id (gnutls_x509_crt_t cert,
690 void *ret,
691 size_t * ret_size, unsigned int *critical)
692{
693 int result, len;
694 gnutls_datum_t id;
695 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
696
697 if (cert == NULL)
698 {
699 gnutls_assert ();
700 return GNUTLS_E_INVALID_REQUEST;
701 }
702
703 if (ret)
704 memset (ret, 0, *ret_size);
705 else
706 *ret_size = 0;
707
708 if ((result = _gnutls_x509_crt_get_extension (cert, "2.5.29.14", 0, &id,
709 critical)) < 0)
710 {
711 return result;
712 }
713
714 if (id.size == 0 || id.data == NULL)
715 {
716 gnutls_assert ();
717 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
718 }
719
720 result =
721 asn1_create_element (_gnutls_get_pkix (), "PKIX1.SubjectKeyIdentifier",
722 &c2);
723 if (result != ASN1_SUCCESS)
724 {
725 gnutls_assert ();
726 _gnutls_free_datum (&id);
727 return _gnutls_asn2err (result);
728 }
729
730 result = asn1_der_decoding (&c2, id.data, id.size, NULL);
731 _gnutls_free_datum (&id);
732
733 if (result != ASN1_SUCCESS)
734 {
735 gnutls_assert ();
736 asn1_delete_structure (&c2);
737 return _gnutls_asn2err (result);
738 }
739
740 len = *ret_size;
741 result = asn1_read_value (c2, "", ret, &len);
742
743 *ret_size = len;
744 asn1_delete_structure (&c2);
745
746 if (result == ASN1_VALUE_NOT_FOUND || result == ASN1_ELEMENT_NOT_FOUND)
747 {
748 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
749 }
750
751 if (result != ASN1_SUCCESS)
752 {
753 gnutls_assert ();
754 return _gnutls_asn2err (result);
755 }
756
757 return 0;
758}
759
760/**
761 * gnutls_x509_crt_get_authority_key_id - This function returns the certificate authority's identifier
762 * @cert: should contain a gnutls_x509_crt_t structure
763 * @result: The place where the identifier will be copied
764 * @result_size: Holds the size of the result field.
765 * @critical: will be non zero if the extension is marked as critical (may be null)
766 *
767 * This function will return the X.509v3 certificate authority's key identifier.
768 * This is obtained by the X.509 Authority Key identifier extension
769 * field (2.5.29.35). Note that this function only returns the keyIdentifier
770 * field of the extension.
771 *
772 * Returns 0 on success and a negative value in case of an error.
773 *
774 **/
775int
776gnutls_x509_crt_get_authority_key_id (gnutls_x509_crt_t cert,
777 void *ret,
778 size_t * ret_size,
779 unsigned int *critical)
780{
781 int result, len;
782 gnutls_datum_t id;
783 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
784
785 if (cert == NULL)
786 {
787 gnutls_assert ();
788 return GNUTLS_E_INVALID_REQUEST;
789 }
790
791 if (ret)
792 memset (ret, 0, *ret_size);
793 else
794 *ret_size = 0;
795
796 if ((result = _gnutls_x509_crt_get_extension (cert, "2.5.29.35", 0, &id,
797 critical)) < 0)
798 {
799 return result;
800 }
801
802 if (id.size == 0 || id.data == NULL)
803 {
804 gnutls_assert ();
805 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
806 }
807
808 result =
809 asn1_create_element (_gnutls_get_pkix (), "PKIX1.AuthorityKeyIdentifier",
810 &c2);
811 if (result != ASN1_SUCCESS)
812 {
813 gnutls_assert ();
814 _gnutls_free_datum (&id);
815 return _gnutls_asn2err (result);
816 }
817
818 result = asn1_der_decoding (&c2, id.data, id.size, NULL);
819 _gnutls_free_datum (&id);
820
821 if (result != ASN1_SUCCESS)
822 {
823 gnutls_assert ();
824 asn1_delete_structure (&c2);
825 return _gnutls_asn2err (result);
826 }
827
828 len = *ret_size;
829 result = asn1_read_value (c2, "keyIdentifier", ret, &len);
830
831 *ret_size = len;
832 asn1_delete_structure (&c2);
833
834 if (result == ASN1_VALUE_NOT_FOUND || result == ASN1_ELEMENT_NOT_FOUND)
835 {
836 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
837 }
838
839 if (result != ASN1_SUCCESS)
840 {
841 gnutls_assert ();
842 return _gnutls_asn2err (result);
843 }
844
845 return 0;
846}
847
848/**
849 * gnutls_x509_crt_get_pk_algorithm - This function returns the certificate's PublicKey algorithm
850 * @cert: should contain a gnutls_x509_crt_t structure
851 * @bits: if bits is non null it will hold the size of the parameters' in bits
852 *
853 * This function will return the public key algorithm of an X.509
854 * certificate.
855 *
856 * If bits is non null, it should have enough size to hold the parameters
857 * size in bits. For RSA the bits returned is the modulus.
858 * For DSA the bits returned are of the public
859 * exponent.
860 *
861 * Returns a member of the gnutls_pk_algorithm_t enumeration on success,
862 * or a negative value on error.
863 *
864 **/
865int
866gnutls_x509_crt_get_pk_algorithm (gnutls_x509_crt_t cert, unsigned int *bits)
867{
868 int result;
869
870 if (cert == NULL)
871 {
872 gnutls_assert ();
873 return GNUTLS_E_INVALID_REQUEST;
874 }
875
876 result = _gnutls_x509_get_pk_algorithm (cert->cert,
877 "tbsCertificate.subjectPublicKeyInfo",
878 bits);
879
880 if (result < 0)
881 {
882 gnutls_assert ();
883 return result;
884 }
885
886 return result;
887
888}
889
890inline static int
891is_type_printable (int type)
892{
893 if (type == GNUTLS_SAN_DNSNAME || type == GNUTLS_SAN_RFC822NAME || type
894 == GNUTLS_SAN_URI)
895 return 1;
896 else
897 return 0;
898}
899
900#define XMPP_OID "1.3.6.1.5.5.7.8.5"
901
902/* returns the type and the name on success.
903 * Type is also returned as a parameter in case of an error.
904 */
905static int
906parse_general_name (ASN1_TYPE src,
907 const char *src_name,
908 int seq,
909 void *name,
910 size_t * name_size,
911 unsigned int *ret_type, int othername_oid)
912{
913 int len;
914 char nptr[MAX_NAME_SIZE];
915 int result;
916 opaque choice_type[128];
917 gnutls_x509_subject_alt_name_t type;
918
919 seq++; /* 0->1, 1->2 etc */
920
921 if (src_name[0] != 0)
922 snprintf (nptr, sizeof (nptr), "%s.?%u", src_name, seq);
923 else
924 snprintf (nptr, sizeof (nptr), "?%u", seq);
925
926 len = sizeof (choice_type);
927 result = asn1_read_value (src, nptr, choice_type, &len);
928
929 if (result == ASN1_VALUE_NOT_FOUND || result == ASN1_ELEMENT_NOT_FOUND)
930 {
931 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
932 }
933
934 if (result != ASN1_SUCCESS)
935 {
936 gnutls_assert ();
937 return _gnutls_asn2err (result);
938 }
939
940 type = _gnutls_x509_san_find_type (choice_type);
941 if (type == (gnutls_x509_subject_alt_name_t) - 1)
942 {
943 gnutls_assert ();
944 return GNUTLS_E_X509_UNKNOWN_SAN;
945 }
946
947 if (ret_type)
948 *ret_type = type;
949
950 if (type == GNUTLS_SAN_OTHERNAME)
951 {
952 if (othername_oid)
953 _gnutls_str_cat (nptr, sizeof (nptr), ".otherName.type-id");
954 else
955 _gnutls_str_cat (nptr, sizeof (nptr), ".otherName.value");
956
957 len = *name_size;
958 result = asn1_read_value (src, nptr, name, &len);
959 *name_size = len;
960
961 if (result == ASN1_MEM_ERROR)
962 return GNUTLS_E_SHORT_MEMORY_BUFFER;
963
964 if (result != ASN1_SUCCESS)
965 {
966 gnutls_assert ();
967 return _gnutls_asn2err (result);
968 }
969
970 if (othername_oid)
971 {
972 if (len > strlen (XMPP_OID) && strcmp (name, XMPP_OID) == 0)
973 type = GNUTLS_SAN_OTHERNAME_XMPP;
974 }
975 else
976 {
977 char oid[42];
978
979 if (src_name[0] != 0)
980 snprintf (nptr, sizeof (nptr), "%s.?%u.otherName.type-id",
981 src_name, seq);
982 else
983 snprintf (nptr, sizeof (nptr), "?%u.otherName.type-id", seq);
984
985 len = sizeof (oid);
986 result = asn1_read_value (src, nptr, oid, &len);
987 if (result != ASN1_SUCCESS)
988 {
989 gnutls_assert ();
990 return _gnutls_asn2err (result);
991 }
992
993 if (len > strlen (XMPP_OID) && strcmp (oid, XMPP_OID) == 0)
994 {
995 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
996
997 result =
998 asn1_create_element (_gnutls_get_pkix (), "PKIX1.XmppAddr",
999 &c2);
1000 if (result != ASN1_SUCCESS)
1001 {
1002 gnutls_assert ();
1003 return _gnutls_asn2err (result);
1004 }
1005
1006 result = asn1_der_decoding (&c2, name, *name_size, NULL);
1007 if (result != ASN1_SUCCESS)
1008 {
1009 gnutls_assert ();
1010 asn1_delete_structure (&c2);
1011 return _gnutls_asn2err (result);
1012 }
1013
1014 result = asn1_read_value (c2, "", name, &len);
1015 *name_size = len;
1016 if (result != ASN1_SUCCESS)
1017 {
1018 gnutls_assert ();
1019 asn1_delete_structure (&c2);
1020 return _gnutls_asn2err (result);
1021 }
1022 asn1_delete_structure (&c2);
1023 }
1024 }
1025 }
1026 else if (type == GNUTLS_SAN_DN)
1027 {
1028 _gnutls_str_cat (nptr, sizeof (nptr), ".directoryName");
1029 result = _gnutls_x509_parse_dn (src, nptr, name, name_size);
1030 if (result < 0)
1031 {
1032 gnutls_assert ();
1033 return result;
1034 }
1035 }
1036 else if (othername_oid)
1037 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1038 else
1039 {
1040 size_t orig_name_size = *name_size;
1041
1042 _gnutls_str_cat (nptr, sizeof (nptr), ".");
1043 _gnutls_str_cat (nptr, sizeof (nptr), choice_type);
1044
1045 len = *name_size;
1046 result = asn1_read_value (src, nptr, name, &len);
1047 *name_size = len;
1048
1049 if (result == ASN1_MEM_ERROR)
1050 {
1051 if (is_type_printable (type))
1052 (*name_size)++;
1053 return GNUTLS_E_SHORT_MEMORY_BUFFER;
1054 }
1055
1056 if (result != ASN1_SUCCESS)
1057 {
1058 gnutls_assert ();
1059 return _gnutls_asn2err (result);
1060 }
1061
1062 if (is_type_printable (type))
1063 {
1064
1065 if (len + 1 > orig_name_size)
1066 {
1067 gnutls_assert ();
1068 (*name_size)++;
1069 return GNUTLS_E_SHORT_MEMORY_BUFFER;
1070 }
1071
1072 /* null terminate it */
1073 ((char *) name)[*name_size] = 0;
1074 }
1075
1076 }
1077
1078 return type;
1079}
1080
1081static int
1082get_subject_alt_name (gnutls_x509_crt_t cert,
1083 unsigned int seq,
1084 void *ret,
1085 size_t * ret_size,
1086 unsigned int *ret_type,
1087 unsigned int *critical, int othername_oid)
1088{
1089 int result;
1090 gnutls_datum_t dnsname;
1091 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
1092 gnutls_x509_subject_alt_name_t type;
1093
1094 if (cert == NULL)
1095 {
1096 gnutls_assert ();
1097 return GNUTLS_E_INVALID_REQUEST;
1098 }
1099
1100 if (ret)
1101 memset (ret, 0, *ret_size);
1102 else
1103 *ret_size = 0;
1104
1105 if ((result =
1106 _gnutls_x509_crt_get_extension (cert, "2.5.29.17", 0, &dnsname,
1107 critical)) < 0)
1108 {
1109 return result;
1110 }
1111
1112 if (dnsname.size == 0 || dnsname.data == NULL)
1113 {
1114 gnutls_assert ();
1115 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1116 }
1117
1118 result =
1119 asn1_create_element (_gnutls_get_pkix (), "PKIX1.SubjectAltName", &c2);
1120 if (result != ASN1_SUCCESS)
1121 {
1122 gnutls_assert ();
1123 _gnutls_free_datum (&dnsname);
1124 return _gnutls_asn2err (result);
1125 }
1126
1127 result = asn1_der_decoding (&c2, dnsname.data, dnsname.size, NULL);
1128 _gnutls_free_datum (&dnsname);
1129
1130 if (result != ASN1_SUCCESS)
1131 {
1132 gnutls_assert ();
1133 asn1_delete_structure (&c2);
1134 return _gnutls_asn2err (result);
1135 }
1136
1137 result = parse_general_name (c2, "", seq, ret, ret_size, ret_type,
1138 othername_oid);
1139
1140 asn1_delete_structure (&c2);
1141
1142 if (result < 0)
1143 {
1144 return result;
1145 }
1146
1147 type = result;
1148
1149 return type;
1150}
1151
1152/**
1153 * gnutls_x509_crt_get_subject_alt_name - Get certificate's alternative name, if any
1154 * @cert: should contain a gnutls_x509_crt_t structure
1155 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
1156 * @ret: is the place where the alternative name will be copied to
1157 * @ret_size: holds the size of ret.
1158 * @critical: will be non zero if the extension is marked as critical (may be null)
1159 *
1160 * This function will return the alternative names, contained in the
1161 * given certificate.
1162 *
1163 * This is specified in X509v3 Certificate Extensions. GNUTLS will
1164 * return the Alternative name (2.5.29.17), or a negative error code.
1165 *
1166 * When the SAN type is otherName, it will extract the data in the
1167 * otherName's value field, and %GNUTLS_SAN_OTHERNAME is returned.
1168 * You may use gnutls_x509_crt_get_subject_alt_othername_oid() to get
1169 * the corresponding OID and the "virtual" SAN types (e.g.,
1170 * %GNUTLS_SAN_OTHERNAME_XMPP).
1171 *
1172 * If an otherName OID is known, the data will be decoded. Otherwise
1173 * the returned data will be DER encoded, and you will have to decode
1174 * it yourself. Currently, only the RFC 3920 id-on-xmppAddr SAN is
1175 * recognized.
1176 *
1177 * Returns the alternative subject name type on success. The type is
1178 * one of the enumerated gnutls_x509_subject_alt_name_t. It will
1179 * return %GNUTLS_E_SHORT_MEMORY_BUFFER if @ret_size is not large
1180 * enough to hold the value. In that case @ret_size will be updated
1181 * with the required size. If the certificate does not have an
1182 * Alternative name with the specified sequence number then
1183 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
1184 *
1185 **/
1186int
1187gnutls_x509_crt_get_subject_alt_name (gnutls_x509_crt_t cert,
1188 unsigned int seq,
1189 void *ret,
1190 size_t * ret_size,
1191 unsigned int *critical)
1192{
1193 return get_subject_alt_name (cert, seq, ret, ret_size, NULL, critical, 0);
1194}
1195
1196/**
1197 * gnutls_x509_crt_get_subject_alt_name2 - Get certificate's alternative name, if any
1198 * @cert: should contain a gnutls_x509_crt_t structure
1199 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
1200 * @ret: is the place where the alternative name will be copied to
1201 * @ret_size: holds the size of ret.
1202 * @ret_type: holds the type of the alternative name (one of gnutls_x509_subject_alt_name_t).
1203 * @critical: will be non zero if the extension is marked as critical (may be null)
1204 *
1205 * This function will return the alternative names, contained in the
1206 * given certificate. It is the same as gnutls_x509_crt_get_subject_alt_name()
1207 * except for the fact that it will return the type of the alternative
1208 * name in @ret_type even if the function fails for some reason (i.e.
1209 * the buffer provided is not enough).
1210 *
1211 * The return values are the same as with gnutls_x509_crt_get_subject_alt_name().
1212 *
1213 **/
1214int
1215gnutls_x509_crt_get_subject_alt_name2 (gnutls_x509_crt_t cert,
1216 unsigned int seq,
1217 void *ret,
1218 size_t * ret_size,
1219 unsigned int *ret_type,
1220 unsigned int *critical)
1221{
1222 return get_subject_alt_name (cert, seq, ret, ret_size, ret_type, critical,
1223 0);
1224}
1225
1226/**
1227 * gnutls_x509_crt_get_subject_alt_othername_oid - Get SAN otherName OID
1228 * @cert: should contain a gnutls_x509_crt_t structure
1229 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
1230 * @ret: is the place where the otherName OID will be copied to
1231 * @ret_size: holds the size of ret.
1232 *
1233 * This function will extract the type OID of an otherName Subject
1234 * Alternative Name, contained in the given certificate, and return
1235 * the type as an enumerated element.
1236 *
1237 * This function is only useful if
1238 * gnutls_x509_crt_get_subject_alt_name() returned
1239 * %GNUTLS_SAN_OTHERNAME.
1240 *
1241 * Returns the alternative subject name type on success. The type is
1242 * one of the enumerated gnutls_x509_subject_alt_name_t. For
1243 * supported OIDs, it will return one of the virtual
1244 * (GNUTLS_SAN_OTHERNAME_*) types, e.g. %GNUTLS_SAN_OTHERNAME_XMPP,
1245 * and %GNUTLS_SAN_OTHERNAME for unknown OIDs. It will return
1246 * %GNUTLS_E_SHORT_MEMORY_BUFFER if @ret_size is not large enough to
1247 * hold the value. In that case @ret_size will be updated with the
1248 * required size. If the certificate does not have an Alternative
1249 * name with the specified sequence number and with the otherName type
1250 * then %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
1251 **/
1252int
1253gnutls_x509_crt_get_subject_alt_othername_oid (gnutls_x509_crt_t cert,
1254 unsigned int seq,
1255 void *ret, size_t * ret_size)
1256{
1257 return get_subject_alt_name (cert, seq, ret, ret_size, NULL, NULL, 1);
1258}
1259
1260/**
1261 * gnutls_x509_crt_get_basic_constraints - This function returns the certificate basic constraints
1262 * @cert: should contain a gnutls_x509_crt_t structure
1263 * @critical: will be non zero if the extension is marked as critical
1264 * @ca: pointer to output integer indicating CA status, may be NULL,
1265 * value is 1 if the certificate CA flag is set, 0 otherwise.
1266 * @pathlen: pointer to output integer indicating path length (may be
1267 * NULL), non-negative values indicate a present pathLenConstraint
1268 * field and the actual value, -1 indicate that the field is absent.
1269 *
1270 * This function will read the certificate's basic constraints, and
1271 * return the certificates CA status. It reads the basicConstraints
1272 * X.509 extension (2.5.29.19).
1273 *
1274 * Return value: If the certificate is a CA a positive value will be
1275 * returned, or zero if the certificate does not have CA flag set. A
1276 * negative value may be returned in case of errors. If the
1277 * certificate does not contain the basicConstraints extension
1278 * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
1279 **/
1280int
1281gnutls_x509_crt_get_basic_constraints (gnutls_x509_crt_t cert,
1282 unsigned int *critical,
1283 int *ca, int *pathlen)
1284{
1285 int result;
1286 gnutls_datum_t basicConstraints;
1287 int tmp_ca;
1288
1289 if (cert == NULL)
1290 {
1291 gnutls_assert ();
1292 return GNUTLS_E_INVALID_REQUEST;
1293 }
1294
1295 if ((result = _gnutls_x509_crt_get_extension (cert, "2.5.29.19", 0,
1296 &basicConstraints, critical))
1297 < 0)
1298 {
1299 return result;
1300 }
1301
1302 if (basicConstraints.size == 0 || basicConstraints.data == NULL)
1303 {
1304 gnutls_assert ();
1305 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1306 }
1307
1308 result = _gnutls_x509_ext_extract_basicConstraints (&tmp_ca, pathlen,
1309 basicConstraints.data,
1310 basicConstraints.size);
1311 if (ca)
1312 *ca = tmp_ca;
1313 _gnutls_free_datum (&basicConstraints);
1314
1315 if (result < 0)
1316 {
1317 gnutls_assert ();
1318 return result;
1319 }
1320
1321 return tmp_ca;
1322}
1323
1324/**
1325 * gnutls_x509_crt_get_ca_status - This function returns the certificate CA status
1326 * @cert: should contain a gnutls_x509_crt_t structure
1327 * @critical: will be non zero if the extension is marked as critical
1328 *
1329 * This function will return certificates CA status, by reading the
1330 * basicConstraints X.509 extension (2.5.29.19). If the certificate is
1331 * a CA a positive value will be returned, or zero if the certificate
1332 * does not have CA flag set.
1333 *
1334 * Use gnutls_x509_crt_get_basic_constraints() if you want to read the
1335 * pathLenConstraint field too.
1336 *
1337 * A negative value may be returned in case of parsing error.
1338 * If the certificate does not contain the basicConstraints extension
1339 * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
1340 *
1341 **/
1342int
1343gnutls_x509_crt_get_ca_status (gnutls_x509_crt_t cert, unsigned int *critical)
1344{
1345 int ca, pathlen;
1346 return gnutls_x509_crt_get_basic_constraints (cert, critical, &ca,
1347 &pathlen);
1348}
1349
1350/**
1351 * gnutls_x509_crt_get_key_usage - This function returns the certificate's key usage
1352 * @cert: should contain a gnutls_x509_crt_t structure
1353 * @key_usage: where the key usage bits will be stored
1354 * @critical: will be non zero if the extension is marked as critical
1355 *
1356 * This function will return certificate's key usage, by reading the
1357 * keyUsage X.509 extension (2.5.29.15). The key usage value will ORed values of the:
1358 * GNUTLS_KEY_DIGITAL_SIGNATURE, GNUTLS_KEY_NON_REPUDIATION,
1359 * GNUTLS_KEY_KEY_ENCIPHERMENT, GNUTLS_KEY_DATA_ENCIPHERMENT,
1360 * GNUTLS_KEY_KEY_AGREEMENT, GNUTLS_KEY_KEY_CERT_SIGN,
1361 * GNUTLS_KEY_CRL_SIGN, GNUTLS_KEY_ENCIPHER_ONLY,
1362 * GNUTLS_KEY_DECIPHER_ONLY.
1363 *
1364 * A negative value may be returned in case of parsing error.
1365 * If the certificate does not contain the keyUsage extension
1366 * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
1367 *
1368 **/
1369int
1370gnutls_x509_crt_get_key_usage (gnutls_x509_crt_t cert,
1371 unsigned int *key_usage,
1372 unsigned int *critical)
1373{
1374 int result;
1375 gnutls_datum_t keyUsage;
1376 uint16_t _usage;
1377
1378 if (cert == NULL)
1379 {
1380 gnutls_assert ();
1381 return GNUTLS_E_INVALID_REQUEST;
1382 }
1383
1384 if ((result =
1385 _gnutls_x509_crt_get_extension (cert, "2.5.29.15", 0, &keyUsage,
1386 critical)) < 0)
1387 {
1388 return result;
1389 }
1390
1391 if (keyUsage.size == 0 || keyUsage.data == NULL)
1392 {
1393 gnutls_assert ();
1394 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1395 }
1396
1397 result = _gnutls_x509_ext_extract_keyUsage (&_usage, keyUsage.data,
1398 keyUsage.size);
1399 _gnutls_free_datum (&keyUsage);
1400
1401 *key_usage = _usage;
1402
1403 if (result < 0)
1404 {
1405 gnutls_assert ();
1406 return result;
1407 }
1408
1409 return 0;
1410}
1411
1412/**
1413 * gnutls_x509_crt_get_proxy - This function returns the proxy certificate info
1414 * @cert: should contain a gnutls_x509_crt_t structure
1415 * @critical: will be non zero if the extension is marked as critical
1416 * @pathlen: pointer to output integer indicating path length (may be
1417 * NULL), non-negative values indicate a present pCPathLenConstraint
1418 * field and the actual value, -1 indicate that the field is absent.
1419 *
1420 * This function will read the certificate's basic constraints, and
1421 * return the certificates CA status. It reads the basicConstraints
1422 * X.509 extension (2.5.29.19).
1423 *
1424 * Return value: If the certificate is a CA a positive value will be
1425 * returned, or zero if the certificate does not have CA flag set. A
1426 * negative value may be returned in case of errors. If the
1427 * certificate does not contain the basicConstraints extension
1428 * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
1429 **/
1430int
1431gnutls_x509_crt_get_proxy (gnutls_x509_crt_t cert,
1432 unsigned int *critical,
1433 int *pathlen,
1434 char **policyLanguage,
1435 char **policy, size_t * sizeof_policy)
1436{
1437 int result;
1438 gnutls_datum_t proxyCertInfo;
1439
1440 if (cert == NULL)
1441 {
1442 gnutls_assert ();
1443 return GNUTLS_E_INVALID_REQUEST;
1444 }
1445
1446 if ((result = _gnutls_x509_crt_get_extension (cert, "1.3.6.1.5.5.7.1.14", 0,
1447 &proxyCertInfo,
1448 critical)) < 0)
1449 {
1450 return result;
1451 }
1452
1453 if (proxyCertInfo.size == 0 || proxyCertInfo.data == NULL)
1454 {
1455 gnutls_assert ();
1456 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1457 }
1458
1459 result = _gnutls_x509_ext_extract_proxyCertInfo (pathlen, policyLanguage,
1460 policy, sizeof_policy,
1461 proxyCertInfo.data,
1462 proxyCertInfo.size);
1463 _gnutls_free_datum (&proxyCertInfo);
1464 if (result < 0)
1465 {
1466 gnutls_assert ();
1467 return result;
1468 }
1469
1470 return 0;
1471}
1472
1473/**
1474 * gnutls_x509_crt_get_extension_by_oid - This function returns the specified extension
1475 * @cert: should contain a gnutls_x509_crt_t structure
1476 * @oid: holds an Object Identified in null terminated string
1477 * @indx: In case multiple same OIDs exist in the extensions, this specifies which to send. Use zero to get the first one.
1478 * @buf: a pointer to a structure to hold the name (may be null)
1479 * @sizeof_buf: initially holds the size of @buf
1480 * @critical: will be non zero if the extension is marked as critical
1481 *
1482 * This function will return the extension specified by the OID in the certificate.
1483 * The extensions will be returned as binary data DER encoded, in the provided
1484 * buffer.
1485 *
1486 * A negative value may be returned in case of parsing error.
1487 * If the certificate does not contain the specified extension
1488 * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
1489 *
1490 **/
1491int
1492gnutls_x509_crt_get_extension_by_oid (gnutls_x509_crt_t cert,
1493 const char *oid,
1494 int indx,
1495 void *buf,
1496 size_t * sizeof_buf,
1497 unsigned int *critical)
1498{
1499 int result;
1500 gnutls_datum_t output;
1501
1502 if (cert == NULL)
1503 {
1504 gnutls_assert ();
1505 return GNUTLS_E_INVALID_REQUEST;
1506 }
1507
1508 if ((result = _gnutls_x509_crt_get_extension (cert, oid, indx, &output,
1509 critical)) < 0)
1510 {
1511 gnutls_assert ();
1512 return result;
1513 }
1514
1515 if (output.size == 0 || output.data == NULL)
1516 {
1517 gnutls_assert ();
1518 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1519 }
1520
1521 if (output.size > (unsigned int) *sizeof_buf)
1522 {
1523 *sizeof_buf = output.size;
1524 _gnutls_free_datum (&output);
1525 return GNUTLS_E_SHORT_MEMORY_BUFFER;
1526 }
1527
1528 *sizeof_buf = output.size;
1529
1530 if (buf)
1531 memcpy (buf, output.data, output.size);
1532
1533 _gnutls_free_datum (&output);
1534
1535 return 0;
1536
1537}
1538
1539/**
1540 * gnutls_x509_crt_get_extension_oid - This function returns the specified extension OID
1541 * @cert: should contain a gnutls_x509_crt_t structure
1542 * @indx: Specifies which extension OID to send. Use zero to get the first one.
1543 * @oid: a pointer to a structure to hold the OID (may be null)
1544 * @sizeof_oid: initially holds the size of @oid
1545 *
1546 * This function will return the requested extension OID in the certificate.
1547 * The extension OID will be stored as a string in the provided buffer.
1548 *
1549 * A negative value may be returned in case of parsing error.
1550 * If your have reached the last extension available
1551 * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
1552 *
1553 **/
1554int
1555gnutls_x509_crt_get_extension_oid (gnutls_x509_crt_t cert,
1556 int indx, void *oid, size_t * sizeof_oid)
1557{
1558 int result;
1559
1560 if (cert == NULL)
1561 {
1562 gnutls_assert ();
1563 return GNUTLS_E_INVALID_REQUEST;
1564 }
1565
1566 result = _gnutls_x509_crt_get_extension_oid (cert, indx, oid, sizeof_oid);
1567 if (result < 0)
1568 {
1569 return result;
1570 }
1571
1572 return 0;
1573
1574}
1575
1576/**
1577 * gnutls_x509_crt_get_extension_info - Get extension id and criticality
1578 * @cert: should contain a gnutls_x509_crt_t structure
1579 * @indx: Specifies which extension OID to send. Use zero to get the first one.
1580 * @oid: a pointer to a structure to hold the OID
1581 * @sizeof_oid: initially holds the size of @oid
1582 * @critical: output variable with critical flag, may be NULL.
1583 *
1584 * This function will return the requested extension OID in the
1585 * certificate, and the critical flag for it. The extension OID will
1586 * be stored as a string in the provided buffer. Use
1587 * gnutls_x509_crt_get_extension_data() to extract the data.
1588 *
1589 * Return 0 on success. A negative value may be returned in case of
1590 * parsing error. If you have reached the last extension available
1591 * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
1592 *
1593 **/
1594int
1595gnutls_x509_crt_get_extension_info (gnutls_x509_crt_t cert,
1596 int indx,
1597 void *oid,
1598 size_t * sizeof_oid, int *critical)
1599{
1600 int result;
1601 char str_critical[10];
1602 char name[MAX_NAME_SIZE];
1603 int len;
1604
1605 if (!cert)
1606 {
1607 gnutls_assert ();
1608 return GNUTLS_E_INVALID_REQUEST;
1609 }
1610
1611 snprintf (name, sizeof (name), "tbsCertificate.extensions.?%u.extnID",
1612 indx + 1);
1613
1614 len = *sizeof_oid;
1615 result = asn1_read_value (cert->cert, name, oid, &len);
1616 *sizeof_oid = len;
1617
1618 if (result == ASN1_ELEMENT_NOT_FOUND)
1619 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1620 else if (result < 0)
1621 {
1622 gnutls_assert ();
1623 return _gnutls_asn2err (result);
1624 }
1625
1626 snprintf (name, sizeof (name), "tbsCertificate.extensions.?%u.critical",
1627 indx + 1);
1628 len = sizeof (str_critical);
1629 result = asn1_read_value (cert->cert, name, str_critical, &len);
1630 if (result < 0)
1631 {
1632 gnutls_assert ();
1633 return _gnutls_asn2err (result);
1634 }
1635
1636 if (critical)
1637 {
1638 if (str_critical[0] == 'T')
1639 *critical = 1;
1640 else
1641 *critical = 0;
1642 }
1643
1644 return 0;
1645
1646}
1647
1648/**
1649 * gnutls_x509_crt_get_extension_data - Get the specified extension data
1650 * @cert: should contain a gnutls_x509_crt_t structure
1651 * @indx: Specifies which extension OID to send. Use zero to get the first one.
1652 * @data: a pointer to a structure to hold the data (may be null)
1653 * @sizeof_data: initially holds the size of @oid
1654 *
1655 * This function will return the requested extension data in the
1656 * certificate. The extension data will be stored as a string in the
1657 * provided buffer.
1658 *
1659 * Use gnutls_x509_crt_get_extension_info() to extract the OID and
1660 * critical flag. Use gnutls_x509_crt_get_extension_by_oid() instead,
1661 * if you want to get data indexed by the extension OID rather than
1662 * sequence.
1663 *
1664 * Return 0 on success. A negative value may be returned in case of
1665 * parsing error. If you have reached the last extension available
1666 * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
1667 **/
1668int
1669gnutls_x509_crt_get_extension_data (gnutls_x509_crt_t cert,
1670 int indx,
1671 void *data, size_t * sizeof_data)
1672{
1673 int result, len;
1674 char name[MAX_NAME_SIZE];
1675
1676 if (!cert)
1677 {
1678 gnutls_assert ();
1679 return GNUTLS_E_INVALID_REQUEST;
1680 }
1681
1682 snprintf (name, sizeof (name), "tbsCertificate.extensions.?%u.extnValue",
1683 indx + 1);
1684
1685 len = *sizeof_data;
1686 result = asn1_read_value (cert->cert, name, data, &len);
1687 *sizeof_data = len;
1688
1689 if (result == ASN1_ELEMENT_NOT_FOUND)
1690 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1691 else if (result < 0)
1692 {
1693 gnutls_assert ();
1694 return _gnutls_asn2err (result);
1695 }
1696
1697 return 0;
1698}
1699
1700static int
1701_gnutls_x509_crt_get_raw_dn2 (gnutls_x509_crt_t cert,
1702 const char *whom, gnutls_datum_t * start)
1703{
1704 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
1705 int result, len1;
1706 int start1, end1;
1707 gnutls_datum_t signed_data = { NULL,
1708 0
1709 };
1710
1711 /* get the issuer of 'cert'
1712 */
1713 if ((result =
1714 asn1_create_element (_gnutls_get_pkix (), "PKIX1.TBSCertificate",
1715 &c2)) != ASN1_SUCCESS)
1716 {
1717 gnutls_assert ();
1718 return _gnutls_asn2err (result);
1719 }
1720
1721 result = _gnutls_x509_get_signed_data (cert->cert, "tbsCertificate",
1722 &signed_data);
1723 if (result < 0)
1724 {
1725 gnutls_assert ();
1726 goto cleanup;
1727 }
1728
1729 result = asn1_der_decoding (&c2, signed_data.data, signed_data.size, NULL);
1730 if (result != ASN1_SUCCESS)
1731 {
1732 gnutls_assert ();
1733 asn1_delete_structure (&c2);
1734 result = _gnutls_asn2err (result);
1735 goto cleanup;
1736 }
1737
1738 result = asn1_der_decoding_startEnd (c2, signed_data.data, signed_data.size,
1739 whom, &start1, &end1);
1740
1741 if (result != ASN1_SUCCESS)
1742 {
1743 gnutls_assert ();
1744 result = _gnutls_asn2err (result);
1745 goto cleanup;
1746 }
1747
1748 len1 = end1 - start1 + 1;
1749
1750 _gnutls_set_datum (start, &signed_data.data[start1], len1);
1751
1752 result = 0;
1753
1754cleanup:asn1_delete_structure (&c2);
1755 _gnutls_free_datum (&signed_data);
1756 return result;
1757}
1758
1759/**
1760 * gnutls_x509_crt_get_raw_issuer_dn - This function returns the issuer's DN DER encoded
1761 * @cert: should contain a gnutls_x509_crt_t structure
1762 * @start: will hold the starting point of the DN
1763 *
1764 * This function will return a pointer to the DER encoded DN structure
1765 * and the length.
1766 *
1767 * Returns 0 on success or a negative value on error.
1768 *
1769 **/
1770int
1771gnutls_x509_crt_get_raw_issuer_dn (gnutls_x509_crt_t cert,
1772 gnutls_datum_t * start)
1773{
1774 return _gnutls_x509_crt_get_raw_dn2 (cert, "issuer", start);
1775}
1776
1777/**
1778 * gnutls_x509_crt_get_raw_dn - This function returns the subject's DN DER encoded
1779 * @cert: should contain a gnutls_x509_crt_t structure
1780 * @start: will hold the starting point of the DN
1781 *
1782 * This function will return a pointer to the DER encoded DN structure and
1783 * the length.
1784 *
1785 * Returns 0 on success, or a negative value on error.
1786 *
1787 **/
1788int
1789gnutls_x509_crt_get_raw_dn (gnutls_x509_crt_t cert, gnutls_datum_t * start)
1790{
1791 return _gnutls_x509_crt_get_raw_dn2 (cert, "subject", start);
1792}
1793
1794static int
1795get_dn (gnutls_x509_crt_t cert, const char *whom, gnutls_x509_dn_t * dn)
1796{
1797 *dn = asn1_find_node (cert->cert, whom);
1798 if (!*dn)
1799 return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND;
1800 return 0;
1801}
1802
1803/**
1804 * gnutls_x509_crt_get_subject: get opaque subject DN pointer
1805 * @cert: should contain a gnutls_x509_crt_t structure
1806 * @dn: output variable with pointer to opaque DN.
1807 *
1808 * Return the Certificate's Subject DN as an opaque data type. You
1809 * may use gnutls_x509_dn_get_rdn_ava() to decode the DN.
1810 *
1811 * Returns: Returns 0 on success, or an error code.
1812 **/
1813int
1814gnutls_x509_crt_get_subject (gnutls_x509_crt_t cert, gnutls_x509_dn_t * dn)
1815{
1816 return get_dn (cert, "tbsCertificate.subject.rdnSequence", dn);
1817}
1818
1819/**
1820 * gnutls_x509_crt_get_issuer: get opaque issuer DN pointer
1821 * @cert: should contain a gnutls_x509_crt_t structure
1822 * @dn: output variable with pointer to opaque DN
1823 *
1824 * Return the Certificate's Issuer DN as an opaque data type. You may
1825 * use gnutls_x509_dn_get_rdn_ava() to decode the DN.
1826 *
1827 * Note that @dn points into the @cert object, and thus you may not
1828 * deallocate @cert and continue to access @dn.
1829 *
1830 * Returns: Returns 0 on success, or an error code.
1831 **/
1832int
1833gnutls_x509_crt_get_issuer (gnutls_x509_crt_t cert, gnutls_x509_dn_t * dn)
1834{
1835 return get_dn (cert, "tbsCertificate.issuer.rdnSequence", dn);
1836}
1837
1838/**
1839 * gnutls_x509_dn_get_rdn_ava:
1840 * @dn: input variable with opaque DN pointer
1841 * @irdn: index of RDN
1842 * @iava: index of AVA.
1843 * @ava: Pointer to structure which will hold output information.
1844 *
1845 * Get pointers to data within the DN.
1846 *
1847 * Note that @ava will contain pointers into the @dn structure, so you
1848 * should not modify any data or deallocate it. Note also that the DN
1849 * in turn points into the original certificate structure, and thus
1850 * you may not deallocate the certificate and continue to access @dn.
1851 *
1852 * Returns: Returns 0 on success, or an error code.
1853 **/
1854int
1855gnutls_x509_dn_get_rdn_ava (gnutls_x509_dn_t dn,
1856 int irdn, int iava, gnutls_x509_ava_st * ava)
1857{
1858 ASN1_TYPE rdn, elem;
1859 long len;
1860 int lenlen, remlen, ret;
1861 char rbuf[MAX_NAME_SIZE];
1862 unsigned char cls, *ptr;
1863
1864 iava++;
1865 irdn++; /* 0->1, 1->2 etc */
1866
1867 snprintf (rbuf, sizeof (rbuf), "rdnSequence.?%d.?%d", irdn, iava);
1868 rdn = asn1_find_node (dn, rbuf);
1869 if (!rdn)
1870 {
1871 gnutls_assert ();
1872 return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND;
1873 }
1874
1875 snprintf (rbuf, sizeof (rbuf), "?%d.type", iava);
1876 elem = asn1_find_node (rdn, rbuf);
1877 if (!elem)
1878 {
1879 gnutls_assert ();
1880 return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND;
1881 }
1882
1883 ava->oid.data = elem->value;
1884 ava->oid.size = elem->value_len;
1885
1886 snprintf (rbuf, sizeof (rbuf), "?%d.value", iava);
1887 elem = asn1_find_node (rdn, rbuf);
1888 if (!elem)
1889 {
1890 gnutls_assert ();
1891 return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND;
1892 }
1893
1894 /* The value still has the previous tag's length bytes, plus the
1895 * current value's tag and length bytes. Decode them.
1896 */
1897
1898 ptr = elem->value;
1899 remlen = elem->value_len;
1900 len = asn1_get_length_der (ptr, remlen, &lenlen);
1901 if (len < 0)
1902 {
1903 gnutls_assert ();
1904 return GNUTLS_E_ASN1_DER_ERROR;
1905 }
1906
1907 ptr += lenlen;
1908 remlen -= lenlen;
1909 ret = asn1_get_tag_der (ptr, remlen, &cls, &lenlen, &ava->value_tag);
1910 if (ret)
1911 {
1912 gnutls_assert ();
1913 return _gnutls_asn2err (ret);
1914 }
1915
1916 ptr += lenlen;
1917 remlen -= lenlen;
1918
1919 ava->value.size = asn1_get_length_der (ptr, remlen, &lenlen);
1920 if (ava->value.size < 0)
1921 {
1922 gnutls_assert ();
1923 return GNUTLS_E_ASN1_DER_ERROR;
1924 }
1925 ava->value.data = ptr + lenlen;
1926
1927 return 0;
1928}
1929
1930/**
1931 * gnutls_x509_crt_get_fingerprint - This function returns the Certificate's fingerprint
1932 * @cert: should contain a gnutls_x509_crt_t structure
1933 * @algo: is a digest algorithm
1934 * @buf: a pointer to a structure to hold the fingerprint (may be null)
1935 * @sizeof_buf: initially holds the size of @buf
1936 *
1937 * This function will calculate and copy the certificate's fingerprint
1938 * in the provided buffer.
1939 *
1940 * If the buffer is null then only the size will be filled.
1941 *
1942 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
1943 * not long enough, and in that case the *sizeof_buf will be updated
1944 * with the required size. On success 0 is returned.
1945 **/
1946int
1947gnutls_x509_crt_get_fingerprint (gnutls_x509_crt_t cert,
1948 gnutls_digest_algorithm_t algo,
1949 void *buf, size_t * sizeof_buf)
1950{
1951 opaque *cert_buf;
1952 int cert_buf_size;
1953 int result;
1954 gnutls_datum_t tmp;
1955
1956 if (sizeof_buf == 0 || cert == NULL)
1957 {
1958 return GNUTLS_E_INVALID_REQUEST;
1959 }
1960
1961 cert_buf_size = 0;
1962 asn1_der_coding (cert->cert, "", NULL, &cert_buf_size, NULL);
1963
1964 cert_buf = gnutls_alloca (cert_buf_size);
1965 if (cert_buf == NULL)
1966 {
1967 gnutls_assert ();
1968 return GNUTLS_E_MEMORY_ERROR;
1969 }
1970
1971 result = asn1_der_coding (cert->cert, "", cert_buf, &cert_buf_size, NULL);
1972
1973 if (result != ASN1_SUCCESS)
1974 {
1975 gnutls_assert ();
1976 gnutls_afree (cert_buf);
1977 return _gnutls_asn2err (result);
1978 }
1979
1980 tmp.data = cert_buf;
1981 tmp.size = cert_buf_size;
1982
1983 result = gnutls_fingerprint (algo, &tmp, buf, sizeof_buf);
1984 gnutls_afree (cert_buf);
1985
1986 return result;
1987}
1988
1989/**
1990 * gnutls_x509_crt_export - This function will export the certificate
1991 * @cert: Holds the certificate
1992 * @format: the format of output params. One of PEM or DER.
1993 * @output_data: will contain a certificate PEM or DER encoded
1994 * @output_data_size: holds the size of output_data (and will be
1995 * replaced by the actual size of parameters)
1996 *
1997 * This function will export the certificate to DER or PEM format.
1998 *
1999 * If the buffer provided is not long enough to hold the output, then
2000 * *output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
2001 * be returned.
2002 *
2003 * If the structure is PEM encoded, it will have a header
2004 * of "BEGIN CERTIFICATE".
2005 *
2006 * Return value: In case of failure a negative value will be
2007 * returned, and 0 on success.
2008 **/
2009int
2010gnutls_x509_crt_export (gnutls_x509_crt_t cert,
2011 gnutls_x509_crt_fmt_t format,
2012 void *output_data, size_t * output_data_size)
2013{
2014 if (cert == NULL)
2015 {
2016 gnutls_assert ();
2017 return GNUTLS_E_INVALID_REQUEST;
2018 }
2019
2020 return _gnutls_x509_export_int (cert->cert, format, "CERTIFICATE",
2021 output_data, output_data_size);
2022}
2023
2024static int
2025rsadsa_get_key_id (gnutls_x509_crt_t crt,
2026 int pk,
2027 unsigned char *output_data, size_t * output_data_size)
2028{
2029 mpi_t params[MAX_PUBLIC_PARAMS_SIZE];
2030 int params_size = MAX_PUBLIC_PARAMS_SIZE;
2031 int i, result = 0;
2032 gnutls_datum_t der = { NULL,
2033 0
2034 };
2035 GNUTLS_HASH_HANDLE hd;
2036
2037 result = _gnutls_x509_crt_get_mpis (crt, params, &params_size);
2038 if (result < 0)
2039 {
2040 gnutls_assert ();
2041 return result;
2042 }
2043
2044 if (pk == GNUTLS_PK_RSA)
2045 {
2046 result = _gnutls_x509_write_rsa_params (params, params_size, &der);
2047 if (result < 0)
2048 {
2049 gnutls_assert ();
2050 goto cleanup;
2051 }
2052 }
2053 else
2054 return GNUTLS_E_INTERNAL_ERROR;
2055
2056 hd = _gnutls_hash_init (GNUTLS_MAC_SHA1);
2057 if (hd == GNUTLS_HASH_FAILED)
2058 {
2059 gnutls_assert ();
2060 result = GNUTLS_E_INTERNAL_ERROR;
2061 goto cleanup;
2062 }
2063
2064 _gnutls_hash (hd, der.data, der.size);
2065
2066 _gnutls_hash_deinit (hd, output_data);
2067 *output_data_size = 20;
2068
2069 result = 0;
2070
2071cleanup:
2072
2073 _gnutls_free_datum (&der);
2074
2075 /* release all allocated MPIs
2076 */
2077 for (i = 0; i < params_size; i++)
2078 {
2079 _gnutls_mpi_release (&params[i]);
2080 }
2081 return result;
2082}
2083
2084/**
2085 * gnutls_x509_crt_get_key_id - Return unique ID of public key's parameters
2086 * @crt: Holds the certificate
2087 * @flags: should be 0 for now
2088 * @output_data: will contain the key ID
2089 * @output_data_size: holds the size of output_data (and will be
2090 * replaced by the actual size of parameters)
2091 *
2092 * This function will return a unique ID the depends on the public
2093 * key parameters. This ID can be used in checking whether a
2094 * certificate corresponds to the given private key.
2095 *
2096 * If the buffer provided is not long enough to hold the output, then
2097 * *output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
2098 * be returned. The output will normally be a SHA-1 hash output,
2099 * which is 20 bytes.
2100 *
2101 * Return value: In case of failure a negative value will be
2102 * returned, and 0 on success.
2103 **/
2104int
2105gnutls_x509_crt_get_key_id (gnutls_x509_crt_t crt,
2106 unsigned int flags,
2107 unsigned char *output_data,
2108 size_t * output_data_size)
2109{
2110 int pk, result = 0;
2111 gnutls_datum_t pubkey;
2112
2113 if (crt == NULL)
2114 {
2115 gnutls_assert ();
2116 return GNUTLS_E_INVALID_REQUEST;
2117 }
2118
2119 if (*output_data_size < 20)
2120 {
2121 gnutls_assert ();
2122 *output_data_size = 20;
2123 return GNUTLS_E_SHORT_MEMORY_BUFFER;
2124 }
2125
2126 pk = gnutls_x509_crt_get_pk_algorithm (crt, NULL);
2127 if (pk < 0)
2128 {
2129 gnutls_assert ();
2130 return pk;
2131 }
2132
2133 if (pk == GNUTLS_PK_RSA)
2134 {
2135 /* This is for compatibility with what GnuTLS has printed for
2136 RSA/DSA before the code below was added. The code below is
2137 applicable to all types, and it would probably be a better
2138 idea to use it for RSA/DSA too, but doing so would break
2139 backwards compatibility. */
2140 return rsadsa_get_key_id (crt, pk, output_data, output_data_size);
2141 }
2142
2143 pubkey.size = 0;
2144 result = asn1_der_coding (crt->cert, "tbsCertificate.subjectPublicKeyInfo",
2145 NULL, &pubkey.size, NULL);
2146 if (result != ASN1_MEM_ERROR)
2147 {
2148 gnutls_assert ();
2149 return _gnutls_asn2err (result);
2150 }
2151
2152 pubkey.data = gnutls_alloca (pubkey.size);
2153 if (pubkey.data == NULL)
2154 {
2155 gnutls_assert ();
2156 return GNUTLS_E_MEMORY_ERROR;
2157 }
2158
2159 result = asn1_der_coding (crt->cert, "tbsCertificate.subjectPublicKeyInfo",
2160 pubkey.data, &pubkey.size, NULL);
2161 if (result != ASN1_SUCCESS)
2162 {
2163 gnutls_assert ();
2164 gnutls_afree (pubkey.data);
2165 return _gnutls_asn2err (result);
2166 }
2167
2168 result = gnutls_fingerprint (GNUTLS_DIG_SHA1, &pubkey, output_data,
2169 output_data_size);
2170
2171 gnutls_afree (pubkey.data);
2172
2173 return result;
2174}
2175
2176#ifdef ENABLE_PKI
2177
2178/**
2179 * gnutls_x509_crt_check_revocation - This function checks if the given certificate is revoked
2180 * @cert: should contain a gnutls_x509_crt_t structure
2181 * @crl_list: should contain a list of gnutls_x509_crl_t structures
2182 * @crl_list_length: the length of the crl_list
2183 *
2184 * This function will return check if the given certificate is
2185 * revoked. It is assumed that the CRLs have been verified before.
2186 *
2187 * Returns: 0 if the certificate is NOT revoked, and 1 if it is. A
2188 * negative value is returned on error.
2189 **/
2190int
2191gnutls_x509_crt_check_revocation (gnutls_x509_crt_t cert,
2192 const gnutls_x509_crl_t * crl_list,
2193 int crl_list_length)
2194{
2195 opaque serial[64];
2196 opaque cert_serial[64];
2197 size_t serial_size, cert_serial_size;
2198 int ncerts, ret, i, j;
2199 gnutls_datum_t dn1, dn2;
2200
2201 if (cert == NULL)
2202 {
2203 gnutls_assert ();
2204 return GNUTLS_E_INVALID_REQUEST;
2205 }
2206
2207 for (j = 0; j < crl_list_length; j++)
2208 { /* do for all the crls */
2209
2210 /* Step 1. check if issuer's DN match
2211 */
2212 ret = _gnutls_x509_crl_get_raw_issuer_dn (crl_list[j], &dn1);
2213 if (ret < 0)
2214 {
2215 gnutls_assert ();
2216 return ret;
2217 }
2218
2219 ret = gnutls_x509_crt_get_raw_issuer_dn (cert, &dn2);
2220 if (ret < 0)
2221 {
2222 gnutls_assert ();
2223 return ret;
2224 }
2225
2226 ret = _gnutls_x509_compare_raw_dn (&dn1, &dn2);
2227 _gnutls_free_datum (&dn1);
2228 _gnutls_free_datum (&dn2);
2229 if (ret == 0)
2230 {
2231 /* issuers do not match so don't even
2232 * bother checking.
2233 */
2234 continue;
2235 }
2236
2237 /* Step 2. Read the certificate's serial number
2238 */
2239 cert_serial_size = sizeof (cert_serial);
2240 ret = gnutls_x509_crt_get_serial (cert, cert_serial, &cert_serial_size);
2241 if (ret < 0)
2242 {
2243 gnutls_assert ();
2244 return ret;
2245 }
2246
2247 /* Step 3. cycle through the CRL serials and compare with
2248 * certificate serial we have.
2249 */
2250
2251 ncerts = gnutls_x509_crl_get_crt_count (crl_list[j]);
2252 if (ncerts < 0)
2253 {
2254 gnutls_assert ();
2255 return ncerts;
2256 }
2257
2258 for (i = 0; i < ncerts; i++)
2259 {
2260 serial_size = sizeof (serial);
2261 ret = gnutls_x509_crl_get_crt_serial (crl_list[j], i, serial,
2262 &serial_size, NULL);
2263
2264 if (ret < 0)
2265 {
2266 gnutls_assert ();
2267 return ret;
2268 }
2269
2270 if (serial_size == cert_serial_size)
2271 {
2272 if (memcmp (serial, cert_serial, serial_size) == 0)
2273 {
2274 /* serials match */
2275 return 1; /* revoked! */
2276 }
2277 }
2278 }
2279
2280 }
2281 return 0; /* not revoked. */
2282}
2283
2284/**
2285 * gnutls_x509_crt_verify_data - This function will verify the given signed data.
2286 * @crt: Holds the certificate
2287 * @flags: should be 0 for now
2288 * @data: holds the data to be signed
2289 * @signature: contains the signature
2290 *
2291 * This function will verify the given signed data, using the
2292 * parameters from the certificate.
2293 *
2294 * Returns: In case of a verification failure 0 is returned, and 1 on
2295 * success.
2296 **/
2297int
2298gnutls_x509_crt_verify_data (gnutls_x509_crt_t crt,
2299 unsigned int flags,
2300 const gnutls_datum_t * data,
2301 const gnutls_datum_t * signature)
2302{
2303 int result;
2304
2305 if (crt == NULL)
2306 {
2307 gnutls_assert ();
2308 return GNUTLS_E_INVALID_REQUEST;
2309 }
2310
2311 result = _gnutls_x509_verify_signature (data, signature, crt);
2312 if (result < 0)
2313 {
2314 gnutls_assert ();
2315 return 0;
2316 }
2317
2318 return result;
2319}
2320
2321/**
2322 * gnutls_x509_crt_get_crl_dist_points - This function returns the CRL distribution points
2323 * @cert: should contain a gnutls_x509_crt_t structure
2324 * @seq: specifies the sequence number of the distribution point (0 for the first one, 1 for the second etc.)
2325 * @ret: is the place where the distribution point will be copied to
2326 * @ret_size: holds the size of ret.
2327 * @reason_flags: Revocation reasons flags.
2328 * @critical: will be non zero if the extension is marked as critical (may be null)
2329 *
2330 * This function will return the CRL distribution points (2.5.29.31),
2331 * contained in the given certificate.
2332 *
2333 * @reason_flags should be an ORed sequence of
2334 * GNUTLS_CRL_REASON_UNUSED, GNUTLS_CRL_REASON_KEY_COMPROMISE,
2335 * GNUTLS_CRL_REASON_CA_COMPROMISE,
2336 * GNUTLS_CRL_REASON_AFFILIATION_CHANGED,
2337 * GNUTLS_CRL_REASON_SUPERSEEDED,
2338 * GNUTLS_CRL_REASON_CESSATION_OF_OPERATION,
2339 * GNUTLS_CRL_REASON_CERTIFICATE_HOLD,
2340 * GNUTLS_CRL_REASON_PRIVILEGE_WITHDRAWN,
2341 * GNUTLS_CRL_REASON_AA_COMPROMISE, or zero for all possible reasons.
2342 *
2343 * This is specified in X509v3 Certificate Extensions. GNUTLS will
2344 * return the distribution point type, or a negative error code on
2345 * error.
2346 *
2347 * Returns %GNUTLS_E_SHORT_MEMORY_BUFFER and updates &@ret_size if
2348 * &@ret_size is not enough to hold the distribution point, or the
2349 * type of the distribution point if everything was ok. The type is
2350 * one of the enumerated %gnutls_x509_subject_alt_name_t. If the
2351 * certificate does not have an Alternative name with the specified
2352 * sequence number then %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is
2353 * returned.
2354 **/
2355int
2356gnutls_x509_crt_get_crl_dist_points (gnutls_x509_crt_t cert,
2357 unsigned int seq,
2358 void *ret,
2359 size_t * ret_size,
2360 unsigned int *reason_flags,
2361 unsigned int *critical)
2362{
2363 int result;
2364 gnutls_datum_t dist_points = { NULL,
2365 0
2366 };
2367 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
2368 char name[MAX_NAME_SIZE];
2369 int len;
2370 gnutls_x509_subject_alt_name_t type;
2371 uint8_t reasons[2];
2372
2373 if (cert == NULL)
2374 {
2375 gnutls_assert ();
2376 return GNUTLS_E_INVALID_REQUEST;
2377 }
2378
2379 if (*ret_size > 0 && ret)
2380 memset (ret, 0, *ret_size);
2381 else
2382 *ret_size = 0;
2383
2384 if (reason_flags)
2385 *reason_flags = 0;
2386
2387 result = _gnutls_x509_crt_get_extension (cert, "2.5.29.31", 0, &dist_points,
2388 critical);
2389 if (result < 0)
2390 {
2391 return result;
2392 }
2393
2394 if (dist_points.size == 0 || dist_points.data == NULL)
2395 {
2396 gnutls_assert ();
2397 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2398 }
2399
2400 result =
2401 asn1_create_element (_gnutls_get_pkix (), "PKIX1.CRLDistributionPoints",
2402 &c2);
2403 if (result != ASN1_SUCCESS)
2404 {
2405 gnutls_assert ();
2406 _gnutls_free_datum (&dist_points);
2407 return _gnutls_asn2err (result);
2408 }
2409
2410 result = asn1_der_decoding (&c2, dist_points.data, dist_points.size, NULL);
2411 _gnutls_free_datum (&dist_points);
2412
2413 if (result != ASN1_SUCCESS)
2414 {
2415 gnutls_assert ();
2416 asn1_delete_structure (&c2);
2417 return _gnutls_asn2err (result);
2418 }
2419
2420 /* Return the different names from the first CRLDistr. point.
2421 * The whole thing is a mess.
2422 */
2423 _gnutls_str_cpy (name, sizeof (name), "?1.distributionPoint.fullName");
2424
2425 result = parse_general_name (c2, name, seq, ret, ret_size, NULL, 0);
2426 if (result < 0)
2427 {
2428 asn1_delete_structure (&c2);
2429 return result;
2430 }
2431
2432 type = result;
2433
2434 /* Read the CRL reasons.
2435 */
2436 if (reason_flags)
2437 {
2438 _gnutls_str_cpy (name, sizeof (name), "?1.reasons");
2439
2440 reasons[0] = reasons[1] = 0;
2441
2442 len = sizeof (reasons);
2443 result = asn1_read_value (c2, name, reasons, &len);
2444
2445 if (result != ASN1_VALUE_NOT_FOUND && result != ASN1_SUCCESS)
2446 {
2447 gnutls_assert ();
2448 asn1_delete_structure (&c2);
2449 return _gnutls_asn2err (result);
2450 }
2451
2452 *reason_flags = reasons[0] | (reasons[1] << 8);
2453 }
2454
2455 return type;
2456}
2457
2458/**
2459 * gnutls_x509_crt_get_key_purpose_oid - This function returns the Certificate's key purpose OIDs
2460 * @cert: should contain a gnutls_x509_crt_t structure
2461 * @indx: This specifies which OID to return. Use zero to get the first one.
2462 * @oid: a pointer to a buffer to hold the OID (may be null)
2463 * @sizeof_oid: initially holds the size of @oid
2464 *
2465 * This function will extract the key purpose OIDs of the Certificate
2466 * specified by the given index. These are stored in the Extended Key
2467 * Usage extension (2.5.29.37) See the GNUTLS_KP_* definitions for
2468 * human readable names.
2469 *
2470 * If @oid is null then only the size will be filled.
2471 *
2472 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
2473 * not long enough, and in that case the *sizeof_oid will be updated
2474 * with the required size. On success 0 is returned.
2475 **/
2476int
2477gnutls_x509_crt_get_key_purpose_oid (gnutls_x509_crt_t cert,
2478 int indx,
2479 void *oid,
2480 size_t * sizeof_oid,
2481 unsigned int *critical)
2482{
2483 char tmpstr[MAX_NAME_SIZE];
2484 int result, len;
2485 gnutls_datum_t id;
2486 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
2487
2488 if (cert == NULL)
2489 {
2490 gnutls_assert ();
2491 return GNUTLS_E_INVALID_REQUEST;
2492 }
2493
2494 if (oid)
2495 memset (oid, 0, *sizeof_oid);
2496 else
2497 *sizeof_oid = 0;
2498
2499 if ((result = _gnutls_x509_crt_get_extension (cert, "2.5.29.37", 0, &id,
2500 critical)) < 0)
2501 {
2502 return result;
2503 }
2504
2505 if (id.size == 0 || id.data == NULL)
2506 {
2507 gnutls_assert ();
2508 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2509 }
2510
2511 result =
2512 asn1_create_element (_gnutls_get_pkix (), "PKIX1.ExtKeyUsageSyntax", &c2);
2513 if (result != ASN1_SUCCESS)
2514 {
2515 gnutls_assert ();
2516 _gnutls_free_datum (&id);
2517 return _gnutls_asn2err (result);
2518 }
2519
2520 result = asn1_der_decoding (&c2, id.data, id.size, NULL);
2521 _gnutls_free_datum (&id);
2522
2523 if (result != ASN1_SUCCESS)
2524 {
2525 gnutls_assert ();
2526 asn1_delete_structure (&c2);
2527 return _gnutls_asn2err (result);
2528 }
2529
2530 indx++;
2531 /* create a string like "?1"
2532 */
2533 snprintf (tmpstr, sizeof (tmpstr), "?%u", indx);
2534
2535 len = *sizeof_oid;
2536 result = asn1_read_value (c2, tmpstr, oid, &len);
2537
2538 *sizeof_oid = len;
2539 asn1_delete_structure (&c2);
2540
2541 if (result == ASN1_VALUE_NOT_FOUND || result == ASN1_ELEMENT_NOT_FOUND)
2542 {
2543 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2544 }
2545
2546 if (result != ASN1_SUCCESS)
2547 {
2548 gnutls_assert ();
2549 return _gnutls_asn2err (result);
2550 }
2551
2552 return 0;
2553
2554}
2555
2556/**
2557 * gnutls_x509_crt_get_pk_rsa_raw - This function will export the RSA public key
2558 * @crt: Holds the certificate
2559 * @m: will hold the modulus
2560 * @e: will hold the public exponent
2561 *
2562 * This function will export the RSA public key's parameters found in
2563 * the given structure. The new parameters will be allocated using
2564 * gnutls_malloc() and will be stored in the appropriate datum.
2565 *
2566 * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error.
2567 **/
2568int
2569gnutls_x509_crt_get_pk_rsa_raw (gnutls_x509_crt_t crt,
2570 gnutls_datum_t * m, gnutls_datum_t * e)
2571{
2572 int ret;
2573 mpi_t params[MAX_PUBLIC_PARAMS_SIZE];
2574 int params_size = MAX_PUBLIC_PARAMS_SIZE;
2575 int i;
2576
2577 if (crt == NULL)
2578 {
2579 gnutls_assert ();
2580 return GNUTLS_E_INVALID_REQUEST;
2581 }
2582
2583 ret = gnutls_x509_crt_get_pk_algorithm (crt, NULL);
2584 if (ret != GNUTLS_PK_RSA)
2585 {
2586 gnutls_assert ();
2587 return GNUTLS_E_INVALID_REQUEST;
2588 }
2589
2590 ret = _gnutls_x509_crt_get_mpis (crt, params, &params_size);
2591 if (ret < 0)
2592 {
2593 gnutls_assert ();
2594 return ret;
2595 }
2596
2597 ret = _gnutls_mpi_dprint (m, params[0]);
2598 if (ret < 0)
2599 {
2600 gnutls_assert ();
2601 goto cleanup;
2602 }
2603
2604 ret = _gnutls_mpi_dprint (e, params[1]);
2605 if (ret < 0)
2606 {
2607 gnutls_assert ();
2608 _gnutls_free_datum (m);
2609 goto cleanup;
2610 }
2611
2612 ret = 0;
2613
2614cleanup:for (i = 0; i < params_size; i++)
2615 {
2616 _gnutls_mpi_release (&params[i]);
2617 }
2618 return ret;
2619}
2620
2621/**
2622 * gnutls_x509_crt_get_pk_dsa_raw - This function will export the DSA public key
2623 * @crt: Holds the certificate
2624 * @p: will hold the p
2625 * @q: will hold the q
2626 * @g: will hold the g
2627 * @y: will hold the y
2628 *
2629 * This function will export the DSA public key's parameters found in
2630 * the given certificate. The new parameters will be allocated using
2631 * gnutls_malloc() and will be stored in the appropriate datum.
2632 *
2633 * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error.
2634 **/
2635int
2636gnutls_x509_crt_get_pk_dsa_raw (gnutls_x509_crt_t crt,
2637 gnutls_datum_t * p,
2638 gnutls_datum_t * q,
2639 gnutls_datum_t * g, gnutls_datum_t * y)
2640{
2641 int ret;
2642 mpi_t params[MAX_PUBLIC_PARAMS_SIZE];
2643 int params_size = MAX_PUBLIC_PARAMS_SIZE;
2644 int i;
2645
2646 if (crt == NULL)
2647 {
2648 gnutls_assert ();
2649 return GNUTLS_E_INVALID_REQUEST;
2650 }
2651
2652 ret = gnutls_x509_crt_get_pk_algorithm (crt, NULL);
2653
2654 ret = _gnutls_x509_crt_get_mpis (crt, params, &params_size);
2655 if (ret < 0)
2656 {
2657 gnutls_assert ();
2658 return ret;
2659 }
2660
2661 /* P */
2662 ret = _gnutls_mpi_dprint (p, params[0]);
2663 if (ret < 0)
2664 {
2665 gnutls_assert ();
2666 goto cleanup;
2667 }
2668
2669 /* Q */
2670 ret = _gnutls_mpi_dprint (q, params[1]);
2671 if (ret < 0)
2672 {
2673 gnutls_assert ();
2674 _gnutls_free_datum (p);
2675 goto cleanup;
2676 }
2677
2678 /* G */
2679 ret = _gnutls_mpi_dprint (g, params[2]);
2680 if (ret < 0)
2681 {
2682 gnutls_assert ();
2683 _gnutls_free_datum (p);
2684 _gnutls_free_datum (q);
2685 goto cleanup;
2686 }
2687
2688 /* Y */
2689 ret = _gnutls_mpi_dprint (y, params[3]);
2690 if (ret < 0)
2691 {
2692 gnutls_assert ();
2693 _gnutls_free_datum (p);
2694 _gnutls_free_datum (g);
2695 _gnutls_free_datum (q);
2696 goto cleanup;
2697 }
2698
2699 ret = 0;
2700
2701cleanup:for (i = 0; i < params_size; i++)
2702 {
2703 _gnutls_mpi_release (&params[i]);
2704 }
2705 return ret;
2706
2707}
2708
2709#endif
2710
2711/**
2712 * gnutls_x509_crt_list_import - This function will import a PEM encoded certificate list
2713 * @certs: The structures to store the parsed certificate. Must not be initialized.
2714 * @cert_max: Initially must hold the maximum number of certs. It will be updated with the number of certs available.
2715 * @data: The PEM encoded certificate.
2716 * @format: One of DER or PEM.
2717 * @flags: must be zero or an OR'd sequence of gnutls_certificate_import_flags.
2718 *
2719 * This function will convert the given PEM encoded certificate list
2720 * to the native gnutls_x509_crt_t format. The output will be stored
2721 * in @certs. They will be automatically initialized.
2722 *
2723 * If the Certificate is PEM encoded it should have a header of "X509
2724 * CERTIFICATE", or "CERTIFICATE".
2725 *
2726 * Returns: the number of certificates read or a negative error value.
2727 **/
2728int
2729gnutls_x509_crt_list_import (gnutls_x509_crt_t * certs,
2730 unsigned int *cert_max,
2731 const gnutls_datum_t * data,
2732 gnutls_x509_crt_fmt_t format, unsigned int flags)
2733{
2734 int size;
2735 const char *ptr;
2736 gnutls_datum_t tmp;
2737 int ret, nocopy = 0;
2738 unsigned int count = 0, j;
2739
2740 if (format == GNUTLS_X509_FMT_DER)
2741 {
2742 if (*cert_max < 1)
2743 {
2744 *cert_max = 1;
2745 return GNUTLS_E_SHORT_MEMORY_BUFFER;
2746 }
2747
2748 count = 1; /* import only the first one */
2749
2750 ret = gnutls_x509_crt_init (&certs[0]);
2751 if (ret < 0)
2752 {
2753 gnutls_assert ();
2754 goto error;
2755 }
2756
2757 ret = gnutls_x509_crt_import (certs[0], data, format);
2758 if (ret < 0)
2759 {
2760 gnutls_assert ();
2761 goto error;
2762 }
2763
2764 *cert_max = 1;
2765 return 1;
2766 }
2767
2768 /* move to the certificate
2769 */
2770 ptr = memmem (data->data, data->size,
2771 PEM_CERT_SEP, sizeof (PEM_CERT_SEP) - 1);
2772 if (ptr == NULL)
2773 ptr = memmem (data->data, data->size,
2774 PEM_CERT_SEP2, sizeof (PEM_CERT_SEP2) - 1);
2775
2776 if (ptr == NULL)
2777 {
2778 gnutls_assert ();
2779 return GNUTLS_E_BASE64_DECODING_ERROR;
2780 }
2781 size = data->size - (ptr - (char *) data->data);
2782
2783 count = 0;
2784
2785 do
2786 {
2787 if (count >= *cert_max)
2788 {
2789 if (!(flags & GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED))
2790 break;
2791 else
2792 nocopy = 1;
2793 }
2794
2795 if (!nocopy)
2796 {
2797 ret = gnutls_x509_crt_init (&certs[count]);
2798 if (ret < 0)
2799 {
2800 gnutls_assert ();
2801 goto error;
2802 }
2803
2804 tmp.data = (void *) ptr;
2805 tmp.size = size;
2806
2807 ret =
2808 gnutls_x509_crt_import (certs[count], &tmp, GNUTLS_X509_FMT_PEM);
2809 if (ret < 0)
2810 {
2811 gnutls_assert ();
2812 goto error;
2813 }
2814 }
2815
2816 /* now we move ptr after the pem header
2817 */
2818 ptr++;
2819 /* find the next certificate (if any)
2820 */
2821 size = data->size - (ptr - (char *) data->data);
2822
2823 if (size > 0)
2824 {
2825 char *ptr2;
2826
2827 ptr2 = memmem (ptr, size, PEM_CERT_SEP, sizeof (PEM_CERT_SEP) - 1);
2828 if (ptr2 == NULL)
2829 ptr2 =
2830 memmem (ptr, size, PEM_CERT_SEP2, sizeof (PEM_CERT_SEP2) - 1);
2831
2832 ptr = ptr2;
2833 }
2834 else
2835 ptr = NULL;
2836
2837 count++;
2838 }
2839 while (ptr != NULL);
2840
2841 *cert_max = count;
2842
2843 if (nocopy == 0)
2844 return count;
2845 else
2846 return GNUTLS_E_SHORT_MEMORY_BUFFER;
2847
2848error:for (j = 0; j < count; j++)
2849 gnutls_x509_crt_deinit (certs[j]);
2850 return ret;
2851}
diff --git a/src/daemon/https/x509/x509.h b/src/daemon/https/x509/x509.h
new file mode 100644
index 00000000..c9bb22ef
--- /dev/null
+++ b/src/daemon/https/x509/x509.h
@@ -0,0 +1,928 @@
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#ifndef X509_H
26# define X509_H
27
28#define MIN(X,Y) ((X) > (Y) ? (Y) : (X));
29
30#ifdef __cplusplus
31extern "C"
32 {
33#endif
34
35#include <gnutls.h>
36// TODO #include "libtasn1.h"
37#include "gnutls_mpi.h"
38
39/* Some OIDs usually found in Distinguished names, or
40 * in Subject Directory Attribute extensions.
41 */
42#define GNUTLS_OID_X520_COUNTRY_NAME "2.5.4.6"
43#define GNUTLS_OID_X520_ORGANIZATION_NAME "2.5.4.10"
44#define GNUTLS_OID_X520_ORGANIZATIONAL_UNIT_NAME "2.5.4.11"
45#define GNUTLS_OID_X520_COMMON_NAME "2.5.4.3"
46#define GNUTLS_OID_X520_LOCALITY_NAME "2.5.4.7"
47#define GNUTLS_OID_X520_STATE_OR_PROVINCE_NAME "2.5.4.8"
48
49#define GNUTLS_OID_X520_INITIALS "2.5.4.43"
50#define GNUTLS_OID_X520_GENERATION_QUALIFIER "2.5.4.44"
51#define GNUTLS_OID_X520_SURNAME "2.5.4.4"
52#define GNUTLS_OID_X520_GIVEN_NAME "2.5.4.42"
53#define GNUTLS_OID_X520_TITLE "2.5.4.12"
54#define GNUTLS_OID_X520_DN_QUALIFIER "2.5.4.46"
55#define GNUTLS_OID_X520_PSEUDONYM "2.5.4.65"
56
57#define GNUTLS_OID_LDAP_DC "0.9.2342.19200300.100.1.25"
58#define GNUTLS_OID_LDAP_UID "0.9.2342.19200300.100.1.1"
59
60/* The following should not be included in DN.
61 */
62#define GNUTLS_OID_PKCS9_EMAIL "1.2.840.113549.1.9.1"
63
64#define GNUTLS_OID_PKIX_DATE_OF_BIRTH "1.3.6.1.5.5.7.9.1"
65#define GNUTLS_OID_PKIX_PLACE_OF_BIRTH "1.3.6.1.5.5.7.9.2"
66#define GNUTLS_OID_PKIX_GENDER "1.3.6.1.5.5.7.9.3"
67#define GNUTLS_OID_PKIX_COUNTRY_OF_CITIZENSHIP "1.3.6.1.5.5.7.9.4"
68#define GNUTLS_OID_PKIX_COUNTRY_OF_RESIDENCE "1.3.6.1.5.5.7.9.5"
69
70/* Key purpose Object Identifiers.
71 */
72#define GNUTLS_KP_TLS_WWW_SERVER "1.3.6.1.5.5.7.3.1"
73#define GNUTLS_KP_TLS_WWW_CLIENT "1.3.6.1.5.5.7.3.2"
74#define GNUTLS_KP_CODE_SIGNING "1.3.6.1.5.5.7.3.3"
75#define GNUTLS_KP_EMAIL_PROTECTION "1.3.6.1.5.5.7.3.4"
76#define GNUTLS_KP_TIME_STAMPING "1.3.6.1.5.5.7.3.8"
77#define GNUTLS_KP_OCSP_SIGNING "1.3.6.1.5.5.7.3.9"
78#define GNUTLS_KP_ANY "2.5.29.37.0"
79
80/* Certificate handling functions.
81 */
82typedef enum gnutls_certificate_import_flags
83 {
84 /* Fail if the certificates in the buffer are more than the space
85 * allocated for certificates. The error code will be
86 * GNUTLS_E_SHORT_MEMORY_BUFFER.
87 */
88 GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED = 1
89 } gnutls_certificate_import_flags;
90
91int gnutls_x509_crt_init(gnutls_x509_crt_t * cert);
92void gnutls_x509_crt_deinit(gnutls_x509_crt_t cert);
93int gnutls_x509_crt_import(gnutls_x509_crt_t cert,
94 const gnutls_datum_t * data,
95 gnutls_x509_crt_fmt_t format);
96int gnutls_x509_crt_list_import(gnutls_x509_crt_t * certs,
97 unsigned int *cert_max,
98 const gnutls_datum_t * data,
99 gnutls_x509_crt_fmt_t format,
100 unsigned int flags);
101int gnutls_x509_crt_export(gnutls_x509_crt_t cert,
102 gnutls_x509_crt_fmt_t format,
103 void *output_data,
104 size_t * output_data_size);
105int gnutls_x509_crt_get_issuer_dn(gnutls_x509_crt_t cert,
106 char *buf,
107 size_t * sizeof_buf);
108int gnutls_x509_crt_get_issuer_dn_oid(gnutls_x509_crt_t cert,
109 int indx,
110 void *oid,
111 size_t * sizeof_oid);
112int gnutls_x509_crt_get_issuer_dn_by_oid(gnutls_x509_crt_t cert,
113 const char *oid,
114 int indx,
115 unsigned int raw_flag,
116 void *buf,
117 size_t * sizeof_buf);
118int gnutls_x509_crt_get_dn(gnutls_x509_crt_t cert,
119 char *buf,
120 size_t * sizeof_buf);
121int gnutls_x509_crt_get_dn_oid(gnutls_x509_crt_t cert,
122 int indx,
123 void *oid,
124 size_t * sizeof_oid);
125int gnutls_x509_crt_get_dn_by_oid(gnutls_x509_crt_t cert,
126 const char *oid,
127 int indx,
128 unsigned int raw_flag,
129 void *buf,
130 size_t * sizeof_buf);
131int gnutls_x509_crt_check_hostname(gnutls_x509_crt_t cert,
132 const char *hostname);
133
134int gnutls_x509_crt_get_signature_algorithm(gnutls_x509_crt_t cert);
135int gnutls_x509_crt_get_signature(gnutls_x509_crt_t cert,
136 char *sig,
137 size_t *sizeof_sig);
138int gnutls_x509_crt_get_version(gnutls_x509_crt_t cert);
139int gnutls_x509_crt_get_key_id(gnutls_x509_crt_t crt,
140 unsigned int flags,
141 unsigned char *output_data,
142 size_t * output_data_size);
143
144int gnutls_x509_crt_set_authority_key_id(gnutls_x509_crt_t cert,
145 const void *id,
146 size_t id_size);
147int gnutls_x509_crt_get_authority_key_id(gnutls_x509_crt_t cert,
148 void *ret,
149 size_t * ret_size,
150 unsigned int *critical);
151
152int gnutls_x509_crt_get_subject_key_id(gnutls_x509_crt_t cert,
153 void *ret,
154 size_t * ret_size,
155 unsigned int *critical);
156
157#define GNUTLS_CRL_REASON_UNUSED 128
158#define GNUTLS_CRL_REASON_KEY_COMPROMISE 64
159#define GNUTLS_CRL_REASON_CA_COMPROMISE 32
160#define GNUTLS_CRL_REASON_AFFILIATION_CHANGED 16
161#define GNUTLS_CRL_REASON_SUPERSEEDED 8
162#define GNUTLS_CRL_REASON_CESSATION_OF_OPERATION 4
163#define GNUTLS_CRL_REASON_CERTIFICATE_HOLD 2
164#define GNUTLS_CRL_REASON_PRIVILEGE_WITHDRAWN 1
165#define GNUTLS_CRL_REASON_AA_COMPROMISE 32768
166
167int gnutls_x509_crt_get_crl_dist_points(gnutls_x509_crt_t cert,
168 unsigned int seq,
169 void *ret,
170 size_t * ret_size,
171 unsigned int *reason_flags,
172 unsigned int *critical);
173int gnutls_x509_crt_set_crl_dist_points(gnutls_x509_crt_t crt,
174 gnutls_x509_subject_alt_name_t
175 type,
176 const void *data_string,
177 unsigned int reason_flags);
178int gnutls_x509_crt_cpy_crl_dist_points(gnutls_x509_crt_t dst,
179 gnutls_x509_crt_t src);
180
181time_t gnutls_x509_crt_get_activation_time(gnutls_x509_crt_t cert);
182time_t gnutls_x509_crt_get_expiration_time(gnutls_x509_crt_t cert);
183int gnutls_x509_crt_get_serial(gnutls_x509_crt_t cert,
184 void *result,
185 size_t * result_size);
186
187int gnutls_x509_crt_get_pk_algorithm(gnutls_x509_crt_t cert,
188 unsigned int *bits);
189int gnutls_x509_crt_get_pk_rsa_raw(gnutls_x509_crt_t crt,
190 gnutls_datum_t * m,
191 gnutls_datum_t * e);
192int gnutls_x509_crt_get_pk_dsa_raw(gnutls_x509_crt_t crt,
193 gnutls_datum_t * p,
194 gnutls_datum_t * q,
195 gnutls_datum_t * g,
196 gnutls_datum_t * y);
197
198int gnutls_x509_crt_get_subject_alt_name(gnutls_x509_crt_t cert,
199 unsigned int seq,
200 void *ret,
201 size_t * ret_size,
202 unsigned int *critical);
203int gnutls_x509_crt_get_subject_alt_name2(gnutls_x509_crt_t cert,
204 unsigned int seq,
205 void *ret,
206 size_t * ret_size,
207 unsigned int* ret_type,
208 unsigned int *critical);
209
210int gnutls_x509_crt_get_subject_alt_othername_oid(gnutls_x509_crt_t cert,
211 unsigned int seq,
212 void *ret,
213 size_t * ret_size);
214
215int gnutls_x509_crt_get_ca_status(gnutls_x509_crt_t cert,
216 unsigned int *critical);
217int gnutls_x509_crt_get_basic_constraints(gnutls_x509_crt_t cert,
218 unsigned int *critical,
219 int *ca,
220 int *pathlen);
221
222/* The key_usage flags are defined in gnutls.h. They are the
223 * GNUTLS_KEY_* definitions.
224 */
225int gnutls_x509_crt_get_key_usage(gnutls_x509_crt_t cert,
226 unsigned int *key_usage,
227 unsigned int *critical);
228int gnutls_x509_crt_set_key_usage(gnutls_x509_crt_t crt,
229 unsigned int usage);
230
231int gnutls_x509_crt_get_proxy(gnutls_x509_crt_t cert,
232 unsigned int *critical,
233 int *pathlen,
234 char **policyLanguage,
235 char **policy,
236 size_t *sizeof_policy);
237
238int gnutls_x509_dn_oid_known(const char *oid);
239
240/* Read extensions by OID. */
241int gnutls_x509_crt_get_extension_oid(gnutls_x509_crt_t cert,
242 int indx,
243 void *oid,
244 size_t * sizeof_oid);
245int gnutls_x509_crt_get_extension_by_oid(gnutls_x509_crt_t cert,
246 const char *oid,
247 int indx,
248 void *buf,
249 size_t * sizeof_buf,
250 unsigned int *critical);
251
252/* Read extensions by sequence number. */
253int gnutls_x509_crt_get_extension_info(gnutls_x509_crt_t cert,
254 int indx,
255 void *oid,
256 size_t * sizeof_oid,
257 int *critical);
258int gnutls_x509_crt_get_extension_data(gnutls_x509_crt_t cert,
259 int indx,
260 void *data,
261 size_t * sizeof_data);
262
263int gnutls_x509_crt_set_extension_by_oid(gnutls_x509_crt_t crt,
264 const char *oid,
265 const void *buf,
266 size_t sizeof_buf,
267 unsigned int critical);
268
269/* X.509 Certificate writing.
270 */
271int gnutls_x509_crt_set_dn_by_oid(gnutls_x509_crt_t crt,
272 const char *oid,
273 unsigned int raw_flag,
274 const void *name,
275 unsigned int sizeof_name);
276int gnutls_x509_crt_set_issuer_dn_by_oid(gnutls_x509_crt_t crt,
277 const char *oid,
278 unsigned int raw_flag,
279 const void *name,
280 unsigned int sizeof_name);
281int gnutls_x509_crt_set_version(gnutls_x509_crt_t crt,
282 unsigned int version);
283int gnutls_x509_crt_set_key(gnutls_x509_crt_t crt,
284 gnutls_x509_privkey_t key);
285int gnutls_x509_crt_set_ca_status(gnutls_x509_crt_t crt,
286 unsigned int ca);
287int gnutls_x509_crt_set_basic_constraints(gnutls_x509_crt_t crt,
288 unsigned int ca,
289 int pathLenConstraint);
290int gnutls_x509_crt_set_subject_alternative_name(gnutls_x509_crt_t crt,
291 gnutls_x509_subject_alt_name_t
292 type,
293 const char *data_string);
294int gnutls_x509_crt_sign(gnutls_x509_crt_t crt,
295 gnutls_x509_crt_t issuer,
296 gnutls_x509_privkey_t issuer_key);
297int gnutls_x509_crt_sign2(gnutls_x509_crt_t crt,
298 gnutls_x509_crt_t issuer,
299 gnutls_x509_privkey_t issuer_key,
300 gnutls_digest_algorithm_t,
301 unsigned int flags);
302int gnutls_x509_crt_set_activation_time(gnutls_x509_crt_t cert,
303 time_t act_time);
304int gnutls_x509_crt_set_expiration_time(gnutls_x509_crt_t cert,
305 time_t exp_time);
306int gnutls_x509_crt_set_serial(gnutls_x509_crt_t cert,
307 const void *serial,
308 size_t serial_size);
309
310int gnutls_x509_crt_set_subject_key_id(gnutls_x509_crt_t cert,
311 const void *id,
312 size_t id_size);
313
314int gnutls_x509_crt_set_proxy_dn(gnutls_x509_crt_t crt,
315 gnutls_x509_crt_t eecrt,
316 unsigned int raw_flag,
317 const void *name,
318 unsigned int sizeof_name);
319int gnutls_x509_crt_set_proxy(gnutls_x509_crt_t crt,
320 int pathLenConstraint,
321 const char *policyLanguage,
322 const char *policy,
323 size_t sizeof_policy);
324
325typedef enum gnutls_certificate_print_formats
326 {
327 GNUTLS_X509_CRT_FULL,
328 GNUTLS_X509_CRT_ONELINE,
329 GNUTLS_X509_CRT_UNSIGNED_FULL
330 } gnutls_certificate_print_formats_t;
331
332int gnutls_x509_crt_print(gnutls_x509_crt_t cert,
333 gnutls_certificate_print_formats_t format,
334 gnutls_datum_t *out);
335int gnutls_x509_crl_print(gnutls_x509_crl_t crl,
336 gnutls_certificate_print_formats_t format,
337 gnutls_datum_t *out);
338
339/* Access to internal Certificate fields.
340 */
341int gnutls_x509_crt_get_raw_issuer_dn(gnutls_x509_crt_t cert,
342 gnutls_datum_t * start);
343int gnutls_x509_crt_get_raw_dn(gnutls_x509_crt_t cert,
344 gnutls_datum_t * start);
345
346/* RDN handling.
347 */
348int gnutls_x509_rdn_get(const gnutls_datum_t * idn,
349 char *buf,
350 size_t * sizeof_buf);
351int gnutls_x509_rdn_get_oid(const gnutls_datum_t * idn,
352 int indx,
353 void *buf,
354 size_t * sizeof_buf);
355
356int gnutls_x509_rdn_get_by_oid(const gnutls_datum_t * idn,
357 const char *oid,
358 int indx,
359 unsigned int raw_flag,
360 void *buf,
361 size_t * sizeof_buf);
362
363typedef void *gnutls_x509_dn_t;
364
365typedef struct gnutls_x509_ava_st
366 {
367 gnutls_datum_t oid;
368 gnutls_datum_t value;
369 unsigned long value_tag;
370 } gnutls_x509_ava_st;
371
372int gnutls_x509_crt_get_subject(gnutls_x509_crt_t cert,
373 gnutls_x509_dn_t *dn);
374int gnutls_x509_crt_get_issuer(gnutls_x509_crt_t cert,
375 gnutls_x509_dn_t *dn);
376int gnutls_x509_dn_get_rdn_ava(gnutls_x509_dn_t dn,
377 int irdn,
378 int iava,
379 gnutls_x509_ava_st *avast);
380
381/* CRL handling functions.
382 */
383int gnutls_x509_crl_init(gnutls_x509_crl_t * crl);
384void gnutls_x509_crl_deinit(gnutls_x509_crl_t crl);
385
386int gnutls_x509_crl_import(gnutls_x509_crl_t crl,
387 const gnutls_datum_t * data,
388 gnutls_x509_crt_fmt_t format);
389int gnutls_x509_crl_export(gnutls_x509_crl_t crl,
390 gnutls_x509_crt_fmt_t format,
391 void *output_data,
392 size_t * output_data_size);
393
394int gnutls_x509_crl_get_issuer_dn(const gnutls_x509_crl_t crl,
395 char *buf,
396 size_t * sizeof_buf);
397int gnutls_x509_crl_get_issuer_dn_by_oid(gnutls_x509_crl_t crl,
398 const char *oid,
399 int indx,
400 unsigned int raw_flag,
401 void *buf,
402 size_t * sizeof_buf);
403int gnutls_x509_crl_get_dn_oid(gnutls_x509_crl_t crl,
404 int indx,
405 void *oid,
406 size_t * sizeof_oid);
407
408int gnutls_x509_crl_get_signature_algorithm(gnutls_x509_crl_t crl);
409int gnutls_x509_crl_get_signature(gnutls_x509_crl_t crl,
410 char *sig,
411 size_t *sizeof_sig);
412int gnutls_x509_crl_get_version(gnutls_x509_crl_t crl);
413
414time_t gnutls_x509_crl_get_this_update(gnutls_x509_crl_t crl);
415time_t gnutls_x509_crl_get_next_update(gnutls_x509_crl_t crl);
416
417int gnutls_x509_crl_get_crt_count(gnutls_x509_crl_t crl);
418int gnutls_x509_crl_get_crt_serial(gnutls_x509_crl_t crl,
419 int indx,
420 unsigned char *serial,
421 size_t * serial_size,
422 time_t * t);
423#define gnutls_x509_crl_get_certificate_count gnutls_x509_crl_get_crt_count
424#define gnutls_x509_crl_get_certificate gnutls_x509_crl_get_crt_serial
425
426int gnutls_x509_crl_check_issuer(gnutls_x509_crl_t crl,
427 gnutls_x509_crt_t issuer);
428
429/* CRL writing.
430 */
431int gnutls_x509_crl_set_version(gnutls_x509_crl_t crl,
432 unsigned int version);
433int gnutls_x509_crl_sign(gnutls_x509_crl_t crl,
434 gnutls_x509_crt_t issuer,
435 gnutls_x509_privkey_t issuer_key);
436int gnutls_x509_crl_sign2(gnutls_x509_crl_t crl,
437 gnutls_x509_crt_t issuer,
438 gnutls_x509_privkey_t issuer_key,
439 gnutls_digest_algorithm_t,
440 unsigned int flags);
441int gnutls_x509_crl_set_this_update(gnutls_x509_crl_t crl,
442 time_t act_time);
443int gnutls_x509_crl_set_next_update(gnutls_x509_crl_t crl,
444 time_t exp_time);
445int gnutls_x509_crl_set_crt_serial(gnutls_x509_crl_t crl,
446 const void *serial,
447 size_t serial_size,
448 time_t revocation_time);
449int gnutls_x509_crl_set_crt(gnutls_x509_crl_t crl,
450 gnutls_x509_crt_t crt,
451 time_t revocation_time);
452
453/* PKCS7 structures handling
454 */
455struct gnutls_pkcs7_int;
456typedef struct gnutls_pkcs7_int *gnutls_pkcs7_t;
457
458int gnutls_pkcs7_init(gnutls_pkcs7_t * pkcs7);
459void gnutls_pkcs7_deinit(gnutls_pkcs7_t pkcs7);
460int gnutls_pkcs7_import(gnutls_pkcs7_t pkcs7,
461 const gnutls_datum_t * data,
462 gnutls_x509_crt_fmt_t format);
463int gnutls_pkcs7_export(gnutls_pkcs7_t pkcs7,
464 gnutls_x509_crt_fmt_t format,
465 void *output_data,
466 size_t * output_data_size);
467
468int gnutls_pkcs7_get_crt_count(gnutls_pkcs7_t pkcs7);
469int gnutls_pkcs7_get_crt_raw(gnutls_pkcs7_t pkcs7,
470 int indx,
471 void *certificate,
472 size_t * certificate_size);
473
474int gnutls_pkcs7_set_crt_raw(gnutls_pkcs7_t pkcs7,
475 const gnutls_datum_t * crt);
476int gnutls_pkcs7_set_crt(gnutls_pkcs7_t pkcs7,
477 gnutls_x509_crt_t crt);
478int gnutls_pkcs7_delete_crt(gnutls_pkcs7_t pkcs7,
479 int indx);
480
481int gnutls_pkcs7_get_crl_raw(gnutls_pkcs7_t pkcs7,
482 int indx,
483 void *crl,
484 size_t * crl_size);
485int gnutls_pkcs7_get_crl_count(gnutls_pkcs7_t pkcs7);
486
487int gnutls_pkcs7_set_crl_raw(gnutls_pkcs7_t pkcs7,
488 const gnutls_datum_t * crt);
489int gnutls_pkcs7_set_crl(gnutls_pkcs7_t pkcs7,
490 gnutls_x509_crl_t crl);
491int gnutls_pkcs7_delete_crl(gnutls_pkcs7_t pkcs7,
492 int indx);
493
494/* X.509 Certificate verification functions.
495 */
496typedef enum gnutls_certificate_verify_flags
497 {
498 /* If set a signer does not have to be a certificate authority. This
499 * flag should normaly be disabled, unless you know what this means.
500 */
501 GNUTLS_VERIFY_DISABLE_CA_SIGN = 1,
502
503 /* Allow only trusted CA certificates that have version 1. This is
504 * safer than GNUTLS_VERIFY_ALLOW_ANY_X509_V1_CA_CRT, and should be
505 * used instead. That way only signers in your trusted list will be
506 * allowed to have certificates of version 1.
507 */
508 GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT = 2,
509
510 /* If a certificate is not signed by anyone trusted but exists in
511 * the trusted CA list do not treat it as trusted.
512 */
513 GNUTLS_VERIFY_DO_NOT_ALLOW_SAME = 4,
514
515 /* Allow CA certificates that have version 1 (both root and
516 * intermediate). This might be dangerous since those haven't the
517 * basicConstraints extension. Must be used in combination with
518 * GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT.
519 */
520 GNUTLS_VERIFY_ALLOW_ANY_X509_V1_CA_CRT = 8,
521
522 /* Allow certificates to be signed using the broken MD2 algorithm.
523 */
524 GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD2 = 16,
525
526 /* Allow certificates to be signed using the broken MD5 algorithm.
527 */
528 GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5 = 32
529 } gnutls_certificate_verify_flags;
530
531int gnutls_x509_crt_check_issuer(gnutls_x509_crt_t cert,
532 gnutls_x509_crt_t issuer);
533
534int gnutls_x509_crt_list_verify(const gnutls_x509_crt_t * cert_list,
535 int cert_list_length,
536 const gnutls_x509_crt_t * CA_list,
537 int CA_list_length,
538 const gnutls_x509_crl_t * CRL_list,
539 int CRL_list_length,
540 unsigned int flags,
541 unsigned int *verify);
542
543int gnutls_x509_crt_verify(gnutls_x509_crt_t cert,
544 const gnutls_x509_crt_t * CA_list,
545 int CA_list_length,
546 unsigned int flags,
547 unsigned int *verify);
548int gnutls_x509_crl_verify(gnutls_x509_crl_t crl,
549 const gnutls_x509_crt_t * CA_list,
550 int CA_list_length,
551 unsigned int flags,
552 unsigned int *verify);
553
554int gnutls_x509_crt_check_revocation(gnutls_x509_crt_t cert,
555 const gnutls_x509_crl_t *
556 crl_list,
557 int crl_list_length);
558
559int gnutls_x509_crt_get_fingerprint(gnutls_x509_crt_t cert,
560 gnutls_digest_algorithm_t algo,
561 void *buf,
562 size_t * sizeof_buf);
563
564int gnutls_x509_crt_get_key_purpose_oid(gnutls_x509_crt_t cert,
565 int indx,
566 void *oid,
567 size_t * sizeof_oid,
568 unsigned int *critical);
569int gnutls_x509_crt_set_key_purpose_oid(gnutls_x509_crt_t cert,
570 const void *oid,
571 unsigned int critical);
572
573/* Private key handling.
574 */
575
576/* Flags for the gnutls_x509_privkey_export_pkcs8() function.
577 */
578typedef enum gnutls_pkcs_encrypt_flags_t
579 {
580 GNUTLS_PKCS_PLAIN = 1, /* if set the private key will not
581 * be encrypted.
582 */
583 GNUTLS_PKCS_USE_PKCS12_3DES = 2,
584 GNUTLS_PKCS_USE_PKCS12_ARCFOUR = 4,
585 GNUTLS_PKCS_USE_PKCS12_RC2_40 = 8,
586 GNUTLS_PKCS_USE_PBES2_3DES = 16
587 } gnutls_pkcs_encrypt_flags_t;
588
589#define GNUTLS_PKCS8_PLAIN GNUTLS_PKCS_PLAIN
590#define GNUTLS_PKCS8_USE_PKCS12_3DES GNUTLS_PKCS_USE_PKCS12_3DES
591#define GNUTLS_PKCS8_USE_PKCS12_ARCFOUR GNUTLS_PKCS_USE_PKCS12_ARCFOUR
592#define GNUTLS_PKCS8_USE_PKCS12_RC2_40 GNUTLS_PKCS_USE_PKCS12_RC2_40
593
594int gnutls_x509_privkey_init(gnutls_x509_privkey_t * key);
595void gnutls_x509_privkey_deinit(gnutls_x509_privkey_t key);
596int gnutls_x509_privkey_cpy(gnutls_x509_privkey_t dst,
597 gnutls_x509_privkey_t src);
598int gnutls_x509_privkey_import(gnutls_x509_privkey_t key,
599 const gnutls_datum_t * data,
600 gnutls_x509_crt_fmt_t format);
601int gnutls_x509_privkey_import_pkcs8(gnutls_x509_privkey_t key,
602 const gnutls_datum_t * data,
603 gnutls_x509_crt_fmt_t format,
604 const char *pass,
605 unsigned int flags);
606int gnutls_x509_privkey_import_rsa_raw(gnutls_x509_privkey_t key,
607 const gnutls_datum_t * m,
608 const gnutls_datum_t * e,
609 const gnutls_datum_t * d,
610 const gnutls_datum_t * p,
611 const gnutls_datum_t * q,
612 const gnutls_datum_t * u);
613int gnutls_x509_privkey_fix(gnutls_x509_privkey_t key);
614
615int gnutls_x509_privkey_export_dsa_raw(gnutls_x509_privkey_t key,
616 gnutls_datum_t * p,
617 gnutls_datum_t * q,
618 gnutls_datum_t * g,
619 gnutls_datum_t * y,
620 gnutls_datum_t * x);
621int gnutls_x509_privkey_import_dsa_raw(gnutls_x509_privkey_t key,
622 const gnutls_datum_t * p,
623 const gnutls_datum_t * q,
624 const gnutls_datum_t * g,
625 const gnutls_datum_t * y,
626 const gnutls_datum_t * x);
627
628int gnutls_x509_privkey_get_pk_algorithm(gnutls_x509_privkey_t key);
629int gnutls_x509_privkey_get_key_id(gnutls_x509_privkey_t key,
630 unsigned int flags,
631 unsigned char *output_data,
632 size_t * output_data_size);
633
634int gnutls_x509_privkey_generate(gnutls_x509_privkey_t key,
635 gnutls_pk_algorithm_t algo,
636 unsigned int bits,
637 unsigned int flags);
638
639int gnutls_x509_privkey_export(gnutls_x509_privkey_t key,
640 gnutls_x509_crt_fmt_t format,
641 void *output_data,
642 size_t * output_data_size);
643int gnutls_x509_privkey_export_pkcs8(gnutls_x509_privkey_t key,
644 gnutls_x509_crt_fmt_t format,
645 const char *password,
646 unsigned int flags,
647 void *output_data,
648 size_t * output_data_size);
649int gnutls_x509_privkey_export_rsa_raw(gnutls_x509_privkey_t key,
650 gnutls_datum_t * m,
651 gnutls_datum_t * e,
652 gnutls_datum_t * d,
653 gnutls_datum_t * p,
654 gnutls_datum_t * q,
655 gnutls_datum_t * u);
656
657/* Signing stuff.
658 */
659int gnutls_x509_privkey_sign_data(gnutls_x509_privkey_t key,
660 gnutls_digest_algorithm_t digest,
661 unsigned int flags,
662 const gnutls_datum_t * data,
663 void *signature,
664 size_t * signature_size);
665int gnutls_x509_privkey_verify_data(gnutls_x509_privkey_t key,
666 unsigned int flags,
667 const gnutls_datum_t * data,
668 const gnutls_datum_t * signature);
669int gnutls_x509_crt_verify_data(gnutls_x509_crt_t crt,
670 unsigned int flags,
671 const gnutls_datum_t * data,
672 const gnutls_datum_t * signature);
673
674int gnutls_x509_privkey_sign_hash(gnutls_x509_privkey_t key,
675 const gnutls_datum_t * hash,
676 gnutls_datum_t * signature);
677
678/* Certificate request stuff.
679 */
680struct gnutls_x509_crq_int;
681typedef struct gnutls_x509_crq_int *gnutls_x509_crq_t;
682
683int gnutls_x509_crq_init(gnutls_x509_crq_t * crq);
684void gnutls_x509_crq_deinit(gnutls_x509_crq_t crq);
685int gnutls_x509_crq_import(gnutls_x509_crq_t crq,
686 const gnutls_datum_t * data,
687 gnutls_x509_crt_fmt_t format);
688int gnutls_x509_crq_get_pk_algorithm(gnutls_x509_crq_t crq,
689 unsigned int *bits);
690int gnutls_x509_crq_get_dn(gnutls_x509_crq_t crq,
691 char *buf,
692 size_t * sizeof_buf);
693int gnutls_x509_crq_get_dn_oid(gnutls_x509_crq_t crq,
694 int indx,
695 void *oid,
696 size_t * sizeof_oid);
697int gnutls_x509_crq_get_dn_by_oid(gnutls_x509_crq_t crq,
698 const char *oid,
699 int indx,
700 unsigned int raw_flag,
701 void *buf,
702 size_t * sizeof_buf);
703int gnutls_x509_crq_set_dn_by_oid(gnutls_x509_crq_t crq,
704 const char *oid,
705 unsigned int raw_flag,
706 const void *name,
707 unsigned int sizeof_name);
708int gnutls_x509_crq_set_version(gnutls_x509_crq_t crq,
709 unsigned int version);
710int gnutls_x509_crq_set_key(gnutls_x509_crq_t crq,
711 gnutls_x509_privkey_t key);
712int gnutls_x509_crq_sign2(gnutls_x509_crq_t crq,
713 gnutls_x509_privkey_t key,
714 gnutls_digest_algorithm_t,
715 unsigned int flags);
716int gnutls_x509_crq_sign(gnutls_x509_crq_t crq,
717 gnutls_x509_privkey_t key);
718
719int gnutls_x509_crq_set_challenge_password(gnutls_x509_crq_t crq,
720 const char *pass);
721int gnutls_x509_crq_get_challenge_password(gnutls_x509_crq_t crq,
722 char *pass,
723 size_t * sizeof_pass);
724
725int gnutls_x509_crq_set_attribute_by_oid(gnutls_x509_crq_t crq,
726 const char *oid,
727 void *buf,
728 size_t sizeof_buf);
729int gnutls_x509_crq_get_attribute_by_oid(gnutls_x509_crq_t crq,
730 const char *oid,
731 int indx,
732 void *buf,
733 size_t * sizeof_buf);
734
735int gnutls_x509_crq_export(gnutls_x509_crq_t crq,
736 gnutls_x509_crt_fmt_t format,
737 void *output_data,
738 size_t * output_data_size);
739
740int gnutls_x509_crt_set_crq(gnutls_x509_crt_t crt,
741 gnutls_x509_crq_t crq);
742
743#ifdef __cplusplus
744}
745#endif
746
747#define HASH_OID_SHA1 "1.3.14.3.2.26"
748#define HASH_OID_MD5 "1.2.840.113549.2.5"
749#define HASH_OID_MD2 "1.2.840.113549.2.2"
750#define HASH_OID_RMD160 "1.3.36.3.2.1"
751#define HASH_OID_SHA256 "2.16.840.1.101.3.4.2.1"
752#define HASH_OID_SHA384 "2.16.840.1.101.3.4.2.2"
753#define HASH_OID_SHA512 "2.16.840.1.101.3.4.2.3"
754
755typedef struct gnutls_x509_crl_int
756 {
757 ASN1_TYPE crl;
758 } gnutls_x509_crl_int;
759
760typedef struct gnutls_x509_crt_int
761 {
762 ASN1_TYPE cert;
763 int use_extensions;
764 } gnutls_x509_crt_int;
765
766#define MAX_PRIV_PARAMS_SIZE 6 /* ok for RSA and DSA */
767
768/* parameters should not be larger than this limit */
769#define DSA_PRIVATE_PARAMS 5
770#define DSA_PUBLIC_PARAMS 4
771#define RSA_PRIVATE_PARAMS 6
772#define RSA_PUBLIC_PARAMS 2
773
774#if MAX_PRIV_PARAMS_SIZE - RSA_PRIVATE_PARAMS < 0
775# error INCREASE MAX_PRIV_PARAMS
776#endif
777
778#if MAX_PRIV_PARAMS_SIZE - DSA_PRIVATE_PARAMS < 0
779# error INCREASE MAX_PRIV_PARAMS
780#endif
781
782typedef struct gnutls_x509_privkey_int
783 {
784 mpi_t params[MAX_PRIV_PARAMS_SIZE]; /* the size of params depends on the public
785 * key algorithm
786 */
787 /*
788 * RSA: [0] is modulus
789 * [1] is public exponent
790 * [2] is private exponent
791 * [3] is prime1 (p)
792 * [4] is prime2 (q)
793 * [5] is coefficient (u == inverse of p mod q)
794 * note that other packages used inverse of q mod p,
795 * so we need to perform conversions.
796 * DSA: [0] is p
797 * [1] is q
798 * [2] is g
799 * [3] is y (public key)
800 * [4] is x (private key)
801 */
802 int params_size; /* holds the number of params */
803
804 gnutls_pk_algorithm_t pk_algorithm;
805
806 int crippled; /* The crippled keys will not use the ASN1_TYPE key.
807 * The encoding will only be performed at the export
808 * phase, to optimize copying etc. Cannot be used with
809 * the exported API (used internally only).
810 */
811 ASN1_TYPE key;
812 } gnutls_x509_privkey_int;
813
814int gnutls_x509_crt_get_issuer_dn_by_oid(gnutls_x509_crt_t cert,
815 const char *oid,
816 int indx,
817 unsigned int raw_flag,
818 void *buf,
819 size_t * sizeof_buf);
820int gnutls_x509_crt_get_subject_alt_name(gnutls_x509_crt_t cert,
821 unsigned int seq,
822 void *ret,
823 size_t * ret_size,
824 unsigned int *critical);
825int gnutls_x509_crt_get_dn_by_oid(gnutls_x509_crt_t cert,
826 const char *oid,
827 int indx,
828 unsigned int raw_flag,
829 void *buf,
830 size_t * sizeof_buf);
831int gnutls_x509_crt_get_ca_status(gnutls_x509_crt_t cert,
832 unsigned int *critical);
833int gnutls_x509_crt_get_pk_algorithm(gnutls_x509_crt_t cert,
834 unsigned int *bits);
835
836int _gnutls_x509_crt_cpy(gnutls_x509_crt_t dest,
837 gnutls_x509_crt_t src);
838
839int gnutls_x509_crt_get_serial(gnutls_x509_crt_t cert,
840 void *result,
841 size_t * result_size);
842
843int _gnutls_x509_compare_raw_dn(const gnutls_datum_t * dn1,
844 const gnutls_datum_t * dn2);
845
846int gnutls_x509_crt_check_revocation(gnutls_x509_crt_t cert,
847 const gnutls_x509_crl_t * crl_list,
848 int crl_list_length);
849
850int _gnutls_x509_crl_cpy(gnutls_x509_crl_t dest,
851 gnutls_x509_crl_t src);
852int _gnutls_x509_crl_get_raw_issuer_dn(gnutls_x509_crl_t crl,
853 gnutls_datum_t * dn);
854int gnutls_x509_crl_get_crt_count(gnutls_x509_crl_t crl);
855int gnutls_x509_crl_get_crt_serial(gnutls_x509_crl_t crl,
856 int indx,
857 unsigned char *serial,
858 size_t * serial_size,
859 time_t * t);
860
861void gnutls_x509_crl_deinit(gnutls_x509_crl_t crl);
862int gnutls_x509_crl_init(gnutls_x509_crl_t * crl);
863int gnutls_x509_crl_import(gnutls_x509_crl_t crl,
864 const gnutls_datum_t * data,
865 gnutls_x509_crt_fmt_t format);
866int gnutls_x509_crl_export(gnutls_x509_crl_t crl,
867 gnutls_x509_crt_fmt_t format,
868 void *output_data,
869 size_t * output_data_size);
870
871int gnutls_x509_crt_init(gnutls_x509_crt_t * cert);
872void gnutls_x509_crt_deinit(gnutls_x509_crt_t cert);
873int gnutls_x509_crt_import(gnutls_x509_crt_t cert,
874 const gnutls_datum_t * data,
875 gnutls_x509_crt_fmt_t format);
876int gnutls_x509_crt_export(gnutls_x509_crt_t cert,
877 gnutls_x509_crt_fmt_t format,
878 void *output_data,
879 size_t * output_data_size);
880
881int gnutls_x509_crt_get_key_usage(gnutls_x509_crt_t cert,
882 unsigned int *key_usage,
883 unsigned int *critical);
884int gnutls_x509_crt_get_signature_algorithm(gnutls_x509_crt_t cert);
885int gnutls_x509_crt_get_version(gnutls_x509_crt_t cert);
886
887int gnutls_x509_privkey_init(gnutls_x509_privkey_t * key);
888void gnutls_x509_privkey_deinit(gnutls_x509_privkey_t key);
889
890int gnutls_x509_privkey_generate(gnutls_x509_privkey_t key,
891 gnutls_pk_algorithm_t algo,
892 unsigned int bits,
893 unsigned int flags);
894
895int gnutls_x509_privkey_import(gnutls_x509_privkey_t key,
896 const gnutls_datum_t * data,
897 gnutls_x509_crt_fmt_t format);
898int gnutls_x509_privkey_get_pk_algorithm(gnutls_x509_privkey_t key);
899int gnutls_x509_privkey_import_rsa_raw(gnutls_x509_privkey_t key,
900 const gnutls_datum_t * m,
901 const gnutls_datum_t * e,
902 const gnutls_datum_t * d,
903 const gnutls_datum_t * p,
904 const gnutls_datum_t * q,
905 const gnutls_datum_t * u);
906int gnutls_x509_privkey_export_rsa_raw(gnutls_x509_privkey_t key,
907 gnutls_datum_t * m,
908 gnutls_datum_t * e,
909 gnutls_datum_t * d,
910 gnutls_datum_t * p,
911 gnutls_datum_t * q,
912 gnutls_datum_t * u);
913int gnutls_x509_privkey_export(gnutls_x509_privkey_t key,
914 gnutls_x509_crt_fmt_t format,
915 void *output_data,
916 size_t * output_data_size);
917
918#define GNUTLS_CRL_REASON_UNUSED 128
919#define GNUTLS_CRL_REASON_KEY_COMPROMISE 64
920#define GNUTLS_CRL_REASON_CA_COMPROMISE 32
921#define GNUTLS_CRL_REASON_AFFILIATION_CHANGED 16
922#define GNUTLS_CRL_REASON_SUPERSEEDED 8
923#define GNUTLS_CRL_REASON_CESSATION_OF_OPERATION 4
924#define GNUTLS_CRL_REASON_CERTIFICATE_HOLD 2
925#define GNUTLS_CRL_REASON_PRIVILEGE_WITHDRAWN 1
926#define GNUTLS_CRL_REASON_AA_COMPROMISE 32768
927
928#endif
diff --git a/src/daemon/https/x509/x509_privkey.c b/src/daemon/https/x509/x509_privkey.c
new file mode 100644
index 00000000..f5c64dee
--- /dev/null
+++ b/src/daemon/https/x509/x509_privkey.c
@@ -0,0 +1,1509 @@
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 <gnutls_datum.h>
27#include <gnutls_global.h>
28#include <gnutls_errors.h>
29#include <gnutls_rsa_export.h>
30#include <gnutls_sig.h>
31#include <common.h>
32#include <gnutls_x509.h>
33#include <x509_b64.h>
34#include <x509.h>
35#include <dn.h>
36#include <mpi.h>
37#include <extensions.h>
38#include <sign.h>
39#include <dsa.h>
40#include <verify.h>
41
42static int _gnutls_asn1_encode_rsa (ASN1_TYPE * c2, mpi_t * params);
43int _gnutls_asn1_encode_dsa (ASN1_TYPE * c2, mpi_t * params);
44
45/* remove this when libgcrypt can handle the PKCS #1 coefficients from
46 * rsa keys
47 */
48#define CALC_COEFF 1
49
50/**
51 * gnutls_x509_privkey_init - This function initializes a gnutls_crl structure
52 * @key: The structure to be initialized
53 *
54 * This function will initialize an private key structure.
55 *
56 * Returns 0 on success.
57 *
58 **/
59int
60gnutls_x509_privkey_init (gnutls_x509_privkey_t * key)
61{
62 *key = gnutls_calloc (1, sizeof (gnutls_x509_privkey_int));
63
64 if (*key)
65 {
66 (*key)->key = ASN1_TYPE_EMPTY;
67 (*key)->pk_algorithm = GNUTLS_PK_UNKNOWN;
68 return 0; /* success */
69 }
70
71 return GNUTLS_E_MEMORY_ERROR;
72}
73
74/**
75 * gnutls_x509_privkey_deinit - This function deinitializes memory used by a gnutls_x509_privkey_t structure
76 * @key: The structure to be initialized
77 *
78 * This function will deinitialize a private key structure.
79 *
80 **/
81void
82gnutls_x509_privkey_deinit (gnutls_x509_privkey_t key)
83{
84 int i;
85
86 if (!key)
87 return;
88
89 for (i = 0; i < key->params_size; i++)
90 {
91 _gnutls_mpi_release (&key->params[i]);
92 }
93
94 asn1_delete_structure (&key->key);
95 gnutls_free (key);
96}
97
98/**
99 * gnutls_x509_privkey_cpy - This function copies a private key
100 * @dst: The destination key, which should be initialized.
101 * @src: The source key
102 *
103 * This function will copy a private key from source to destination key.
104 *
105 **/
106int
107gnutls_x509_privkey_cpy (gnutls_x509_privkey_t dst, gnutls_x509_privkey_t src)
108{
109 int i, ret;
110
111 if (!src || !dst)
112 return GNUTLS_E_INVALID_REQUEST;
113
114 for (i = 0; i < src->params_size; i++)
115 {
116 dst->params[i] = _gnutls_mpi_copy (src->params[i]);
117 if (dst->params[i] == NULL)
118 return GNUTLS_E_MEMORY_ERROR;
119 }
120
121 dst->params_size = src->params_size;
122 dst->pk_algorithm = src->pk_algorithm;
123 dst->crippled = src->crippled;
124
125 if (!src->crippled)
126 {
127 switch (dst->pk_algorithm)
128 {
129 case GNUTLS_PK_RSA:
130 ret = _gnutls_asn1_encode_rsa (&dst->key, dst->params);
131 if (ret < 0)
132 {
133 gnutls_assert ();
134 return ret;
135 }
136 break;
137 default:
138 gnutls_assert ();
139 return GNUTLS_E_INVALID_REQUEST;
140 }
141 }
142
143 return 0;
144}
145
146/* Converts an RSA PKCS#1 key to
147 * an internal structure (gnutls_private_key)
148 */
149ASN1_TYPE
150_gnutls_privkey_decode_pkcs1_rsa_key (const gnutls_datum_t * raw_key,
151 gnutls_x509_privkey_t pkey)
152{
153 int result;
154 ASN1_TYPE pkey_asn;
155
156 if ((result = asn1_create_element (_gnutls_get_gnutls_asn (),
157 "GNUTLS.RSAPrivateKey",
158 &pkey_asn)) != ASN1_SUCCESS)
159 {
160 gnutls_assert ();
161 return NULL;
162 }
163
164 if ((sizeof (pkey->params) / sizeof (mpi_t)) < RSA_PRIVATE_PARAMS)
165 {
166 gnutls_assert ();
167 /* internal error. Increase the mpi_ts in params */
168 return NULL;
169 }
170
171 result = asn1_der_decoding (&pkey_asn, raw_key->data, raw_key->size, NULL);
172 if (result != ASN1_SUCCESS)
173 {
174 gnutls_assert ();
175 goto error;
176 }
177
178 if ((result = _gnutls_x509_read_int (pkey_asn, "modulus", &pkey->params[0]))
179 < 0)
180 {
181 gnutls_assert ();
182 goto error;
183 }
184
185 if ((result = _gnutls_x509_read_int (pkey_asn, "publicExponent",
186 &pkey->params[1])) < 0)
187 {
188 gnutls_assert ();
189 goto error;
190 }
191
192 if ((result = _gnutls_x509_read_int (pkey_asn, "privateExponent",
193 &pkey->params[2])) < 0)
194 {
195 gnutls_assert ();
196 goto error;
197 }
198
199 if ((result = _gnutls_x509_read_int (pkey_asn, "prime1", &pkey->params[3]))
200 < 0)
201 {
202 gnutls_assert ();
203 goto error;
204 }
205
206 if ((result = _gnutls_x509_read_int (pkey_asn, "prime2", &pkey->params[4]))
207 < 0)
208 {
209 gnutls_assert ();
210 goto error;
211 }
212
213#ifdef CALC_COEFF
214 /* Calculate the coefficient. This is because the gcrypt
215 * library is uses the p,q in the reverse order.
216 */
217 pkey->params[5] =
218 _gnutls_mpi_snew (_gnutls_mpi_get_nbits (pkey->params[0]));
219
220 if (pkey->params[5] == NULL)
221 {
222 gnutls_assert ();
223 goto error;
224 }
225
226 _gnutls_mpi_invm (pkey->params[5], pkey->params[3], pkey->params[4]);
227 /* p, q */
228#else
229 if ((result = _gnutls_x509_read_int (pkey_asn, "coefficient",
230 &pkey->params[5])) < 0)
231 {
232 gnutls_assert ();
233 goto error;
234 }
235#endif
236 pkey->params_size = 6;
237
238 return pkey_asn;
239
240error:asn1_delete_structure (&pkey_asn);
241 _gnutls_mpi_release (&pkey->params[0]);
242 _gnutls_mpi_release (&pkey->params[1]);
243 _gnutls_mpi_release (&pkey->params[2]);
244 _gnutls_mpi_release (&pkey->params[3]);
245 _gnutls_mpi_release (&pkey->params[4]);
246 _gnutls_mpi_release (&pkey->params[5]);
247 return NULL;
248
249}
250
251static ASN1_TYPE
252decode_dsa_key (const gnutls_datum_t * raw_key, gnutls_x509_privkey_t pkey)
253{
254 int result;
255 ASN1_TYPE dsa_asn;
256
257 if ((result = asn1_create_element (_gnutls_get_gnutls_asn (),
258 "GNUTLS.DSAPrivateKey",
259 &dsa_asn)) != ASN1_SUCCESS)
260 {
261 gnutls_assert ();
262 return NULL;
263 }
264
265 if ((sizeof (pkey->params) / sizeof (mpi_t)) < DSA_PRIVATE_PARAMS)
266 {
267 gnutls_assert ();
268 /* internal error. Increase the mpi_ts in params */
269 return NULL;
270 }
271
272 result = asn1_der_decoding (&dsa_asn, raw_key->data, raw_key->size, NULL);
273 if (result != ASN1_SUCCESS)
274 {
275 gnutls_assert ();
276 goto error;
277 }
278
279 if ((result = _gnutls_x509_read_int (dsa_asn, "p", &pkey->params[0])) < 0)
280 {
281 gnutls_assert ();
282 goto error;
283 }
284
285 if ((result = _gnutls_x509_read_int (dsa_asn, "q", &pkey->params[1])) < 0)
286 {
287 gnutls_assert ();
288 goto error;
289 }
290
291 if ((result = _gnutls_x509_read_int (dsa_asn, "g", &pkey->params[2])) < 0)
292 {
293 gnutls_assert ();
294 goto error;
295 }
296
297 if ((result = _gnutls_x509_read_int (dsa_asn, "Y", &pkey->params[3])) < 0)
298 {
299 gnutls_assert ();
300 goto error;
301 }
302
303 if ((result =
304 _gnutls_x509_read_int (dsa_asn, "priv", &pkey->params[4])) < 0)
305 {
306 gnutls_assert ();
307 goto error;
308 }
309 pkey->params_size = 5;
310
311 return dsa_asn;
312
313error:asn1_delete_structure (&dsa_asn);
314 _gnutls_mpi_release (&pkey->params[0]);
315 _gnutls_mpi_release (&pkey->params[1]);
316 _gnutls_mpi_release (&pkey->params[2]);
317 _gnutls_mpi_release (&pkey->params[3]);
318 _gnutls_mpi_release (&pkey->params[4]);
319 return NULL;
320
321}
322
323#define PEM_KEY_DSA "DSA PRIVATE KEY"
324#define PEM_KEY_RSA "RSA PRIVATE KEY"
325
326/**
327 * gnutls_x509_privkey_import - This function will import a DER or PEM encoded key
328 * @key: The structure to store the parsed key
329 * @data: The DER or PEM encoded certificate.
330 * @format: One of DER or PEM
331 *
332 * This function will convert the given DER or PEM encoded key
333 * to the native gnutls_x509_privkey_t format. The output will be stored in @key .
334 *
335 * If the key is PEM encoded it should have a header of "RSA PRIVATE KEY", or
336 * "DSA PRIVATE KEY".
337 *
338 * Returns 0 on success.
339 *
340 **/
341int
342gnutls_x509_privkey_import (gnutls_x509_privkey_t key,
343 const gnutls_datum_t * data,
344 gnutls_x509_crt_fmt_t format)
345{
346 int result = 0, need_free = 0;
347 gnutls_datum_t _data;
348
349 if (key == NULL)
350 {
351 gnutls_assert ();
352 return GNUTLS_E_INVALID_REQUEST;
353 }
354
355 _data.data = data->data;
356 _data.size = data->size;
357
358 key->pk_algorithm = GNUTLS_PK_UNKNOWN;
359
360 /* If the Certificate is in PEM format then decode it
361 */
362 if (format == GNUTLS_X509_FMT_PEM)
363 {
364 opaque *out;
365
366 /* Try the first header */
367 result
368 = _gnutls_fbase64_decode (PEM_KEY_RSA, data->data, data->size, &out);
369 key->pk_algorithm = GNUTLS_PK_RSA;
370
371 // TODO rm
372// if (result == GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR)
373// {
374// /* try for the second header */
375// result = _gnutls_fbase64_decode(PEM_KEY_DSA, data->data, data->size,
376// &out);
377// key->pk_algorithm = GNUTLS_PK_DSA;
378//
379// if (result <= 0)
380// {
381// if (result == 0)
382// result = GNUTLS_E_INTERNAL_ERROR;
383// gnutls_assert ();
384// return result;
385// }
386// }
387
388 _data.data = out;
389 _data.size = result;
390
391 need_free = 1;
392 }
393
394 if (key->pk_algorithm == GNUTLS_PK_RSA)
395 {
396 key->key = _gnutls_privkey_decode_pkcs1_rsa_key (&_data, key);
397 if (key->key == NULL)
398 gnutls_assert ();
399 }
400 else
401 {
402 /* Try decoding with both, and accept the one that
403 * succeeds.
404 */
405 key->pk_algorithm = GNUTLS_PK_RSA;
406 key->key = _gnutls_privkey_decode_pkcs1_rsa_key (&_data, key);
407
408 // TODO rm
409// if (key->key == NULL)
410// {
411// key->pk_algorithm = GNUTLS_PK_DSA;
412// key->key = decode_dsa_key(&_data, key);
413// if (key->key == NULL)
414// gnutls_assert();
415// }
416 }
417
418 if (key->key == NULL)
419 {
420 gnutls_assert ();
421 result = GNUTLS_E_ASN1_DER_ERROR;
422 goto cleanup;
423 }
424
425 if (need_free)
426 _gnutls_free_datum (&_data);
427
428 /* The key has now been decoded.
429 */
430
431 return 0;
432
433cleanup:key->pk_algorithm = GNUTLS_PK_UNKNOWN;
434 if (need_free)
435 _gnutls_free_datum (&_data);
436 return result;
437}
438
439#define FREE_RSA_PRIVATE_PARAMS for (i=0;i<RSA_PRIVATE_PARAMS;i++) \
440 _gnutls_mpi_release(&key->params[i])
441#define FREE_DSA_PRIVATE_PARAMS for (i=0;i<DSA_PRIVATE_PARAMS;i++) \
442 _gnutls_mpi_release(&key->params[i])
443
444/**
445 * gnutls_x509_privkey_import_rsa_raw - This function will import a raw RSA key
446 * @key: The structure to store the parsed key
447 * @m: holds the modulus
448 * @e: holds the public exponent
449 * @d: holds the private exponent
450 * @p: holds the first prime (p)
451 * @q: holds the second prime (q)
452 * @u: holds the coefficient
453 *
454 * This function will convert the given RSA raw parameters
455 * to the native gnutls_x509_privkey_t format. The output will be stored in @key.
456 *
457 **/
458int
459gnutls_x509_privkey_import_rsa_raw (gnutls_x509_privkey_t key,
460 const gnutls_datum_t * m,
461 const gnutls_datum_t * e,
462 const gnutls_datum_t * d,
463 const gnutls_datum_t * p,
464 const gnutls_datum_t * q,
465 const gnutls_datum_t * u)
466{
467 int i = 0, ret;
468 size_t siz = 0;
469
470 if (key == NULL)
471 {
472 gnutls_assert ();
473 return GNUTLS_E_INVALID_REQUEST;
474 }
475
476 siz = m->size;
477 if (_gnutls_mpi_scan_nz (&key->params[0], m->data, &siz))
478 {
479 gnutls_assert ();
480 FREE_RSA_PRIVATE_PARAMS;
481 return GNUTLS_E_MPI_SCAN_FAILED;
482 }
483
484 siz = e->size;
485 if (_gnutls_mpi_scan_nz (&key->params[1], e->data, &siz))
486 {
487 gnutls_assert ();
488 FREE_RSA_PRIVATE_PARAMS;
489 return GNUTLS_E_MPI_SCAN_FAILED;
490 }
491
492 siz = d->size;
493 if (_gnutls_mpi_scan_nz (&key->params[2], d->data, &siz))
494 {
495 gnutls_assert ();
496 FREE_RSA_PRIVATE_PARAMS;
497 return GNUTLS_E_MPI_SCAN_FAILED;
498 }
499
500 siz = p->size;
501 if (_gnutls_mpi_scan_nz (&key->params[3], p->data, &siz))
502 {
503 gnutls_assert ();
504 FREE_RSA_PRIVATE_PARAMS;
505 return GNUTLS_E_MPI_SCAN_FAILED;
506 }
507
508 siz = q->size;
509 if (_gnutls_mpi_scan_nz (&key->params[4], q->data, &siz))
510 {
511 gnutls_assert ();
512 FREE_RSA_PRIVATE_PARAMS;
513 return GNUTLS_E_MPI_SCAN_FAILED;
514 }
515
516#ifdef CALC_COEFF
517 key->params[5] = _gnutls_mpi_snew (_gnutls_mpi_get_nbits (key->params[0]));
518
519 if (key->params[5] == NULL)
520 {
521 gnutls_assert ();
522 FREE_RSA_PRIVATE_PARAMS;
523 return GNUTLS_E_MEMORY_ERROR;
524 }
525
526 _gnutls_mpi_invm (key->params[5], key->params[3], key->params[4]);
527#else
528 siz = u->size;
529 if (_gnutls_mpi_scan_nz (&key->params[5], u->data, &siz))
530 {
531 gnutls_assert ();
532 FREE_RSA_PRIVATE_PARAMS;
533 return GNUTLS_E_MPI_SCAN_FAILED;
534 }
535#endif
536
537 if (!key->crippled)
538 {
539 ret = _gnutls_asn1_encode_rsa (&key->key, key->params);
540 if (ret < 0)
541 {
542 gnutls_assert ();
543 FREE_RSA_PRIVATE_PARAMS;
544 return ret;
545 }
546 }
547
548 key->params_size = RSA_PRIVATE_PARAMS;
549 key->pk_algorithm = GNUTLS_PK_RSA;
550
551 return 0;
552
553}
554
555/**
556 * gnutls_x509_privkey_get_pk_algorithm - This function returns the key's PublicKey algorithm
557 * @key: should contain a gnutls_x509_privkey_t structure
558 *
559 * This function will return the public key algorithm of a private
560 * key.
561 *
562 * Returns a member of the gnutls_pk_algorithm_t enumeration on success,
563 * or a negative value on error.
564 *
565 **/
566int
567gnutls_x509_privkey_get_pk_algorithm (gnutls_x509_privkey_t key)
568{
569 if (key == NULL)
570 {
571 gnutls_assert ();
572 return GNUTLS_E_INVALID_REQUEST;
573 }
574
575 return key->pk_algorithm;
576}
577
578/**
579 * gnutls_x509_privkey_export - This function will export the private key
580 * @key: Holds the key
581 * @format: the format of output params. One of PEM or DER.
582 * @output_data: will contain a private key PEM or DER encoded
583 * @output_data_size: holds the size of output_data (and will be
584 * replaced by the actual size of parameters)
585 *
586 * This function will export the private key to a PKCS1 structure for
587 * RSA keys, or an integer sequence for DSA keys. The DSA keys are in
588 * the same format with the parameters used by openssl.
589 *
590 * If the buffer provided is not long enough to hold the output, then
591 * *output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
592 * be returned.
593 *
594 * If the structure is PEM encoded, it will have a header
595 * of "BEGIN RSA PRIVATE KEY".
596 *
597 * Return value: In case of failure a negative value will be
598 * returned, and 0 on success.
599 *
600 **/
601int
602gnutls_x509_privkey_export (gnutls_x509_privkey_t key,
603 gnutls_x509_crt_fmt_t format,
604 void *output_data, size_t * output_data_size)
605{
606 char *msg;
607 int ret;
608
609 if (key == NULL)
610 {
611 gnutls_assert ();
612 return GNUTLS_E_INVALID_REQUEST;
613 }
614
615 if (key->pk_algorithm == GNUTLS_PK_RSA)
616 msg = PEM_KEY_RSA;
617 else
618 msg = NULL;
619
620 if (key->crippled)
621 { /* encode the parameters on the fly.
622 */
623 switch (key->pk_algorithm)
624 {
625 case GNUTLS_PK_RSA:
626 ret = _gnutls_asn1_encode_rsa (&key->key, key->params);
627 if (ret < 0)
628 {
629 gnutls_assert ();
630 return ret;
631 }
632 break;
633 default:
634 gnutls_assert ();
635 return GNUTLS_E_INVALID_REQUEST;
636 }
637 }
638
639 return _gnutls_x509_export_int (key->key, format, msg, output_data,
640 output_data_size);
641}
642
643/**
644 * gnutls_x509_privkey_export_rsa_raw - This function will export the RSA private key
645 * @key: a structure that holds the rsa parameters
646 * @m: will hold the modulus
647 * @e: will hold the public exponent
648 * @d: will hold the private exponent
649 * @p: will hold the first prime (p)
650 * @q: will hold the second prime (q)
651 * @u: will hold the coefficient
652 *
653 * This function will export the RSA private key's parameters found in the given
654 * structure. The new parameters will be allocated using
655 * gnutls_malloc() and will be stored in the appropriate datum.
656 *
657 **/
658int
659gnutls_x509_privkey_export_rsa_raw (gnutls_x509_privkey_t key,
660 gnutls_datum_t * m,
661 gnutls_datum_t * e,
662 gnutls_datum_t * d,
663 gnutls_datum_t * p,
664 gnutls_datum_t * q, gnutls_datum_t * u)
665{
666 int ret;
667 mpi_t coeff = NULL;
668
669 if (key == NULL)
670 {
671 gnutls_assert ();
672 return GNUTLS_E_INVALID_REQUEST;
673 }
674
675 m->data = e->data = d->data = p->data = q->data = u->data = NULL;
676 m->size = e->size = d->size = p->size = q->size = u->size = 0;
677
678 ret = _gnutls_mpi_dprint (m, key->params[0]);
679 if (ret < 0)
680 {
681 gnutls_assert ();
682 goto error;
683 }
684
685 /* E */
686 ret = _gnutls_mpi_dprint (e, key->params[1]);
687 if (ret < 0)
688 {
689 gnutls_assert ();
690 goto error;
691 }
692
693 /* D */
694 ret = _gnutls_mpi_dprint (d, key->params[2]);
695 if (ret < 0)
696 {
697 gnutls_assert ();
698 goto error;
699 }
700
701 /* P */
702 ret = _gnutls_mpi_dprint (p, key->params[3]);
703 if (ret < 0)
704 {
705 gnutls_assert ();
706 goto error;
707 }
708
709 /* Q */
710 ret = _gnutls_mpi_dprint (q, key->params[4]);
711 if (ret < 0)
712 {
713 gnutls_assert ();
714 goto error;
715 }
716
717#ifdef CALC_COEFF
718 coeff = _gnutls_mpi_snew (_gnutls_mpi_get_nbits (key->params[0]));
719
720 if (coeff == NULL)
721 {
722 gnutls_assert ();
723 ret = GNUTLS_E_MEMORY_ERROR;
724 goto error;
725 }
726
727 _gnutls_mpi_invm (coeff, key->params[4], key->params[3]);
728 ret = _gnutls_mpi_dprint (u, coeff);
729 if (ret < 0)
730 {
731 gnutls_assert ();
732 goto error;
733 }
734
735 _gnutls_mpi_release (&coeff);
736#else
737 /* U */
738 ret = _gnutls_mpi_dprint (u, key->params[5]);
739 if (ret < 0)
740 {
741 gnutls_assert ();
742 goto error;
743 }
744#endif
745
746 return 0;
747
748error:_gnutls_free_datum (m);
749 _gnutls_free_datum (d);
750 _gnutls_free_datum (e);
751 _gnutls_free_datum (p);
752 _gnutls_free_datum (q);
753 _gnutls_mpi_release (&coeff);
754
755 return ret;
756}
757
758/**
759 * gnutls_x509_privkey_export_dsa_raw - This function will export the DSA private key
760 * @params: a structure that holds the DSA parameters
761 * @p: will hold the p
762 * @q: will hold the q
763 * @g: will hold the g
764 * @y: will hold the y
765 * @x: will hold the x
766 *
767 * This function will export the DSA private key's parameters found in the given
768 * structure. The new parameters will be allocated using
769 * gnutls_malloc() and will be stored in the appropriate datum.
770 *
771 **/
772int
773gnutls_x509_privkey_export_dsa_raw (gnutls_x509_privkey_t key,
774 gnutls_datum_t * p,
775 gnutls_datum_t * q,
776 gnutls_datum_t * g,
777 gnutls_datum_t * y, gnutls_datum_t * x)
778{
779 int ret;
780
781 if (key == NULL)
782 {
783 gnutls_assert ();
784 return GNUTLS_E_INVALID_REQUEST;
785 }
786
787 /* P */
788 ret = _gnutls_mpi_dprint (p, key->params[0]);
789 if (ret < 0)
790 {
791 gnutls_assert ();
792 return ret;
793 }
794
795 /* Q */
796 ret = _gnutls_mpi_dprint (q, key->params[1]);
797 if (ret < 0)
798 {
799 gnutls_assert ();
800 _gnutls_free_datum (p);
801 return ret;
802 }
803
804 /* G */
805 ret = _gnutls_mpi_dprint (g, key->params[2]);
806 if (ret < 0)
807 {
808 gnutls_assert ();
809 _gnutls_free_datum (p);
810 _gnutls_free_datum (q);
811 return ret;
812 }
813
814 /* Y */
815 ret = _gnutls_mpi_dprint (y, key->params[3]);
816 if (ret < 0)
817 {
818 gnutls_assert ();
819 _gnutls_free_datum (p);
820 _gnutls_free_datum (g);
821 _gnutls_free_datum (q);
822 return ret;
823 }
824
825 /* X */
826 ret = _gnutls_mpi_dprint (x, key->params[4]);
827 if (ret < 0)
828 {
829 gnutls_assert ();
830 _gnutls_free_datum (y);
831 _gnutls_free_datum (p);
832 _gnutls_free_datum (g);
833 _gnutls_free_datum (q);
834 return ret;
835 }
836
837 return 0;
838}
839
840/* Encodes the RSA parameters into an ASN.1 RSA private key structure.
841 */
842static int
843_gnutls_asn1_encode_rsa (ASN1_TYPE * c2, mpi_t * params)
844{
845 int result, i;
846 size_t size[8], total;
847 opaque *m_data, *pube_data, *prie_data;
848 opaque *p1_data, *p2_data, *u_data, *exp1_data, *exp2_data;
849 opaque *all_data = NULL, *p;
850 mpi_t exp1 = NULL, exp2 = NULL, q1 = NULL, p1 = NULL, u = NULL;
851 opaque null = '\0';
852
853 /* Read all the sizes */
854 total = 0;
855 for (i = 0; i < 5; i++)
856 {
857 _gnutls_mpi_print_lz (NULL, &size[i], params[i]);
858 total += size[i];
859 }
860
861 /* Now generate exp1 and exp2
862 */
863 exp1 = _gnutls_mpi_salloc_like (params[0]); /* like modulus */
864 if (exp1 == NULL)
865 {
866 gnutls_assert ();
867 result = GNUTLS_E_MEMORY_ERROR;
868 goto cleanup;
869 }
870
871 exp2 = _gnutls_mpi_salloc_like (params[0]);
872 if (exp2 == NULL)
873 {
874 gnutls_assert ();
875 result = GNUTLS_E_MEMORY_ERROR;
876 goto cleanup;
877 }
878
879 q1 = _gnutls_mpi_salloc_like (params[4]);
880 if (q1 == NULL)
881 {
882 gnutls_assert ();
883 result = GNUTLS_E_MEMORY_ERROR;
884 goto cleanup;
885 }
886
887 p1 = _gnutls_mpi_salloc_like (params[3]);
888 if (p1 == NULL)
889 {
890 gnutls_assert ();
891 result = GNUTLS_E_MEMORY_ERROR;
892 goto cleanup;
893 }
894
895 u = _gnutls_mpi_salloc_like (params[3]);
896 if (u == NULL)
897 {
898 gnutls_assert ();
899 result = GNUTLS_E_MEMORY_ERROR;
900 goto cleanup;
901 }
902
903 _gnutls_mpi_invm (u, params[4], params[3]);
904 /* inverse of q mod p */
905 _gnutls_mpi_print_lz (NULL, &size[5], u);
906 total += size[5];
907
908 _gnutls_mpi_sub_ui (p1, params[3], 1);
909 _gnutls_mpi_sub_ui (q1, params[4], 1);
910
911 _gnutls_mpi_mod (exp1, params[2], p1);
912 _gnutls_mpi_mod (exp2, params[2], q1);
913
914 /* calculate exp's size */
915 _gnutls_mpi_print_lz (NULL, &size[6], exp1);
916 total += size[6];
917
918 _gnutls_mpi_print_lz (NULL, &size[7], exp2);
919 total += size[7];
920
921 /* Encoding phase.
922 * allocate data enough to hold everything
923 */
924 all_data = gnutls_secure_malloc (total);
925 if (all_data == NULL)
926 {
927 gnutls_assert ();
928 result = GNUTLS_E_MEMORY_ERROR;
929 goto cleanup;
930 }
931
932 p = all_data;
933 m_data = p;
934 p += size[0];
935 pube_data = p;
936 p += size[1];
937 prie_data = p;
938 p += size[2];
939 p1_data = p;
940 p += size[3];
941 p2_data = p;
942 p += size[4];
943 u_data = p;
944 p += size[5];
945 exp1_data = p;
946 p += size[6];
947 exp2_data = p;
948
949 _gnutls_mpi_print_lz (m_data, &size[0], params[0]);
950 _gnutls_mpi_print_lz (pube_data, &size[1], params[1]);
951 _gnutls_mpi_print_lz (prie_data, &size[2], params[2]);
952 _gnutls_mpi_print_lz (p1_data, &size[3], params[3]);
953 _gnutls_mpi_print_lz (p2_data, &size[4], params[4]);
954 _gnutls_mpi_print_lz (u_data, &size[5], u);
955 _gnutls_mpi_print_lz (exp1_data, &size[6], exp1);
956 _gnutls_mpi_print_lz (exp2_data, &size[7], exp2);
957
958 /* Ok. Now we have the data. Create the asn1 structures
959 */
960
961 if ((result =
962 asn1_create_element (_gnutls_get_gnutls_asn (), "GNUTLS.RSAPrivateKey",
963 c2)) != ASN1_SUCCESS)
964 {
965 gnutls_assert ();
966 result = _gnutls_asn2err (result);
967 goto cleanup;
968 }
969
970 /* Write PRIME
971 */
972 if ((result = asn1_write_value (*c2, "modulus", m_data, size[0]))
973 != ASN1_SUCCESS)
974 {
975 gnutls_assert ();
976 result = _gnutls_asn2err (result);
977 goto cleanup;
978 }
979
980 if ((result = asn1_write_value (*c2, "publicExponent", pube_data, size[1]))
981 != ASN1_SUCCESS)
982 {
983 gnutls_assert ();
984 result = _gnutls_asn2err (result);
985 goto cleanup;
986 }
987
988 if ((result = asn1_write_value (*c2, "privateExponent", prie_data, size[2]))
989 != ASN1_SUCCESS)
990 {
991 gnutls_assert ();
992 result = _gnutls_asn2err (result);
993 goto cleanup;
994 }
995
996 if ((result = asn1_write_value (*c2, "prime1", p1_data, size[3]))
997 != ASN1_SUCCESS)
998 {
999 gnutls_assert ();
1000 result = _gnutls_asn2err (result);
1001 goto cleanup;
1002 }
1003
1004 if ((result = asn1_write_value (*c2, "prime2", p2_data, size[4]))
1005 != ASN1_SUCCESS)
1006 {
1007 gnutls_assert ();
1008 result = _gnutls_asn2err (result);
1009 goto cleanup;
1010 }
1011
1012 if ((result = asn1_write_value (*c2, "exponent1", exp1_data, size[6]))
1013 != ASN1_SUCCESS)
1014 {
1015 gnutls_assert ();
1016 result = _gnutls_asn2err (result);
1017 goto cleanup;
1018 }
1019
1020 if ((result = asn1_write_value (*c2, "exponent2", exp2_data, size[7]))
1021 != ASN1_SUCCESS)
1022 {
1023 gnutls_assert ();
1024 result = _gnutls_asn2err (result);
1025 goto cleanup;
1026 }
1027
1028 if ((result = asn1_write_value (*c2, "coefficient", u_data, size[5]))
1029 != ASN1_SUCCESS)
1030 {
1031 gnutls_assert ();
1032 result = _gnutls_asn2err (result);
1033 goto cleanup;
1034 }
1035
1036 _gnutls_mpi_release (&exp1);
1037 _gnutls_mpi_release (&exp2);
1038 _gnutls_mpi_release (&q1);
1039 _gnutls_mpi_release (&p1);
1040 _gnutls_mpi_release (&u);
1041 gnutls_free (all_data);
1042
1043 if ((result = asn1_write_value (*c2, "otherPrimeInfos",
1044 NULL, 0)) != ASN1_SUCCESS)
1045 {
1046 gnutls_assert ();
1047 result = _gnutls_asn2err (result);
1048 goto cleanup;
1049 }
1050
1051 if ((result = asn1_write_value (*c2, "version", &null, 1)) != ASN1_SUCCESS)
1052 {
1053 gnutls_assert ();
1054 result = _gnutls_asn2err (result);
1055 goto cleanup;
1056 }
1057
1058 return 0;
1059
1060cleanup:_gnutls_mpi_release (&u);
1061 _gnutls_mpi_release (&exp1);
1062 _gnutls_mpi_release (&exp2);
1063 _gnutls_mpi_release (&q1);
1064 _gnutls_mpi_release (&p1);
1065 asn1_delete_structure (c2);
1066 gnutls_free (all_data);
1067
1068 return result;
1069}
1070
1071/* Encodes the DSA parameters into an ASN.1 DSAPrivateKey structure.
1072 */
1073int
1074_gnutls_asn1_encode_dsa (ASN1_TYPE * c2, mpi_t * params)
1075{
1076 int result, i;
1077 size_t size[DSA_PRIVATE_PARAMS], total;
1078 opaque *p_data, *q_data, *g_data, *x_data, *y_data;
1079 opaque *all_data = NULL, *p;
1080 opaque null = '\0';
1081
1082 /* Read all the sizes */
1083 total = 0;
1084 for (i = 0; i < DSA_PRIVATE_PARAMS; i++)
1085 {
1086 _gnutls_mpi_print_lz (NULL, &size[i], params[i]);
1087 total += size[i];
1088 }
1089
1090 /* Encoding phase.
1091 * allocate data enough to hold everything
1092 */
1093 all_data = gnutls_secure_malloc (total);
1094 if (all_data == NULL)
1095 {
1096 gnutls_assert ();
1097 result = GNUTLS_E_MEMORY_ERROR;
1098 goto cleanup;
1099 }
1100
1101 p = all_data;
1102 p_data = p;
1103 p += size[0];
1104 q_data = p;
1105 p += size[1];
1106 g_data = p;
1107 p += size[2];
1108 y_data = p;
1109 p += size[3];
1110 x_data = p;
1111
1112 _gnutls_mpi_print_lz (p_data, &size[0], params[0]);
1113 _gnutls_mpi_print_lz (q_data, &size[1], params[1]);
1114 _gnutls_mpi_print_lz (g_data, &size[2], params[2]);
1115 _gnutls_mpi_print_lz (y_data, &size[3], params[3]);
1116 _gnutls_mpi_print_lz (x_data, &size[4], params[4]);
1117
1118 /* Ok. Now we have the data. Create the asn1 structures
1119 */
1120
1121 if ((result =
1122 asn1_create_element (_gnutls_get_gnutls_asn (), "GNUTLS.DSAPrivateKey",
1123 c2)) != ASN1_SUCCESS)
1124 {
1125 gnutls_assert ();
1126 result = _gnutls_asn2err (result);
1127 goto cleanup;
1128 }
1129
1130 /* Write PRIME
1131 */
1132 if ((result = asn1_write_value (*c2, "p", p_data, size[0])) != ASN1_SUCCESS)
1133 {
1134 gnutls_assert ();
1135 result = _gnutls_asn2err (result);
1136 goto cleanup;
1137 }
1138
1139 if ((result = asn1_write_value (*c2, "q", q_data, size[1])) != ASN1_SUCCESS)
1140 {
1141 gnutls_assert ();
1142 result = _gnutls_asn2err (result);
1143 goto cleanup;
1144 }
1145
1146 if ((result = asn1_write_value (*c2, "g", g_data, size[2])) != ASN1_SUCCESS)
1147 {
1148 gnutls_assert ();
1149 result = _gnutls_asn2err (result);
1150 goto cleanup;
1151 }
1152
1153 if ((result = asn1_write_value (*c2, "Y", y_data, size[3])) != ASN1_SUCCESS)
1154 {
1155 gnutls_assert ();
1156 result = _gnutls_asn2err (result);
1157 goto cleanup;
1158 }
1159
1160 if ((result =
1161 asn1_write_value (*c2, "priv", x_data, size[4])) != ASN1_SUCCESS)
1162 {
1163 gnutls_assert ();
1164 result = _gnutls_asn2err (result);
1165 goto cleanup;
1166 }
1167
1168 gnutls_free (all_data);
1169
1170 if ((result = asn1_write_value (*c2, "version", &null, 1)) != ASN1_SUCCESS)
1171 {
1172 gnutls_assert ();
1173 result = _gnutls_asn2err (result);
1174 goto cleanup;
1175 }
1176
1177 return 0;
1178
1179cleanup:asn1_delete_structure (c2);
1180 gnutls_free (all_data);
1181
1182 return result;
1183}
1184
1185/**
1186 * gnutls_x509_privkey_generate - This function will generate a private key
1187 * @key: should contain a gnutls_x509_privkey_t structure
1188 * @algo: is one of RSA or DSA.
1189 * @bits: the size of the modulus
1190 * @flags: unused for now. Must be 0.
1191 *
1192 * This function will generate a random private key. Note that
1193 * this function must be called on an empty private key.
1194 *
1195 * Returns 0 on success or a negative value on error.
1196 *
1197 **/
1198int
1199gnutls_x509_privkey_generate (gnutls_x509_privkey_t key,
1200 gnutls_pk_algorithm_t algo,
1201 unsigned int bits, unsigned int flags)
1202{
1203 int ret, params_len;
1204 int i;
1205
1206 if (key == NULL)
1207 {
1208 gnutls_assert ();
1209 return GNUTLS_E_INVALID_REQUEST;
1210 }
1211
1212 switch (algo)
1213 {
1214 case GNUTLS_PK_RSA:
1215 ret = _gnutls_rsa_generate_params (key->params, &params_len, bits);
1216 if (ret < 0)
1217 {
1218 gnutls_assert ();
1219 return ret;
1220 }
1221
1222 if (!key->crippled)
1223 {
1224 ret = _gnutls_asn1_encode_rsa (&key->key, key->params);
1225 if (ret < 0)
1226 {
1227 gnutls_assert ();
1228 goto cleanup;
1229 }
1230 }
1231
1232 key->params_size = params_len;
1233 key->pk_algorithm = GNUTLS_PK_RSA;
1234
1235 break;
1236 default:
1237 gnutls_assert ();
1238 return GNUTLS_E_INVALID_REQUEST;
1239 }
1240
1241 return 0;
1242
1243cleanup:key->pk_algorithm = GNUTLS_PK_UNKNOWN;
1244 key->params_size = 0;
1245 for (i = 0; i < params_len; i++)
1246 _gnutls_mpi_release (&key->params[i]);
1247
1248 return ret;
1249}
1250
1251/**
1252 * gnutls_x509_privkey_get_key_id - Return unique ID of the key's parameters
1253 * @key: Holds the key
1254 * @flags: should be 0 for now
1255 * @output_data: will contain the key ID
1256 * @output_data_size: holds the size of output_data (and will be
1257 * replaced by the actual size of parameters)
1258 *
1259 * This function will return a unique ID the depends on the public key
1260 * parameters. This ID can be used in checking whether a certificate
1261 * corresponds to the given key.
1262 *
1263 * If the buffer provided is not long enough to hold the output, then
1264 * *output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
1265 * be returned. The output will normally be a SHA-1 hash output,
1266 * which is 20 bytes.
1267 *
1268 * Return value: In case of failure a negative value will be
1269 * returned, and 0 on success.
1270 *
1271 **/
1272int
1273gnutls_x509_privkey_get_key_id (gnutls_x509_privkey_t key,
1274 unsigned int flags,
1275 unsigned char *output_data,
1276 size_t * output_data_size)
1277{
1278 int result;
1279 GNUTLS_HASH_HANDLE hd;
1280 gnutls_datum_t der = { NULL,
1281 0
1282 };
1283
1284 if (key == NULL || key->crippled)
1285 {
1286 gnutls_assert ();
1287 return GNUTLS_E_INVALID_REQUEST;
1288 }
1289
1290 if (*output_data_size < 20)
1291 {
1292 gnutls_assert ();
1293 *output_data_size = 20;
1294 return GNUTLS_E_SHORT_MEMORY_BUFFER;
1295 }
1296
1297 if (key->pk_algorithm == GNUTLS_PK_RSA)
1298 {
1299 result = _gnutls_x509_write_rsa_params (key->params, key->params_size,
1300 &der);
1301 if (result < 0)
1302 {
1303 gnutls_assert ();
1304 goto cleanup;
1305 }
1306 }
1307 else
1308 return GNUTLS_E_INTERNAL_ERROR;
1309
1310 hd = _gnutls_hash_init (GNUTLS_MAC_SHA1);
1311 if (hd == GNUTLS_HASH_FAILED)
1312 {
1313 gnutls_assert ();
1314 result = GNUTLS_E_INTERNAL_ERROR;
1315 goto cleanup;
1316 }
1317
1318 _gnutls_hash (hd, der.data, der.size);
1319
1320 _gnutls_hash_deinit (hd, output_data);
1321 *output_data_size = 20;
1322
1323 result = 0;
1324
1325cleanup:
1326
1327 _gnutls_free_datum (&der);
1328 return result;
1329}
1330
1331#ifdef ENABLE_PKI
1332
1333/**
1334 * gnutls_x509_privkey_sign_data - This function will sign the given data using the private key params
1335 * @key: Holds the key
1336 * @digest: should be MD5 or SHA1
1337 * @flags: should be 0 for now
1338 * @data: holds the data to be signed
1339 * @signature: will contain the signature
1340 * @signature_size: holds the size of signature (and will be replaced
1341 * by the new size)
1342 *
1343 * This function will sign the given data using a signature algorithm
1344 * supported by the private key. Signature algorithms are always used
1345 * together with a hash functions. Different hash functions may be
1346 * used for the RSA algorithm, but only SHA-1 for the DSA keys.
1347 *
1348 * If the buffer provided is not long enough to hold the output, then
1349 * *signature_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
1350 * be returned.
1351 *
1352 * In case of failure a negative value will be returned, and
1353 * 0 on success.
1354 *
1355 **/
1356int
1357gnutls_x509_privkey_sign_data (gnutls_x509_privkey_t key,
1358 gnutls_digest_algorithm_t digest,
1359 unsigned int flags,
1360 const gnutls_datum_t * data,
1361 void *signature, size_t * signature_size)
1362{
1363 int result;
1364 gnutls_datum_t sig = { NULL, 0 };
1365
1366 if (key == NULL)
1367 {
1368 gnutls_assert ();
1369 return GNUTLS_E_INVALID_REQUEST;
1370 }
1371
1372 result = _gnutls_x509_sign (data, digest, key, &sig);
1373 if (result < 0)
1374 {
1375 gnutls_assert ();
1376 return result;
1377 }
1378
1379 if (*signature_size < sig.size)
1380 {
1381 *signature_size = sig.size;
1382 _gnutls_free_datum (&sig);
1383 return GNUTLS_E_SHORT_MEMORY_BUFFER;
1384 }
1385
1386 *signature_size = sig.size;
1387 memcpy (signature, sig.data, sig.size);
1388
1389 _gnutls_free_datum (&sig);
1390
1391 return 0;
1392}
1393
1394/**
1395 * gnutls_x509_privkey_sign_hash - This function will sign the given data using the private key params
1396 * @key: Holds the key
1397 * @hash: holds the data to be signed
1398 * @signature: will contain newly allocated signature
1399 *
1400 * This function will sign the given hash using the private key.
1401 *
1402 * Return value: In case of failure a negative value will be returned,
1403 * and 0 on success.
1404 **/
1405int
1406gnutls_x509_privkey_sign_hash (gnutls_x509_privkey_t key,
1407 const gnutls_datum_t * hash,
1408 gnutls_datum_t * signature)
1409{
1410 int result;
1411
1412 if (key == NULL)
1413 {
1414 gnutls_assert ();
1415 return GNUTLS_E_INVALID_REQUEST;
1416 }
1417
1418 result = _gnutls_sign (key->pk_algorithm, key->params,
1419 key->params_size, hash, signature);
1420 if (result < 0)
1421 {
1422 gnutls_assert ();
1423 return result;
1424 }
1425
1426 return 0;
1427}
1428
1429/**
1430 * gnutls_x509_privkey_verify_data - This function will verify the given signed data.
1431 * @key: Holds the key
1432 * @flags: should be 0 for now
1433 * @data: holds the data to be signed
1434 * @signature: contains the signature
1435 *
1436 * This function will verify the given signed data, using the parameters in the
1437 * private key.
1438 *
1439 * In case of a verification failure 0 is returned, and
1440 * 1 on success.
1441 *
1442 **/
1443int
1444gnutls_x509_privkey_verify_data (gnutls_x509_privkey_t key,
1445 unsigned int flags,
1446 const gnutls_datum_t * data,
1447 const gnutls_datum_t * signature)
1448{
1449 int result;
1450
1451 if (key == NULL)
1452 {
1453 gnutls_assert ();
1454 return GNUTLS_E_INVALID_REQUEST;
1455 }
1456
1457 result = _gnutls_x509_privkey_verify_signature (data, signature, key);
1458 if (result < 0)
1459 {
1460 gnutls_assert ();
1461 return 0;
1462 }
1463
1464 return result;
1465}
1466
1467/**
1468 * gnutls_x509_privkey_fix - This function will recalculate some parameters of the key.
1469 * @key: Holds the key
1470 *
1471 * This function will recalculate the secondary parameters in a key.
1472 * In RSA keys, this can be the coefficient and exponent1,2.
1473 *
1474 * Return value: In case of failure a negative value will be
1475 * returned, and 0 on success.
1476 *
1477 **/
1478int
1479gnutls_x509_privkey_fix (gnutls_x509_privkey_t key)
1480{
1481 int ret;
1482
1483 if (key == NULL)
1484 {
1485 gnutls_assert ();
1486 return GNUTLS_E_INVALID_REQUEST;
1487 }
1488
1489 if (!key->crippled)
1490 asn1_delete_structure (&key->key);
1491 switch (key->pk_algorithm)
1492 {
1493 case GNUTLS_PK_RSA:
1494 ret = _gnutls_asn1_encode_rsa (&key->key, key->params);
1495 if (ret < 0)
1496 {
1497 gnutls_assert ();
1498 return ret;
1499 }
1500 break;
1501 default:
1502 gnutls_assert ();
1503 return GNUTLS_E_INVALID_REQUEST;
1504 }
1505
1506 return 0;
1507}
1508
1509#endif
diff --git a/src/daemon/https/x509/x509_verify.c b/src/daemon/https/x509/x509_verify.c
new file mode 100644
index 00000000..f01fed9d
--- /dev/null
+++ b/src/daemon/https/x509/x509_verify.c
@@ -0,0 +1,1037 @@
1/*
2 * Copyright (C) 2003, 2004, 2005, 2006, 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/* All functions which relate to X.509 certificate verification stuff are
26 * included here
27 */
28
29#include <gnutls_int.h>
30#include <gnutls_errors.h>
31#include <gnutls_cert.h>
32#include <libtasn1.h>
33#include <gnutls_global.h>
34#include <gnutls_num.h> /* MAX */
35#include <gnutls_sig.h>
36#include <gnutls_str.h>
37#include <gnutls_datum.h>
38#include <dn.h>
39#include <x509.h>
40#include <mpi.h>
41#include <common.h>
42#include <verify.h>
43
44static int _gnutls_verify_certificate2 (gnutls_x509_crt_t cert,
45 const gnutls_x509_crt_t * trusted_cas,
46 int tcas_size,
47 unsigned int flags,
48 unsigned int *output);
49int _gnutls_x509_verify_signature (const gnutls_datum_t * signed_data,
50 const gnutls_datum_t * signature,
51 gnutls_x509_crt_t issuer);
52
53static
54 int is_crl_issuer (gnutls_x509_crl_t crl, gnutls_x509_crt_t issuer_cert);
55static int _gnutls_verify_crl2 (gnutls_x509_crl_t crl,
56 const gnutls_x509_crt_t * trusted_cas,
57 int tcas_size,
58 unsigned int flags, unsigned int *output);
59
60/* Checks if the issuer of a certificate is a
61 * Certificate Authority, or if the certificate is the same
62 * as the issuer (and therefore it doesn't need to be a CA).
63 *
64 * Returns true or false, if the issuer is a CA,
65 * or not.
66 */
67static int
68check_if_ca (gnutls_x509_crt_t cert,
69 gnutls_x509_crt_t issuer, unsigned int flags)
70{
71 gnutls_datum_t cert_signed_data = { NULL,
72 0
73 };
74 gnutls_datum_t issuer_signed_data = { NULL,
75 0
76 };
77 gnutls_datum_t cert_signature = { NULL,
78 0
79 };
80 gnutls_datum_t issuer_signature = { NULL,
81 0
82 };
83 int result;
84
85 /* Check if the issuer is the same with the
86 * certificate. This is added in order for trusted
87 * certificates to be able to verify themselves.
88 */
89
90 result = _gnutls_x509_get_signed_data (issuer->cert, "tbsCertificate",
91 &issuer_signed_data);
92 if (result < 0)
93 {
94 gnutls_assert ();
95 goto cleanup;
96 }
97
98 result = _gnutls_x509_get_signed_data (cert->cert, "tbsCertificate",
99 &cert_signed_data);
100 if (result < 0)
101 {
102 gnutls_assert ();
103 goto cleanup;
104 }
105
106 result = _gnutls_x509_get_signature (issuer->cert, "signature",
107 &issuer_signature);
108 if (result < 0)
109 {
110 gnutls_assert ();
111 goto cleanup;
112 }
113
114 result =
115 _gnutls_x509_get_signature (cert->cert, "signature", &cert_signature);
116 if (result < 0)
117 {
118 gnutls_assert ();
119 goto cleanup;
120 }
121
122 /* If the subject certificate is the same as the issuer
123 * return true.
124 */
125 if (!(flags & GNUTLS_VERIFY_DO_NOT_ALLOW_SAME))
126 if (cert_signed_data.size == issuer_signed_data.size)
127 {
128 if ((memcmp (cert_signed_data.data, issuer_signed_data.data,
129 cert_signed_data.size) == 0) && (cert_signature.size
130 ==
131 issuer_signature.size)
132 &&
133 (memcmp
134 (cert_signature.data, issuer_signature.data,
135 cert_signature.size) == 0))
136 {
137 result = 1;
138 goto cleanup;
139 }
140 }
141
142 if (gnutls_x509_crt_get_ca_status (issuer, NULL) == 1)
143 {
144 result = 1;
145 goto cleanup;
146 }
147 else
148 gnutls_assert ();
149
150 result = 0;
151
152cleanup:_gnutls_free_datum (&cert_signed_data);
153 _gnutls_free_datum (&issuer_signed_data);
154 _gnutls_free_datum (&cert_signature);
155 _gnutls_free_datum (&issuer_signature);
156 return result;
157}
158
159/* This function checks if 'certs' issuer is 'issuer_cert'.
160 * This does a straight (DER) compare of the issuer/subject fields in
161 * the given certificates.
162 *
163 * Returns 1 if they match and zero if they don't match. Otherwise
164 * a negative value is returned to indicate error.
165 */
166static int
167is_issuer (gnutls_x509_crt_t cert, gnutls_x509_crt_t issuer_cert)
168{
169 gnutls_datum_t dn1 = { NULL,
170 0
171 }, dn2 =
172 {
173 NULL, 0};
174 int ret;
175
176 ret = gnutls_x509_crt_get_raw_issuer_dn (cert, &dn1);
177 if (ret < 0)
178 {
179 gnutls_assert ();
180 goto cleanup;
181 }
182
183 ret = gnutls_x509_crt_get_raw_dn (issuer_cert, &dn2);
184 if (ret < 0)
185 {
186 gnutls_assert ();
187 goto cleanup;
188 }
189
190 ret = _gnutls_x509_compare_raw_dn (&dn1, &dn2);
191
192cleanup:_gnutls_free_datum (&dn1);
193 _gnutls_free_datum (&dn2);
194 return ret;
195
196}
197
198static inline gnutls_x509_crt_t
199find_issuer (gnutls_x509_crt_t cert,
200 const gnutls_x509_crt_t * trusted_cas, int tcas_size)
201{
202 int i;
203
204 /* this is serial search.
205 */
206
207 for (i = 0; i < tcas_size; i++)
208 {
209 if (is_issuer (cert, trusted_cas[i]) == 1)
210 return trusted_cas[i];
211 }
212
213 gnutls_assert ();
214 return NULL;
215}
216
217/*
218 * Verifies the given certificate again a certificate list of
219 * trusted CAs.
220 *
221 * Returns only 0 or 1. If 1 it means that the certificate
222 * was successfuly verified.
223 *
224 * 'flags': an OR of the gnutls_certificate_verify_flags enumeration.
225 *
226 * Output will hold some extra information about the verification
227 * procedure.
228 */
229static int
230_gnutls_verify_certificate2 (gnutls_x509_crt_t cert,
231 const gnutls_x509_crt_t * trusted_cas,
232 int tcas_size,
233 unsigned int flags, unsigned int *output)
234{
235 gnutls_datum_t cert_signed_data = { NULL,
236 0
237 };
238 gnutls_datum_t cert_signature = { NULL,
239 0
240 };
241 gnutls_x509_crt_t issuer;
242 int ret, issuer_version, result;
243
244 if (output)
245 *output = 0;
246
247 if (tcas_size >= 1)
248 issuer = find_issuer (cert, trusted_cas, tcas_size);
249 else
250 {
251 gnutls_assert ();
252 if (output)
253 *output |= GNUTLS_CERT_SIGNER_NOT_FOUND | GNUTLS_CERT_INVALID;
254 return 0;
255 }
256
257 /* issuer is not in trusted certificate
258 * authorities.
259 */
260 if (issuer == NULL)
261 {
262 if (output)
263 *output |= GNUTLS_CERT_SIGNER_NOT_FOUND | GNUTLS_CERT_INVALID;
264 gnutls_assert ();
265 return 0;
266 }
267
268 issuer_version = gnutls_x509_crt_get_version (issuer);
269 if (issuer_version < 0)
270 {
271 gnutls_assert ();
272 return issuer_version;
273 }
274
275 if (!(flags & GNUTLS_VERIFY_DISABLE_CA_SIGN) && !((flags
276 &
277 GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT)
278 && issuer_version == 1))
279 {
280 if (check_if_ca (cert, issuer, flags) == 0)
281 {
282 gnutls_assert ();
283 if (output)
284 *output |= GNUTLS_CERT_SIGNER_NOT_CA | GNUTLS_CERT_INVALID;
285 return 0;
286 }
287 }
288
289 result = _gnutls_x509_get_signed_data (cert->cert, "tbsCertificate",
290 &cert_signed_data);
291 if (result < 0)
292 {
293 gnutls_assert ();
294 goto cleanup;
295 }
296
297 result =
298 _gnutls_x509_get_signature (cert->cert, "signature", &cert_signature);
299 if (result < 0)
300 {
301 gnutls_assert ();
302 goto cleanup;
303 }
304
305 ret = _gnutls_x509_verify_signature (&cert_signed_data, &cert_signature,
306 issuer);
307 if (ret < 0)
308 {
309 gnutls_assert ();
310 }
311 else if (ret == 0)
312 {
313 gnutls_assert ();
314 /* error. ignore it */
315 if (output)
316 *output |= GNUTLS_CERT_INVALID;
317 ret = 0;
318 }
319
320 /* If the certificate is not self signed check if the algorithms
321 * used are secure. If the certificate is self signed it doesn't
322 * really matter.
323 */
324 if (is_issuer (cert, cert) == 0)
325 {
326 int sigalg;
327
328 sigalg = gnutls_x509_crt_get_signature_algorithm (cert);
329
330 if (((sigalg == GNUTLS_SIGN_RSA_MD2) && !(flags
331 &
332 GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD2))
333 || ((sigalg == GNUTLS_SIGN_RSA_MD5)
334 && !(flags & GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5)))
335 {
336 if (output)
337 *output |= GNUTLS_CERT_INSECURE_ALGORITHM | GNUTLS_CERT_INVALID;
338 }
339 }
340
341 result = ret;
342
343cleanup:_gnutls_free_datum (&cert_signed_data);
344 _gnutls_free_datum (&cert_signature);
345
346 return result;
347}
348
349/**
350 * gnutls_x509_crt_check_issuer - This function checks if the certificate given has the given issuer
351 * @cert: is the certificate to be checked
352 * @issuer: is the certificate of a possible issuer
353 *
354 * This function will check if the given certificate was issued by the
355 * given issuer. It will return true (1) if the given certificate is issued
356 * by the given issuer, and false (0) if not.
357 *
358 * A negative value is returned in case of an error.
359 *
360 **/
361int
362gnutls_x509_crt_check_issuer (gnutls_x509_crt_t cert,
363 gnutls_x509_crt_t issuer)
364{
365 return is_issuer (cert, issuer);
366}
367
368/* The algorithm used is:
369 * 1. Check last certificate in the chain. If it is not verified return.
370 * 2. Check if any certificates in the chain are revoked. If yes return.
371 * 3. Try to verify the rest of certificates in the chain. If not verified return.
372 * 4. Return 0.
373 *
374 * Note that the return value is an OR of GNUTLS_CERT_* elements.
375 *
376 * This function verifies a X.509 certificate list. The certificate list should
377 * lead to a trusted CA in order to be trusted.
378 */
379static unsigned int
380_gnutls_x509_verify_certificate (const gnutls_x509_crt_t * certificate_list,
381 int clist_size,
382 const gnutls_x509_crt_t * trusted_cas,
383 int tcas_size,
384 const gnutls_x509_crl_t * CRLs,
385 int crls_size, unsigned int flags)
386{
387 int i = 0, ret;
388 unsigned int status = 0, output;
389
390 /* Verify the last certificate in the certificate path
391 * against the trusted CA certificate list.
392 *
393 * If no CAs are present returns CERT_INVALID. Thus works
394 * in self signed etc certificates.
395 */
396 ret = _gnutls_verify_certificate2 (certificate_list[clist_size - 1],
397 trusted_cas, tcas_size, flags, &output);
398
399 if (ret == 0)
400 {
401 /* if the last certificate in the certificate
402 * list is invalid, then the certificate is not
403 * trusted.
404 */
405 gnutls_assert ();
406 status |= output;
407 status |= GNUTLS_CERT_INVALID;
408 return status;
409 }
410
411 /* Check for revoked certificates in the chain
412 */
413#ifdef ENABLE_PKI
414 for (i = 0; i < clist_size; i++)
415 {
416 ret = gnutls_x509_crt_check_revocation (certificate_list[i],
417 CRLs, crls_size);
418 if (ret == 1)
419 { /* revoked */
420 status |= GNUTLS_CERT_REVOKED;
421 status |= GNUTLS_CERT_INVALID;
422 return status;
423 }
424 }
425#endif
426
427 /* Check if the last certificate in the path is self signed.
428 * In that case ignore it (a certificate is trusted only if it
429 * leads to a trusted party by us, not the server's).
430 */
431 if (gnutls_x509_crt_check_issuer (certificate_list[clist_size - 1],
432 certificate_list[clist_size - 1]) > 0
433 && clist_size > 0)
434 {
435 clist_size--;
436 }
437
438 /* Verify the certificate path (chain)
439 */
440 for (i = clist_size - 1; i > 0; i--)
441 {
442 if (i - 1 < 0)
443 break;
444
445 /* note that here we disable this V1 CA flag. So that no version 1
446 * certificates can exist in a supplied chain.
447 */
448 if (!(flags & GNUTLS_VERIFY_ALLOW_ANY_X509_V1_CA_CRT))
449 flags ^= GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT;
450 if ((ret = _gnutls_verify_certificate2 (certificate_list[i - 1],
451 &certificate_list[i], 1, flags,
452 NULL)) == 0)
453 {
454 status |= GNUTLS_CERT_INVALID;
455 return status;
456 }
457 }
458
459 return 0;
460}
461
462/* Reads the digest information.
463 * we use DER here, although we should use BER. It works fine
464 * anyway.
465 */
466static int
467decode_ber_digest_info (const gnutls_datum_t * info,
468 gnutls_mac_algorithm_t * hash,
469 opaque * digest, int *digest_size)
470{
471 ASN1_TYPE dinfo = ASN1_TYPE_EMPTY;
472 int result;
473 char str[1024];
474 int len;
475
476 if ((result = asn1_create_element (_gnutls_get_gnutls_asn (),
477 "GNUTLS.DigestInfo",
478 &dinfo)) != ASN1_SUCCESS)
479 {
480 gnutls_assert ();
481 return _gnutls_asn2err (result);
482 }
483
484 result = asn1_der_decoding (&dinfo, info->data, info->size, NULL);
485 if (result != ASN1_SUCCESS)
486 {
487 gnutls_assert ();
488 asn1_delete_structure (&dinfo);
489 return _gnutls_asn2err (result);
490 }
491
492 len = sizeof (str) - 1;
493 result = asn1_read_value (dinfo, "digestAlgorithm.algorithm", str, &len);
494 if (result != ASN1_SUCCESS)
495 {
496 gnutls_assert ();
497 asn1_delete_structure (&dinfo);
498 return _gnutls_asn2err (result);
499 }
500
501 *hash = _gnutls_x509_oid2mac_algorithm (str);
502
503 if (*hash == GNUTLS_MAC_UNKNOWN)
504 {
505
506 _gnutls_x509_log ("verify.c: HASH OID: %s\n", str);
507
508 gnutls_assert ();
509 asn1_delete_structure (&dinfo);
510 return GNUTLS_E_UNKNOWN_ALGORITHM;
511 }
512
513 len = sizeof (str) - 1;
514 result = asn1_read_value (dinfo, "digestAlgorithm.parameters", str, &len);
515 /* To avoid permitting garbage in the parameters field, either the
516 parameters field is not present, or it contains 0x05 0x00. */
517 if (!
518 (result == ASN1_ELEMENT_NOT_FOUND
519 || (result == ASN1_SUCCESS && len == 2 && str[0] == 0x05
520 && str[1] == 0x00)))
521 {
522 gnutls_assert ();
523 asn1_delete_structure (&dinfo);
524 return GNUTLS_E_ASN1_GENERIC_ERROR;
525 }
526
527 result = asn1_read_value (dinfo, "digest", digest, digest_size);
528 if (result != ASN1_SUCCESS)
529 {
530 gnutls_assert ();
531 asn1_delete_structure (&dinfo);
532 return _gnutls_asn2err (result);
533 }
534
535 asn1_delete_structure (&dinfo);
536
537 return 0;
538}
539
540/* if hash==MD5 then we do RSA-MD5
541 * if hash==SHA then we do RSA-SHA
542 * params[0] is modulus
543 * params[1] is public key
544 */
545static int
546_pkcs1_rsa_verify_sig (const gnutls_datum_t * text,
547 const gnutls_datum_t * signature,
548 mpi_t * params, int params_len)
549{
550 gnutls_mac_algorithm_t hash = GNUTLS_MAC_UNKNOWN;
551 int ret;
552 opaque digest[MAX_HASH_SIZE], md[MAX_HASH_SIZE];
553 int digest_size;
554 GNUTLS_HASH_HANDLE hd;
555 gnutls_datum_t decrypted;
556
557 ret =
558 _gnutls_pkcs1_rsa_decrypt (&decrypted, signature, params, params_len, 1);
559 if (ret < 0)
560 {
561 gnutls_assert ();
562 return ret;
563 }
564
565 /* decrypted is a BER encoded data of type DigestInfo
566 */
567
568 digest_size = sizeof (digest);
569 if ((ret = decode_ber_digest_info (&decrypted, &hash, digest, &digest_size))
570 != 0)
571 {
572 gnutls_assert ();
573 _gnutls_free_datum (&decrypted);
574 return ret;
575 }
576
577 _gnutls_free_datum (&decrypted);
578
579 if (digest_size != _gnutls_hash_get_algo_len (hash))
580 {
581 gnutls_assert ();
582 return GNUTLS_E_ASN1_GENERIC_ERROR;
583 }
584
585 hd = _gnutls_hash_init (hash);
586 if (hd == NULL)
587 {
588 gnutls_assert ();
589 return GNUTLS_E_HASH_FAILED;
590 }
591
592 _gnutls_hash (hd, text->data, text->size);
593 _gnutls_hash_deinit (hd, md);
594
595 if (memcmp (md, digest, digest_size) != 0)
596 {
597 gnutls_assert ();
598 return GNUTLS_E_PK_SIG_VERIFY_FAILED;
599 }
600
601 return 0;
602}
603
604/* Hashes input data and verifies a DSA signature.
605 */
606static int
607dsa_verify_sig (const gnutls_datum_t * text,
608 const gnutls_datum_t * signature,
609 mpi_t * params, int params_len)
610{
611 int ret;
612 opaque _digest[MAX_HASH_SIZE];
613 gnutls_datum_t digest;
614 GNUTLS_HASH_HANDLE hd;
615
616 hd = _gnutls_hash_init (GNUTLS_MAC_SHA1);
617 if (hd == NULL)
618 {
619 gnutls_assert ();
620 return GNUTLS_E_HASH_FAILED;
621 }
622
623 _gnutls_hash (hd, text->data, text->size);
624 _gnutls_hash_deinit (hd, _digest);
625
626 digest.data = _digest;
627 digest.size = 20;
628
629 ret = _gnutls_dsa_verify (&digest, signature, params, params_len);
630
631 return ret;
632}
633
634/* Verifies the signature data, and returns 0 if not verified,
635 * or 1 otherwise.
636 */
637static int
638verify_sig (const gnutls_datum_t * tbs,
639 const gnutls_datum_t * signature,
640 gnutls_pk_algorithm_t pk,
641 mpi_t * issuer_params, int issuer_params_size)
642{
643
644 switch (pk)
645 {
646 case GNUTLS_PK_RSA:
647
648 if (_pkcs1_rsa_verify_sig
649 (tbs, signature, issuer_params, issuer_params_size) != 0)
650 {
651 gnutls_assert ();
652 return 0;
653 }
654
655 return 1;
656 break;
657
658 default:
659 gnutls_assert ();
660 return GNUTLS_E_INTERNAL_ERROR;
661
662 }
663}
664
665/* verifies if the certificate is properly signed.
666 * returns 0 on failure and 1 on success.
667 *
668 * 'tbs' is the signed data
669 * 'signature' is the signature!
670 */
671int
672_gnutls_x509_verify_signature (const gnutls_datum_t * tbs,
673 const gnutls_datum_t * signature,
674 gnutls_x509_crt_t issuer)
675{
676 mpi_t issuer_params[MAX_PUBLIC_PARAMS_SIZE];
677 int ret, issuer_params_size, i;
678
679 /* Read the MPI parameters from the issuer's certificate.
680 */
681 issuer_params_size = MAX_PUBLIC_PARAMS_SIZE;
682 ret =
683 _gnutls_x509_crt_get_mpis (issuer, issuer_params, &issuer_params_size);
684 if (ret < 0)
685 {
686 gnutls_assert ();
687 return ret;
688 }
689
690 ret = verify_sig (tbs, signature, gnutls_x509_crt_get_pk_algorithm (issuer,
691 NULL),
692 issuer_params, issuer_params_size);
693 if (ret < 0)
694 {
695 gnutls_assert ();
696 }
697
698 /* release all allocated MPIs
699 */
700 for (i = 0; i < issuer_params_size; i++)
701 {
702 _gnutls_mpi_release (&issuer_params[i]);
703 }
704
705 return ret;
706}
707
708/* verifies if the certificate is properly signed.
709 * returns 0 on failure and 1 on success.
710 *
711 * 'tbs' is the signed data
712 * 'signature' is the signature!
713 */
714int
715_gnutls_x509_privkey_verify_signature (const gnutls_datum_t * tbs,
716 const gnutls_datum_t * signature,
717 gnutls_x509_privkey_t issuer)
718{
719 int ret;
720
721 ret = verify_sig (tbs, signature, issuer->pk_algorithm, issuer->params,
722 issuer->params_size);
723 if (ret < 0)
724 {
725 gnutls_assert ();
726 }
727
728 return ret;
729}
730
731/**
732 * gnutls_x509_crt_list_verify - This function verifies the given certificate list
733 * @cert_list: is the certificate list to be verified
734 * @cert_list_length: holds the number of certificate in cert_list
735 * @CA_list: is the CA list which will be used in verification
736 * @CA_list_length: holds the number of CA certificate in CA_list
737 * @CRL_list: holds a list of CRLs.
738 * @CRL_list_length: the length of CRL list.
739 * @flags: Flags that may be used to change the verification algorithm. Use OR of the gnutls_certificate_verify_flags enumerations.
740 * @verify: will hold the certificate verification output.
741 *
742 * This function will try to verify the given certificate list and return its status.
743 * Note that expiration and activation dates are not checked
744 * by this function, you should check them using the appropriate functions.
745 *
746 * If no flags are specified (0), this function will use the
747 * basicConstraints (2.5.29.19) PKIX extension. This means that only a certificate
748 * authority is allowed to sign a certificate.
749 *
750 * You must also check the peer's name in order to check if the verified
751 * certificate belongs to the actual peer.
752 *
753 * The certificate verification output will be put in @verify and will be
754 * one or more of the gnutls_certificate_status_t enumerated elements bitwise or'd.
755 * For a more detailed verification status use gnutls_x509_crt_verify() per list
756 * element.
757 *
758 * GNUTLS_CERT_INVALID: the certificate chain is not valid.
759 *
760 * GNUTLS_CERT_REVOKED: a certificate in the chain has been revoked.
761 *
762 * Returns 0 on success and a negative value in case of an error.
763 *
764 **/
765int
766gnutls_x509_crt_list_verify (const gnutls_x509_crt_t * cert_list,
767 int cert_list_length,
768 const gnutls_x509_crt_t * CA_list,
769 int CA_list_length,
770 const gnutls_x509_crl_t * CRL_list,
771 int CRL_list_length,
772 unsigned int flags, unsigned int *verify)
773{
774 if (cert_list == NULL || cert_list_length == 0)
775 return GNUTLS_E_NO_CERTIFICATE_FOUND;
776
777 /* Verify certificate
778 */
779 *verify = _gnutls_x509_verify_certificate (cert_list, cert_list_length,
780 CA_list, CA_list_length,
781 CRL_list, CRL_list_length,
782 flags);
783
784 return 0;
785}
786
787/**
788 * gnutls_x509_crt_verify - This function verifies the given certificate against a given trusted one
789 * @cert: is the certificate to be verified
790 * @CA_list: is one certificate that is considered to be trusted one
791 * @CA_list_length: holds the number of CA certificate in CA_list
792 * @flags: Flags that may be used to change the verification algorithm. Use OR of the gnutls_certificate_verify_flags enumerations.
793 * @verify: will hold the certificate verification output.
794 *
795 * This function will try to verify the given certificate and return its status.
796 * The verification output in this functions cannot be GNUTLS_CERT_NOT_VALID.
797 *
798 * Returns 0 on success and a negative value in case of an error.
799 *
800 **/
801int
802gnutls_x509_crt_verify (gnutls_x509_crt_t cert,
803 const gnutls_x509_crt_t * CA_list,
804 int CA_list_length,
805 unsigned int flags, unsigned int *verify)
806{
807 int ret;
808 /* Verify certificate
809 */
810 ret = _gnutls_verify_certificate2 (cert, CA_list, CA_list_length, flags,
811 verify);
812 if (ret < 0)
813 {
814 gnutls_assert ();
815 return ret;
816 }
817
818 return 0;
819}
820
821#ifdef ENABLE_PKI
822
823/**
824 * gnutls_x509_crl_check_issuer - This function checks if the CRL given has the given issuer
825 * @crl: is the CRL to be checked
826 * @issuer: is the certificate of a possible issuer
827 *
828 * This function will check if the given CRL was issued by the
829 * given issuer certificate. It will return true (1) if the given CRL was issued
830 * by the given issuer, and false (0) if not.
831 *
832 * A negative value is returned in case of an error.
833 *
834 **/
835int
836gnutls_x509_crl_check_issuer (gnutls_x509_crl_t cert,
837 gnutls_x509_crt_t issuer)
838{
839 return is_crl_issuer (cert, issuer);
840}
841
842/**
843 * gnutls_x509_crl_verify - This function verifies the given crl against a given trusted one
844 * @crl: is the crl to be verified
845 * @CA_list: is a certificate list that is considered to be trusted one
846 * @CA_list_length: holds the number of CA certificates in CA_list
847 * @flags: Flags that may be used to change the verification algorithm. Use OR of the gnutls_certificate_verify_flags enumerations.
848 * @verify: will hold the crl verification output.
849 *
850 * This function will try to verify the given crl and return its status.
851 * See gnutls_x509_crt_list_verify() for a detailed description of
852 * return values.
853 *
854 * Returns 0 on success and a negative value in case of an error.
855 *
856 **/
857int
858gnutls_x509_crl_verify (gnutls_x509_crl_t crl,
859 const gnutls_x509_crt_t * CA_list,
860 int CA_list_length, unsigned int flags,
861 unsigned int *verify)
862{
863 int ret;
864 /* Verify crl
865 */
866 ret = _gnutls_verify_crl2 (crl, CA_list, CA_list_length, flags, verify);
867 if (ret < 0)
868 {
869 gnutls_assert ();
870 return ret;
871 }
872
873 return 0;
874}
875
876/* The same as above, but here we've got a CRL.
877 */
878static int
879is_crl_issuer (gnutls_x509_crl_t crl, gnutls_x509_crt_t issuer_cert)
880{
881 gnutls_datum_t dn1 = { NULL, 0 }, dn2 =
882 {
883 NULL, 0};
884 int ret;
885
886 ret = _gnutls_x509_crl_get_raw_issuer_dn (crl, &dn1);
887 if (ret < 0)
888 {
889 gnutls_assert ();
890 goto cleanup;
891 }
892
893 ret = gnutls_x509_crt_get_raw_dn (issuer_cert, &dn2);
894 if (ret < 0)
895 {
896 gnutls_assert ();
897 return ret;
898 }
899
900 ret = _gnutls_x509_compare_raw_dn (&dn1, &dn2);
901
902cleanup:
903 _gnutls_free_datum (&dn1);
904 _gnutls_free_datum (&dn2);
905
906 return ret;
907}
908
909static inline gnutls_x509_crt_t
910find_crl_issuer (gnutls_x509_crl_t crl,
911 const gnutls_x509_crt_t * trusted_cas, int tcas_size)
912{
913 int i;
914
915 /* this is serial search.
916 */
917
918 for (i = 0; i < tcas_size; i++)
919 {
920 if (is_crl_issuer (crl, trusted_cas[i]) == 1)
921 return trusted_cas[i];
922 }
923
924 gnutls_assert ();
925 return NULL;
926}
927
928/*
929 * Returns only 0 or 1. If 1 it means that the CRL
930 * was successfuly verified.
931 *
932 * 'flags': an OR of the gnutls_certificate_verify_flags enumeration.
933 *
934 * Output will hold information about the verification
935 * procedure.
936 */
937static int
938_gnutls_verify_crl2 (gnutls_x509_crl_t crl,
939 const gnutls_x509_crt_t * trusted_cas,
940 int tcas_size, unsigned int flags, unsigned int *output)
941{
942 /* CRL is ignored for now */
943 gnutls_datum_t crl_signed_data = { NULL, 0 };
944 gnutls_datum_t crl_signature = { NULL, 0 };
945 gnutls_x509_crt_t issuer;
946 int ret, result;
947
948 if (output)
949 *output = 0;
950
951 if (tcas_size >= 1)
952 issuer = find_crl_issuer (crl, trusted_cas, tcas_size);
953 else
954 {
955 gnutls_assert ();
956 if (output)
957 *output |= GNUTLS_CERT_SIGNER_NOT_FOUND | GNUTLS_CERT_INVALID;
958 return 0;
959 }
960
961 /* issuer is not in trusted certificate
962 * authorities.
963 */
964 if (issuer == NULL)
965 {
966 gnutls_assert ();
967 if (output)
968 *output |= GNUTLS_CERT_SIGNER_NOT_FOUND | GNUTLS_CERT_INVALID;
969 return 0;
970 }
971
972 if (!(flags & GNUTLS_VERIFY_DISABLE_CA_SIGN))
973 {
974 if (gnutls_x509_crt_get_ca_status (issuer, NULL) != 1)
975 {
976 gnutls_assert ();
977 if (output)
978 *output |= GNUTLS_CERT_SIGNER_NOT_CA | GNUTLS_CERT_INVALID;
979 return 0;
980 }
981 }
982
983 result =
984 _gnutls_x509_get_signed_data (crl->crl, "tbsCertList", &crl_signed_data);
985 if (result < 0)
986 {
987 gnutls_assert ();
988 goto cleanup;
989 }
990
991 result = _gnutls_x509_get_signature (crl->crl, "signature", &crl_signature);
992 if (result < 0)
993 {
994 gnutls_assert ();
995 goto cleanup;
996 }
997
998 ret =
999 _gnutls_x509_verify_signature (&crl_signed_data, &crl_signature, issuer);
1000 if (ret < 0)
1001 {
1002 gnutls_assert ();
1003 }
1004 else if (ret == 0)
1005 {
1006 gnutls_assert ();
1007 /* error. ignore it */
1008 if (output)
1009 *output |= GNUTLS_CERT_INVALID;
1010 ret = 0;
1011 }
1012
1013 {
1014 int sigalg;
1015
1016 sigalg = gnutls_x509_crl_get_signature_algorithm (crl);
1017
1018 if (((sigalg == GNUTLS_SIGN_RSA_MD2) &&
1019 !(flags & GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD2)) ||
1020 ((sigalg == GNUTLS_SIGN_RSA_MD5) &&
1021 !(flags & GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5)))
1022 {
1023 if (output)
1024 *output |= GNUTLS_CERT_INSECURE_ALGORITHM | GNUTLS_CERT_INVALID;
1025 }
1026 }
1027
1028 result = ret;
1029
1030cleanup:
1031 _gnutls_free_datum (&crl_signed_data);
1032 _gnutls_free_datum (&crl_signature);
1033
1034 return result;
1035}
1036
1037#endif
diff --git a/src/daemon/https/x509/x509_write.c b/src/daemon/https/x509/x509_write.c
new file mode 100644
index 00000000..d9529c33
--- /dev/null
+++ b/src/daemon/https/x509/x509_write.c
@@ -0,0 +1,1094 @@
1/*
2 * Copyright (C) 2003, 2004, 2005, 2006, 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/* This file contains functions to handle X.509 certificate generation.
26 */
27
28#include <gnutls_int.h>
29
30#ifdef ENABLE_PKI
31
32#include <gnutls_datum.h>
33#include <gnutls_global.h>
34#include <gnutls_errors.h>
35#include <common.h>
36#include <gnutls_x509.h>
37#include <x509_b64.h>
38#include <crq.h>
39#include <dn.h>
40#include <mpi.h>
41#include <sign.h>
42#include <extensions.h>
43#include <libtasn1.h>
44
45static void disable_optional_stuff (gnutls_x509_crt_t cert);
46
47/**
48 * gnutls_x509_crt_set_dn_by_oid - This function will set the Certificate request subject's distinguished name
49 * @crt: should contain a gnutls_x509_crt_t structure
50 * @oid: holds an Object Identifier in a null terminated string
51 * @raw_flag: must be 0, or 1 if the data are DER encoded
52 * @name: a pointer to the name
53 * @sizeof_name: holds the size of @name
54 *
55 * This function will set the part of the name of the Certificate subject, specified
56 * by the given OID. The input string should be ASCII or UTF-8 encoded.
57 *
58 * Some helper macros with popular OIDs can be found in gnutls/x509.h
59 * With this function you can only set the known OIDs. You can test
60 * for known OIDs using gnutls_x509_dn_oid_known(). For OIDs that are
61 * not known (by gnutls) you should properly DER encode your data, and
62 * call this function with raw_flag set.
63 *
64 * Returns 0 on success.
65 *
66 **/
67int
68gnutls_x509_crt_set_dn_by_oid (gnutls_x509_crt_t crt, const char *oid,
69 unsigned int raw_flag, const void *name,
70 unsigned int sizeof_name)
71{
72 if (sizeof_name == 0 || name == NULL || crt == NULL)
73 {
74 return GNUTLS_E_INVALID_REQUEST;
75 }
76
77 return _gnutls_x509_set_dn_oid (crt->cert, "tbsCertificate.subject",
78 oid, raw_flag, name, sizeof_name);
79}
80
81/**
82 * gnutls_x509_crt_set_issuer_dn_by_oid - This function will set the Certificate request issuer's distinguished name
83 * @crt: should contain a gnutls_x509_crt_t structure
84 * @oid: holds an Object Identifier in a null terminated string
85 * @raw_flag: must be 0, or 1 if the data are DER encoded
86 * @name: a pointer to the name
87 * @sizeof_name: holds the size of @name
88 *
89 * This function will set the part of the name of the Certificate issuer, specified
90 * by the given OID. The input string should be ASCII or UTF-8 encoded.
91 *
92 * Some helper macros with popular OIDs can be found in gnutls/x509.h
93 * With this function you can only set the known OIDs. You can test
94 * for known OIDs using gnutls_x509_dn_oid_known(). For OIDs that are
95 * not known (by gnutls) you should properly DER encode your data, and
96 * call this function with raw_flag set.
97 *
98 * Normally you do not need to call this function, since the signing
99 * operation will copy the signer's name as the issuer of the certificate.
100 *
101 * Returns 0 on success.
102 *
103 **/
104int
105gnutls_x509_crt_set_issuer_dn_by_oid (gnutls_x509_crt_t crt,
106 const char *oid,
107 unsigned int raw_flag,
108 const void *name,
109 unsigned int sizeof_name)
110{
111 if (sizeof_name == 0 || name == NULL || crt == NULL)
112 {
113 return GNUTLS_E_INVALID_REQUEST;
114 }
115
116 return _gnutls_x509_set_dn_oid (crt->cert, "tbsCertificate.issuer", oid,
117 raw_flag, name, sizeof_name);
118}
119
120/**
121 * gnutls_x509_crt_set_proxy_dn - Set Proxy Certificate subject's distinguished name
122 * @crt: a gnutls_x509_crt_t structure with the new proxy cert
123 * @eecrt: the end entity certificate that will be issuing the proxy
124 * @raw_flag: must be 0, or 1 if the CN is DER encoded
125 * @name: a pointer to the CN name, may be NULL (but MUST then be added later)
126 * @sizeof_name: holds the size of @name
127 *
128 * This function will set the subject in @crt to the end entity's
129 * @eecrt subject name, and add a single Common Name component @name
130 * of size @sizeof_name. This corresponds to the required proxy
131 * certificate naming style. Note that if @name is %NULL, you MUST
132 * set it later by using gnutls_x509_crt_set_dn_by_oid() or similar.
133 *
134 * Returns 0 on success.
135 *
136 **/
137int
138gnutls_x509_crt_set_proxy_dn (gnutls_x509_crt_t crt, gnutls_x509_crt_t eecrt,
139 unsigned int raw_flag, const void *name,
140 unsigned int sizeof_name)
141{
142 int result;
143
144 if (crt == NULL || eecrt == NULL)
145 {
146 return GNUTLS_E_INVALID_REQUEST;
147 }
148
149 result = asn1_copy_node (crt->cert, "tbsCertificate.subject",
150 eecrt->cert, "tbsCertificate.subject");
151 if (result != ASN1_SUCCESS)
152 {
153 gnutls_assert ();
154 return _gnutls_asn2err (result);
155 }
156
157 if (name && sizeof_name)
158 {
159 return _gnutls_x509_set_dn_oid (crt->cert, "tbsCertificate.subject",
160 GNUTLS_OID_X520_COMMON_NAME,
161 raw_flag, name, sizeof_name);
162 }
163
164 return 0;
165}
166
167/**
168 * gnutls_x509_crt_set_version - This function will set the Certificate request version
169 * @crt: should contain a gnutls_x509_crt_t structure
170 * @version: holds the version number. For X.509v1 certificates must be 1.
171 *
172 * This function will set the version of the certificate. This must
173 * be one for X.509 version 1, and so on. Plain certificates without
174 * extensions must have version set to one.
175 *
176 * To create well-formed certificates, you must specify version 3 if
177 * you use any certificate extensions. Extensions are created by
178 * functions such as gnutls_x509_crt_set_subject_alternative_name or
179 * gnutls_x509_crt_set_key_usage.
180 *
181 * Returns 0 on success.
182 *
183 **/
184int
185gnutls_x509_crt_set_version (gnutls_x509_crt_t crt, unsigned int version)
186{
187 int result;
188 unsigned char null = version;
189
190 if (crt == NULL)
191 {
192 gnutls_assert ();
193 return GNUTLS_E_INVALID_REQUEST;
194 }
195
196 if (null > 0)
197 null--;
198
199 result = asn1_write_value (crt->cert, "tbsCertificate.version", &null, 1);
200 if (result != ASN1_SUCCESS)
201 {
202 gnutls_assert ();
203 return _gnutls_asn2err (result);
204 }
205
206 return 0;
207}
208
209/**
210 * gnutls_x509_crt_set_key - This function will associate the Certificate with a key
211 * @crt: should contain a gnutls_x509_crt_t structure
212 * @key: holds a private key
213 *
214 * This function will set the public parameters from the given private key to the
215 * certificate. Only RSA keys are currently supported.
216 *
217 * Returns 0 on success.
218 *
219 **/
220int
221gnutls_x509_crt_set_key (gnutls_x509_crt_t crt, gnutls_x509_privkey_t key)
222{
223 int result;
224
225 if (crt == NULL)
226 {
227 gnutls_assert ();
228 return GNUTLS_E_INVALID_REQUEST;
229 }
230
231 result = _gnutls_x509_encode_and_copy_PKI_params (crt->cert,
232 "tbsCertificate.subjectPublicKeyInfo",
233 key->pk_algorithm,
234 key->params,
235 key->params_size);
236
237 if (result < 0)
238 {
239 gnutls_assert ();
240 return result;
241 }
242
243 return 0;
244}
245
246/**
247 * gnutls_x509_crt_set_crq - This function will associate the Certificate with a request
248 * @crt: should contain a gnutls_x509_crt_t structure
249 * @crq: holds a certificate request
250 *
251 * This function will set the name and public parameters from the given certificate request to the
252 * certificate. Only RSA keys are currently supported.
253 *
254 * Returns 0 on success.
255 *
256 **/
257int
258gnutls_x509_crt_set_crq (gnutls_x509_crt_t crt, gnutls_x509_crq_t crq)
259{
260 int result;
261 int pk_algorithm;
262
263 if (crt == NULL || crq == NULL)
264 {
265 gnutls_assert ();
266 return GNUTLS_E_INVALID_REQUEST;
267 }
268
269 pk_algorithm = gnutls_x509_crq_get_pk_algorithm (crq, NULL);
270
271 result = asn1_copy_node (crt->cert, "tbsCertificate.subject",
272 crq->crq, "certificationRequestInfo.subject");
273 if (result != ASN1_SUCCESS)
274 {
275 gnutls_assert ();
276 return _gnutls_asn2err (result);
277 }
278
279 result =
280 asn1_copy_node (crt->cert, "tbsCertificate.subjectPublicKeyInfo",
281 crq->crq, "certificationRequestInfo.subjectPKInfo");
282 if (result != ASN1_SUCCESS)
283 {
284 gnutls_assert ();
285 return _gnutls_asn2err (result);
286 }
287
288 return 0;
289}
290
291/**
292 * gnutls_x509_crt_set_extension_by_oid - This function will set an arbitrary extension
293 * @crt: should contain a gnutls_x509_crt_t structure
294 * @oid: holds an Object Identified in null terminated string
295 * @buf: a pointer to a DER encoded data
296 * @sizeof_buf: holds the size of @buf
297 * @critical: should be non zero if the extension is to be marked as critical
298 *
299 * This function will set an the extension, by the specified OID, in the certificate.
300 * The extension data should be binary data DER encoded.
301 *
302 * Returns 0 on success and a negative value in case of an error.
303 *
304 **/
305int
306gnutls_x509_crt_set_extension_by_oid (gnutls_x509_crt_t crt,
307 const char *oid, const void *buf,
308 size_t sizeof_buf,
309 unsigned int critical)
310{
311 int result;
312 gnutls_datum_t der_data;
313
314 der_data.data = (void *) buf;
315 der_data.size = sizeof_buf;
316
317 if (crt == NULL)
318 {
319 gnutls_assert ();
320 return GNUTLS_E_INVALID_REQUEST;
321 }
322
323 result = _gnutls_x509_crt_set_extension (crt, oid, &der_data, critical);
324 if (result < 0)
325 {
326 gnutls_assert ();
327 return result;
328 }
329
330 crt->use_extensions = 1;
331
332 return 0;
333
334}
335
336/**
337 * gnutls_x509_crt_set_basic_constraints - This function will set the basicConstraints extension
338 * @crt: should contain a gnutls_x509_crt_t structure
339 * @ca: true(1) or false(0). Depending on the Certificate authority status.
340 * @pathLenConstraint: non-negative values indicate maximum length of path,
341 * and negative values indicate that the pathLenConstraints field should
342 * not be present.
343 *
344 * This function will set the basicConstraints certificate extension.
345 *
346 * Returns 0 on success.
347 *
348 **/
349int
350gnutls_x509_crt_set_basic_constraints (gnutls_x509_crt_t crt,
351 unsigned int ca, int pathLenConstraint)
352{
353 int result;
354 gnutls_datum_t der_data;
355
356 if (crt == NULL)
357 {
358 gnutls_assert ();
359 return GNUTLS_E_INVALID_REQUEST;
360 }
361
362 /* generate the extension.
363 */
364 result = _gnutls_x509_ext_gen_basicConstraints (ca, pathLenConstraint,
365 &der_data);
366 if (result < 0)
367 {
368 gnutls_assert ();
369 return result;
370 }
371
372 result = _gnutls_x509_crt_set_extension (crt, "2.5.29.19", &der_data, 1);
373
374 _gnutls_free_datum (&der_data);
375
376 if (result < 0)
377 {
378 gnutls_assert ();
379 return result;
380 }
381
382 crt->use_extensions = 1;
383
384 return 0;
385}
386
387/**
388 * gnutls_x509_crt_set_ca_status - This function will set the basicConstraints extension
389 * @crt: should contain a gnutls_x509_crt_t structure
390 * @ca: true(1) or false(0). Depending on the Certificate authority status.
391 *
392 * This function will set the basicConstraints certificate extension.
393 * Use gnutls_x509_crt_set_basic_constraints() if you want to control
394 * the pathLenConstraint field too.
395 *
396 * Returns 0 on success.
397 *
398 **/
399int
400gnutls_x509_crt_set_ca_status (gnutls_x509_crt_t crt, unsigned int ca)
401{
402 return gnutls_x509_crt_set_basic_constraints (crt, ca, -1);
403}
404
405/**
406 * gnutls_x509_crt_set_key_usage - This function will set the keyUsage extension
407 * @crt: should contain a gnutls_x509_crt_t structure
408 * @usage: an ORed sequence of the GNUTLS_KEY_* elements.
409 *
410 * This function will set the keyUsage certificate extension.
411 *
412 * Returns 0 on success.
413 *
414 **/
415int
416gnutls_x509_crt_set_key_usage (gnutls_x509_crt_t crt, unsigned int usage)
417{
418 int result;
419 gnutls_datum_t der_data;
420
421 if (crt == NULL)
422 {
423 gnutls_assert ();
424 return GNUTLS_E_INVALID_REQUEST;
425 }
426
427 /* generate the extension.
428 */
429 result = _gnutls_x509_ext_gen_keyUsage ((uint16_t) usage, &der_data);
430 if (result < 0)
431 {
432 gnutls_assert ();
433 return result;
434 }
435
436 result = _gnutls_x509_crt_set_extension (crt, "2.5.29.15", &der_data, 1);
437
438 _gnutls_free_datum (&der_data);
439
440 if (result < 0)
441 {
442 gnutls_assert ();
443 return result;
444 }
445
446 crt->use_extensions = 1;
447
448 return 0;
449}
450
451/**
452 * gnutls_x509_crt_set_subject_alternative_name - This function will set the subject Alternative Name
453 * @crt: should contain a gnutls_x509_crt_t structure
454 * @type: is one of the gnutls_x509_subject_alt_name_t enumerations
455 * @data_string: The data to be set
456 *
457 * This function will set the subject alternative name certificate extension.
458 *
459 * Returns 0 on success.
460 *
461 **/
462int
463gnutls_x509_crt_set_subject_alternative_name (gnutls_x509_crt_t crt,
464 gnutls_x509_subject_alt_name_t
465 type, const char *data_string)
466{
467 int result;
468 gnutls_datum_t der_data;
469 gnutls_datum_t dnsname;
470 unsigned int critical;
471
472 if (crt == NULL)
473 {
474 gnutls_assert ();
475 return GNUTLS_E_INVALID_REQUEST;
476 }
477
478 /* Check if the extension already exists.
479 */
480 result =
481 _gnutls_x509_crt_get_extension (crt, "2.5.29.17", 0, &dnsname, &critical);
482
483 if (result >= 0)
484 _gnutls_free_datum (&dnsname);
485 if (result != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
486 {
487 gnutls_assert ();
488 return GNUTLS_E_INVALID_REQUEST;
489 }
490
491 /* generate the extension.
492 */
493 result =
494 _gnutls_x509_ext_gen_subject_alt_name (type, data_string, &der_data);
495 if (result < 0)
496 {
497 gnutls_assert ();
498 return result;
499 }
500
501 result = _gnutls_x509_crt_set_extension (crt, "2.5.29.17", &der_data, 0);
502
503 _gnutls_free_datum (&der_data);
504
505 if (result < 0)
506 {
507 gnutls_assert ();
508 return result;
509 }
510
511 crt->use_extensions = 1;
512
513 return 0;
514}
515
516/**
517 * gnutls_x509_crt_set_proxy - Set the proxyCertInfo extension
518 * @crt: should contain a gnutls_x509_crt_t structure
519 * @pathLenConstraint: non-negative values indicate maximum length of path,
520 * and negative values indicate that the pathLenConstraints field should
521 * not be present.
522 * @policyLanguage: OID describing the language of @policy.
523 * @policy: opaque byte array with policy language, can be %NULL
524 * @sizeof_policy: size of @policy.
525 *
526 * This function will set the proxyCertInfo extension.
527 *
528 * Returns 0 on success.
529 *
530 **/
531int
532gnutls_x509_crt_set_proxy (gnutls_x509_crt_t crt,
533 int pathLenConstraint,
534 const char *policyLanguage,
535 const char *policy, size_t sizeof_policy)
536{
537 int result;
538 gnutls_datum_t der_data;
539
540 if (crt == NULL)
541 {
542 gnutls_assert ();
543 return GNUTLS_E_INVALID_REQUEST;
544 }
545
546 /* generate the extension.
547 */
548 result = _gnutls_x509_ext_gen_proxyCertInfo (pathLenConstraint,
549 policyLanguage,
550 policy, sizeof_policy,
551 &der_data);
552 if (result < 0)
553 {
554 gnutls_assert ();
555 return result;
556 }
557
558 result = _gnutls_x509_crt_set_extension (crt, "1.3.6.1.5.5.7.1.14",
559 &der_data, 1);
560
561 _gnutls_free_datum (&der_data);
562
563 if (result < 0)
564 {
565 gnutls_assert ();
566 return result;
567 }
568
569 crt->use_extensions = 1;
570
571 return 0;
572}
573
574/**
575 * gnutls_x509_crt_sign2 - This function will sign a certificate with a key
576 * @crt: should contain a gnutls_x509_crt_t structure
577 * @issuer: is the certificate of the certificate issuer
578 * @issuer_key: holds the issuer's private key
579 * @dig: The message digest to use. GNUTLS_DIG_SHA1 is the safe choice unless you know what you're doing.
580 * @flags: must be 0
581 *
582 * This function will sign the certificate with the issuer's private key, and
583 * will copy the issuer's information into the certificate.
584 *
585 * This must be the last step in a certificate generation since all
586 * the previously set parameters are now signed.
587 *
588 * Returns 0 on success.
589 *
590 **/
591int
592gnutls_x509_crt_sign2 (gnutls_x509_crt_t crt, gnutls_x509_crt_t issuer,
593 gnutls_x509_privkey_t issuer_key,
594 gnutls_digest_algorithm_t dig, unsigned int flags)
595{
596 int result;
597
598 if (crt == NULL || issuer == NULL || issuer_key == NULL)
599 {
600 gnutls_assert ();
601 return GNUTLS_E_INVALID_REQUEST;
602 }
603
604 /* disable all the unneeded OPTIONAL fields.
605 */
606 disable_optional_stuff (crt);
607
608 result = _gnutls_x509_pkix_sign (crt->cert, "tbsCertificate",
609 dig, issuer, issuer_key);
610 if (result < 0)
611 {
612 gnutls_assert ();
613 return result;
614 }
615
616 return 0;
617}
618
619/**
620 * gnutls_x509_crt_sign - This function will sign a certificate with a key
621 * @crt: should contain a gnutls_x509_crt_t structure
622 * @issuer: is the certificate of the certificate issuer
623 * @issuer_key: holds the issuer's private key
624 *
625 * This function is the same a gnutls_x509_crt_sign2() with no flags, and
626 * SHA1 as the hash algorithm.
627 *
628 * Returns 0 on success.
629 *
630 **/
631int
632gnutls_x509_crt_sign (gnutls_x509_crt_t crt, gnutls_x509_crt_t issuer,
633 gnutls_x509_privkey_t issuer_key)
634{
635 return gnutls_x509_crt_sign2 (crt, issuer, issuer_key, GNUTLS_DIG_SHA1, 0);
636}
637
638/**
639 * gnutls_x509_crt_set_activation_time - This function will set the Certificate's activation time
640 * @cert: should contain a gnutls_x509_crt_t structure
641 * @act_time: The actual time
642 *
643 * This function will set the time this Certificate was or will be activated.
644 *
645 * Returns 0 on success, or a negative value in case of an error.
646 *
647 **/
648int
649gnutls_x509_crt_set_activation_time (gnutls_x509_crt_t cert, time_t act_time)
650{
651 if (cert == NULL)
652 {
653 gnutls_assert ();
654 return GNUTLS_E_INVALID_REQUEST;
655 }
656
657 return _gnutls_x509_set_time (cert->cert,
658 "tbsCertificate.validity.notBefore",
659 act_time);
660}
661
662/**
663 * gnutls_x509_crt_set_expiration_time - This function will set the Certificate's expiration time
664 * @cert: should contain a gnutls_x509_crt_t structure
665 * @exp_time: The actual time
666 *
667 * This function will set the time this Certificate will expire.
668 *
669 * Returns 0 on success, or a negative value in case of an error.
670 *
671 **/
672int
673gnutls_x509_crt_set_expiration_time (gnutls_x509_crt_t cert, time_t exp_time)
674{
675 if (cert == NULL)
676 {
677 gnutls_assert ();
678 return GNUTLS_E_INVALID_REQUEST;
679 }
680 return _gnutls_x509_set_time (cert->cert,
681 "tbsCertificate.validity.notAfter", exp_time);
682}
683
684/**
685 * gnutls_x509_crt_set_serial - This function will set the certificate's serial number
686 * @cert: should contain a gnutls_x509_crt_t structure
687 * @serial: The serial number
688 * @serial_size: Holds the size of the serial field.
689 *
690 * This function will set the X.509 certificate's serial number.
691 * Serial is not always a 32 or 64bit number. Some CAs use
692 * large serial numbers, thus it may be wise to handle it as something
693 * opaque.
694 *
695 * Returns 0 on success, or a negative value in case of an error.
696 *
697 **/
698int
699gnutls_x509_crt_set_serial (gnutls_x509_crt_t cert, const void *serial,
700 size_t serial_size)
701{
702 int ret;
703
704 if (cert == NULL)
705 {
706 gnutls_assert ();
707 return GNUTLS_E_INVALID_REQUEST;
708 }
709
710 ret =
711 asn1_write_value (cert->cert, "tbsCertificate.serialNumber", serial,
712 serial_size);
713 if (ret != ASN1_SUCCESS)
714 {
715 gnutls_assert ();
716 return _gnutls_asn2err (ret);
717 }
718
719 return 0;
720
721}
722
723/* If OPTIONAL fields have not been initialized then
724 * disable them.
725 */
726static void
727disable_optional_stuff (gnutls_x509_crt_t cert)
728{
729
730 asn1_write_value (cert->cert, "tbsCertificate.issuerUniqueID", NULL, 0);
731
732 asn1_write_value (cert->cert, "tbsCertificate.subjectUniqueID", NULL, 0);
733
734 if (cert->use_extensions == 0)
735 {
736 _gnutls_x509_log ("Disabling X.509 extensions.\n");
737 asn1_write_value (cert->cert, "tbsCertificate.extensions", NULL, 0);
738 }
739
740 return;
741}
742
743/**
744 * gnutls_x509_crt_set_crl_dist_points - This function will set the CRL dist points
745 * @crt: should contain a gnutls_x509_crt_t structure
746 * @type: is one of the gnutls_x509_subject_alt_name_t enumerations
747 * @data_string: The data to be set
748 * @reason_flags: revocation reasons
749 *
750 * This function will set the CRL distribution points certificate extension.
751 *
752 * Returns 0 on success.
753 *
754 **/
755int
756gnutls_x509_crt_set_crl_dist_points (gnutls_x509_crt_t crt,
757 gnutls_x509_subject_alt_name_t
758 type, const void *data_string,
759 unsigned int reason_flags)
760{
761 int result;
762 gnutls_datum_t der_data;
763 gnutls_datum_t oldname;
764 unsigned int critical;
765
766 if (crt == NULL)
767 {
768 gnutls_assert ();
769 return GNUTLS_E_INVALID_REQUEST;
770 }
771
772 /* Check if the extension already exists.
773 */
774 result =
775 _gnutls_x509_crt_get_extension (crt, "2.5.29.31", 0, &oldname, &critical);
776
777 if (result >= 0)
778 _gnutls_free_datum (&oldname);
779 if (result != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
780 {
781 gnutls_assert ();
782 return GNUTLS_E_INVALID_REQUEST;
783 }
784
785 /* generate the extension.
786 */
787 result =
788 _gnutls_x509_ext_gen_crl_dist_points (type, data_string,
789 reason_flags, &der_data);
790 if (result < 0)
791 {
792 gnutls_assert ();
793 return result;
794 }
795
796 result = _gnutls_x509_crt_set_extension (crt, "2.5.29.31", &der_data, 0);
797
798 _gnutls_free_datum (&der_data);
799
800 if (result < 0)
801 {
802 gnutls_assert ();
803 return result;
804 }
805
806 crt->use_extensions = 1;
807
808 return 0;
809}
810
811/**
812 * gnutls_x509_crt_cpy_crl_dist_points - This function will copy the CRL dist points
813 * @dst: should contain a gnutls_x509_crt_t structure
814 * @src: the certificate where the dist points will be copied from
815 *
816 * This function will copy the CRL distribution points certificate
817 * extension, from the source to the destination certificate.
818 * This may be useful to copy from a CA certificate to issued ones.
819 *
820 * Returns 0 on success.
821 *
822 **/
823int
824gnutls_x509_crt_cpy_crl_dist_points (gnutls_x509_crt_t dst,
825 gnutls_x509_crt_t src)
826{
827 int result;
828 gnutls_datum_t der_data;
829 unsigned int critical;
830
831 if (dst == NULL || src == NULL)
832 {
833 gnutls_assert ();
834 return GNUTLS_E_INVALID_REQUEST;
835 }
836
837 /* Check if the extension already exists.
838 */
839 result =
840 _gnutls_x509_crt_get_extension (src, "2.5.29.31", 0, &der_data,
841 &critical);
842 if (result < 0)
843 {
844 gnutls_assert ();
845 return result;
846 }
847
848 result =
849 _gnutls_x509_crt_set_extension (dst, "2.5.29.31", &der_data, critical);
850 _gnutls_free_datum (&der_data);
851
852 if (result < 0)
853 {
854 gnutls_assert ();
855 return result;
856 }
857
858 dst->use_extensions = 1;
859
860 return 0;
861}
862
863/**
864 * gnutls_x509_crt_set_subject_key_id - This function will set the certificate's subject key id
865 * @cert: should contain a gnutls_x509_crt_t structure
866 * @id: The key ID
867 * @id_size: Holds the size of the serial field.
868 *
869 * This function will set the X.509 certificate's subject key ID extension.
870 *
871 * Returns 0 on success, or a negative value in case of an error.
872 *
873 **/
874int
875gnutls_x509_crt_set_subject_key_id (gnutls_x509_crt_t cert,
876 const void *id, size_t id_size)
877{
878 int result;
879 gnutls_datum_t old_id, der_data;
880 unsigned int critical;
881
882 if (cert == NULL)
883 {
884 gnutls_assert ();
885 return GNUTLS_E_INVALID_REQUEST;
886 }
887
888 /* Check if the extension already exists.
889 */
890 result =
891 _gnutls_x509_crt_get_extension (cert, "2.5.29.14", 0, &old_id, &critical);
892
893 if (result >= 0)
894 _gnutls_free_datum (&old_id);
895 if (result != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
896 {
897 gnutls_assert ();
898 return GNUTLS_E_INVALID_REQUEST;
899 }
900
901 /* generate the extension.
902 */
903 result = _gnutls_x509_ext_gen_key_id (id, id_size, &der_data);
904 if (result < 0)
905 {
906 gnutls_assert ();
907 return result;
908 }
909
910 result = _gnutls_x509_crt_set_extension (cert, "2.5.29.14", &der_data, 0);
911
912 _gnutls_free_datum (&der_data);
913
914 if (result < 0)
915 {
916 gnutls_assert ();
917 return result;
918 }
919
920 cert->use_extensions = 1;
921
922 return 0;
923}
924
925/**
926 * gnutls_x509_crt_set_authority_key_id - This function will set the certificate authority's key id
927 * @cert: should contain a gnutls_x509_crt_t structure
928 * @id: The key ID
929 * @id_size: Holds the size of the serial field.
930 *
931 * This function will set the X.509 certificate's authority key ID extension.
932 * Only the keyIdentifier field can be set with this function.
933 *
934 * Returns 0 on success, or a negative value in case of an error.
935 *
936 **/
937int
938gnutls_x509_crt_set_authority_key_id (gnutls_x509_crt_t cert,
939 const void *id, size_t id_size)
940{
941 int result;
942 gnutls_datum_t old_id, der_data;
943 unsigned int critical;
944
945 if (cert == NULL)
946 {
947 gnutls_assert ();
948 return GNUTLS_E_INVALID_REQUEST;
949 }
950
951 /* Check if the extension already exists.
952 */
953 result =
954 _gnutls_x509_crt_get_extension (cert, "2.5.29.35", 0, &old_id, &critical);
955
956 if (result >= 0)
957 _gnutls_free_datum (&old_id);
958 if (result != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
959 {
960 gnutls_assert ();
961 return GNUTLS_E_INVALID_REQUEST;
962 }
963
964 /* generate the extension.
965 */
966 result = _gnutls_x509_ext_gen_auth_key_id (id, id_size, &der_data);
967 if (result < 0)
968 {
969 gnutls_assert ();
970 return result;
971 }
972
973 result = _gnutls_x509_crt_set_extension (cert, "2.5.29.35", &der_data, 0);
974
975 _gnutls_free_datum (&der_data);
976
977 if (result < 0)
978 {
979 gnutls_assert ();
980 return result;
981 }
982
983 cert->use_extensions = 1;
984
985 return 0;
986}
987
988/**
989 * gnutls_x509_crt_set_key_purpose_oid - This function sets the Certificate's key purpose OIDs
990 * @cert: should contain a gnutls_x509_crt_t structure
991 * @oid: a pointer to a null terminated string that holds the OID
992 * @critical: Whether this extension will be critical or not
993 *
994 * This function will set the key purpose OIDs of the Certificate.
995 * These are stored in the Extended Key Usage extension (2.5.29.37)
996 * See the GNUTLS_KP_* definitions for human readable names.
997 *
998 * Subsequent calls to this function will append OIDs to the OID list.
999 *
1000 * On success 0 is returned.
1001 *
1002 **/
1003int
1004gnutls_x509_crt_set_key_purpose_oid (gnutls_x509_crt_t cert,
1005 const void *oid, unsigned int critical)
1006{
1007 int result;
1008 gnutls_datum_t old_id, der_data;
1009 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
1010
1011 if (cert == NULL)
1012 {
1013 gnutls_assert ();
1014 return GNUTLS_E_INVALID_REQUEST;
1015 }
1016
1017 result = asn1_create_element
1018 (_gnutls_get_pkix (), "PKIX1.ExtKeyUsageSyntax", &c2);
1019 if (result != ASN1_SUCCESS)
1020 {
1021 gnutls_assert ();
1022 return _gnutls_asn2err (result);
1023 }
1024
1025 /* Check if the extension already exists.
1026 */
1027 result =
1028 _gnutls_x509_crt_get_extension (cert, "2.5.29.37", 0, &old_id, NULL);
1029
1030 if (result >= 0)
1031 {
1032 /* decode it.
1033 */
1034 result = asn1_der_decoding (&c2, old_id.data, old_id.size, NULL);
1035 _gnutls_free_datum (&old_id);
1036
1037 if (result != ASN1_SUCCESS)
1038 {
1039 gnutls_assert ();
1040 asn1_delete_structure (&c2);
1041 return _gnutls_asn2err (result);
1042 }
1043
1044 }
1045
1046 /* generate the extension.
1047 */
1048 /* 1. create a new element.
1049 */
1050 result = asn1_write_value (c2, "", "NEW", 1);
1051 if (result != ASN1_SUCCESS)
1052 {
1053 gnutls_assert ();
1054 asn1_delete_structure (&c2);
1055 return _gnutls_asn2err (result);
1056 }
1057
1058 /* 2. Add the OID.
1059 */
1060 result = asn1_write_value (c2, "?LAST", oid, 1);
1061 if (result != ASN1_SUCCESS)
1062 {
1063 gnutls_assert ();
1064 asn1_delete_structure (&c2);
1065 return _gnutls_asn2err (result);
1066 }
1067
1068 result = _gnutls_x509_der_encode (c2, "", &der_data, 0);
1069 asn1_delete_structure (&c2);
1070
1071 if (result != ASN1_SUCCESS)
1072 {
1073 gnutls_assert ();
1074 return _gnutls_asn2err (result);
1075 }
1076
1077 result = _gnutls_x509_crt_set_extension (cert, "2.5.29.37",
1078 &der_data, critical);
1079
1080 _gnutls_free_datum (&der_data);
1081
1082 if (result < 0)
1083 {
1084 gnutls_assert ();
1085 return result;
1086 }
1087
1088 cert->use_extensions = 1;
1089
1090 return 0;
1091
1092}
1093
1094#endif /* ENABLE_PKI */