aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/daemon/https/tls/gnutls_x509.c2
-rw-r--r--src/daemon/https/x509/Makefile.am5
-rw-r--r--src/daemon/https/x509/pkcs12.c1309
-rw-r--r--src/daemon/https/x509/pkcs12.h108
-rw-r--r--src/daemon/https/x509/pkcs12_bag.c770
-rw-r--r--src/daemon/https/x509/privkey_pkcs8.c838
6 files changed, 43 insertions, 2989 deletions
diff --git a/src/daemon/https/tls/gnutls_x509.c b/src/daemon/https/tls/gnutls_x509.c
index 811f5dbe..183f12ba 100644
--- a/src/daemon/https/tls/gnutls_x509.c
+++ b/src/daemon/https/tls/gnutls_x509.c
@@ -1159,8 +1159,6 @@ MHD__gnutls_certificate_set_x509_crl_mem (MHD_gtls_cert_credentials_t
1159 return ret; 1159 return ret;
1160} 1160}
1161 1161
1162#include <pkcs12.h>
1163
1164/** 1162/**
1165 * MHD__gnutls_certificate_free_crls - Used to free all the CRLs from a MHD_gtls_cert_credentials_t structure 1163 * MHD__gnutls_certificate_free_crls - Used to free all the CRLs from a MHD_gtls_cert_credentials_t structure
1166 * @sc: is an #MHD_gtls_cert_credentials_t structure. 1164 * @sc: is an #MHD_gtls_cert_credentials_t structure.
diff --git a/src/daemon/https/x509/Makefile.am b/src/daemon/https/x509/Makefile.am
index 04c715a2..4156d2e3 100644
--- a/src/daemon/https/x509/Makefile.am
+++ b/src/daemon/https/x509/Makefile.am
@@ -20,9 +20,7 @@ dn.c dn.h \
20dsa.c dsa.h \ 20dsa.c dsa.h \
21extensions.c extensions.h \ 21extensions.c extensions.h \
22mpi.c mpi.h \ 22mpi.c mpi.h \
23pkcs12_bag.c \ 23pkcs12_encr.c pkcs12.h \
24pkcs12.c pkcs12.h \
25pkcs12_encr.c \
26pkcs7.c pkcs7.h \ 24pkcs7.c pkcs7.h \
27x509_privkey.c privkey.h \ 25x509_privkey.c privkey.h \
28privkey_pkcs8.c \ 26privkey_pkcs8.c \
@@ -30,3 +28,4 @@ rfc2818_hostname.c rfc2818.h \
30sign.c sign.h \ 28sign.c sign.h \
31x509_verify.c verify.h \ 29x509_verify.c verify.h \
32x509.c x509.h 30x509.c x509.h
31
diff --git a/src/daemon/https/x509/pkcs12.c b/src/daemon/https/x509/pkcs12.c
deleted file mode 100644
index af069e0d..00000000
--- a/src/daemon/https/x509/pkcs12.c
+++ /dev/null
@@ -1,1309 +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/* 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_decodeMHD_pkcs12_auth_safe (ASN1_TYPE pkcs12, ASN1_TYPE * authen_safe,
50 MHD_gnutls_datum_t * raw)
51{
52 char oid[128];
53 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
54 MHD_gnutls_datum_t auth_safe = { NULL, 0 };
55 int tmp_size, len, result;
56
57 len = sizeof (oid) - 1;
58 result = MHD__asn1_read_value (pkcs12, "authSafe.contentType", oid, &len);
59 if (result != ASN1_SUCCESS)
60 {
61 MHD_gnutls_assert ();
62 return MHD_gtls_asn2err (result);
63 }
64
65 if (strcmp (oid, DATA_OID) != 0)
66 {
67 MHD_gnutls_assert ();
68 MHD__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 MHD__gnutls_x509_read_value (pkcs12, "authSafe.content", &auth_safe, 1);
78 if (result < 0)
79 {
80 MHD_gnutls_assert ();
81 goto cleanup;
82 }
83
84 /* Step 2. Extract the authenticatedSafe.
85 */
86
87 if ((result = MHD__asn1_create_element
88 (MHD__gnutls_get_pkix (), "PKIX1.pkcs-12-AuthenticatedSafe",
89 &c2)) != ASN1_SUCCESS)
90 {
91 MHD_gnutls_assert ();
92 result = MHD_gtls_asn2err (result);
93 goto cleanup;
94 }
95
96 result = MHD__asn1_der_decoding (&c2, auth_safe.data, auth_safe.size, NULL);
97 if (result != ASN1_SUCCESS)
98 {
99 MHD_gnutls_assert ();
100 result = MHD_gtls_asn2err (result);
101 goto cleanup;
102 }
103
104 if (raw == NULL)
105 {
106 MHD__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 MHD__asn1_delete_structure (&c2);
118
119 return 0;
120
121cleanup:
122 if (c2)
123 MHD__asn1_delete_structure (&c2);
124 MHD__gnutls_free_datum (&auth_safe);
125 return result;
126}
127
128/**
129 * MHD_gnutlsMHD_pkcs12_init - This function initializes a MHD_gnutlsMHD_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
140MHD_gnutlsMHD_pkcs12_init (MHD_gnutlsMHD_pkcs12_t * pkcs12)
141{
142 *pkcs12 = MHD_gnutls_calloc (1, sizeof (MHD_gnutlsMHD_pkcs12_int));
143
144 if (*pkcs12)
145 {
146 int result = MHD__asn1_create_element (MHD__gnutls_get_pkix (),
147 "PKIX1.pkcs-12-PFX",
148 &(*pkcs12)->pkcs12);
149 if (result != ASN1_SUCCESS)
150 {
151 MHD_gnutls_assert ();
152 MHD_gnutls_free (*pkcs12);
153 return MHD_gtls_asn2err (result);
154 }
155 return 0; /* success */
156 }
157 return GNUTLS_E_MEMORY_ERROR;
158}
159
160/**
161 * MHD_gnutlsMHD_pkcs12_deinit - This function deinitializes memory used by a MHD_gnutlsMHD_pkcs12_t structure
162 * @pkcs12: The structure to be initialized
163 *
164 * This function will deinitialize a PKCS12 structure.
165 *
166 **/
167void
168MHD_gnutlsMHD_pkcs12_deinit (MHD_gnutlsMHD_pkcs12_t pkcs12)
169{
170 if (!pkcs12)
171 return;
172
173 if (pkcs12->pkcs12)
174 MHD__asn1_delete_structure (&pkcs12->pkcs12);
175
176 MHD_gnutls_free (pkcs12);
177}
178
179/**
180 * MHD_gnutlsMHD_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 MHD_gnutls_privkey_pkcs8_flags
185 *
186 * This function will convert the given DER or PEM encoded PKCS12
187 * to the native MHD_gnutlsMHD_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
195MHD_gnutlsMHD_pkcs12_import (MHD_gnutlsMHD_pkcs12_t pkcs12,
196 const MHD_gnutls_datum_t * data,
197 MHD_gnutls_x509_crt_fmt_t format, unsigned int flags)
198{
199 int result = 0, need_free = 0;
200 MHD_gnutls_datum_t _data;
201
202 _data.data = data->data;
203 _data.size = data->size;
204
205 if (pkcs12 == NULL)
206 {
207 MHD_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 = MHD__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 MHD_gnutls_assert ();
225 return result;
226 }
227
228 _data.data = out;
229 _data.size = result;
230
231 need_free = 1;
232 }
233
234 result = MHD__asn1_der_decoding (&pkcs12->pkcs12, _data.data, _data.size, NULL);
235 if (result != ASN1_SUCCESS)
236 {
237 result = MHD_gtls_asn2err (result);
238 MHD_gnutls_assert ();
239 goto cleanup;
240 }
241
242 if (need_free)
243 MHD__gnutls_free_datum (&_data);
244
245 return 0;
246
247cleanup:
248 if (need_free)
249 MHD__gnutls_free_datum (&_data);
250 return result;
251}
252
253
254/**
255 * MHD_gnutlsMHD_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
276MHD_gnutlsMHD_pkcs12_export (MHD_gnutlsMHD_pkcs12_t pkcs12,
277 MHD_gnutls_x509_crt_fmt_t format, void *output_data,
278 size_t * output_data_size)
279{
280 if (pkcs12 == NULL)
281 {
282 MHD_gnutls_assert ();
283 return GNUTLS_E_INVALID_REQUEST;
284 }
285
286 return MHD__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
344MHD_pkcs12_decode_safe_contents (const MHD_gnutls_datum_t * content,
345 MHD_gnutlsMHD_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 MHD_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 = MHD__asn1_create_element
359 (MHD__gnutls_get_pkix (), "PKIX1.pkcs-12-SafeContents",
360 &c2)) != ASN1_SUCCESS)
361 {
362 MHD_gnutls_assert ();
363 result = MHD_gtls_asn2err (result);
364 goto cleanup;
365 }
366
367 result = MHD__asn1_der_decoding (&c2, content->data, content->size, NULL);
368 if (result != ASN1_SUCCESS)
369 {
370 MHD_gnutls_assert ();
371 result = MHD_gtls_asn2err (result);
372 goto cleanup;
373 }
374
375 /* Count the number of bags
376 */
377 result = MHD__asn1_number_of_elements (c2, "", &count);
378 if (result != ASN1_SUCCESS)
379 {
380 MHD_gnutls_assert ();
381 result = MHD_gtls_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 = MHD__asn1_read_value (c2, root, oid, &len);
394 if (result != ASN1_SUCCESS)
395 {
396 MHD_gnutls_assert ();
397 result = MHD_gtls_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 MHD_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 = MHD__gnutls_x509_read_value (c2, root, &bag->element[i].data, 0);
417 if (result < 0)
418 {
419 MHD_gnutls_assert ();
420 goto cleanup;
421 }
422
423 if (bag_type == GNUTLS_BAG_CERTIFICATE || bag_type == GNUTLS_BAG_CRL)
424 {
425 MHD_gnutls_datum_t tmp = bag->element[i].data;
426
427 result =
428 MHD_pkcs12_decode_crt_bag (bag_type, &tmp, &bag->element[i].data);
429 if (result < 0)
430 {
431 MHD_gnutls_assert ();
432 goto cleanup;
433 }
434
435 MHD__gnutls_free_datum (&tmp);
436 }
437
438 /* read the bag attributes
439 */
440 snprintf (root, sizeof (root), "?%u.bagAttributes", i + 1);
441
442 result = MHD__asn1_number_of_elements (c2, root, &attributes);
443 if (result != ASN1_SUCCESS && result != ASN1_ELEMENT_NOT_FOUND)
444 {
445 MHD_gnutls_assert ();
446 result = MHD_gtls_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 MHD__gnutls_x509_decode_and_read_attribute (c2, root, oid,
462 sizeof (oid), &attr_val,
463 1, 0);
464
465 if (result < 0)
466 {
467 MHD_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 MHD__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 MHD__gnutls_free_datum (&attr_val);
482 MHD_gnutls_assert ();
483 MHD__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 MHD__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 MHD__gnutls_free_datum (&attr_val);
500 MHD_gnutls_assert ();
501 MHD__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 MHD__gnutls_free_datum (&attr_val);
511 MHD__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 MHD__asn1_delete_structure (&c2);
522
523
524 return 0;
525
526cleanup:
527 if (c2)
528 MHD__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 MHD_gnutlsMHD_pkcs12_bag_t bag)
537{
538 MHD_gnutls_datum_t content = { NULL, 0 };
539 int result;
540
541 /* Step 1. Extract the content.
542 */
543
544 result = MHD__gnutls_x509_read_value (sc, sc_name, &content, 1);
545 if (result < 0)
546 {
547 MHD_gnutls_assert ();
548 goto cleanup;
549 }
550
551 result = MHD_pkcs12_decode_safe_contents (&content, bag);
552 if (result < 0)
553 {
554 MHD_gnutls_assert ();
555 goto cleanup;
556 }
557
558 MHD__gnutls_free_datum (&content);
559
560 return 0;
561
562cleanup:
563 MHD__gnutls_free_datum (&content);
564 return result;
565}
566
567
568/**
569 * MHD_gnutlsMHD_pkcs12_get_bag - This function returns a Bag from a PKCS12 structure
570 * @pkcs12: should contain a MHD_gnutlsMHD_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
582MHD_gnutlsMHD_pkcs12_get_bag (MHD_gnutlsMHD_pkcs12_t pkcs12,
583 int indx, MHD_gnutlsMHD_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 MHD_gnutls_assert ();
593 return GNUTLS_E_INVALID_REQUEST;
594 }
595
596 /* Step 1. decode the data.
597 */
598 result = _decodeMHD_pkcs12_auth_safe (pkcs12->pkcs12, &c2, NULL);
599 if (result < 0)
600 {
601 MHD_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 = MHD__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 MHD_gnutls_assert ();
622 result = MHD_gtls_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 = MHD__gnutls_x509_read_value (c2, root2, &bag->element[0].data, 0);
643 if (result < 0)
644 {
645 MHD_gnutls_assert ();
646 goto cleanup;
647 }
648
649 result = 0;
650
651cleanup:
652 if (c2)
653 MHD__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 = MHD__asn1_write_value (pkcs12, "version", &three, 1);
669 if (result != ASN1_SUCCESS)
670 {
671 MHD_gnutls_assert ();
672 result = MHD_gtls_asn2err (result);
673 goto cleanup;
674 }
675
676 /* Write the content type of the data
677 */
678 result = MHD__asn1_write_value (pkcs12, "authSafe.contentType", DATA_OID, 1);
679 if (result != ASN1_SUCCESS)
680 {
681 MHD_gnutls_assert ();
682 result = MHD_gtls_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 = MHD__asn1_create_element
691 (MHD__gnutls_get_pkix (), "PKIX1.pkcs-12-AuthenticatedSafe",
692 &c2)) != ASN1_SUCCESS)
693 {
694 MHD_gnutls_assert ();
695 result = MHD_gtls_asn2err (result);
696 goto cleanup;
697 }
698
699 result =
700 MHD__gnutls_x509_der_encode_and_copy (c2, "", pkcs12, "authSafe.content", 1);
701 if (result < 0)
702 {
703 MHD_gnutls_assert ();
704 goto cleanup;
705 }
706 MHD__asn1_delete_structure (&c2);
707
708 return 0;
709
710cleanup:
711 MHD__asn1_delete_structure (&c2);
712 return result;
713
714}
715
716/**
717 * MHD_gnutlsMHD_pkcs12_set_bag - This function inserts a Bag into a PKCS12 structure
718 * @pkcs12: should contain a MHD_gnutlsMHD_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
726MHD_gnutlsMHD_pkcs12_set_bag (MHD_gnutlsMHD_pkcs12_t pkcs12, MHD_gnutlsMHD_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 MHD_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 = MHD__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 MHD_gnutls_assert ();
750 return result;
751 }
752 }
753
754 /* Step 2. decode the authenticatedSafe.
755 */
756 result = _decodeMHD_pkcs12_auth_safe (pkcs12->pkcs12, &c2, NULL);
757 if (result < 0)
758 {
759 MHD_gnutls_assert ();
760 return result;
761 }
762
763 /* Step 3. Encode the bag elements into a SafeContents
764 * structure.
765 */
766 result = MHD_pkcs12_encode_safe_contents (bag, &safe_cont, &enc);
767 if (result < 0)
768 {
769 MHD_gnutls_assert ();
770 return result;
771 }
772
773 /* Step 4. Insert the encoded SafeContents into the AuthenticatedSafe
774 * structure.
775 */
776 result = MHD__asn1_write_value (c2, "", "NEW", 1);
777 if (result != ASN1_SUCCESS)
778 {
779 MHD_gnutls_assert ();
780 result = MHD_gtls_asn2err (result);
781 goto cleanup;
782 }
783
784 if (enc)
785 result = MHD__asn1_write_value (c2, "?LAST.contentType", ENC_DATA_OID, 1);
786 else
787 result = MHD__asn1_write_value (c2, "?LAST.contentType", DATA_OID, 1);
788 if (result != ASN1_SUCCESS)
789 {
790 MHD_gnutls_assert ();
791 result = MHD_gtls_asn2err (result);
792 goto cleanup;
793 }
794
795 if (enc)
796 {
797 /* Encrypted packets are written directly.
798 */
799 result =
800 MHD__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 MHD_gnutls_assert ();
806 result = MHD_gtls_asn2err (result);
807 goto cleanup;
808 }
809 }
810 else
811 {
812 result =
813 MHD__gnutls_x509_der_encode_and_copy (safe_cont, "", c2,
814 "?LAST.content", 1);
815 if (result < 0)
816 {
817 MHD_gnutls_assert ();
818 goto cleanup;
819 }
820 }
821
822 MHD__asn1_delete_structure (&safe_cont);
823
824
825 /* Step 5. Reencode and copy the AuthenticatedSafe into the pkcs12
826 * structure.
827 */
828 result =
829 MHD__gnutls_x509_der_encode_and_copy (c2, "", pkcs12->pkcs12,
830 "authSafe.content", 1);
831 if (result < 0)
832 {
833 MHD_gnutls_assert ();
834 goto cleanup;
835 }
836
837 MHD__asn1_delete_structure (&c2);
838
839 return 0;
840
841cleanup:
842 MHD__asn1_delete_structure (&c2);
843 MHD__asn1_delete_structure (&safe_cont);
844 return result;
845}
846
847/**
848 * MHD_gnutlsMHD_pkcs12_generate_mac - This function generates the MAC of the PKCS12 structure
849 * @pkcs12: should contain a MHD_gnutlsMHD_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
857MHD_gnutlsMHD_pkcs12_generate_mac (MHD_gnutlsMHD_pkcs12_t pkcs12, const char *pass)
858{
859 opaque salt[8], key[20];
860 int result;
861 mac_hd_t td1 = NULL;
862 MHD_gnutls_datum_t tmp = { NULL, 0 };
863 opaque sha_mac[20];
864
865 if (pkcs12 == NULL)
866 {
867 MHD_gnutls_assert ();
868 return GNUTLS_E_INVALID_REQUEST;
869 }
870
871 /* Generate the salt.
872 */
873 if (MHD_gc_nonce (salt, sizeof (salt)) != GC_OK)
874 {
875 MHD_gnutls_assert ();
876 return GNUTLS_E_RANDOM_FAILED;
877 }
878
879 /* Write the salt into the structure.
880 */
881 result =
882 MHD__asn1_write_value (pkcs12->pkcs12, "macData.macSalt", salt, sizeof (salt));
883 if (result != ASN1_SUCCESS)
884 {
885 MHD_gnutls_assert ();
886 result = MHD_gtls_asn2err (result);
887 goto cleanup;
888 }
889
890 /* Generate the key.
891 */
892 result = MHD_pkcs12_string_to_key (3 /*MAC*/, salt, sizeof (salt),
893 1, pass, sizeof (key), key);
894 if (result < 0)
895 {
896 MHD_gnutls_assert ();
897 goto cleanup;
898 }
899
900 /* Get the data to be MACed
901 */
902 result = _decodeMHD_pkcs12_auth_safe (pkcs12->pkcs12, NULL, &tmp);
903 if (result < 0)
904 {
905 MHD_gnutls_assert ();
906 goto cleanup;
907 }
908
909 /* MAC the data
910 */
911 td1 = MHD_gtls_MHD_hmac_init (MHD_GNUTLS_MAC_SHA1, key, sizeof (key));
912 if (td1 == GNUTLS_MAC_FAILED)
913 {
914 MHD_gnutls_assert ();
915 result = GNUTLS_E_INTERNAL_ERROR;
916 goto cleanup;
917 }
918
919 MHD_gnutls_hash (td1, tmp.data, tmp.size);
920 MHD__gnutls_free_datum (&tmp);
921
922 MHD_gnutls_MHD_hmac_deinit (td1, sha_mac);
923
924
925 result =
926 MHD__asn1_write_value (pkcs12->pkcs12, "macData.mac.digest", sha_mac,
927 sizeof (sha_mac));
928 if (result != ASN1_SUCCESS)
929 {
930 MHD_gnutls_assert ();
931 result = MHD_gtls_asn2err (result);
932 goto cleanup;
933 }
934
935 result =
936 MHD__asn1_write_value (pkcs12->pkcs12,
937 "macData.mac.digestAlgorithm.parameters", NULL, 0);
938 if (result != ASN1_SUCCESS)
939 {
940 MHD_gnutls_assert ();
941 result = MHD_gtls_asn2err (result);
942 goto cleanup;
943 }
944
945 result =
946 MHD__asn1_write_value (pkcs12->pkcs12,
947 "macData.mac.digestAlgorithm.algorithm", HASH_OID_SHA1,
948 1);
949 if (result != ASN1_SUCCESS)
950 {
951 MHD_gnutls_assert ();
952 result = MHD_gtls_asn2err (result);
953 goto cleanup;
954 }
955
956 return 0;
957
958cleanup:
959 MHD__gnutls_free_datum (&tmp);
960 return result;
961}
962
963/**
964 * MHD_gnutlsMHD_pkcs12_verify_mac - This function verifies the MAC of the PKCS12 structure
965 * @pkcs12: should contain a MHD_gnutlsMHD_pkcs12_t structure
966 * @pass: The password for the MAC
967 *
968 * This function will verify the MAC for the PKCS12 structure.
969 * Returns 0 on success.
970 *
971 **/
972int
973MHD_gnutlsMHD_pkcs12_verify_mac (MHD_gnutlsMHD_pkcs12_t pkcs12, const char *pass)
974{
975 opaque key[20];
976 int result;
977 unsigned int iter;
978 int len;
979 mac_hd_t td1 = NULL;
980 MHD_gnutls_datum_t tmp = { NULL, 0 }, salt =
981 {
982 NULL, 0};
983 opaque sha_mac[20];
984 opaque sha_mac_orig[20];
985
986 if (pkcs12 == NULL)
987 {
988 MHD_gnutls_assert ();
989 return GNUTLS_E_INVALID_REQUEST;
990 }
991
992 /* read the iterations
993 */
994
995 result =
996 MHD__gnutls_x509_read_uint (pkcs12->pkcs12, "macData.iterations", &iter);
997 if (result < 0)
998 {
999 iter = 1; /* the default */
1000 }
1001
1002
1003 /* Read the salt from the structure.
1004 */
1005 result =
1006 MHD__gnutls_x509_read_value (pkcs12->pkcs12, "macData.macSalt", &salt, 0);
1007 if (result != ASN1_SUCCESS)
1008 {
1009 MHD_gnutls_assert ();
1010 result = MHD_gtls_asn2err (result);
1011 goto cleanup;
1012 }
1013
1014 /* Generate the key.
1015 */
1016 result = MHD_pkcs12_string_to_key (3 /*MAC*/, salt.data, salt.size,
1017 iter, pass, sizeof (key), key);
1018 if (result < 0)
1019 {
1020 MHD_gnutls_assert ();
1021 goto cleanup;
1022 }
1023
1024 MHD__gnutls_free_datum (&salt);
1025
1026 /* Get the data to be MACed
1027 */
1028 result = _decodeMHD_pkcs12_auth_safe (pkcs12->pkcs12, NULL, &tmp);
1029 if (result < 0)
1030 {
1031 MHD_gnutls_assert ();
1032 goto cleanup;
1033 }
1034
1035 /* MAC the data
1036 */
1037 td1 = MHD_gtls_MHD_hmac_init (MHD_GNUTLS_MAC_SHA1, key, sizeof (key));
1038 if (td1 == GNUTLS_MAC_FAILED)
1039 {
1040 MHD_gnutls_assert ();
1041 result = GNUTLS_E_INTERNAL_ERROR;
1042 goto cleanup;
1043 }
1044
1045 MHD_gnutls_hash (td1, tmp.data, tmp.size);
1046 MHD__gnutls_free_datum (&tmp);
1047
1048 MHD_gnutls_MHD_hmac_deinit (td1, sha_mac);
1049
1050 len = sizeof (sha_mac_orig);
1051 result =
1052 MHD__asn1_read_value (pkcs12->pkcs12, "macData.mac.digest", sha_mac_orig,
1053 &len);
1054 if (result != ASN1_SUCCESS)
1055 {
1056 MHD_gnutls_assert ();
1057 result = MHD_gtls_asn2err (result);
1058 goto cleanup;
1059 }
1060
1061 if (memcmp (sha_mac_orig, sha_mac, sizeof (sha_mac)) != 0)
1062 {
1063 MHD_gnutls_assert ();
1064 return GNUTLS_E_MAC_VERIFY_FAILED;
1065 }
1066
1067 return 0;
1068
1069cleanup:
1070 MHD__gnutls_free_datum (&tmp);
1071 MHD__gnutls_free_datum (&salt);
1072 return result;
1073}
1074
1075
1076static int
1077write_attributes (MHD_gnutlsMHD_pkcs12_bag_t bag, int elem,
1078 ASN1_TYPE c2, const char *where)
1079{
1080 int result;
1081 char root[128];
1082
1083 /* If the bag attributes are empty, then write
1084 * nothing to the attribute field.
1085 */
1086 if (bag->element[elem].friendly_name == NULL &&
1087 bag->element[elem].local_key_id.data == NULL)
1088 {
1089 /* no attributes
1090 */
1091 result = MHD__asn1_write_value (c2, where, NULL, 0);
1092 if (result != ASN1_SUCCESS)
1093 {
1094 MHD_gnutls_assert ();
1095 return MHD_gtls_asn2err (result);
1096 }
1097
1098 return 0;
1099 }
1100
1101 if (bag->element[elem].local_key_id.data != NULL)
1102 {
1103
1104 /* Add a new Attribute
1105 */
1106 result = MHD__asn1_write_value (c2, where, "NEW", 1);
1107 if (result != ASN1_SUCCESS)
1108 {
1109 MHD_gnutls_assert ();
1110 return MHD_gtls_asn2err (result);
1111 }
1112
1113 MHD_gtls_str_cpy (root, sizeof (root), where);
1114 MHD_gtls_str_cat (root, sizeof (root), ".?LAST");
1115
1116 result =
1117 MHD__gnutls_x509_encode_and_write_attribute (KEY_ID_OID, c2, root,
1118 bag->element[elem].
1119 local_key_id.data,
1120 bag->element[elem].
1121 local_key_id.size, 1);
1122 if (result < 0)
1123 {
1124 MHD_gnutls_assert ();
1125 return result;
1126 }
1127 }
1128
1129 if (bag->element[elem].friendly_name != NULL)
1130 {
1131 opaque *name;
1132 int size, i;
1133 const char *p;
1134
1135 /* Add a new Attribute
1136 */
1137 result = MHD__asn1_write_value (c2, where, "NEW", 1);
1138 if (result != ASN1_SUCCESS)
1139 {
1140 MHD_gnutls_assert ();
1141 return MHD_gtls_asn2err (result);
1142 }
1143
1144 /* convert name to BMPString
1145 */
1146 size = strlen (bag->element[elem].friendly_name) * 2;
1147 name = MHD_gnutls_malloc (size);
1148
1149 if (name == NULL)
1150 {
1151 MHD_gnutls_assert ();
1152 return GNUTLS_E_MEMORY_ERROR;
1153 }
1154
1155 p = bag->element[elem].friendly_name;
1156 for (i = 0; i < size; i += 2)
1157 {
1158 name[i] = 0;
1159 name[i + 1] = *p;
1160 p++;
1161 }
1162
1163 MHD_gtls_str_cpy (root, sizeof (root), where);
1164 MHD_gtls_str_cat (root, sizeof (root), ".?LAST");
1165
1166 result =
1167 MHD__gnutls_x509_encode_and_write_attribute (FRIENDLY_NAME_OID, c2,
1168 root, name, size, 1);
1169
1170 MHD_gnutls_free (name);
1171
1172 if (result < 0)
1173 {
1174 MHD_gnutls_assert ();
1175 return result;
1176 }
1177 }
1178
1179 return 0;
1180}
1181
1182
1183/* Encodes the bag into a SafeContents structure, and puts the output in
1184 * the given datum. Enc is set to non zero if the data are encrypted;
1185 */
1186int
1187MHD_pkcs12_encode_safe_contents (MHD_gnutlsMHD_pkcs12_bag_t bag, ASN1_TYPE * contents,
1188 int *enc)
1189{
1190 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
1191 int result;
1192 int i;
1193 const char *oid;
1194
1195 if (bag->element[0].type == GNUTLS_BAG_ENCRYPTED && enc)
1196 {
1197 *enc = 1;
1198 return 0; /* ENCRYPTED BAG, do nothing. */
1199 }
1200 else if (enc)
1201 *enc = 0;
1202
1203 /* Step 1. Create the SEQUENCE.
1204 */
1205
1206 if ((result = MHD__asn1_create_element
1207 (MHD__gnutls_get_pkix (), "PKIX1.pkcs-12-SafeContents",
1208 &c2)) != ASN1_SUCCESS)
1209 {
1210 MHD_gnutls_assert ();
1211 result = MHD_gtls_asn2err (result);
1212 goto cleanup;
1213 }
1214
1215 for (i = 0; i < bag->bag_elements; i++)
1216 {
1217
1218 oid = bag_to_oid (bag->element[i].type);
1219 if (oid == NULL)
1220 {
1221 MHD_gnutls_assert ();
1222 continue;
1223 }
1224
1225 result = MHD__asn1_write_value (c2, "", "NEW", 1);
1226 if (result != ASN1_SUCCESS)
1227 {
1228 MHD_gnutls_assert ();
1229 result = MHD_gtls_asn2err (result);
1230 goto cleanup;
1231 }
1232
1233 /* Copy the bag type.
1234 */
1235 result = MHD__asn1_write_value (c2, "?LAST.bagId", oid, 1);
1236 if (result != ASN1_SUCCESS)
1237 {
1238 MHD_gnutls_assert ();
1239 result = MHD_gtls_asn2err (result);
1240 goto cleanup;
1241 }
1242
1243 /* Set empty attributes
1244 */
1245 result = write_attributes (bag, i, c2, "?LAST.bagAttributes");
1246 if (result < 0)
1247 {
1248 MHD_gnutls_assert ();
1249 goto cleanup;
1250 }
1251
1252
1253 /* Copy the Bag Value
1254 */
1255
1256 if (bag->element[i].type == GNUTLS_BAG_CERTIFICATE ||
1257 bag->element[i].type == GNUTLS_BAG_CRL)
1258 {
1259 MHD_gnutls_datum_t tmp;
1260
1261 /* in that case encode it to a CertBag or
1262 * a CrlBag.
1263 */
1264
1265 result =
1266 MHD_pkcs12_encode_crt_bag (bag->element[i].type,
1267 &bag->element[i].data, &tmp);
1268
1269 if (result < 0)
1270 {
1271 MHD_gnutls_assert ();
1272 goto cleanup;
1273 }
1274
1275 result = MHD__gnutls_x509_write_value (c2, "?LAST.bagValue", &tmp, 0);
1276
1277 MHD__gnutls_free_datum (&tmp);
1278
1279 }
1280 else
1281 {
1282
1283 result = MHD__gnutls_x509_write_value (c2, "?LAST.bagValue",
1284 &bag->element[i].data, 0);
1285 }
1286
1287 if (result < 0)
1288 {
1289 MHD_gnutls_assert ();
1290 goto cleanup;
1291 }
1292
1293 }
1294
1295 /* Encode the data and copy them into the datum
1296 */
1297 *contents = c2;
1298
1299 return 0;
1300
1301cleanup:
1302 if (c2)
1303 MHD__asn1_delete_structure (&c2);
1304 return result;
1305
1306}
1307
1308
1309#endif /* ENABLE_PKI */
diff --git a/src/daemon/https/x509/pkcs12.h b/src/daemon/https/x509/pkcs12.h
index 565ed5e5..a9738b94 100644
--- a/src/daemon/https/x509/pkcs12.h
+++ b/src/daemon/https/x509/pkcs12.h
@@ -37,15 +37,15 @@ extern "C"
37 37
38/* PKCS12 structures handling 38/* PKCS12 structures handling
39 */ 39 */
40 struct MHD_gnutlsMHD_pkcs12_int; 40 struct MHD_gnutls_pkcs12_int;
41 41
42 struct MHD_gnutlsMHD_pkcs12_bag_int; 42 struct MHD_gnutls_pkcs12_bag_int;
43 typedef struct MHD_gnutlsMHD_pkcs12_int 43 typedef struct MHD_gnutls_pkcs12_int
44 { 44 {
45 ASN1_TYPE pkcs12; 45 ASN1_TYPE pkcs12;
46 } MHD_gnutlsMHD_pkcs12_int; 46 } MHD_gnutls_pkcs12_int;
47 47
48 typedef enum MHD_gnutlsMHD_pkcs12_bag_type_t 48 typedef enum MHD_gnutls_pkcs12_bag_type_t
49 { 49 {
50 GNUTLS_BAG_EMPTY = 0, 50 GNUTLS_BAG_EMPTY = 0,
51 51
@@ -55,73 +55,62 @@ extern "C"
55 GNUTLS_BAG_CRL, 55 GNUTLS_BAG_CRL,
56 GNUTLS_BAG_ENCRYPTED = 10, 56 GNUTLS_BAG_ENCRYPTED = 10,
57 GNUTLS_BAG_UNKNOWN = 20 57 GNUTLS_BAG_UNKNOWN = 20
58 } MHD_gnutlsMHD_pkcs12_bag_type_t; 58 } MHD_gnutls_pkcs12_bag_type_t;
59 59
60 struct bag_element 60 struct bag_element
61 { 61 {
62 MHD_gnutls_datum_t data; 62 MHD_gnutls_datum_t data;
63 MHD_gnutlsMHD_pkcs12_bag_type_t type; 63 MHD_gnutls_pkcs12_bag_type_t type;
64 MHD_gnutls_datum_t local_key_id; 64 MHD_gnutls_datum_t local_key_id;
65 char *friendly_name; 65 char *friendly_name;
66 }; 66 };
67 67
68 typedef struct MHD_gnutlsMHD_pkcs12_bag_int 68 typedef struct MHD_gnutls_pkcs12_bag_int
69 { 69 {
70 struct bag_element element[MAX_BAG_ELEMENTS]; 70 struct bag_element element[MAX_BAG_ELEMENTS];
71 int bag_elements; 71 int bag_elements;
72 } MHD_gnutlsMHD_pkcs12_bag_int; 72 } MHD_gnutls_pkcs12_bag_int;
73 73
74/* Bag attributes */ 74/* Bag attributes */
75#define FRIENDLY_NAME_OID "1.2.840.113549.1.9.20" 75#define FRIENDLY_NAME_OID "1.2.840.113549.1.9.20"
76#define KEY_ID_OID "1.2.840.113549.1.9.21" 76#define KEY_ID_OID "1.2.840.113549.1.9.21"
77 77
78 typedef struct MHD_gnutlsMHD_pkcs12_int *MHD_gnutlsMHD_pkcs12_t; 78 typedef struct MHD_gnutls_pkcs12_int *MHD_gnutls_pkcs12_t;
79 typedef struct MHD_gnutlsMHD_pkcs12_bag_int *MHD_gnutlsMHD_pkcs12_bag_t; 79 typedef struct MHD_gnutls_pkcs12_bag_int *MHD_gnutls_pkcs12_bag_t;
80 80
81 int MHD_gnutlsMHD_pkcs12_init (MHD_gnutlsMHD_pkcs12_t * pkcs12); 81 int MHD_gnutls_pkcs12_init (MHD_gnutls_pkcs12_t * pkcs12);
82 void MHD_gnutlsMHD_pkcs12_deinit (MHD_gnutlsMHD_pkcs12_t pkcs12); 82 void MHD_gnutls_pkcs12_deinit (MHD_gnutls_pkcs12_t pkcs12);
83 int MHD_gnutlsMHD_pkcs12_import (MHD_gnutlsMHD_pkcs12_t pkcs12, 83 int MHD_gnutls_pkcs12_import (MHD_gnutls_pkcs12_t pkcs12,
84 const MHD_gnutls_datum_t * data, 84 const MHD_gnutls_datum_t * data,
85 MHD_gnutls_x509_crt_fmt_t format, unsigned int flags); 85 MHD_gnutls_x509_crt_fmt_t format, unsigned int flags);
86 int MHD_gnutlsMHD_pkcs12_export (MHD_gnutlsMHD_pkcs12_t pkcs12, 86 int MHD_gnutls_pkcs12_export (MHD_gnutls_pkcs12_t pkcs12,
87 MHD_gnutls_x509_crt_fmt_t format, 87 MHD_gnutls_x509_crt_fmt_t format,
88 void *output_data, size_t * output_data_size); 88 void *output_data, size_t * output_data_size);
89 89
90 int MHD_gnutlsMHD_pkcs12_get_bag (MHD_gnutlsMHD_pkcs12_t pkcs12, 90 int MHD_gnutls_pkcs12_bag_decrypt (MHD_gnutls_pkcs12_bag_t bag, const char *pass);
91 int indx, MHD_gnutlsMHD_pkcs12_bag_t bag); 91 int MHD_gnutls_pkcs12_bag_encrypt (MHD_gnutls_pkcs12_bag_t bag,
92 int MHD_gnutlsMHD_pkcs12_set_bag (MHD_gnutlsMHD_pkcs12_t pkcs12, MHD_gnutlsMHD_pkcs12_bag_t bag);
93
94 int MHD_gnutlsMHD_pkcs12_generate_mac (MHD_gnutlsMHD_pkcs12_t pkcs12, const char *pass);
95 int MHD_gnutlsMHD_pkcs12_verify_mac (MHD_gnutlsMHD_pkcs12_t pkcs12, const char *pass);
96
97 int MHD_gnutlsMHD_pkcs12_bag_decrypt (MHD_gnutlsMHD_pkcs12_bag_t bag, const char *pass);
98 int MHD_gnutlsMHD_pkcs12_bag_encrypt (MHD_gnutlsMHD_pkcs12_bag_t bag,
99 const char *pass, unsigned int flags); 92 const char *pass, unsigned int flags);
100 93
101 MHD_gnutlsMHD_pkcs12_bag_type_t MHD_gnutlsMHD_pkcs12_bag_get_type (MHD_gnutlsMHD_pkcs12_bag_t 94 int MHD_gnutls_pkcs12_bag_get_data (MHD_gnutls_pkcs12_bag_t bag,
102 bag, int indx);
103 int MHD_gnutlsMHD_pkcs12_bag_get_data (MHD_gnutlsMHD_pkcs12_bag_t bag,
104 int indx, MHD_gnutls_datum_t * data); 95 int indx, MHD_gnutls_datum_t * data);
105 int MHD_gnutlsMHD_pkcs12_bag_set_data (MHD_gnutlsMHD_pkcs12_bag_t bag, 96 int MHD_gnutls_pkcs12_bag_set_data (MHD_gnutls_pkcs12_bag_t bag,
106 MHD_gnutlsMHD_pkcs12_bag_type_t type, 97 MHD_gnutls_pkcs12_bag_type_t type,
107 const MHD_gnutls_datum_t * data); 98 const MHD_gnutls_datum_t * data);
108 int MHD_gnutlsMHD_pkcs12_bag_set_crl (MHD_gnutlsMHD_pkcs12_bag_t bag, 99 int MHD_gnutls_pkcs12_bag_set_crl (MHD_gnutls_pkcs12_bag_t bag,
109 MHD_gnutls_x509_crl_t crl); 100 MHD_gnutls_x509_crl_t crl);
110 int MHD_gnutlsMHD_pkcs12_bag_set_crt (MHD_gnutlsMHD_pkcs12_bag_t bag, 101 int MHD_gnutls_pkcs12_bag_set_crt (MHD_gnutls_pkcs12_bag_t bag,
111 MHD_gnutls_x509_crt_t crt); 102 MHD_gnutls_x509_crt_t crt);
112 103
113 int MHD_gnutlsMHD_pkcs12_bag_init (MHD_gnutlsMHD_pkcs12_bag_t * bag); 104 int MHD_gnutls_pkcs12_bag_get_count (MHD_gnutls_pkcs12_bag_t bag);
114 void MHD_gnutlsMHD_pkcs12_bag_deinit (MHD_gnutlsMHD_pkcs12_bag_t bag);
115 int MHD_gnutlsMHD_pkcs12_bag_get_count (MHD_gnutlsMHD_pkcs12_bag_t bag);
116 105
117 int MHD_gnutlsMHD_pkcs12_bag_get_key_id (MHD_gnutlsMHD_pkcs12_bag_t bag, 106 int MHD_gnutls_pkcs12_bag_get_key_id (MHD_gnutls_pkcs12_bag_t bag,
118 int indx, MHD_gnutls_datum_t * id); 107 int indx, MHD_gnutls_datum_t * id);
119 int MHD_gnutlsMHD_pkcs12_bag_set_key_id (MHD_gnutlsMHD_pkcs12_bag_t bag, 108 int MHD_gnutls_pkcs12_bag_set_key_id (MHD_gnutls_pkcs12_bag_t bag,
120 int indx, const MHD_gnutls_datum_t * id); 109 int indx, const MHD_gnutls_datum_t * id);
121 110
122 int MHD_gnutlsMHD_pkcs12_bag_get_friendly_name (MHD_gnutlsMHD_pkcs12_bag_t bag, 111 int MHD_gnutls_pkcs12_bag_get_friendly_name (MHD_gnutls_pkcs12_bag_t bag,
123 int indx, char **name); 112 int indx, char **name);
124 int MHD_gnutlsMHD_pkcs12_bag_set_friendly_name (MHD_gnutlsMHD_pkcs12_bag_t bag, 113 int MHD_gnutls_pkcs12_bag_set_friendly_name (MHD_gnutls_pkcs12_bag_t bag,
125 int indx, const char *name); 114 int indx, const char *name);
126 115
127#ifdef __cplusplus 116#ifdef __cplusplus
@@ -138,48 +127,19 @@ extern "C"
138#define DATA_OID "1.2.840.113549.1.7.1" 127#define DATA_OID "1.2.840.113549.1.7.1"
139#define ENC_DATA_OID "1.2.840.113549.1.7.6" 128#define ENC_DATA_OID "1.2.840.113549.1.7.6"
140 129
141int MHD_gnutlsMHD_pkcs12_init (MHD_gnutlsMHD_pkcs12_t * pkcs12);
142void MHD_gnutlsMHD_pkcs12_deinit (MHD_gnutlsMHD_pkcs12_t pkcs12);
143int MHD_gnutlsMHD_pkcs12_import (MHD_gnutlsMHD_pkcs12_t pkcs12,
144 const MHD_gnutls_datum_t * data,
145 MHD_gnutls_x509_crt_fmt_t format, unsigned int flags);
146
147int MHD_gnutlsMHD_pkcs12_get_bag (MHD_gnutlsMHD_pkcs12_t pkcs12,
148 int indx, MHD_gnutlsMHD_pkcs12_bag_t bag);
149
150int MHD_gnutlsMHD_pkcs12_bag_init (MHD_gnutlsMHD_pkcs12_bag_t * bag);
151void MHD_gnutlsMHD_pkcs12_bag_deinit (MHD_gnutlsMHD_pkcs12_bag_t bag);
152
153int MHD_pkcs12_string_to_key (unsigned int id,
154 const opaque * salt,
155 unsigned int salt_size,
156 unsigned int iter,
157 const char *pw,
158 unsigned int req_keylen, opaque * keybuf);
159
160int MHD__gnutls_pkcs7_decrypt_data (const MHD_gnutls_datum_t * data,
161 const char *password, MHD_gnutls_datum_t * dec);
162
163typedef enum schema_id 130typedef enum schema_id
164{ 131{
165 PBES2, /* the stuff in PKCS #5 */ 132 PBES2, /* the stuff in PKCS #5 */
166 PKCS12_3DES_SHA1, /* the fucking stuff in PKCS #12 */ 133 PKCS12_3DES_SHA1, /* the stuff in PKCS #12 */
167 PKCS12_ARCFOUR_SHA1, 134 PKCS12_ARCFOUR_SHA1,
168 PKCS12_RC2_40_SHA1 135 PKCS12_RC2_40_SHA1
169} schema_id; 136} schema_id;
170 137
171int MHD__gnutls_pkcs7_encrypt_data (schema_id schema, 138int MHD_pkcs12_string_to_key (unsigned int id,
172 const MHD_gnutls_datum_t * data, 139 const opaque * salt,
173 const char *password, MHD_gnutls_datum_t * enc); 140 unsigned int salt_size,
174int MHD_pkcs12_decode_safe_contents (const MHD_gnutls_datum_t * content, 141 unsigned int iter,
175 MHD_gnutlsMHD_pkcs12_bag_t bag); 142 const char *pw,
176 143 unsigned int req_keylen, opaque * keybuf);
177int MHD_pkcs12_encode_safe_contents (MHD_gnutlsMHD_pkcs12_bag_t bag,
178 ASN1_TYPE * content, int *enc);
179
180int MHD_pkcs12_decode_crt_bag (MHD_gnutlsMHD_pkcs12_bag_type_t type,
181 const MHD_gnutls_datum_t * in, MHD_gnutls_datum_t * out);
182int MHD_pkcs12_encode_crt_bag (MHD_gnutlsMHD_pkcs12_bag_type_t type,
183 const MHD_gnutls_datum_t * raw, MHD_gnutls_datum_t * out);
184 144
185#endif /* GNUTLS_PKCS12_H */ 145#endif /* GNUTLS_PKCS12_H */
diff --git a/src/daemon/https/x509/pkcs12_bag.c b/src/daemon/https/x509/pkcs12_bag.c
deleted file mode 100644
index 10529273..00000000
--- a/src/daemon/https/x509/pkcs12_bag.c
+++ /dev/null
@@ -1,770 +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/* 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 * MHD_gnutlsMHD_pkcs12_bag_init - This function initializes a MHD_gnutlsMHD_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
51MHD_gnutlsMHD_pkcs12_bag_init (MHD_gnutlsMHD_pkcs12_bag_t * bag)
52{
53 *bag = MHD_gnutls_calloc (1, sizeof (MHD_gnutlsMHD_pkcs12_bag_int));
54
55 if (*bag)
56 {
57 return 0; /* success */
58 }
59 return GNUTLS_E_MEMORY_ERROR;
60}
61
62static inline void
63MHD_pkcs12_bag_free_data (MHD_gnutlsMHD_pkcs12_bag_t bag)
64{
65 int i;
66
67 for (i = 0; i < bag->bag_elements; i++)
68 {
69 MHD__gnutls_free_datum (&bag->element[i].data);
70 MHD__gnutls_free_datum (&bag->element[i].local_key_id);
71 MHD_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 * MHD_gnutlsMHD_pkcs12_bag_deinit - This function deinitializes memory used by a MHD_gnutlsMHD_pkcs12_t structure
81 * @bag: The structure to be initialized
82 *
83 * This function will deinitialize a PKCS12 Bag structure.
84 *
85 **/
86void
87MHD_gnutlsMHD_pkcs12_bag_deinit (MHD_gnutlsMHD_pkcs12_bag_t bag)
88{
89 if (!bag)
90 return;
91
92 MHD_pkcs12_bag_free_data (bag);
93
94 MHD_gnutls_free (bag);
95}
96
97/**
98 * MHD_gnutlsMHD_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 MHD_gnutlsMHD_pkcs12_bag_type_t
103 * enumerations.
104 *
105 **/
106MHD_gnutlsMHD_pkcs12_bag_type_t
107MHD_gnutlsMHD_pkcs12_bag_get_type (MHD_gnutlsMHD_pkcs12_bag_t bag, int indx)
108{
109 if (bag == NULL)
110 {
111 MHD_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 * MHD_gnutlsMHD_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
128MHD_gnutlsMHD_pkcs12_bag_get_count (MHD_gnutlsMHD_pkcs12_bag_t bag)
129{
130 if (bag == NULL)
131 {
132 MHD_gnutls_assert ();
133 return GNUTLS_E_INVALID_REQUEST;
134 }
135
136 return bag->bag_elements;
137}
138
139/**
140 * MHD_gnutlsMHD_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
153MHD_gnutlsMHD_pkcs12_bag_get_data (MHD_gnutlsMHD_pkcs12_bag_t bag, int indx,
154 MHD_gnutls_datum_t * data)
155{
156 if (bag == NULL)
157 {
158 MHD_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
175MHD_pkcs12_decode_crt_bag (MHD_gnutlsMHD_pkcs12_bag_type_t type,
176 const MHD_gnutls_datum_t * in, MHD_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 = MHD__asn1_create_element (MHD__gnutls_get_pkix (),
184 "PKIX1.pkcs-12-CertBag",
185 &c2)) != ASN1_SUCCESS)
186 {
187 MHD_gnutls_assert ();
188 ret = MHD_gtls_asn2err (ret);
189 goto cleanup;
190 }
191
192 ret = MHD__asn1_der_decoding (&c2, in->data, in->size, NULL);
193 if (ret != ASN1_SUCCESS)
194 {
195 MHD_gnutls_assert ();
196 ret = MHD_gtls_asn2err (ret);
197 goto cleanup;
198 }
199
200 ret = MHD__gnutls_x509_read_value (c2, "certValue", out, 1);
201 if (ret < 0)
202 {
203 MHD_gnutls_assert ();
204 goto cleanup;
205 }
206
207 }
208 else
209 { /* CRL */
210 if ((ret = MHD__asn1_create_element (MHD__gnutls_get_pkix (),
211 "PKIX1.pkcs-12-CRLBag",
212 &c2)) != ASN1_SUCCESS)
213 {
214 MHD_gnutls_assert ();
215 ret = MHD_gtls_asn2err (ret);
216 goto cleanup;
217 }
218
219 ret = MHD__asn1_der_decoding (&c2, in->data, in->size, NULL);
220 if (ret != ASN1_SUCCESS)
221 {
222 MHD_gnutls_assert ();
223 ret = MHD_gtls_asn2err (ret);
224 goto cleanup;
225 }
226
227 ret = MHD__gnutls_x509_read_value (c2, "crlValue", out, 1);
228 if (ret < 0)
229 {
230 MHD_gnutls_assert ();
231 goto cleanup;
232 }
233 }
234
235 MHD__asn1_delete_structure (&c2);
236
237 return 0;
238
239
240cleanup:
241
242 MHD__asn1_delete_structure (&c2);
243 return ret;
244}
245
246
247int
248MHD_pkcs12_encode_crt_bag (MHD_gnutlsMHD_pkcs12_bag_type_t type,
249 const MHD_gnutls_datum_t * raw, MHD_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 = MHD__asn1_create_element (MHD__gnutls_get_pkix (),
257 "PKIX1.pkcs-12-CertBag",
258 &c2)) != ASN1_SUCCESS)
259 {
260 MHD_gnutls_assert ();
261 ret = MHD_gtls_asn2err (ret);
262 goto cleanup;
263 }
264
265 ret = MHD__asn1_write_value (c2, "certId", X509_CERT_OID, 1);
266 if (ret != ASN1_SUCCESS)
267 {
268 MHD_gnutls_assert ();
269 ret = MHD_gtls_asn2err (ret);
270 goto cleanup;
271 }
272
273 ret = MHD__gnutls_x509_write_value (c2, "certValue", raw, 1);
274 if (ret < 0)
275 {
276 MHD_gnutls_assert ();
277 goto cleanup;
278 }
279
280 }
281 else
282 { /* CRL */
283 if ((ret = MHD__asn1_create_element (MHD__gnutls_get_pkix (),
284 "PKIX1.pkcs-12-CRLBag",
285 &c2)) != ASN1_SUCCESS)
286 {
287 MHD_gnutls_assert ();
288 ret = MHD_gtls_asn2err (ret);
289 goto cleanup;
290 }
291
292 ret = MHD__asn1_write_value (c2, "crlId", X509_CRL_OID, 1);
293 if (ret != ASN1_SUCCESS)
294 {
295 MHD_gnutls_assert ();
296 ret = MHD_gtls_asn2err (ret);
297 goto cleanup;
298 }
299
300 ret = MHD__gnutls_x509_write_value (c2, "crlValue", raw, 1);
301 if (ret < 0)
302 {
303 MHD_gnutls_assert ();
304 goto cleanup;
305 }
306 }
307
308 ret = MHD__gnutls_x509_der_encode (c2, "", out, 0);
309
310 if (ret < 0)
311 {
312 MHD_gnutls_assert ();
313 goto cleanup;
314 }
315
316 MHD__asn1_delete_structure (&c2);
317
318 return 0;
319
320
321cleanup:
322
323 MHD__asn1_delete_structure (&c2);
324 return ret;
325}
326
327
328/**
329 * MHD_gnutlsMHD_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
342MHD_gnutlsMHD_pkcs12_bag_set_data (MHD_gnutlsMHD_pkcs12_bag_t bag,
343 MHD_gnutlsMHD_pkcs12_bag_type_t type,
344 const MHD_gnutls_datum_t * data)
345{
346 int ret;
347 if (bag == NULL)
348 {
349 MHD_gnutls_assert ();
350 return GNUTLS_E_INVALID_REQUEST;
351 }
352
353 if (bag->bag_elements == MAX_BAG_ELEMENTS - 1)
354 {
355 MHD_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 MHD_gnutls_assert ();
371 return GNUTLS_E_INVALID_REQUEST;
372 }
373 }
374
375 ret =
376 MHD__gnutls_set_datum (&bag->element[bag->bag_elements].data,
377 data->data, data->size);
378
379 if (ret < 0)
380 {
381 MHD_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 * MHD_gnutlsMHD_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 MHD_gnutlsMHD_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
405MHD_gnutlsMHD_pkcs12_bag_set_crt (MHD_gnutlsMHD_pkcs12_bag_t bag, MHD_gnutls_x509_crt_t crt)
406{
407 int ret;
408 MHD_gnutls_datum_t data;
409
410 if (bag == NULL)
411 {
412 MHD_gnutls_assert ();
413 return GNUTLS_E_INVALID_REQUEST;
414 }
415
416 ret = MHD__gnutls_x509_der_encode (crt->cert, "", &data, 0);
417 if (ret < 0)
418 {
419 MHD_gnutls_assert ();
420 return ret;
421 }
422
423 ret = MHD_gnutlsMHD_pkcs12_bag_set_data (bag, GNUTLS_BAG_CERTIFICATE, &data);
424
425 MHD__gnutls_free_datum (&data);
426
427 return ret;
428}
429
430/**
431 * MHD_gnutlsMHD_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 MHD_gnutlsMHD_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
443MHD_gnutlsMHD_pkcs12_bag_set_crl (MHD_gnutlsMHD_pkcs12_bag_t bag, MHD_gnutls_x509_crl_t crl)
444{
445 int ret;
446 MHD_gnutls_datum_t data;
447
448
449 if (bag == NULL)
450 {
451 MHD_gnutls_assert ();
452 return GNUTLS_E_INVALID_REQUEST;
453 }
454
455 ret = MHD__gnutls_x509_der_encode (crl->crl, "", &data, 0);
456 if (ret < 0)
457 {
458 MHD_gnutls_assert ();
459 return ret;
460 }
461
462 ret = MHD_gnutlsMHD_pkcs12_bag_set_data (bag, GNUTLS_BAG_CRL, &data);
463
464 MHD__gnutls_free_datum (&data);
465
466 return ret;
467}
468
469/**
470 * MHD_gnutlsMHD_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
483MHD_gnutlsMHD_pkcs12_bag_set_key_id (MHD_gnutlsMHD_pkcs12_bag_t bag, int indx,
484 const MHD_gnutls_datum_t * id)
485{
486 int ret;
487
488
489 if (bag == NULL)
490 {
491 MHD_gnutls_assert ();
492 return GNUTLS_E_INVALID_REQUEST;
493 }
494
495 if (indx > bag->bag_elements - 1)
496 {
497 MHD_gnutls_assert ();
498 return GNUTLS_E_INVALID_REQUEST;
499 }
500
501 ret = MHD__gnutls_set_datum (&bag->element[indx].local_key_id,
502 id->data, id->size);
503
504 if (ret < 0)
505 {
506 MHD_gnutls_assert ();
507 return ret;
508 }
509
510 return 0;
511}
512
513/**
514 * MHD_gnutlsMHD_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
526MHD_gnutlsMHD_pkcs12_bag_get_key_id (MHD_gnutlsMHD_pkcs12_bag_t bag, int indx,
527 MHD_gnutls_datum_t * id)
528{
529 if (bag == NULL)
530 {
531 MHD_gnutls_assert ();
532 return GNUTLS_E_INVALID_REQUEST;
533 }
534
535 if (indx > bag->bag_elements - 1)
536 {
537 MHD_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 * MHD_gnutlsMHD_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
560MHD_gnutlsMHD_pkcs12_bag_get_friendly_name (MHD_gnutlsMHD_pkcs12_bag_t bag, int indx,
561 char **name)
562{
563 if (bag == NULL)
564 {
565 MHD_gnutls_assert ();
566 return GNUTLS_E_INVALID_REQUEST;
567 }
568
569 if (indx > bag->bag_elements - 1)
570 {
571 MHD_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 * MHD_gnutlsMHD_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
595MHD_gnutlsMHD_pkcs12_bag_set_friendly_name (MHD_gnutlsMHD_pkcs12_bag_t bag, int indx,
596 const char *name)
597{
598 if (bag == NULL)
599 {
600 MHD_gnutls_assert ();
601 return GNUTLS_E_INVALID_REQUEST;
602 }
603
604 if (indx > bag->bag_elements - 1)
605 {
606 MHD_gnutls_assert ();
607 return GNUTLS_E_INVALID_REQUEST;
608 }
609
610 bag->element[indx].friendly_name = MHD_gnutls_strdup (name);
611
612 if (name == NULL)
613 {
614 MHD_gnutls_assert ();
615 return GNUTLS_E_MEMORY_ERROR;
616 }
617
618 return 0;
619}
620
621
622/**
623 * MHD_gnutlsMHD_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
631MHD_gnutlsMHD_pkcs12_bag_decrypt (MHD_gnutlsMHD_pkcs12_bag_t bag, const char *pass)
632{
633 int ret;
634 MHD_gnutls_datum_t dec;
635
636 if (bag == NULL)
637 {
638 MHD_gnutls_assert ();
639 return GNUTLS_E_INVALID_REQUEST;
640 }
641
642 if (bag->element[0].type != GNUTLS_BAG_ENCRYPTED)
643 {
644 MHD_gnutls_assert ();
645 return GNUTLS_E_INVALID_REQUEST;
646 }
647
648 ret = MHD__gnutls_pkcs7_decrypt_data (&bag->element[0].data, pass, &dec);
649
650 if (ret < 0)
651 {
652 MHD_gnutls_assert ();
653 return ret;
654 }
655
656 /* decryption succeeded. Now decode the SafeContents
657 * stuff, and parse it.
658 */
659
660 MHD__gnutls_free_datum (&bag->element[0].data);
661
662 ret = MHD_pkcs12_decode_safe_contents (&dec, bag);
663
664 MHD__gnutls_free_datum (&dec);
665
666 if (ret < 0)
667 {
668 MHD_gnutls_assert ();
669 return ret;
670 }
671
672 return 0;
673}
674
675/**
676 * MHD_gnutlsMHD_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 MHD_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
685MHD_gnutlsMHD_pkcs12_bag_encrypt (MHD_gnutlsMHD_pkcs12_bag_t bag, const char *pass,
686 unsigned int flags)
687{
688 int ret;
689 ASN1_TYPE safe_cont = ASN1_TYPE_EMPTY;
690 MHD_gnutls_datum_t der = { NULL, 0 };
691 MHD_gnutls_datum_t enc = { NULL, 0 };
692 schema_id id;
693
694 if (bag == NULL)
695 {
696 MHD_gnutls_assert ();
697 return GNUTLS_E_INVALID_REQUEST;
698 }
699
700 if (bag->element[0].type == GNUTLS_BAG_ENCRYPTED)
701 {
702 MHD_gnutls_assert ();
703 return GNUTLS_E_INVALID_REQUEST;
704 }
705
706 /* Encode the whole bag to a safe contents
707 * structure.
708 */
709 ret = MHD_pkcs12_encode_safe_contents (bag, &safe_cont, NULL);
710 if (ret < 0)
711 {
712 MHD_gnutls_assert ();
713 return ret;
714 }
715
716 /* DER encode the SafeContents.
717 */
718 ret = MHD__gnutls_x509_der_encode (safe_cont, "", &der, 0);
719
720 MHD__asn1_delete_structure (&safe_cont);
721
722 if (ret < 0)
723 {
724 MHD_gnutls_assert ();
725 return ret;
726 }
727
728 if (flags & GNUTLS_PKCS_PLAIN)
729 {
730 MHD_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 = MHD__gnutls_pkcs7_encrypt_data (id, &der, pass, &enc);
746
747 MHD__gnutls_free_datum (&der);
748
749 if (ret < 0)
750 {
751 MHD_gnutls_assert ();
752 return ret;
753 }
754
755 /* encryption succeeded.
756 */
757
758 MHD_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/privkey_pkcs8.c b/src/daemon/https/x509/privkey_pkcs8.c
index 1ef59d2f..741552e1 100644
--- a/src/daemon/https/x509/privkey_pkcs8.c
+++ b/src/daemon/https/x509/privkey_pkcs8.c
@@ -34,8 +34,8 @@
34#include <gnutls_x509.h> 34#include <gnutls_x509.h>
35#include <x509_b64.h> 35#include <x509_b64.h>
36#include <x509.h> 36#include <x509.h>
37#include <dn.h>
38#include <pkcs12.h> 37#include <pkcs12.h>
38#include <dn.h>
39#include <privkey.h> 39#include <privkey.h>
40#include <extensions.h> 40#include <extensions.h>
41#include <mpi.h> 41#include <mpi.h>
@@ -68,10 +68,6 @@ struct pbe_enc_params
68 int iv_size; 68 int iv_size;
69}; 69};
70 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 MHD_gnutls_datum_t * key);
75static int read_pbkdf2_params (ASN1_TYPE pbes2_asn, 71static int read_pbkdf2_params (ASN1_TYPE pbes2_asn,
76 const MHD_gnutls_datum_t * der, 72 const MHD_gnutls_datum_t * der,
77 struct pbkdf2_params *params); 73 struct pbkdf2_params *params);
@@ -85,18 +81,8 @@ static int decrypt_data (schema_id, ASN1_TYPE pkcs8_asn, const char *root,
85 MHD_gnutls_datum_t * decrypted_data); 81 MHD_gnutls_datum_t * decrypted_data);
86static int decode_private_key_info (const MHD_gnutls_datum_t * der, 82static int decode_private_key_info (const MHD_gnutls_datum_t * der,
87 MHD_gnutls_x509_privkey_t pkey); 83 MHD_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 MHD_gnutls_datum_t * plain,
93 const struct pbe_enc_params *enc_params,
94 MHD_gnutls_datum_t * key, MHD_gnutls_datum_t * encrypted);
95
96static int readMHD_pkcs12_kdf_params (ASN1_TYPE pbes2_asn, 84static int readMHD_pkcs12_kdf_params (ASN1_TYPE pbes2_asn,
97 struct pbkdf2_params *params); 85 struct pbkdf2_params *params);
98static int writeMHD_pkcs12_kdf_params (ASN1_TYPE pbes2_asn,
99 const struct pbkdf2_params *params);
100 86
101#define PEM_PKCS8 "ENCRYPTED PRIVATE KEY" 87#define PEM_PKCS8 "ENCRYPTED PRIVATE KEY"
102#define PEM_UNENCRYPTED_PKCS8 "PRIVATE KEY" 88#define PEM_UNENCRYPTED_PKCS8 "PRIVATE KEY"
@@ -104,7 +90,7 @@ static int writeMHD_pkcs12_kdf_params (ASN1_TYPE pbes2_asn,
104/* Returns a negative error code if the encryption schema in 90/* Returns a negative error code if the encryption schema in
105 * the OID is not supported. The schema ID is returned. 91 * the OID is not supported. The schema ID is returned.
106 */ 92 */
107inline static int 93static int
108check_schema (const char *oid) 94check_schema (const char *oid)
109{ 95{
110 96
@@ -420,78 +406,6 @@ error:
420 return ret; 406 return ret;
421} 407}
422 408
423/* TODO rm if unsed - we will probable support only RSA certificates */
424/* Decodes an DSA privateKey and params from a PKCS8 structure.
425static int
426_decode_pkcs8_dsa_key (ASN1_TYPE pkcs8_asn, MHD_gnutls_x509_privkey pkey)
427 {
428 int ret;
429 MHD_gnutls_datum tmp;
430
431 ret = MHD__gnutls_x509_read_value (pkcs8_asn, "privateKey", &tmp, 0);
432 if (ret < 0)
433 {
434 MHD_gnutls_assert ();
435 goto error;
436 }
437
438 ret = MHD__gnutls_x509_read_der_int (tmp.data, tmp.size, &pkey->params[4]);
439 MHD__gnutls_free_datum (&tmp);
440
441 if (ret < 0)
442 {
443 MHD_gnutls_assert ();
444 goto error;
445 }
446
447 ret =
448 MHD__gnutls_x509_read_value (pkcs8_asn, "privateKeyAlgorithm.parameters",
449 &tmp, 0);
450 if (ret < 0)
451 {
452 MHD_gnutls_assert ();
453 goto error;
454 }
455
456 ret = MHD__gnutls_x509_read_dsa_params (tmp.data, tmp.size, pkey->params);
457 MHD__gnutls_free_datum (&tmp);
458 if (ret < 0)
459 {
460 MHD_gnutls_assert ();
461 goto error;
462 }
463
464 the public key can be generated as g^x mod p
465 pkey->params[3] = MHD__gnutls_mpi_alloc_like (pkey->params[0]);
466 if (pkey->params[3] == NULL)
467 {
468 MHD_gnutls_assert ();
469 goto error;
470 }
471
472 MHD__gnutls_mpi_powm (pkey->params[3], pkey->params[2], pkey->params[4],
473 pkey->params[0]);
474
475 if (!pkey->crippled)
476 {
477 ret = MHD__gnutls_asn1_encode_dsa (&pkey->key, pkey->params);
478 if (ret < 0)
479 {
480 MHD_gnutls_assert ();
481 goto error;
482 }
483 }
484
485 pkey->params_size = DSA_PRIVATE_PARAMS;
486
487 return 0;
488
489 error:
490 MHD_gnutls_x509_privkey_deinit (pkey);
491 return ret;
492 }
493*/
494
495static int 409static int
496decode_private_key_info (const MHD_gnutls_datum_t * der, 410decode_private_key_info (const MHD_gnutls_datum_t * der,
497 MHD_gnutls_x509_privkey_t pkey) 411 MHD_gnutls_x509_privkey_t pkey)
@@ -532,7 +446,7 @@ decode_private_key_info (const MHD_gnutls_datum_t * der,
532 446
533 /* we only support RSA and DSA private keys. 447 /* we only support RSA and DSA private keys.
534 */ 448 */
535 if (strcmp (oid, PK_PKIX1_RSA_OID) == 0) 449 if (strcmp ((const char*) oid, PK_PKIX1_RSA_OID) == 0)
536 pkey->pk_algorithm = MHD_GNUTLS_PK_RSA; 450 pkey->pk_algorithm = MHD_GNUTLS_PK_RSA;
537 else 451 else
538 { 452 {
@@ -824,49 +738,9 @@ error:
824 738
825} 739}
826 740
827/* Writes the PBE parameters for PKCS-12 schemas.
828 */
829static int
830writeMHD_pkcs12_kdf_params (ASN1_TYPE pbes2_asn,
831 const struct pbkdf2_params *kdf_params)
832{
833 int result;
834
835 /* write the salt
836 */
837 result =
838 MHD__asn1_write_value (pbes2_asn, "salt",
839 kdf_params->salt, kdf_params->salt_size);
840 if (result != ASN1_SUCCESS)
841 {
842 MHD_gnutls_assert ();
843 result = MHD_gtls_asn2err (result);
844 goto error;
845 }
846 MHD__gnutls_hard_log ("salt.size: %d\n", kdf_params->salt_size);
847
848 /* write the iteration count
849 */
850 result =
851 MHD__gnutls_x509_write_uint32 (pbes2_asn, "iterations",
852 kdf_params->iter_count);
853 if (result < 0)
854 {
855 MHD_gnutls_assert ();
856 goto error;
857 }
858 MHD__gnutls_hard_log ("iterationCount: %d\n", kdf_params->iter_count);
859
860 return 0;
861
862error:
863 return result;
864
865}
866
867/* Converts an OID to a gnutls cipher type. 741/* Converts an OID to a gnutls cipher type.
868 */ 742 */
869inline static int 743static int
870oid2cipher (const char *oid, enum MHD_GNUTLS_CipherAlgorithm *algo) 744oid2cipher (const char *oid, enum MHD_GNUTLS_CipherAlgorithm *algo)
871{ 745{
872 746
@@ -1025,8 +899,9 @@ decrypt_data (schema_id schema, ASN1_TYPE pkcs8_asn,
1025 if (schema == PBES2) 899 if (schema == PBES2)
1026 { 900 {
1027 result = MHD_gc_pbkdf2_sha1 (password, strlen (password), 901 result = MHD_gc_pbkdf2_sha1 (password, strlen (password),
1028 kdf_params->salt, kdf_params->salt_size, 902 (const char*) kdf_params->salt, kdf_params->salt_size,
1029 kdf_params->iter_count, key, key_size); 903 kdf_params->iter_count,
904 (char*) key, key_size);
1030 905
1031 if (result != GC_OK) 906 if (result != GC_OK)
1032 { 907 {
@@ -1095,704 +970,5 @@ error:
1095 return result; 970 return result;
1096} 971}
1097 972
1098/* Writes the PBKDF2 parameters.
1099 */
1100static int
1101write_pbkdf2_params (ASN1_TYPE pbes2_asn,
1102 const struct pbkdf2_params *kdf_params)
1103{
1104 int result;
1105 ASN1_TYPE pbkdf2_asn = ASN1_TYPE_EMPTY;
1106 opaque tmp[64];
1107
1108 /* Write the key derivation algorithm
1109 */
1110 result =
1111 MHD__asn1_write_value (pbes2_asn, "keyDerivationFunc.algorithm",
1112 PBKDF2_OID, 1);
1113 if (result != ASN1_SUCCESS)
1114 {
1115 MHD_gnutls_assert ();
1116 return MHD_gtls_asn2err (result);
1117 }
1118
1119 /* Now write the key derivation and the encryption
1120 * functions.
1121 */
1122 if ((result =
1123 MHD__asn1_create_element (MHD__gnutls_get_pkix (),
1124 "PKIX1.pkcs-5-PBKDF2-params",
1125 &pbkdf2_asn)) != ASN1_SUCCESS)
1126 {
1127 MHD_gnutls_assert ();
1128 return MHD_gtls_asn2err (result);
1129 }
1130
1131 result = MHD__asn1_write_value (pbkdf2_asn, "salt", "specified", 1);
1132 if (result != ASN1_SUCCESS)
1133 {
1134 MHD_gnutls_assert ();
1135 result = MHD_gtls_asn2err (result);
1136 goto error;
1137 }
1138
1139 /* write the salt
1140 */
1141 result =
1142 MHD__asn1_write_value (pbkdf2_asn, "salt.specified",
1143 kdf_params->salt, kdf_params->salt_size);
1144 if (result != ASN1_SUCCESS)
1145 {
1146 MHD_gnutls_assert ();
1147 result = MHD_gtls_asn2err (result);
1148 goto error;
1149 }
1150 MHD__gnutls_hard_log ("salt.specified.size: %d\n", kdf_params->salt_size);
1151
1152 /* write the iteration count
1153 */
1154 MHD_gtls_write_uint32 (kdf_params->iter_count, tmp);
1155
1156 result = MHD__asn1_write_value (pbkdf2_asn, "iterationCount", tmp, 4);
1157 if (result != ASN1_SUCCESS)
1158 {
1159 MHD_gnutls_assert ();
1160 result = MHD_gtls_asn2err (result);
1161 goto error;
1162 }
1163 MHD__gnutls_hard_log ("iterationCount: %d\n", kdf_params->iter_count);
1164
1165 /* write the keylength, if it is set.
1166 */
1167 result = MHD__asn1_write_value (pbkdf2_asn, "keyLength", NULL, 0);
1168 if (result != ASN1_SUCCESS)
1169 {
1170 MHD_gnutls_assert ();
1171 result = MHD_gtls_asn2err (result);
1172 goto error;
1173 }
1174
1175 /* We write an emptry prf.
1176 */
1177 result = MHD__asn1_write_value (pbkdf2_asn, "prf", NULL, 0);
1178 if (result != ASN1_SUCCESS)
1179 {
1180 MHD_gnutls_assert ();
1181 result = MHD_gtls_asn2err (result);
1182 goto error;
1183 }
1184
1185 /* now encode them an put the DER output
1186 * in the keyDerivationFunc.parameters
1187 */
1188 result = MHD__gnutls_x509_der_encode_and_copy (pbkdf2_asn, "",
1189 pbes2_asn,
1190 "keyDerivationFunc.parameters",
1191 0);
1192 if (result < 0)
1193 {
1194 MHD_gnutls_assert ();
1195 goto error;
1196 }
1197
1198 return 0;
1199
1200error:
1201 MHD__asn1_delete_structure (&pbkdf2_asn);
1202 return result;
1203
1204}
1205
1206static int
1207write_pbe_enc_params (ASN1_TYPE pbes2_asn,
1208 const struct pbe_enc_params *params)
1209{
1210 int result;
1211 ASN1_TYPE pbe_asn = ASN1_TYPE_EMPTY;
1212
1213 /* Write the encryption algorithm
1214 */
1215 result =
1216 MHD__asn1_write_value (pbes2_asn, "encryptionScheme.algorithm",
1217 DES_EDE3_CBC_OID, 1);
1218 if (result != ASN1_SUCCESS)
1219 {
1220 MHD_gnutls_assert ();
1221 goto error;
1222 }
1223 MHD__gnutls_hard_log ("encryptionScheme.algorithm: %s\n", DES_EDE3_CBC_OID);
1224
1225 /* Now check the encryption parameters.
1226 */
1227 if ((result =
1228 MHD__asn1_create_element (MHD__gnutls_get_pkix (),
1229 "PKIX1.pkcs-5-des-EDE3-CBC-params",
1230 &pbe_asn)) != ASN1_SUCCESS)
1231 {
1232 MHD_gnutls_assert ();
1233 return MHD_gtls_asn2err (result);
1234 }
1235
1236 /* read the salt */
1237 result = MHD__asn1_write_value (pbe_asn, "", params->iv, params->iv_size);
1238 if (result != ASN1_SUCCESS)
1239 {
1240 MHD_gnutls_assert ();
1241 result = MHD_gtls_asn2err (result);
1242 goto error;
1243 }
1244 MHD__gnutls_hard_log ("IV.size: %d\n", params->iv_size);
1245
1246 /* now encode them an put the DER output
1247 * in the encryptionScheme.parameters
1248 */
1249 result = MHD__gnutls_x509_der_encode_and_copy (pbe_asn, "",
1250 pbes2_asn,
1251 "encryptionScheme.parameters",
1252 0);
1253 if (result < 0)
1254 {
1255 MHD_gnutls_assert ();
1256 goto error;
1257 }
1258
1259 return 0;
1260
1261error:
1262 MHD__asn1_delete_structure (&pbe_asn);
1263 return result;
1264
1265}
1266
1267/* Generates a key and also stores the key parameters.
1268 */
1269static int
1270generate_key (schema_id schema,
1271 const char *password,
1272 struct pbkdf2_params *kdf_params,
1273 struct pbe_enc_params *enc_params, MHD_gnutls_datum_t * key)
1274{
1275 opaque rnd[2];
1276 int ret;
1277
1278 /* We should use the flags here to use different
1279 * encryption algorithms etc.
1280 */
1281
1282 if (schema == PKCS12_ARCFOUR_SHA1)
1283 enc_params->cipher = MHD_GNUTLS_CIPHER_ARCFOUR_128;
1284 else if (schema == PKCS12_3DES_SHA1)
1285 enc_params->cipher = MHD_GNUTLS_CIPHER_3DES_CBC;
1286 else if (schema == PKCS12_RC2_40_SHA1)
1287 enc_params->cipher = MHD_GNUTLS_CIPHER_RC2_40_CBC;
1288
1289 if (MHD_gc_pseudo_random (rnd, 2) != GC_OK)
1290 {
1291 MHD_gnutls_assert ();
1292 return GNUTLS_E_RANDOM_FAILED;
1293 }
1294
1295 /* generate salt */
1296
1297 if (schema == PBES2)
1298 {
1299 kdf_params->salt_size =
1300 MIN (sizeof (kdf_params->salt), (unsigned) (10 + (rnd[1] % 10)));
1301 }
1302 else
1303 kdf_params->salt_size = 8;
1304
1305 if (MHD_gc_pseudo_random (kdf_params->salt, kdf_params->salt_size) != GC_OK)
1306 {
1307 MHD_gnutls_assert ();
1308 return GNUTLS_E_RANDOM_FAILED;
1309 }
1310
1311 kdf_params->iter_count = 256 + rnd[0];
1312 key->size = kdf_params->key_size =
1313 MHD__gnutls_cipher_get_key_size (enc_params->cipher);
1314
1315 enc_params->iv_size = MHD_gtls_cipher_get_iv_size (enc_params->cipher);
1316
1317 key->data = MHD_gnutls_secure_malloc (key->size);
1318 if (key->data == NULL)
1319 {
1320 MHD_gnutls_assert ();
1321 return GNUTLS_E_MEMORY_ERROR;
1322 }
1323
1324 /* now generate the key.
1325 */
1326
1327 if (schema == PBES2)
1328 {
1329
1330 ret = MHD_gc_pbkdf2_sha1 (password, strlen (password),
1331 kdf_params->salt, kdf_params->salt_size,
1332 kdf_params->iter_count,
1333 key->data, kdf_params->key_size);
1334 if (ret != GC_OK)
1335 {
1336 MHD_gnutls_assert ();
1337 return GNUTLS_E_ENCRYPTION_FAILED;
1338 }
1339
1340 if (enc_params->iv_size &&
1341 MHD_gc_nonce (enc_params->iv, enc_params->iv_size) != GC_OK)
1342 {
1343 MHD_gnutls_assert ();
1344 return GNUTLS_E_RANDOM_FAILED;
1345 }
1346 }
1347 else
1348 { /* PKCS12 schemas */
1349 ret =
1350 MHD_pkcs12_string_to_key (1 /*KEY*/, kdf_params->salt,
1351 kdf_params->salt_size,
1352 kdf_params->iter_count, password,
1353 kdf_params->key_size, key->data);
1354 if (ret < 0)
1355 {
1356 MHD_gnutls_assert ();
1357 return ret;
1358 }
1359
1360 /* Now generate the IV
1361 */
1362 if (enc_params->iv_size)
1363 {
1364 ret =
1365 MHD_pkcs12_string_to_key (2 /*IV*/, kdf_params->salt,
1366 kdf_params->salt_size,
1367 kdf_params->iter_count, password,
1368 enc_params->iv_size, enc_params->iv);
1369 if (ret < 0)
1370 {
1371 MHD_gnutls_assert ();
1372 return ret;
1373 }
1374 }
1375 }
1376
1377 return 0;
1378}
1379
1380/* Encodes the parameters to be written in the encryptionAlgorithm.parameters
1381 * part.
1382 */
1383static int
1384write_schema_params (schema_id schema, ASN1_TYPE pkcs8_asn,
1385 const char *where,
1386 const struct pbkdf2_params *kdf_params,
1387 const struct pbe_enc_params *enc_params)
1388{
1389 int result;
1390 ASN1_TYPE pbes2_asn = ASN1_TYPE_EMPTY;
1391
1392 if (schema == PBES2)
1393 {
1394 if ((result =
1395 MHD__asn1_create_element (MHD__gnutls_get_pkix (),
1396 "PKIX1.pkcs-5-PBES2-params",
1397 &pbes2_asn)) != ASN1_SUCCESS)
1398 {
1399 MHD_gnutls_assert ();
1400 return MHD_gtls_asn2err (result);
1401 }
1402
1403 result = write_pbkdf2_params (pbes2_asn, kdf_params);
1404 if (result < 0)
1405 {
1406 MHD_gnutls_assert ();
1407 goto error;
1408 }
1409
1410 result = write_pbe_enc_params (pbes2_asn, enc_params);
1411 if (result < 0)
1412 {
1413 MHD_gnutls_assert ();
1414 goto error;
1415 }
1416
1417 result = MHD__gnutls_x509_der_encode_and_copy (pbes2_asn, "",
1418 pkcs8_asn, where, 0);
1419 if (result < 0)
1420 {
1421 MHD_gnutls_assert ();
1422 goto error;
1423 }
1424
1425 MHD__asn1_delete_structure (&pbes2_asn);
1426 }
1427 else
1428 { /* PKCS12 schemas */
1429
1430 if ((result =
1431 MHD__asn1_create_element (MHD__gnutls_get_pkix (),
1432 "PKIX1.pkcs-12-PbeParams",
1433 &pbes2_asn)) != ASN1_SUCCESS)
1434 {
1435 MHD_gnutls_assert ();
1436 result = MHD_gtls_asn2err (result);
1437 goto error;
1438 }
1439
1440 result = writeMHD_pkcs12_kdf_params (pbes2_asn, kdf_params);
1441 if (result < 0)
1442 {
1443 MHD_gnutls_assert ();
1444 goto error;
1445 }
1446
1447 result = MHD__gnutls_x509_der_encode_and_copy (pbes2_asn, "",
1448 pkcs8_asn, where, 0);
1449 if (result < 0)
1450 {
1451 MHD_gnutls_assert ();
1452 goto error;
1453 }
1454
1455 MHD__asn1_delete_structure (&pbes2_asn);
1456
1457 }
1458
1459 return 0;
1460
1461error:
1462 MHD__asn1_delete_structure (&pbes2_asn);
1463 return result;
1464
1465}
1466
1467static int
1468encrypt_data (const MHD_gnutls_datum_t * plain,
1469 const struct pbe_enc_params *enc_params,
1470 MHD_gnutls_datum_t * key, MHD_gnutls_datum_t * encrypted)
1471{
1472 int result;
1473 int data_size;
1474 opaque *data = NULL;
1475 MHD_gnutls_datum_t d_iv;
1476 cipher_hd_t ch = NULL;
1477 opaque pad, pad_size;
1478
1479 pad_size = MHD_gtls_cipher_get_block_size (enc_params->cipher);
1480
1481 if (pad_size == 1) /* stream */
1482 pad_size = 0;
1483
1484 data = MHD_gnutls_malloc (plain->size + pad_size);
1485 if (data == NULL)
1486 {
1487 MHD_gnutls_assert ();
1488 return GNUTLS_E_MEMORY_ERROR;
1489 }
1490
1491 memcpy (data, plain->data, plain->size);
1492
1493 if (pad_size > 0)
1494 {
1495 pad = pad_size - (plain->size % pad_size);
1496 if (pad == 0)
1497 pad = pad_size;
1498 memset (&data[plain->size], pad, pad);
1499 }
1500 else
1501 pad = 0;
1502
1503 data_size = plain->size + pad;
1504
1505 d_iv.data = (opaque *) enc_params->iv;
1506 d_iv.size = enc_params->iv_size;
1507 ch = MHD_gtls_cipher_init (enc_params->cipher, key, &d_iv);
1508
1509 if (ch == GNUTLS_CIPHER_FAILED)
1510 {
1511 MHD_gnutls_assert ();
1512 result = GNUTLS_E_ENCRYPTION_FAILED;
1513 goto error;
1514 }
1515
1516 result = MHD_gtls_cipher_encrypt (ch, data, data_size);
1517 if (result < 0)
1518 {
1519 MHD_gnutls_assert ();
1520 goto error;
1521 }
1522
1523 encrypted->data = data;
1524 encrypted->size = data_size;
1525
1526 MHD_gnutls_cipher_deinit (ch);
1527
1528 return 0;
1529
1530error:
1531 MHD_gnutls_free (data);
1532 if (ch != NULL)
1533 MHD_gnutls_cipher_deinit (ch);
1534 return result;
1535}
1536
1537/* Decrypts a PKCS #7 encryptedData. The output is allocated
1538 * and stored in dec.
1539 */
1540int
1541MHD__gnutls_pkcs7_decrypt_data (const MHD_gnutls_datum_t * data,
1542 const char *password, MHD_gnutls_datum_t * dec)
1543{
1544 int result, len;
1545 char enc_oid[64];
1546 MHD_gnutls_datum_t tmp;
1547 ASN1_TYPE pbes2_asn = ASN1_TYPE_EMPTY, pkcs7_asn = ASN1_TYPE_EMPTY;
1548 int params_start, params_end, params_len;
1549 struct pbkdf2_params kdf_params;
1550 struct pbe_enc_params enc_params;
1551 schema_id schema;
1552
1553 if ((result =
1554 MHD__asn1_create_element (MHD__gnutls_get_pkix (),
1555 "PKIX1.pkcs-7-EncryptedData",
1556 &pkcs7_asn)) != ASN1_SUCCESS)
1557 {
1558 MHD_gnutls_assert ();
1559 result = MHD_gtls_asn2err (result);
1560 goto error;
1561 }
1562
1563 result = MHD__asn1_der_decoding (&pkcs7_asn, data->data, data->size, NULL);
1564 if (result != ASN1_SUCCESS)
1565 {
1566 MHD_gnutls_assert ();
1567 result = MHD_gtls_asn2err (result);
1568 goto error;
1569 }
1570
1571 /* Check the encryption schema OID
1572 */
1573 len = sizeof (enc_oid);
1574 result =
1575 MHD__asn1_read_value (pkcs7_asn,
1576 "encryptedContentInfo.contentEncryptionAlgorithm.algorithm",
1577 enc_oid, &len);
1578 if (result != ASN1_SUCCESS)
1579 {
1580 MHD_gnutls_assert ();
1581 result = MHD_gtls_asn2err (result);
1582 goto error;
1583 }
1584
1585 if ((result = check_schema (enc_oid)) < 0)
1586 {
1587 MHD_gnutls_assert ();
1588 goto error;
1589 }
1590 schema = result;
1591
1592 /* Get the DER encoding of the parameters.
1593 */
1594 result =
1595 MHD__asn1_der_decoding_startEnd (pkcs7_asn, data->data, data->size,
1596 "encryptedContentInfo.contentEncryptionAlgorithm.parameters",
1597 &params_start, &params_end);
1598 if (result != ASN1_SUCCESS)
1599 {
1600 MHD_gnutls_assert ();
1601 result = MHD_gtls_asn2err (result);
1602 goto error;
1603 }
1604 params_len = params_end - params_start + 1;
1605
1606 result =
1607 read_pkcs_schema_params (schema, password,
1608 &data->data[params_start],
1609 params_len, &kdf_params, &enc_params);
1610 if (result < ASN1_SUCCESS)
1611 {
1612 MHD_gnutls_assert ();
1613 result = MHD_gtls_asn2err (result);
1614 goto error;
1615 }
1616
1617 /* Parameters have been decoded. Now
1618 * decrypt the EncryptedData.
1619 */
1620
1621 result =
1622 decrypt_data (schema, pkcs7_asn,
1623 "encryptedContentInfo.encryptedContent", password,
1624 &kdf_params, &enc_params, &tmp);
1625 if (result < 0)
1626 {
1627 MHD_gnutls_assert ();
1628 goto error;
1629 }
1630
1631 MHD__asn1_delete_structure (&pkcs7_asn);
1632
1633 *dec = tmp;
1634
1635 return 0;
1636
1637error:
1638 MHD__asn1_delete_structure (&pbes2_asn);
1639 MHD__asn1_delete_structure (&pkcs7_asn);
1640 return result;
1641}
1642
1643/* Encrypts to a PKCS #7 encryptedData. The output is allocated
1644 * and stored in enc.
1645 */
1646int
1647MHD__gnutls_pkcs7_encrypt_data (schema_id schema,
1648 const MHD_gnutls_datum_t * data,
1649 const char *password, MHD_gnutls_datum_t * enc)
1650{
1651 int result;
1652 MHD_gnutls_datum_t key = { NULL, 0 };
1653 MHD_gnutls_datum_t tmp = { NULL, 0 };
1654 ASN1_TYPE pkcs7_asn = ASN1_TYPE_EMPTY;
1655 struct pbkdf2_params kdf_params;
1656 struct pbe_enc_params enc_params;
1657
1658 if ((result =
1659 MHD__asn1_create_element (MHD__gnutls_get_pkix (),
1660 "PKIX1.pkcs-7-EncryptedData",
1661 &pkcs7_asn)) != ASN1_SUCCESS)
1662 {
1663 MHD_gnutls_assert ();
1664 result = MHD_gtls_asn2err (result);
1665 goto error;
1666 }
1667
1668 /* Write the encryption schema OID
1669 */
1670 switch (schema)
1671 {
1672 case PBES2:
1673 result =
1674 MHD__asn1_write_value (pkcs7_asn,
1675 "encryptedContentInfo.contentEncryptionAlgorithm.algorithm",
1676 PBES2_OID, 1);
1677 break;
1678 case PKCS12_3DES_SHA1:
1679 result =
1680 MHD__asn1_write_value (pkcs7_asn,
1681 "encryptedContentInfo.contentEncryptionAlgorithm.algorithm",
1682 PKCS12_PBE_3DES_SHA1_OID, 1);
1683 break;
1684 case PKCS12_ARCFOUR_SHA1:
1685 result =
1686 MHD__asn1_write_value (pkcs7_asn,
1687 "encryptedContentInfo.contentEncryptionAlgorithm.algorithm",
1688 PKCS12_PBE_ARCFOUR_SHA1_OID, 1);
1689 break;
1690 case PKCS12_RC2_40_SHA1:
1691 result =
1692 MHD__asn1_write_value (pkcs7_asn,
1693 "encryptedContentInfo.contentEncryptionAlgorithm.algorithm",
1694 PKCS12_PBE_RC2_40_SHA1_OID, 1);
1695 break;
1696
1697 }
1698
1699 if (result != ASN1_SUCCESS)
1700 {
1701 MHD_gnutls_assert ();
1702 result = MHD_gtls_asn2err (result);
1703 goto error;
1704 }
1705
1706 /* Generate a symmetric key.
1707 */
1708
1709 result = generate_key (schema, password, &kdf_params, &enc_params, &key);
1710 if (result < 0)
1711 {
1712 MHD_gnutls_assert ();
1713 goto error;
1714 }
1715
1716 result = write_schema_params (schema, pkcs7_asn,
1717 "encryptedContentInfo.contentEncryptionAlgorithm.parameters",
1718 &kdf_params, &enc_params);
1719 if (result < 0)
1720 {
1721 MHD_gnutls_assert ();
1722 goto error;
1723 }
1724
1725 /* Parameters have been encoded. Now
1726 * encrypt the Data.
1727 */
1728 result = encrypt_data (data, &enc_params, &key, &tmp);
1729 if (result < 0)
1730 {
1731 MHD_gnutls_assert ();
1732 goto error;
1733 }
1734
1735 /* write the encrypted data.
1736 */
1737 result =
1738 MHD__asn1_write_value (pkcs7_asn,
1739 "encryptedContentInfo.encryptedContent", tmp.data,
1740 tmp.size);
1741 if (result != ASN1_SUCCESS)
1742 {
1743 MHD_gnutls_assert ();
1744 result = MHD_gtls_asn2err (result);
1745 goto error;
1746 }
1747
1748 MHD__gnutls_free_datum (&tmp);
1749 MHD__gnutls_free_datum (&key);
1750
1751 /* Now write the rest of the pkcs-7 stuff.
1752 */
1753
1754 result = MHD__gnutls_x509_write_uint32 (pkcs7_asn, "version", 0);
1755 if (result < 0)
1756 {
1757 MHD_gnutls_assert ();
1758 goto error;
1759 }
1760
1761 result =
1762 MHD__asn1_write_value (pkcs7_asn, "encryptedContentInfo.contentType",
1763 DATA_OID, 1);
1764 if (result != ASN1_SUCCESS)
1765 {
1766 MHD_gnutls_assert ();
1767 result = MHD_gtls_asn2err (result);
1768 goto error;
1769 }
1770
1771 result = MHD__asn1_write_value (pkcs7_asn, "unprotectedAttrs", NULL, 0);
1772 if (result != ASN1_SUCCESS)
1773 {
1774 MHD_gnutls_assert ();
1775 result = MHD_gtls_asn2err (result);
1776 goto error;
1777 }
1778
1779 /* Now encode and copy the DER stuff.
1780 */
1781 result = MHD__gnutls_x509_der_encode (pkcs7_asn, "", enc, 0);
1782
1783 MHD__asn1_delete_structure (&pkcs7_asn);
1784
1785 if (result < 0)
1786 {
1787 MHD_gnutls_assert ();
1788 goto error;
1789 }
1790
1791error:
1792 MHD__gnutls_free_datum (&key);
1793 MHD__gnutls_free_datum (&tmp);
1794 MHD__asn1_delete_structure (&pkcs7_asn);
1795 return result;
1796}
1797 973
1798#endif 974#endif