aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2008-11-16 05:00:43 +0000
committerChristian Grothoff <christian@grothoff.org>2008-11-16 05:00:43 +0000
commit8fa092106e3f8d0213f8a2c7252524dd340f443e (patch)
treefca45ed5d6b454f6ec9d4f84ffae59204ff661ce
parent26766bf6f7a161b7df8170d5e8f1a088da13f12c (diff)
downloadlibmicrohttpd-8fa092106e3f8d0213f8a2c7252524dd340f443e.tar.gz
libmicrohttpd-8fa092106e3f8d0213f8a2c7252524dd340f443e.zip
even more dce
-rw-r--r--src/daemon/https/x509/Makefile.am1
-rw-r--r--src/daemon/https/x509/dn.c545
-rw-r--r--src/daemon/https/x509/dn.h52
-rw-r--r--src/daemon/https/x509/x509.c622
-rw-r--r--src/daemon/https/x509/x509.h69
-rw-r--r--src/daemon/https/x509/x509_privkey.c544
6 files changed, 0 insertions, 1833 deletions
diff --git a/src/daemon/https/x509/Makefile.am b/src/daemon/https/x509/Makefile.am
index 9091fc4f..d5f64286 100644
--- a/src/daemon/https/x509/Makefile.am
+++ b/src/daemon/https/x509/Makefile.am
@@ -18,7 +18,6 @@ libx509_la_LDFLAGS = -lgcrypt
18 18
19libx509_la_SOURCES = \ 19libx509_la_SOURCES = \
20common.c common.h \ 20common.c common.h \
21dn.c dn.h \
22extensions.c extensions.h \ 21extensions.c extensions.h \
23mpi.c mpi.h \ 22mpi.c mpi.h \
24pkcs12.h \ 23pkcs12.h \
diff --git a/src/daemon/https/x509/dn.c b/src/daemon/https/x509/dn.c
deleted file mode 100644
index fb4fa57e..00000000
--- a/src/daemon/https/x509/dn.c
+++ /dev/null
@@ -1,545 +0,0 @@
1/*
2 * Copyright (C) 2003, 2004, 2005, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25#include <gnutls_int.h>
26#include <libtasn1.h>
27#include <gnutls_datum.h>
28#include <gnutls_global.h>
29#include <gnutls_errors.h>
30#include <gnutls_str.h>
31#include <common.h>
32#include <gnutls_num.h>
33#include <dn.h>
34
35/* This file includes all the required to parse an X.509 Distriguished
36 * Name (you need a parser just to read a name in the X.509 protoocols!!!)
37 */
38
39/* Converts the given OID to an ldap acceptable string or
40 * a dotted OID.
41 */
42static const char *
43oid2ldap_string (const char *oid)
44{
45 const char *ret;
46
47 ret = MHD__gnutls_x509_oid2ldap_string (oid);
48 if (ret)
49 return ret;
50
51 /* else return the OID in dotted format */
52 return oid;
53}
54
55/* Escapes a string following the rules from RFC2253.
56 */
57static char *
58str_escape (char *str, char *buffer, unsigned int buffer_size)
59{
60 int str_length, j, i;
61
62 if (str == NULL || buffer == NULL)
63 return NULL;
64
65 str_length = MIN (strlen (str), buffer_size - 1);
66
67 for (i = j = 0; i < str_length; i++)
68 {
69 if (str[i] == ',' || str[i] == '+' || str[i] == '"'
70 || str[i] == '\\' || str[i] == '<' || str[i] == '>'
71 || str[i] == ';')
72 buffer[j++] = '\\';
73
74 buffer[j++] = str[i];
75 }
76
77 /* null terminate the string */
78 buffer[j] = 0;
79
80 return buffer;
81}
82
83/* Parses an X509 DN in the MHD__asn1_struct, and puts the output into
84 * the string buf. The output is an LDAP encoded DN.
85 *
86 * MHD__asn1_rdn_name must be a string in the form "tbsCertificate.issuer.rdnSequence".
87 * That is to point in the rndSequence.
88 */
89int
90MHD__gnutls_x509_parse_dn (ASN1_TYPE MHD__asn1_struct,
91 const char *MHD__asn1_rdn_name, char *buf,
92 size_t * sizeof_buf)
93{
94 MHD_gtls_string out_str;
95 int k2, k1, result;
96 char tmpbuffer1[MAX_NAME_SIZE];
97 char tmpbuffer2[MAX_NAME_SIZE];
98 char tmpbuffer3[MAX_NAME_SIZE];
99 opaque value[MAX_STRING_LEN], *value2 = NULL;
100 char *escaped = NULL;
101 const char *ldap_desc;
102 char oid[128];
103 int len, printable;
104 char *string = NULL;
105 size_t sizeof_string, sizeof_escaped;
106
107 if (sizeof_buf == NULL)
108 {
109 MHD_gnutls_assert ();
110 return GNUTLS_E_INVALID_REQUEST;
111 }
112
113 if (*sizeof_buf > 0 && buf)
114 buf[0] = 0;
115 else
116 *sizeof_buf = 0;
117
118 MHD_gtls_string_init (&out_str, MHD_gnutls_malloc, MHD_gnutls_realloc,
119 MHD_gnutls_free);
120
121 k1 = 0;
122 do
123 {
124
125 k1++;
126 /* create a string like "tbsCertList.issuer.rdnSequence.?1"
127 */
128 if (MHD__asn1_rdn_name[0] != 0)
129 snprintf (tmpbuffer1, sizeof (tmpbuffer1), "%s.?%u",
130 MHD__asn1_rdn_name, k1);
131 else
132 snprintf (tmpbuffer1, sizeof (tmpbuffer1), "?%u", k1);
133
134 len = sizeof (value) - 1;
135 result =
136 MHD__asn1_read_value (MHD__asn1_struct, tmpbuffer1, value, &len);
137
138 if (result == ASN1_ELEMENT_NOT_FOUND)
139 {
140 break;
141 }
142
143 if (result != ASN1_VALUE_NOT_FOUND)
144 {
145 MHD_gnutls_assert ();
146 result = MHD_gtls_asn2err (result);
147 goto cleanup;
148 }
149
150 k2 = 0;
151
152 do
153 { /* Move to the attibute type and values
154 */
155 k2++;
156
157 if (tmpbuffer1[0] != 0)
158 snprintf (tmpbuffer2, sizeof (tmpbuffer2), "%s.?%u", tmpbuffer1,
159 k2);
160 else
161 snprintf (tmpbuffer2, sizeof (tmpbuffer2), "?%u", k2);
162
163 /* Try to read the RelativeDistinguishedName attributes.
164 */
165
166 len = sizeof (value) - 1;
167 result =
168 MHD__asn1_read_value (MHD__asn1_struct, tmpbuffer2, value, &len);
169
170 if (result == ASN1_ELEMENT_NOT_FOUND)
171 break;
172 if (result != ASN1_VALUE_NOT_FOUND)
173 {
174 MHD_gnutls_assert ();
175 result = MHD_gtls_asn2err (result);
176 goto cleanup;
177 }
178
179 /* Read the OID
180 */
181 MHD_gtls_str_cpy (tmpbuffer3, sizeof (tmpbuffer3), tmpbuffer2);
182 MHD_gtls_str_cat (tmpbuffer3, sizeof (tmpbuffer3), ".type");
183
184 len = sizeof (oid) - 1;
185 result =
186 MHD__asn1_read_value (MHD__asn1_struct, tmpbuffer3, oid, &len);
187
188 if (result == ASN1_ELEMENT_NOT_FOUND)
189 break;
190 else if (result != ASN1_SUCCESS)
191 {
192 MHD_gnutls_assert ();
193 result = MHD_gtls_asn2err (result);
194 goto cleanup;
195 }
196
197 /* Read the Value
198 */
199 MHD_gtls_str_cpy (tmpbuffer3, sizeof (tmpbuffer3), tmpbuffer2);
200 MHD_gtls_str_cat (tmpbuffer3, sizeof (tmpbuffer3), ".value");
201
202 len = 0;
203 result =
204 MHD__asn1_read_value (MHD__asn1_struct, tmpbuffer3, NULL, &len);
205
206 value2 = MHD_gnutls_malloc (len);
207 if (value2 == NULL)
208 {
209 MHD_gnutls_assert ();
210 result = GNUTLS_E_MEMORY_ERROR;
211 goto cleanup;
212 }
213
214 result =
215 MHD__asn1_read_value (MHD__asn1_struct, tmpbuffer3, value2, &len);
216
217 if (result != ASN1_SUCCESS)
218 {
219 MHD_gnutls_assert ();
220 result = MHD_gtls_asn2err (result);
221 goto cleanup;
222 }
223#define STR_APPEND(y) if ((result=MHD_gtls_string_append_str( &out_str, y)) < 0) { \
224 MHD_gnutls_assert(); \
225 goto cleanup; \
226}
227 /* The encodings of adjoining RelativeDistinguishedNames are separated
228 * by a comma character (',' ASCII 44).
229 */
230
231 /* Where there is a multi-valued RDN, the outputs from adjoining
232 * AttributeTypeAndValues are separated by a plus ('+' ASCII 43)
233 * character.
234 */
235 if (k1 != 1)
236 { /* the first time do not append a comma */
237 if (k2 != 1)
238 { /* adjoining multi-value RDN */
239 STR_APPEND ("+");
240 }
241 else
242 {
243 STR_APPEND (",");
244 }
245 }
246
247 ldap_desc = oid2ldap_string (oid);
248 printable = MHD__gnutls_x509_oid_data_printable (oid);
249
250 sizeof_escaped = 2 * len + 1;
251
252 escaped = MHD_gnutls_malloc (sizeof_escaped);
253 if (escaped == NULL)
254 {
255 MHD_gnutls_assert ();
256 result = GNUTLS_E_MEMORY_ERROR;
257 goto cleanup;
258 }
259
260 sizeof_string = 2 * len + 2; /* in case it is not printable */
261
262 string = MHD_gnutls_malloc (sizeof_string);
263 if (string == NULL)
264 {
265 MHD_gnutls_assert ();
266 result = GNUTLS_E_MEMORY_ERROR;
267 goto cleanup;
268 }
269
270 STR_APPEND (ldap_desc);
271 STR_APPEND ("=");
272 result = 0;
273
274 if (printable)
275 result =
276 MHD__gnutls_x509_oid_data2string (oid,
277 value2, len,
278 string, &sizeof_string);
279
280 if (!printable || result < 0)
281 result =
282 MHD__gnutls_x509_data2hex ((const unsigned char *) value2, len,
283 (unsigned char *) string,
284 &sizeof_string);
285
286 if (result < 0)
287 {
288 MHD_gnutls_assert ();
289 MHD__gnutls_x509_log
290 ("Found OID: '%s' with value '%s'\n",
291 oid, MHD_gtls_bin2hex (value2, len, escaped,
292 sizeof_escaped));
293 goto cleanup;
294 }
295 STR_APPEND (str_escape (string, escaped, sizeof_escaped));
296 MHD_gnutls_free (string);
297 string = NULL;
298
299 MHD_gnutls_free (escaped);
300 escaped = NULL;
301 MHD_gnutls_free (value2);
302 value2 = NULL;
303
304 }
305 while (1);
306
307 }
308 while (1);
309
310 if (out_str.length >= (unsigned int) *sizeof_buf)
311 {
312 MHD_gnutls_assert ();
313 *sizeof_buf = out_str.length + 1;
314 result = GNUTLS_E_SHORT_MEMORY_BUFFER;
315 goto cleanup;
316 }
317
318 if (buf)
319 {
320 memcpy (buf, out_str.data, out_str.length);
321 buf[out_str.length] = 0;
322 }
323 *sizeof_buf = out_str.length;
324
325 result = 0;
326
327cleanup:
328 MHD_gnutls_free (value2);
329 MHD_gnutls_free (string);
330 MHD_gnutls_free (escaped);
331 MHD_gtls_string_clear (&out_str);
332 return result;
333}
334
335/* Parses an X509 DN in the MHD__asn1_struct, and searches for the
336 * given OID in the DN.
337 *
338 * If raw_flag == 0, the output will be encoded in the LDAP way. (#hex for non printable)
339 * Otherwise the raw DER data are returned.
340 *
341 * MHD__asn1_rdn_name must be a string in the form "tbsCertificate.issuer.rdnSequence".
342 * That is to point in the rndSequence.
343 *
344 * indx specifies which OID to return. Ie 0 means return the first specified
345 * OID found, 1 the second etc.
346 */
347int
348MHD__gnutls_x509_parse_dn_oid (ASN1_TYPE MHD__asn1_struct,
349 const char *MHD__asn1_rdn_name,
350 const char *given_oid, int indx,
351 unsigned int raw_flag,
352 void *buf, size_t * sizeof_buf)
353{
354 int k2, k1, result;
355 char tmpbuffer1[MAX_NAME_SIZE];
356 char tmpbuffer2[MAX_NAME_SIZE];
357 char tmpbuffer3[MAX_NAME_SIZE];
358 opaque value[256];
359 char oid[128];
360 int len, printable;
361 int i = 0;
362 char *cbuf = buf;
363
364 if (cbuf == NULL)
365 *sizeof_buf = 0;
366 else
367 cbuf[0] = 0;
368
369 k1 = 0;
370 do
371 {
372
373 k1++;
374 /* create a string like "tbsCertList.issuer.rdnSequence.?1"
375 */
376 if (MHD__asn1_rdn_name[0] != 0)
377 snprintf (tmpbuffer1, sizeof (tmpbuffer1), "%s.?%u",
378 MHD__asn1_rdn_name, k1);
379 else
380 snprintf (tmpbuffer1, sizeof (tmpbuffer1), "?%u", k1);
381
382 len = sizeof (value) - 1;
383 result =
384 MHD__asn1_read_value (MHD__asn1_struct, tmpbuffer1, value, &len);
385
386 if (result == ASN1_ELEMENT_NOT_FOUND)
387 {
388 MHD_gnutls_assert ();
389 break;
390 }
391
392 if (result != ASN1_VALUE_NOT_FOUND)
393 {
394 MHD_gnutls_assert ();
395 result = MHD_gtls_asn2err (result);
396 goto cleanup;
397 }
398
399 k2 = 0;
400
401 do
402 { /* Move to the attibute type and values
403 */
404 k2++;
405
406 if (tmpbuffer1[0] != 0)
407 snprintf (tmpbuffer2, sizeof (tmpbuffer2), "%s.?%u", tmpbuffer1,
408 k2);
409 else
410 snprintf (tmpbuffer2, sizeof (tmpbuffer2), "?%u", k2);
411
412 /* Try to read the RelativeDistinguishedName attributes.
413 */
414
415 len = sizeof (value) - 1;
416 result =
417 MHD__asn1_read_value (MHD__asn1_struct, tmpbuffer2, value, &len);
418
419 if (result == ASN1_ELEMENT_NOT_FOUND)
420 {
421 break;
422 }
423 if (result != ASN1_VALUE_NOT_FOUND)
424 {
425 MHD_gnutls_assert ();
426 result = MHD_gtls_asn2err (result);
427 goto cleanup;
428 }
429
430 /* Read the OID
431 */
432 MHD_gtls_str_cpy (tmpbuffer3, sizeof (tmpbuffer3), tmpbuffer2);
433 MHD_gtls_str_cat (tmpbuffer3, sizeof (tmpbuffer3), ".type");
434
435 len = sizeof (oid) - 1;
436 result =
437 MHD__asn1_read_value (MHD__asn1_struct, tmpbuffer3, oid, &len);
438
439 if (result == ASN1_ELEMENT_NOT_FOUND)
440 break;
441 else if (result != ASN1_SUCCESS)
442 {
443 MHD_gnutls_assert ();
444 result = MHD_gtls_asn2err (result);
445 goto cleanup;
446 }
447
448 if (strcmp (oid, given_oid) == 0 && indx == i++)
449 { /* Found the OID */
450
451 /* Read the Value
452 */
453 MHD_gtls_str_cpy (tmpbuffer3, sizeof (tmpbuffer3), tmpbuffer2);
454 MHD_gtls_str_cat (tmpbuffer3, sizeof (tmpbuffer3), ".value");
455
456 len = *sizeof_buf;
457 result =
458 MHD__asn1_read_value (MHD__asn1_struct, tmpbuffer3, buf,
459 &len);
460
461 if (result != ASN1_SUCCESS)
462 {
463 MHD_gnutls_assert ();
464 if (result == ASN1_MEM_ERROR)
465 *sizeof_buf = len;
466 result = MHD_gtls_asn2err (result);
467 goto cleanup;
468 }
469
470 if (raw_flag != 0)
471 {
472 if ((unsigned) len > *sizeof_buf)
473 {
474 *sizeof_buf = len;
475 result = GNUTLS_E_SHORT_MEMORY_BUFFER;
476 goto cleanup;
477 }
478 *sizeof_buf = len;
479
480 return 0;
481
482 }
483 else
484 { /* parse data. raw_flag == 0 */
485 printable = MHD__gnutls_x509_oid_data_printable (oid);
486
487 if (printable == 1)
488 result =
489 MHD__gnutls_x509_oid_data2string (oid, buf, len,
490 cbuf, sizeof_buf);
491 else
492 result =
493 MHD__gnutls_x509_data2hex (buf, len,
494 (unsigned char *) cbuf,
495 sizeof_buf);
496
497 if (result < 0)
498 {
499 MHD_gnutls_assert ();
500 goto cleanup;
501 }
502
503 return 0;
504
505 } /* raw_flag == 0 */
506 }
507 }
508 while (1);
509
510 }
511 while (1);
512
513 MHD_gnutls_assert ();
514
515 result = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
516
517cleanup:
518 return result;
519}
520
521/*
522 * Compares the DER encoded part of a DN.
523 *
524 * FIXME: use a real DN comparison algorithm.
525 *
526 * Returns 1 if the DN's match and zero if they don't match. Otherwise
527 * a negative value is returned to indicate error.
528 */
529int
530MHD__gnutls_x509_compare_raw_dn (const MHD_gnutls_datum_t * dn1,
531 const MHD_gnutls_datum_t * dn2)
532{
533
534 if (dn1->size != dn2->size)
535 {
536 MHD_gnutls_assert ();
537 return 0;
538 }
539 if (memcmp (dn1->data, dn2->data, dn2->size) != 0)
540 {
541 MHD_gnutls_assert ();
542 return 0;
543 }
544 return 1; /* they match */
545}
diff --git a/src/daemon/https/x509/dn.h b/src/daemon/https/x509/dn.h
deleted file mode 100644
index cc226871..00000000
--- a/src/daemon/https/x509/dn.h
+++ /dev/null
@@ -1,52 +0,0 @@
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 MHD__gnutls_x509_parse_dn (ASN1_TYPE MHD__asn1_struct,
41 const char *MHD__asn1_rdn_name, char *buf,
42 size_t * sizeof_buf);
43
44int MHD__gnutls_x509_parse_dn_oid (ASN1_TYPE MHD__asn1_struct,
45 const char *MHD__asn1_rdn_name,
46 const char *oid, int indx,
47 unsigned int raw_flag, void *buf,
48 size_t * sizeof_buf);
49
50
51
52#endif
diff --git a/src/daemon/https/x509/x509.c b/src/daemon/https/x509/x509.c
index 8e3135c8..9ce1e76d 100644
--- a/src/daemon/https/x509/x509.c
+++ b/src/daemon/https/x509/x509.c
@@ -32,7 +32,6 @@
32#include <gnutls_x509.h> 32#include <gnutls_x509.h>
33#include <x509_b64.h> 33#include <x509_b64.h>
34#include <x509.h> 34#include <x509.h>
35#include <dn.h>
36#include <extensions.h> 35#include <extensions.h>
37#include <libtasn1.h> 36#include <libtasn1.h>
38#include <mpi.h> 37#include <mpi.h>
@@ -178,148 +177,6 @@ cleanup:MHD_gnutls_free (signature);
178} 177}
179 178
180/** 179/**
181 * MHD_gnutls_x509_crt_get_dn_by_oid - This function returns the Certificate's distinguished name
182 * @cert: should contain a MHD_gnutls_x509_crt_t structure
183 * @oid: holds an Object Identified in null terminated string
184 * @indx: In case multiple same OIDs exist in the RDN, this specifies which to send. Use zero to get the first one.
185 * @raw_flag: If non zero returns the raw DER data of the DN part.
186 * @buf: a pointer where the DN part will be copied (may be null).
187 * @sizeof_buf: initially holds the size of @buf
188 *
189 * This function will extract the part of the name of the Certificate
190 * subject specified by the given OID. The output, if the raw flag is not
191 * used, will be encoded as described in RFC2253. Thus a string that is
192 * ASCII or UTF-8 encoded, depending on the certificate data.
193 *
194 * Some helper macros with popular OIDs can be found in gnutls/x509.h
195 * If raw flag is zero, this function will only return known OIDs as
196 * text. Other OIDs will be DER encoded, as described in RFC2253 --
197 * in hex format with a '\#' prefix. You can check about known OIDs
198 * using MHD_gnutls_x509_dn_oid_known().
199 *
200 * If @buf is null then only the size will be filled.
201 *
202 * Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
203 * long enough, and in that case the *sizeof_buf will be updated with
204 * the required size. On success 0 is returned.
205 *
206 **/
207int
208MHD_gnutls_x509_crt_get_dn_by_oid (MHD_gnutls_x509_crt_t cert,
209 const char *oid,
210 int indx,
211 unsigned int raw_flag,
212 void *buf, size_t * sizeof_buf)
213{
214 if (cert == NULL)
215 {
216 MHD_gnutls_assert ();
217 return GNUTLS_E_INVALID_REQUEST;
218 }
219
220 return MHD__gnutls_x509_parse_dn_oid (cert->cert,
221 "tbsCertificate.subject.rdnSequence",
222 oid, indx, raw_flag, buf, sizeof_buf);
223}
224
225/**
226 * MHD_gnutls_x509_crt_get_signature_algorithm - This function returns the Certificate's signature algorithm
227 * @cert: should contain a MHD_gnutls_x509_crt_t structure
228 *
229 * This function will return a value of the MHD_gnutls_sign_algorithm_t enumeration that
230 * is the signature algorithm.
231 *
232 * Returns a negative value on error.
233 *
234 **/
235int
236MHD_gnutls_x509_crt_get_signature_algorithm (MHD_gnutls_x509_crt_t cert)
237{
238 int result;
239 MHD_gnutls_datum_t sa;
240
241 if (cert == NULL)
242 {
243 MHD_gnutls_assert ();
244 return GNUTLS_E_INVALID_REQUEST;
245 }
246
247 /* Read the signature algorithm. Note that parameters are not
248 * read. They will be read from the issuer's certificate if needed.
249 */
250 result =
251 MHD__gnutls_x509_read_value (cert->cert, "signatureAlgorithm.algorithm",
252 &sa, 0);
253
254 if (result < 0)
255 {
256 MHD_gnutls_assert ();
257 return result;
258 }
259
260 result = MHD_gtls_x509_oid2sign_algorithm ((const char *) sa.data);
261
262 MHD__gnutls_free_datum (&sa);
263
264 return result;
265}
266
267/**
268 * MHD_gnutls_x509_crt_get_signature - Returns the Certificate's signature
269 * @cert: should contain a MHD_gnutls_x509_crt_t structure
270 * @sig: a pointer where the signature part will be copied (may be null).
271 * @sizeof_sig: initially holds the size of @sig
272 *
273 * This function will extract the signature field of a certificate.
274 *
275 * Returns 0 on success, and a negative value on error.
276 **/
277int
278MHD_gnutls_x509_crt_get_signature (MHD_gnutls_x509_crt_t cert,
279 char *sig, size_t * sizeof_sig)
280{
281 int result;
282 int bits, len;
283
284 if (cert == NULL)
285 {
286 MHD_gnutls_assert ();
287 return GNUTLS_E_INVALID_REQUEST;
288 }
289
290 bits = 0;
291 result = MHD__asn1_read_value (cert->cert, "signature", NULL, &bits);
292 if (result != ASN1_MEM_ERROR)
293 {
294 MHD_gnutls_assert ();
295 return MHD_gtls_asn2err (result);
296 }
297
298 if (bits % 8 != 0)
299 {
300 MHD_gnutls_assert ();
301 return GNUTLS_E_CERTIFICATE_ERROR;
302 }
303
304 len = bits / 8;
305
306 if (*sizeof_sig < len)
307 {
308 *sizeof_sig = bits / 8;
309 return GNUTLS_E_SHORT_MEMORY_BUFFER;
310 }
311
312 result = MHD__asn1_read_value (cert->cert, "signature", sig, &len);
313 if (result != ASN1_SUCCESS)
314 {
315 MHD_gnutls_assert ();
316 return MHD_gtls_asn2err (result);
317 }
318
319 return 0;
320}
321
322/**
323 * MHD_gnutls_x509_crt_get_version - This function returns the Certificate's version number 180 * MHD_gnutls_x509_crt_get_version - This function returns the Certificate's version number
324 * @cert: should contain a MHD_gnutls_x509_crt_t structure 181 * @cert: should contain a MHD_gnutls_x509_crt_t structure
325 * 182 *
@@ -400,50 +257,6 @@ MHD_gnutls_x509_crt_get_expiration_time (MHD_gnutls_x509_crt_t cert)
400} 257}
401 258
402/** 259/**
403 * MHD_gnutls_x509_crt_get_serial - This function returns the certificate's serial number
404 * @cert: should contain a MHD_gnutls_x509_crt_t structure
405 * @result: The place where the serial number will be copied
406 * @result_size: Holds the size of the result field.
407 *
408 * This function will return the X.509 certificate's serial number.
409 * This is obtained by the X509 Certificate serialNumber
410 * field. Serial is not always a 32 or 64bit number. Some CAs use
411 * large serial numbers, thus it may be wise to handle it as something
412 * opaque.
413 *
414 * Returns 0 on success and a negative value in case of an error.
415 *
416 **/
417int
418MHD_gnutls_x509_crt_get_serial (MHD_gnutls_x509_crt_t cert,
419 void *result, size_t * result_size)
420{
421 int ret, len;
422
423 if (cert == NULL)
424 {
425 MHD_gnutls_assert ();
426 return GNUTLS_E_INVALID_REQUEST;
427 }
428
429 len = *result_size;
430 ret
431 =
432 MHD__asn1_read_value (cert->cert, "tbsCertificate.serialNumber", result,
433 &len);
434 *result_size = len;
435
436 if (ret != ASN1_SUCCESS)
437 {
438 MHD_gnutls_assert ();
439 return MHD_gtls_asn2err (ret);
440 }
441
442 return 0;
443}
444
445
446/**
447 * MHD_gnutls_x509_crt_get_pk_algorithm - This function returns the certificate's PublicKey algorithm 260 * MHD_gnutls_x509_crt_get_pk_algorithm - This function returns the certificate's PublicKey algorithm
448 * @cert: should contain a MHD_gnutls_x509_crt_t structure 261 * @cert: should contain a MHD_gnutls_x509_crt_t structure
449 * @bits: if bits is non null it will hold the size of the parameters' in bits 262 * @bits: if bits is non null it will hold the size of the parameters' in bits
@@ -496,396 +309,6 @@ is_type_printable (int type)
496 return 0; 309 return 0;
497} 310}
498 311
499#define XMPP_OID "1.3.6.1.5.5.7.8.5"
500
501/* returns the type and the name on success.
502 * Type is also returned as a parameter in case of an error.
503 */
504static int
505parse_general_name (ASN1_TYPE src,
506 const char *src_name,
507 int seq,
508 void *name,
509 size_t * name_size,
510 unsigned int *ret_type, int othername_oid)
511{
512 int len;
513 char nptr[MAX_NAME_SIZE];
514 int result;
515 opaque choice_type[128];
516 MHD_gnutls_x509_subject_alt_name_t type;
517
518 seq++; /* 0->1, 1->2 etc */
519
520 if (src_name[0] != 0)
521 snprintf (nptr, sizeof (nptr), "%s.?%u", src_name, seq);
522 else
523 snprintf (nptr, sizeof (nptr), "?%u", seq);
524
525 len = sizeof (choice_type);
526 result = MHD__asn1_read_value (src, nptr, choice_type, &len);
527
528 if (result == ASN1_VALUE_NOT_FOUND || result == ASN1_ELEMENT_NOT_FOUND)
529 {
530 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
531 }
532
533 if (result != ASN1_SUCCESS)
534 {
535 MHD_gnutls_assert ();
536 return MHD_gtls_asn2err (result);
537 }
538
539 type = MHD__gnutls_x509_san_find_type ((char *) choice_type);
540 if (type == (MHD_gnutls_x509_subject_alt_name_t) - 1)
541 {
542 MHD_gnutls_assert ();
543 return GNUTLS_E_X509_UNKNOWN_SAN;
544 }
545
546 if (ret_type)
547 *ret_type = type;
548
549 if (type == GNUTLS_SAN_OTHERNAME)
550 {
551 if (othername_oid)
552 MHD_gtls_str_cat (nptr, sizeof (nptr), ".otherName.type-id");
553 else
554 MHD_gtls_str_cat (nptr, sizeof (nptr), ".otherName.value");
555
556 len = *name_size;
557 result = MHD__asn1_read_value (src, nptr, name, &len);
558 *name_size = len;
559
560 if (result == ASN1_MEM_ERROR)
561 return GNUTLS_E_SHORT_MEMORY_BUFFER;
562
563 if (result != ASN1_SUCCESS)
564 {
565 MHD_gnutls_assert ();
566 return MHD_gtls_asn2err (result);
567 }
568
569 if (othername_oid)
570 {
571 if (len > strlen (XMPP_OID) && strcmp (name, XMPP_OID) == 0)
572 type = GNUTLS_SAN_OTHERNAME_XMPP;
573 }
574 else
575 {
576 char oid[42];
577
578 if (src_name[0] != 0)
579 snprintf (nptr, sizeof (nptr), "%s.?%u.otherName.type-id",
580 src_name, seq);
581 else
582 snprintf (nptr, sizeof (nptr), "?%u.otherName.type-id", seq);
583
584 len = sizeof (oid);
585 result = MHD__asn1_read_value (src, nptr, oid, &len);
586 if (result != ASN1_SUCCESS)
587 {
588 MHD_gnutls_assert ();
589 return MHD_gtls_asn2err (result);
590 }
591
592 if (len > strlen (XMPP_OID) && strcmp (oid, XMPP_OID) == 0)
593 {
594 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
595
596 result =
597 MHD__asn1_create_element (MHD__gnutls_get_pkix (),
598 "PKIX1.XmppAddr", &c2);
599 if (result != ASN1_SUCCESS)
600 {
601 MHD_gnutls_assert ();
602 return MHD_gtls_asn2err (result);
603 }
604
605 result = MHD__asn1_der_decoding (&c2, name, *name_size, NULL);
606 if (result != ASN1_SUCCESS)
607 {
608 MHD_gnutls_assert ();
609 MHD__asn1_delete_structure (&c2);
610 return MHD_gtls_asn2err (result);
611 }
612
613 result = MHD__asn1_read_value (c2, "", name, &len);
614 *name_size = len;
615 if (result != ASN1_SUCCESS)
616 {
617 MHD_gnutls_assert ();
618 MHD__asn1_delete_structure (&c2);
619 return MHD_gtls_asn2err (result);
620 }
621 MHD__asn1_delete_structure (&c2);
622 }
623 }
624 }
625 else if (type == GNUTLS_SAN_DN)
626 {
627 MHD_gtls_str_cat (nptr, sizeof (nptr), ".directoryName");
628 result = MHD__gnutls_x509_parse_dn (src, nptr, name, name_size);
629 if (result < 0)
630 {
631 MHD_gnutls_assert ();
632 return result;
633 }
634 }
635 else if (othername_oid)
636 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
637 else
638 {
639 size_t orig_name_size = *name_size;
640
641 MHD_gtls_str_cat (nptr, sizeof (nptr), ".");
642 MHD_gtls_str_cat (nptr, sizeof (nptr), (const char *) choice_type);
643
644 len = *name_size;
645 result = MHD__asn1_read_value (src, nptr, name, &len);
646 *name_size = len;
647
648 if (result == ASN1_MEM_ERROR)
649 {
650 if (is_type_printable (type))
651 (*name_size)++;
652 return GNUTLS_E_SHORT_MEMORY_BUFFER;
653 }
654
655 if (result != ASN1_SUCCESS)
656 {
657 MHD_gnutls_assert ();
658 return MHD_gtls_asn2err (result);
659 }
660
661 if (is_type_printable (type))
662 {
663
664 if (len + 1 > orig_name_size)
665 {
666 MHD_gnutls_assert ();
667 (*name_size)++;
668 return GNUTLS_E_SHORT_MEMORY_BUFFER;
669 }
670
671 /* null terminate it */
672 ((char *) name)[*name_size] = 0;
673 }
674
675 }
676
677 return type;
678}
679
680static int
681get_subject_alt_name (MHD_gnutls_x509_crt_t cert,
682 unsigned int seq,
683 void *ret,
684 size_t * ret_size,
685 unsigned int *ret_type,
686 unsigned int *critical, int othername_oid)
687{
688 int result;
689 MHD_gnutls_datum_t dnsname;
690 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
691 MHD_gnutls_x509_subject_alt_name_t type;
692
693 if (cert == NULL)
694 {
695 MHD_gnutls_assert ();
696 return GNUTLS_E_INVALID_REQUEST;
697 }
698
699 if (ret)
700 memset (ret, 0, *ret_size);
701 else
702 *ret_size = 0;
703
704 if ((result =
705 MHD__gnutls_x509_crt_get_extension (cert, "2.5.29.17", 0, &dnsname,
706 critical)) < 0)
707 {
708 return result;
709 }
710
711 if (dnsname.size == 0 || dnsname.data == NULL)
712 {
713 MHD_gnutls_assert ();
714 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
715 }
716
717 result =
718 MHD__asn1_create_element (MHD__gnutls_get_pkix (), "PKIX1.SubjectAltName",
719 &c2);
720 if (result != ASN1_SUCCESS)
721 {
722 MHD_gnutls_assert ();
723 MHD__gnutls_free_datum (&dnsname);
724 return MHD_gtls_asn2err (result);
725 }
726
727 result = MHD__asn1_der_decoding (&c2, dnsname.data, dnsname.size, NULL);
728 MHD__gnutls_free_datum (&dnsname);
729
730 if (result != ASN1_SUCCESS)
731 {
732 MHD_gnutls_assert ();
733 MHD__asn1_delete_structure (&c2);
734 return MHD_gtls_asn2err (result);
735 }
736
737 result = parse_general_name (c2, "", seq, ret, ret_size, ret_type,
738 othername_oid);
739
740 MHD__asn1_delete_structure (&c2);
741
742 if (result < 0)
743 {
744 return result;
745 }
746
747 type = result;
748
749 return type;
750}
751
752/**
753 * MHD_gnutls_x509_crt_get_subject_alt_name - Get certificate's alternative name, if any
754 * @cert: should contain a MHD_gnutls_x509_crt_t structure
755 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
756 * @ret: is the place where the alternative name will be copied to
757 * @ret_size: holds the size of ret.
758 * @critical: will be non zero if the extension is marked as critical (may be null)
759 *
760 * This function will return the alternative names, contained in the
761 * given certificate.
762 *
763 * This is specified in X509v3 Certificate Extensions. GNUTLS will
764 * return the Alternative name (2.5.29.17), or a negative error code.
765 *
766 * When the SAN type is otherName, it will extract the data in the
767 * otherName's value field, and %GNUTLS_SAN_OTHERNAME is returned.
768 * You may use MHD_gnutls_x509_crt_get_subject_alt_othername_oid() to get
769 * the corresponding OID and the "virtual" SAN types (e.g.,
770 * %GNUTLS_SAN_OTHERNAME_XMPP).
771 *
772 * If an otherName OID is known, the data will be decoded. Otherwise
773 * the returned data will be DER encoded, and you will have to decode
774 * it yourself. Currently, only the RFC 3920 id-on-xmppAddr SAN is
775 * recognized.
776 *
777 * Returns the alternative subject name type on success. The type is
778 * one of the enumerated MHD_gnutls_x509_subject_alt_name_t. It will
779 * return %GNUTLS_E_SHORT_MEMORY_BUFFER if @ret_size is not large
780 * enough to hold the value. In that case @ret_size will be updated
781 * with the required size. If the certificate does not have an
782 * Alternative name with the specified sequence number then
783 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
784 *
785 **/
786int
787MHD_gnutls_x509_crt_get_subject_alt_name (MHD_gnutls_x509_crt_t cert,
788 unsigned int seq,
789 void *ret,
790 size_t * ret_size,
791 unsigned int *critical)
792{
793 return get_subject_alt_name (cert, seq, ret, ret_size, NULL, critical, 0);
794}
795
796/**
797 * MHD_gnutls_x509_crt_get_basic_constraints - This function returns the certificate basic constraints
798 * @cert: should contain a MHD_gnutls_x509_crt_t structure
799 * @critical: will be non zero if the extension is marked as critical
800 * @ca: pointer to output integer indicating CA status, may be NULL,
801 * value is 1 if the certificate CA flag is set, 0 otherwise.
802 * @pathlen: pointer to output integer indicating path length (may be
803 * NULL), non-negative values indicate a present pathLenConstraint
804 * field and the actual value, -1 indicate that the field is absent.
805 *
806 * This function will read the certificate's basic constraints, and
807 * return the certificates CA status. It reads the basicConstraints
808 * X.509 extension (2.5.29.19).
809 *
810 * Return value: If the certificate is a CA a positive value will be
811 * returned, or zero if the certificate does not have CA flag set. A
812 * negative value may be returned in case of errors. If the
813 * certificate does not contain the basicConstraints extension
814 * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
815 **/
816static int
817MHD_gnutls_x509_crt_get_basic_constraints (MHD_gnutls_x509_crt_t cert,
818 unsigned int *critical,
819 int *ca, int *pathlen)
820{
821 int result;
822 MHD_gnutls_datum_t basicConstraints;
823 int tmp_ca;
824
825 if (cert == NULL)
826 {
827 MHD_gnutls_assert ();
828 return GNUTLS_E_INVALID_REQUEST;
829 }
830
831 if ((result = MHD__gnutls_x509_crt_get_extension (cert, "2.5.29.19", 0,
832 &basicConstraints,
833 critical)) < 0)
834 {
835 return result;
836 }
837
838 if (basicConstraints.size == 0 || basicConstraints.data == NULL)
839 {
840 MHD_gnutls_assert ();
841 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
842 }
843
844 result = MHD__gnutls_x509_ext_extract_basicConstraints (&tmp_ca, pathlen,
845 basicConstraints.
846 data,
847 basicConstraints.
848 size);
849 if (ca)
850 *ca = tmp_ca;
851 MHD__gnutls_free_datum (&basicConstraints);
852
853 if (result < 0)
854 {
855 MHD_gnutls_assert ();
856 return result;
857 }
858
859 return tmp_ca;
860}
861
862/**
863 * MHD_gnutls_x509_crt_get_ca_status - This function returns the certificate CA status
864 * @cert: should contain a MHD_gnutls_x509_crt_t structure
865 * @critical: will be non zero if the extension is marked as critical
866 *
867 * This function will return certificates CA status, by reading the
868 * basicConstraints X.509 extension (2.5.29.19). If the certificate is
869 * a CA a positive value will be returned, or zero if the certificate
870 * does not have CA flag set.
871 *
872 * Use MHD_gnutls_x509_crt_get_basic_constraints() if you want to read the
873 * pathLenConstraint field too.
874 *
875 * A negative value may be returned in case of parsing error.
876 * If the certificate does not contain the basicConstraints extension
877 * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
878 *
879 **/
880int
881MHD_gnutls_x509_crt_get_ca_status (MHD_gnutls_x509_crt_t cert,
882 unsigned int *critical)
883{
884 int ca, pathlen;
885 return MHD_gnutls_x509_crt_get_basic_constraints (cert, critical, &ca,
886 &pathlen);
887}
888
889/** 312/**
890 * MHD_gnutls_x509_crt_get_key_usage - This function returns the certificate's key usage 313 * MHD_gnutls_x509_crt_get_key_usage - This function returns the certificate's key usage
891 * @cert: should contain a MHD_gnutls_x509_crt_t structure 314 * @cert: should contain a MHD_gnutls_x509_crt_t structure
@@ -1013,24 +436,6 @@ cleanup:MHD__asn1_delete_structure (&c2);
1013} 436}
1014 437
1015/** 438/**
1016 * MHD_gnutls_x509_crt_get_raw_issuer_dn - This function returns the issuer's DN DER encoded
1017 * @cert: should contain a MHD_gnutls_x509_crt_t structure
1018 * @start: will hold the starting point of the DN
1019 *
1020 * This function will return a pointer to the DER encoded DN structure
1021 * and the length.
1022 *
1023 * Returns 0 on success or a negative value on error.
1024 *
1025 **/
1026int
1027MHD_gnutls_x509_crt_get_raw_issuer_dn (MHD_gnutls_x509_crt_t cert,
1028 MHD_gnutls_datum_t * start)
1029{
1030 return MHD__gnutls_x509_crt_get_raw_dn2 (cert, "issuer", start);
1031}
1032
1033/**
1034 * MHD_gnutls_x509_crt_get_raw_dn - This function returns the subject's DN DER encoded 439 * MHD_gnutls_x509_crt_get_raw_dn - This function returns the subject's DN DER encoded
1035 * @cert: should contain a MHD_gnutls_x509_crt_t structure 440 * @cert: should contain a MHD_gnutls_x509_crt_t structure
1036 * @start: will hold the starting point of the DN 441 * @start: will hold the starting point of the DN
@@ -1048,33 +453,6 @@ MHD_gnutls_x509_crt_get_raw_dn (MHD_gnutls_x509_crt_t cert,
1048 return MHD__gnutls_x509_crt_get_raw_dn2 (cert, "subject", start); 453 return MHD__gnutls_x509_crt_get_raw_dn2 (cert, "subject", start);
1049} 454}
1050 455
1051static int
1052get_dn (MHD_gnutls_x509_crt_t cert, const char *whom,
1053 MHD_gnutls_x509_dn_t * dn)
1054{
1055 *dn = MHD__asn1_find_node (cert->cert, whom);
1056 if (!*dn)
1057 return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND;
1058 return 0;
1059}
1060
1061/**
1062 * MHD_gnutls_x509_crt_get_subject: get opaque subject DN pointer
1063 * @cert: should contain a MHD_gnutls_x509_crt_t structure
1064 * @dn: output variable with pointer to opaque DN.
1065 *
1066 * Return the Certificate's Subject DN as an opaque data type. You
1067 * may use MHD_gnutls_x509_dn_get_rdn_ava() to decode the DN.
1068 *
1069 * Returns: Returns 0 on success, or an error code.
1070 **/
1071int
1072MHD_gnutls_x509_crt_get_subject (MHD_gnutls_x509_crt_t cert,
1073 MHD_gnutls_x509_dn_t * dn)
1074{
1075 return get_dn (cert, "tbsCertificate.subject.rdnSequence", dn);
1076}
1077
1078/** 456/**
1079 * MHD_gnutls_x509_crt_export - This function will export the certificate 457 * MHD_gnutls_x509_crt_export - This function will export the certificate
1080 * @cert: Holds the certificate 458 * @cert: Holds the certificate
diff --git a/src/daemon/https/x509/x509.h b/src/daemon/https/x509/x509.h
index 1c060373..be14b784 100644
--- a/src/daemon/https/x509/x509.h
+++ b/src/daemon/https/x509/x509.h
@@ -97,10 +97,6 @@ extern "C"
97 MHD_gnutls_x509_crt_fmt_t format, 97 MHD_gnutls_x509_crt_fmt_t format,
98 void *output_data, 98 void *output_data,
99 size_t * output_data_size); 99 size_t * output_data_size);
100 int MHD_gnutls_x509_crt_get_signature_algorithm (MHD_gnutls_x509_crt_t
101 cert);
102 int MHD_gnutls_x509_crt_get_signature (MHD_gnutls_x509_crt_t cert,
103 char *sig, size_t * sizeof_sig);
104 int MHD_gnutls_x509_crt_get_version (MHD_gnutls_x509_crt_t cert); 100 int MHD_gnutls_x509_crt_get_version (MHD_gnutls_x509_crt_t cert);
105 101
106#define GNUTLS_CRL_REASON_UNUSED 128 102#define GNUTLS_CRL_REASON_UNUSED 128
@@ -115,16 +111,8 @@ extern "C"
115 111
116 time_t MHD_gnutls_x509_crt_get_activation_time (MHD_gnutls_x509_crt_t cert); 112 time_t MHD_gnutls_x509_crt_get_activation_time (MHD_gnutls_x509_crt_t cert);
117 time_t MHD_gnutls_x509_crt_get_expiration_time (MHD_gnutls_x509_crt_t cert); 113 time_t MHD_gnutls_x509_crt_get_expiration_time (MHD_gnutls_x509_crt_t cert);
118 int MHD_gnutls_x509_crt_get_serial (MHD_gnutls_x509_crt_t cert,
119 void *result, size_t * result_size);
120
121 int MHD_gnutls_x509_crt_get_pk_algorithm (MHD_gnutls_x509_crt_t cert, 114 int MHD_gnutls_x509_crt_get_pk_algorithm (MHD_gnutls_x509_crt_t cert,
122 unsigned int *bits); 115 unsigned int *bits);
123 int MHD_gnutls_x509_crt_get_subject_alt_name (MHD_gnutls_x509_crt_t cert,
124 unsigned int seq,
125 void *ret,
126 size_t * ret_size,
127 unsigned int *critical);
128 int MHD_gnutls_x509_crt_get_ca_status (MHD_gnutls_x509_crt_t cert, 116 int MHD_gnutls_x509_crt_get_ca_status (MHD_gnutls_x509_crt_t cert,
129 unsigned int *critical); 117 unsigned int *critical);
130/* The key_usage flags are defined in gnutls.h. They are the 118/* The key_usage flags are defined in gnutls.h. They are the
@@ -213,8 +201,6 @@ extern "C"
213 format, MHD_gnutls_datum_t * out); 201 format, MHD_gnutls_datum_t * out);
214/* Access to internal Certificate fields. 202/* Access to internal Certificate fields.
215 */ 203 */
216 int MHD_gnutls_x509_crt_get_raw_issuer_dn (MHD_gnutls_x509_crt_t cert,
217 MHD_gnutls_datum_t * start);
218 int MHD_gnutls_x509_crt_get_raw_dn (MHD_gnutls_x509_crt_t cert, 204 int MHD_gnutls_x509_crt_get_raw_dn (MHD_gnutls_x509_crt_t cert,
219 MHD_gnutls_datum_t * start); 205 MHD_gnutls_datum_t * start);
220 206
@@ -227,8 +213,6 @@ extern "C"
227 unsigned long value_tag; 213 unsigned long value_tag;
228 } MHD_gnutls_x509_ava_st; 214 } MHD_gnutls_x509_ava_st;
229 215
230 int MHD_gnutls_x509_crt_get_subject (MHD_gnutls_x509_crt_t cert,
231 MHD_gnutls_x509_dn_t * dn);
232 struct MHD_gnutls_pkcs7_int; 216 struct MHD_gnutls_pkcs7_int;
233 typedef struct MHD_gnutls_pkcs7_int *MHD_gnutls_pkcs7_t; 217 typedef struct MHD_gnutls_pkcs7_int *MHD_gnutls_pkcs7_t;
234 218
@@ -325,38 +309,9 @@ extern "C"
325 309
326 int MHD_gnutls_x509_privkey_init (MHD_gnutls_x509_privkey_t * key); 310 int MHD_gnutls_x509_privkey_init (MHD_gnutls_x509_privkey_t * key);
327 void MHD_gnutls_x509_privkey_deinit (MHD_gnutls_x509_privkey_t key); 311 void MHD_gnutls_x509_privkey_deinit (MHD_gnutls_x509_privkey_t key);
328 int MHD_gnutls_x509_privkey_cpy (MHD_gnutls_x509_privkey_t dst,
329 MHD_gnutls_x509_privkey_t src);
330 int MHD_gnutls_x509_privkey_import (MHD_gnutls_x509_privkey_t key, 312 int MHD_gnutls_x509_privkey_import (MHD_gnutls_x509_privkey_t key,
331 const MHD_gnutls_datum_t * data, 313 const MHD_gnutls_datum_t * data,
332 MHD_gnutls_x509_crt_fmt_t format); 314 MHD_gnutls_x509_crt_fmt_t format);
333 int MHD_gnutls_x509_privkey_import_pkcs8 (MHD_gnutls_x509_privkey_t key,
334 const MHD_gnutls_datum_t * data,
335 MHD_gnutls_x509_crt_fmt_t format,
336 const char *pass,
337 unsigned int flags);
338 int MHD_gnutls_x509_privkey_import_rsa_raw (MHD_gnutls_x509_privkey_t key,
339 const MHD_gnutls_datum_t * m,
340 const MHD_gnutls_datum_t * e,
341 const MHD_gnutls_datum_t * d,
342 const MHD_gnutls_datum_t * p,
343 const MHD_gnutls_datum_t * q,
344 const MHD_gnutls_datum_t * u);
345 int MHD_gnutls_x509_privkey_export_dsa_raw (MHD_gnutls_x509_privkey_t key,
346 MHD_gnutls_datum_t * p,
347 MHD_gnutls_datum_t * q,
348 MHD_gnutls_datum_t * g,
349 MHD_gnutls_datum_t * y,
350 MHD_gnutls_datum_t * x);
351 int MHD_gnutls_x509_privkey_import_dsa_raw (MHD_gnutls_x509_privkey_t key,
352 const MHD_gnutls_datum_t * p,
353 const MHD_gnutls_datum_t * q,
354 const MHD_gnutls_datum_t * g,
355 const MHD_gnutls_datum_t * y,
356 const MHD_gnutls_datum_t * x);
357
358 int MHD_gnutls_x509_privkey_get_pk_algorithm (MHD_gnutls_x509_privkey_t
359 key);
360 int MHD_gnutls_x509_privkey_get_key_id (MHD_gnutls_x509_privkey_t key, 315 int MHD_gnutls_x509_privkey_get_key_id (MHD_gnutls_x509_privkey_t key,
361 unsigned int flags, 316 unsigned int flags,
362 unsigned char *output_data, 317 unsigned char *output_data,
@@ -457,27 +412,12 @@ typedef struct MHD_gtls_x509_privkey_int
457 ASN1_TYPE key; 412 ASN1_TYPE key;
458} MHD_gnutls_x509_privkey_int; 413} MHD_gnutls_x509_privkey_int;
459 414
460int MHD_gnutls_x509_crt_get_subject_alt_name (MHD_gnutls_x509_crt_t cert,
461 unsigned int seq,
462 void *ret,
463 size_t * ret_size,
464 unsigned int *critical);
465int MHD_gnutls_x509_crt_get_dn_by_oid (MHD_gnutls_x509_crt_t cert,
466 const char *oid,
467 int indx,
468 unsigned int raw_flag,
469 void *buf, size_t * sizeof_buf);
470int MHD_gnutls_x509_crt_get_ca_status (MHD_gnutls_x509_crt_t cert,
471 unsigned int *critical);
472int MHD_gnutls_x509_crt_get_pk_algorithm (MHD_gnutls_x509_crt_t cert, 415int MHD_gnutls_x509_crt_get_pk_algorithm (MHD_gnutls_x509_crt_t cert,
473 unsigned int *bits); 416 unsigned int *bits);
474 417
475int MHD_gnutls_x509_crt_get_serial (MHD_gnutls_x509_crt_t cert, 418int MHD_gnutls_x509_crt_get_serial (MHD_gnutls_x509_crt_t cert,
476 void *result, size_t * result_size); 419 void *result, size_t * result_size);
477 420
478int MHD__gnutls_x509_compare_raw_dn (const MHD_gnutls_datum_t * dn1,
479 const MHD_gnutls_datum_t * dn2);
480
481int MHD_gnutls_x509_crt_check_revocation (MHD_gnutls_x509_crt_t cert, 421int MHD_gnutls_x509_crt_check_revocation (MHD_gnutls_x509_crt_t cert,
482 const MHD_gnutls_x509_crl_t * 422 const MHD_gnutls_x509_crl_t *
483 crl_list, int crl_list_length); 423 crl_list, int crl_list_length);
@@ -494,7 +434,6 @@ int MHD_gnutls_x509_crt_export (MHD_gnutls_x509_crt_t cert,
494int MHD_gnutls_x509_crt_get_key_usage (MHD_gnutls_x509_crt_t cert, 434int MHD_gnutls_x509_crt_get_key_usage (MHD_gnutls_x509_crt_t cert,
495 unsigned int *key_usage, 435 unsigned int *key_usage,
496 unsigned int *critical); 436 unsigned int *critical);
497int MHD_gnutls_x509_crt_get_signature_algorithm (MHD_gnutls_x509_crt_t cert);
498int MHD_gnutls_x509_crt_get_version (MHD_gnutls_x509_crt_t cert); 437int MHD_gnutls_x509_crt_get_version (MHD_gnutls_x509_crt_t cert);
499 438
500int MHD_gnutls_x509_privkey_init (MHD_gnutls_x509_privkey_t * key); 439int MHD_gnutls_x509_privkey_init (MHD_gnutls_x509_privkey_t * key);
@@ -507,14 +446,6 @@ int MHD_gnutls_x509_privkey_generate (MHD_gnutls_x509_privkey_t key,
507int MHD_gnutls_x509_privkey_import (MHD_gnutls_x509_privkey_t key, 446int MHD_gnutls_x509_privkey_import (MHD_gnutls_x509_privkey_t key,
508 const MHD_gnutls_datum_t * data, 447 const MHD_gnutls_datum_t * data,
509 MHD_gnutls_x509_crt_fmt_t format); 448 MHD_gnutls_x509_crt_fmt_t format);
510int MHD_gnutls_x509_privkey_get_pk_algorithm (MHD_gnutls_x509_privkey_t key);
511int MHD_gnutls_x509_privkey_import_rsa_raw (MHD_gnutls_x509_privkey_t key,
512 const MHD_gnutls_datum_t * m,
513 const MHD_gnutls_datum_t * e,
514 const MHD_gnutls_datum_t * d,
515 const MHD_gnutls_datum_t * p,
516 const MHD_gnutls_datum_t * q,
517 const MHD_gnutls_datum_t * u);
518int MHD_gnutls_x509_privkey_export_rsa_raw (MHD_gnutls_x509_privkey_t key, 449int MHD_gnutls_x509_privkey_export_rsa_raw (MHD_gnutls_x509_privkey_t key,
519 MHD_gnutls_datum_t * m, 450 MHD_gnutls_datum_t * m,
520 MHD_gnutls_datum_t * e, 451 MHD_gnutls_datum_t * e,
diff --git a/src/daemon/https/x509/x509_privkey.c b/src/daemon/https/x509/x509_privkey.c
index df4e0faa..b935c3f8 100644
--- a/src/daemon/https/x509/x509_privkey.c
+++ b/src/daemon/https/x509/x509_privkey.c
@@ -32,13 +32,9 @@
32#include <gnutls_x509.h> 32#include <gnutls_x509.h>
33#include <x509_b64.h> 33#include <x509_b64.h>
34#include <x509.h> 34#include <x509.h>
35#include <dn.h>
36#include <mpi.h> 35#include <mpi.h>
37#include <extensions.h> 36#include <extensions.h>
38 37
39static int MHD__gnutls_asn1_encode_rsa (ASN1_TYPE * c2, mpi_t * params);
40int MHD__gnutls_asn1_encode_dsa (ASN1_TYPE * c2, mpi_t * params);
41
42/* remove this when libgcrypt can handle the PKCS #1 coefficients from 38/* remove this when libgcrypt can handle the PKCS #1 coefficients from
43 * rsa keys 39 * rsa keys
44 */ 40 */
@@ -92,54 +88,6 @@ MHD_gnutls_x509_privkey_deinit (MHD_gnutls_x509_privkey_t key)
92 MHD_gnutls_free (key); 88 MHD_gnutls_free (key);
93} 89}
94 90
95/**
96 * MHD_gnutls_x509_privkey_cpy - This function copies a private key
97 * @dst: The destination key, which should be initialized.
98 * @src: The source key
99 *
100 * This function will copy a private key from source to destination key.
101 *
102 **/
103int
104MHD_gnutls_x509_privkey_cpy (MHD_gnutls_x509_privkey_t dst,
105 MHD_gnutls_x509_privkey_t src)
106{
107 int i, ret;
108
109 if (!src || !dst)
110 return GNUTLS_E_INVALID_REQUEST;
111
112 for (i = 0; i < src->params_size; i++)
113 {
114 dst->params[i] = MHD__gnutls_mpi_copy (src->params[i]);
115 if (dst->params[i] == NULL)
116 return GNUTLS_E_MEMORY_ERROR;
117 }
118
119 dst->params_size = src->params_size;
120 dst->pk_algorithm = src->pk_algorithm;
121 dst->crippled = src->crippled;
122
123 if (!src->crippled)
124 {
125 switch (dst->pk_algorithm)
126 {
127 case MHD_GNUTLS_PK_RSA:
128 ret = MHD__gnutls_asn1_encode_rsa (&dst->key, dst->params);
129 if (ret < 0)
130 {
131 MHD_gnutls_assert ();
132 return ret;
133 }
134 break;
135 default:
136 MHD_gnutls_assert ();
137 return GNUTLS_E_INVALID_REQUEST;
138 }
139 }
140
141 return 0;
142}
143 91
144/* Converts an RSA PKCS#1 key to 92/* Converts an RSA PKCS#1 key to
145 * an internal structure (MHD_gnutls_private_key) 93 * an internal structure (MHD_gnutls_private_key)
@@ -340,495 +288,3 @@ MHD_gnutls_x509_privkey_import (MHD_gnutls_x509_privkey_t key,
340 return 0; 288 return 0;
341} 289}
342 290
343#define FREE_RSA_PRIVATE_PARAMS for (i=0;i<RSA_PRIVATE_PARAMS;i++) \
344 MHD_gtls_mpi_release(&key->params[i])
345#define FREE_DSA_PRIVATE_PARAMS for (i=0;i<DSA_PRIVATE_PARAMS;i++) \
346 MHD_gtls_mpi_release(&key->params[i])
347
348/**
349 * MHD_gnutls_x509_privkey_import_rsa_raw - This function will import a raw RSA key
350 * @key: The structure to store the parsed key
351 * @m: holds the modulus
352 * @e: holds the public exponent
353 * @d: holds the private exponent
354 * @p: holds the first prime (p)
355 * @q: holds the second prime (q)
356 * @u: holds the coefficient
357 *
358 * This function will convert the given RSA raw parameters
359 * to the native MHD_gnutls_x509_privkey_t format. The output will be stored in @key.
360 *
361 **/
362int
363MHD_gnutls_x509_privkey_import_rsa_raw (MHD_gnutls_x509_privkey_t key,
364 const MHD_gnutls_datum_t * m,
365 const MHD_gnutls_datum_t * e,
366 const MHD_gnutls_datum_t * d,
367 const MHD_gnutls_datum_t * p,
368 const MHD_gnutls_datum_t * q,
369 const MHD_gnutls_datum_t * u)
370{
371 int i = 0, ret;
372 size_t siz = 0;
373
374 if (key == NULL)
375 {
376 MHD_gnutls_assert ();
377 return GNUTLS_E_INVALID_REQUEST;
378 }
379
380 siz = m->size;
381 if (MHD_gtls_mpi_scan_nz (&key->params[0], m->data, &siz))
382 {
383 MHD_gnutls_assert ();
384 FREE_RSA_PRIVATE_PARAMS;
385 return GNUTLS_E_MPI_SCAN_FAILED;
386 }
387
388 siz = e->size;
389 if (MHD_gtls_mpi_scan_nz (&key->params[1], e->data, &siz))
390 {
391 MHD_gnutls_assert ();
392 FREE_RSA_PRIVATE_PARAMS;
393 return GNUTLS_E_MPI_SCAN_FAILED;
394 }
395
396 siz = d->size;
397 if (MHD_gtls_mpi_scan_nz (&key->params[2], d->data, &siz))
398 {
399 MHD_gnutls_assert ();
400 FREE_RSA_PRIVATE_PARAMS;
401 return GNUTLS_E_MPI_SCAN_FAILED;
402 }
403
404 siz = p->size;
405 if (MHD_gtls_mpi_scan_nz (&key->params[3], p->data, &siz))
406 {
407 MHD_gnutls_assert ();
408 FREE_RSA_PRIVATE_PARAMS;
409 return GNUTLS_E_MPI_SCAN_FAILED;
410 }
411
412 siz = q->size;
413 if (MHD_gtls_mpi_scan_nz (&key->params[4], q->data, &siz))
414 {
415 MHD_gnutls_assert ();
416 FREE_RSA_PRIVATE_PARAMS;
417 return GNUTLS_E_MPI_SCAN_FAILED;
418 }
419
420#ifdef CALC_COEFF
421 key->params[5] =
422 MHD__gnutls_mpi_snew (MHD__gnutls_mpi_get_nbits (key->params[0]));
423
424 if (key->params[5] == NULL)
425 {
426 MHD_gnutls_assert ();
427 FREE_RSA_PRIVATE_PARAMS;
428 return GNUTLS_E_MEMORY_ERROR;
429 }
430
431 MHD__gnutls_mpi_invm (key->params[5], key->params[3], key->params[4]);
432#else
433 siz = u->size;
434 if (MHD_gtls_mpi_scan_nz (&key->params[5], u->data, &siz))
435 {
436 MHD_gnutls_assert ();
437 FREE_RSA_PRIVATE_PARAMS;
438 return GNUTLS_E_MPI_SCAN_FAILED;
439 }
440#endif
441
442 if (!key->crippled)
443 {
444 ret = MHD__gnutls_asn1_encode_rsa (&key->key, key->params);
445 if (ret < 0)
446 {
447 MHD_gnutls_assert ();
448 FREE_RSA_PRIVATE_PARAMS;
449 return ret;
450 }
451 }
452
453 key->params_size = RSA_PRIVATE_PARAMS;
454 key->pk_algorithm = MHD_GNUTLS_PK_RSA;
455
456 return 0;
457
458}
459
460/**
461 * MHD_gnutls_x509_privkey_get_pk_algorithm - This function returns the key's PublicKey algorithm
462 * @key: should contain a MHD_gnutls_x509_privkey_t structure
463 *
464 * This function will return the public key algorithm of a private
465 * key.
466 *
467 * Returns a member of the enum MHD_GNUTLS_PublicKeyAlgorithm enumeration on success,
468 * or a negative value on error.
469 *
470 **/
471int
472MHD_gnutls_x509_privkey_get_pk_algorithm (MHD_gnutls_x509_privkey_t key)
473{
474 if (key == NULL)
475 {
476 MHD_gnutls_assert ();
477 return GNUTLS_E_INVALID_REQUEST;
478 }
479
480 return key->pk_algorithm;
481}
482
483/* Encodes the RSA parameters into an ASN.1 RSA private key structure.
484 */
485static int
486MHD__gnutls_asn1_encode_rsa (ASN1_TYPE * c2, mpi_t * params)
487{
488 int result, i;
489 size_t size[8], total;
490 opaque *m_data, *pube_data, *prie_data;
491 opaque *p1_data, *p2_data, *u_data, *exp1_data, *exp2_data;
492 opaque *all_data = NULL, *p;
493 mpi_t exp1 = NULL, exp2 = NULL, q1 = NULL, p1 = NULL, u = NULL;
494 opaque null = '\0';
495
496 /* Read all the sizes */
497 total = 0;
498 for (i = 0; i < 5; i++)
499 {
500 MHD_gtls_mpi_print_lz (NULL, &size[i], params[i]);
501 total += size[i];
502 }
503
504 /* Now generate exp1 and exp2
505 */
506 exp1 = MHD__gnutls_mpi_salloc_like (params[0]); /* like modulus */
507 if (exp1 == NULL)
508 {
509 MHD_gnutls_assert ();
510 result = GNUTLS_E_MEMORY_ERROR;
511 goto cleanup;
512 }
513
514 exp2 = MHD__gnutls_mpi_salloc_like (params[0]);
515 if (exp2 == NULL)
516 {
517 MHD_gnutls_assert ();
518 result = GNUTLS_E_MEMORY_ERROR;
519 goto cleanup;
520 }
521
522 q1 = MHD__gnutls_mpi_salloc_like (params[4]);
523 if (q1 == NULL)
524 {
525 MHD_gnutls_assert ();
526 result = GNUTLS_E_MEMORY_ERROR;
527 goto cleanup;
528 }
529
530 p1 = MHD__gnutls_mpi_salloc_like (params[3]);
531 if (p1 == NULL)
532 {
533 MHD_gnutls_assert ();
534 result = GNUTLS_E_MEMORY_ERROR;
535 goto cleanup;
536 }
537
538 u = MHD__gnutls_mpi_salloc_like (params[3]);
539 if (u == NULL)
540 {
541 MHD_gnutls_assert ();
542 result = GNUTLS_E_MEMORY_ERROR;
543 goto cleanup;
544 }
545
546 MHD__gnutls_mpi_invm (u, params[4], params[3]);
547 /* inverse of q mod p */
548 MHD_gtls_mpi_print_lz (NULL, &size[5], u);
549 total += size[5];
550
551 MHD__gnutls_mpi_sub_ui (p1, params[3], 1);
552 MHD__gnutls_mpi_sub_ui (q1, params[4], 1);
553
554 MHD__gnutls_mpi_mod (exp1, params[2], p1);
555 MHD__gnutls_mpi_mod (exp2, params[2], q1);
556
557 /* calculate exp's size */
558 MHD_gtls_mpi_print_lz (NULL, &size[6], exp1);
559 total += size[6];
560
561 MHD_gtls_mpi_print_lz (NULL, &size[7], exp2);
562 total += size[7];
563
564 /* Encoding phase.
565 * allocate data enough to hold everything
566 */
567 all_data = MHD_gnutls_secure_malloc (total);
568 if (all_data == NULL)
569 {
570 MHD_gnutls_assert ();
571 result = GNUTLS_E_MEMORY_ERROR;
572 goto cleanup;
573 }
574
575 p = all_data;
576 m_data = p;
577 p += size[0];
578 pube_data = p;
579 p += size[1];
580 prie_data = p;
581 p += size[2];
582 p1_data = p;
583 p += size[3];
584 p2_data = p;
585 p += size[4];
586 u_data = p;
587 p += size[5];
588 exp1_data = p;
589 p += size[6];
590 exp2_data = p;
591
592 MHD_gtls_mpi_print_lz (m_data, &size[0], params[0]);
593 MHD_gtls_mpi_print_lz (pube_data, &size[1], params[1]);
594 MHD_gtls_mpi_print_lz (prie_data, &size[2], params[2]);
595 MHD_gtls_mpi_print_lz (p1_data, &size[3], params[3]);
596 MHD_gtls_mpi_print_lz (p2_data, &size[4], params[4]);
597 MHD_gtls_mpi_print_lz (u_data, &size[5], u);
598 MHD_gtls_mpi_print_lz (exp1_data, &size[6], exp1);
599 MHD_gtls_mpi_print_lz (exp2_data, &size[7], exp2);
600
601 /* Ok. Now we have the data. Create the asn1 structures
602 */
603
604 if ((result =
605 MHD__asn1_create_element (MHD__gnutls_getMHD__gnutls_asn (),
606 "GNUTLS.RSAPrivateKey", c2)) != ASN1_SUCCESS)
607 {
608 MHD_gnutls_assert ();
609 result = MHD_gtls_asn2err (result);
610 goto cleanup;
611 }
612
613 /* Write PRIME
614 */
615 if ((result = MHD__asn1_write_value (*c2, "modulus", m_data, size[0]))
616 != ASN1_SUCCESS)
617 {
618 MHD_gnutls_assert ();
619 result = MHD_gtls_asn2err (result);
620 goto cleanup;
621 }
622
623 if ((result =
624 MHD__asn1_write_value (*c2, "publicExponent", pube_data,
625 size[1])) != ASN1_SUCCESS)
626 {
627 MHD_gnutls_assert ();
628 result = MHD_gtls_asn2err (result);
629 goto cleanup;
630 }
631
632 if ((result =
633 MHD__asn1_write_value (*c2, "privateExponent", prie_data,
634 size[2])) != ASN1_SUCCESS)
635 {
636 MHD_gnutls_assert ();
637 result = MHD_gtls_asn2err (result);
638 goto cleanup;
639 }
640
641 if ((result = MHD__asn1_write_value (*c2, "prime1", p1_data, size[3]))
642 != ASN1_SUCCESS)
643 {
644 MHD_gnutls_assert ();
645 result = MHD_gtls_asn2err (result);
646 goto cleanup;
647 }
648
649 if ((result = MHD__asn1_write_value (*c2, "prime2", p2_data, size[4]))
650 != ASN1_SUCCESS)
651 {
652 MHD_gnutls_assert ();
653 result = MHD_gtls_asn2err (result);
654 goto cleanup;
655 }
656
657 if ((result = MHD__asn1_write_value (*c2, "exponent1", exp1_data, size[6]))
658 != ASN1_SUCCESS)
659 {
660 MHD_gnutls_assert ();
661 result = MHD_gtls_asn2err (result);
662 goto cleanup;
663 }
664
665 if ((result = MHD__asn1_write_value (*c2, "exponent2", exp2_data, size[7]))
666 != ASN1_SUCCESS)
667 {
668 MHD_gnutls_assert ();
669 result = MHD_gtls_asn2err (result);
670 goto cleanup;
671 }
672
673 if ((result = MHD__asn1_write_value (*c2, "coefficient", u_data, size[5]))
674 != ASN1_SUCCESS)
675 {
676 MHD_gnutls_assert ();
677 result = MHD_gtls_asn2err (result);
678 goto cleanup;
679 }
680
681 MHD_gtls_mpi_release (&exp1);
682 MHD_gtls_mpi_release (&exp2);
683 MHD_gtls_mpi_release (&q1);
684 MHD_gtls_mpi_release (&p1);
685 MHD_gtls_mpi_release (&u);
686 MHD_gnutls_free (all_data);
687
688 if ((result = MHD__asn1_write_value (*c2, "otherPrimeInfos",
689 NULL, 0)) != ASN1_SUCCESS)
690 {
691 MHD_gnutls_assert ();
692 result = MHD_gtls_asn2err (result);
693 goto cleanup;
694 }
695
696 if ((result =
697 MHD__asn1_write_value (*c2, "version", &null, 1)) != ASN1_SUCCESS)
698 {
699 MHD_gnutls_assert ();
700 result = MHD_gtls_asn2err (result);
701 goto cleanup;
702 }
703
704 return 0;
705
706cleanup:MHD_gtls_mpi_release (&u);
707 MHD_gtls_mpi_release (&exp1);
708 MHD_gtls_mpi_release (&exp2);
709 MHD_gtls_mpi_release (&q1);
710 MHD_gtls_mpi_release (&p1);
711 MHD__asn1_delete_structure (c2);
712 MHD_gnutls_free (all_data);
713
714 return result;
715}
716
717/* Encodes the DSA parameters into an ASN.1 DSAPrivateKey structure.
718 */
719int
720MHD__gnutls_asn1_encode_dsa (ASN1_TYPE * c2, mpi_t * params)
721{
722 int result, i;
723 size_t size[DSA_PRIVATE_PARAMS], total;
724 opaque *p_data, *q_data, *g_data, *x_data, *y_data;
725 opaque *all_data = NULL, *p;
726 opaque null = '\0';
727
728 /* Read all the sizes */
729 total = 0;
730 for (i = 0; i < DSA_PRIVATE_PARAMS; i++)
731 {
732 MHD_gtls_mpi_print_lz (NULL, &size[i], params[i]);
733 total += size[i];
734 }
735
736 /* Encoding phase.
737 * allocate data enough to hold everything
738 */
739 all_data = MHD_gnutls_secure_malloc (total);
740 if (all_data == NULL)
741 {
742 MHD_gnutls_assert ();
743 result = GNUTLS_E_MEMORY_ERROR;
744 goto cleanup;
745 }
746
747 p = all_data;
748 p_data = p;
749 p += size[0];
750 q_data = p;
751 p += size[1];
752 g_data = p;
753 p += size[2];
754 y_data = p;
755 p += size[3];
756 x_data = p;
757
758 MHD_gtls_mpi_print_lz (p_data, &size[0], params[0]);
759 MHD_gtls_mpi_print_lz (q_data, &size[1], params[1]);
760 MHD_gtls_mpi_print_lz (g_data, &size[2], params[2]);
761 MHD_gtls_mpi_print_lz (y_data, &size[3], params[3]);
762 MHD_gtls_mpi_print_lz (x_data, &size[4], params[4]);
763
764 /* Ok. Now we have the data. Create the asn1 structures
765 */
766
767 if ((result =
768 MHD__asn1_create_element (MHD__gnutls_getMHD__gnutls_asn (),
769 "GNUTLS.DSAPrivateKey", c2)) != ASN1_SUCCESS)
770 {
771 MHD_gnutls_assert ();
772 result = MHD_gtls_asn2err (result);
773 goto cleanup;
774 }
775
776 /* Write PRIME
777 */
778 if ((result =
779 MHD__asn1_write_value (*c2, "p", p_data, size[0])) != ASN1_SUCCESS)
780 {
781 MHD_gnutls_assert ();
782 result = MHD_gtls_asn2err (result);
783 goto cleanup;
784 }
785
786 if ((result =
787 MHD__asn1_write_value (*c2, "q", q_data, size[1])) != ASN1_SUCCESS)
788 {
789 MHD_gnutls_assert ();
790 result = MHD_gtls_asn2err (result);
791 goto cleanup;
792 }
793
794 if ((result =
795 MHD__asn1_write_value (*c2, "g", g_data, size[2])) != ASN1_SUCCESS)
796 {
797 MHD_gnutls_assert ();
798 result = MHD_gtls_asn2err (result);
799 goto cleanup;
800 }
801
802 if ((result =
803 MHD__asn1_write_value (*c2, "Y", y_data, size[3])) != ASN1_SUCCESS)
804 {
805 MHD_gnutls_assert ();
806 result = MHD_gtls_asn2err (result);
807 goto cleanup;
808 }
809
810 if ((result =
811 MHD__asn1_write_value (*c2, "priv", x_data, size[4])) != ASN1_SUCCESS)
812 {
813 MHD_gnutls_assert ();
814 result = MHD_gtls_asn2err (result);
815 goto cleanup;
816 }
817
818 MHD_gnutls_free (all_data);
819
820 if ((result =
821 MHD__asn1_write_value (*c2, "version", &null, 1)) != ASN1_SUCCESS)
822 {
823 MHD_gnutls_assert ();
824 result = MHD_gtls_asn2err (result);
825 goto cleanup;
826 }
827
828 return 0;
829
830cleanup:MHD__asn1_delete_structure (c2);
831 MHD_gnutls_free (all_data);
832
833 return result;
834}