aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2008-11-16 04:23:30 +0000
committerChristian Grothoff <christian@grothoff.org>2008-11-16 04:23:30 +0000
commite81f372ed145575566e03120bc759360b66b1ffe (patch)
treec3c58ddcac3b11d26c28ef9c5772715e6356ab54
parenta61b09be334f7fafefa5ce067bb2d0b8e44f9ec7 (diff)
downloadlibmicrohttpd-e81f372ed145575566e03120bc759360b66b1ffe.tar.gz
libmicrohttpd-e81f372ed145575566e03120bc759360b66b1ffe.zip
dce
-rw-r--r--src/daemon/https/tls/gnutls_cert.c4
-rw-r--r--src/daemon/https/tls/gnutls_x509.c232
-rw-r--r--src/daemon/https/x509/Makefile.am6
-rw-r--r--src/daemon/https/x509/crl.c437
-rw-r--r--src/daemon/https/x509/mpi.c317
-rw-r--r--src/daemon/https/x509/mpi.h19
-rw-r--r--src/daemon/https/x509/pkcs12_encr.c169
-rw-r--r--src/daemon/https/x509/pkcs7.c1029
-rw-r--r--src/daemon/https/x509/pkcs7.h30
-rw-r--r--src/daemon/https/x509/privkey_pkcs8.c984
-rw-r--r--src/daemon/https/x509/sign.c264
-rw-r--r--src/daemon/https/x509/sign.h28
-rw-r--r--src/daemon/https/x509/x509.c110
-rw-r--r--src/daemon/https/x509/x509_privkey.c1
-rw-r--r--src/daemon/https/x509/x509_verify.c245
15 files changed, 1 insertions, 3874 deletions
diff --git a/src/daemon/https/tls/gnutls_cert.c b/src/daemon/https/tls/gnutls_cert.c
index 52be5fb5..201557b3 100644
--- a/src/daemon/https/tls/gnutls_cert.c
+++ b/src/daemon/https/tls/gnutls_cert.c
@@ -186,10 +186,6 @@ MHD__gnutls_certificate_free_credentials (MHD_gtls_cert_credentials_t sc)
186 MHD__gnutls_certificate_free_keys (sc); 186 MHD__gnutls_certificate_free_keys (sc);
187 MHD__gnutls_certificate_free_cas (sc); 187 MHD__gnutls_certificate_free_cas (sc);
188 MHD__gnutls_certificate_free_ca_names (sc); 188 MHD__gnutls_certificate_free_ca_names (sc);
189#ifdef ENABLE_PKI
190 MHD__gnutls_certificate_free_crls (sc);
191#endif
192
193#ifdef KEYRING_HACK 189#ifdef KEYRING_HACK
194 MHD__gnutls_free_datum (&sc->keyring); 190 MHD__gnutls_free_datum (&sc->keyring);
195#endif 191#endif
diff --git a/src/daemon/https/tls/gnutls_x509.c b/src/daemon/https/tls/gnutls_x509.c
index a326ac01..3ec47e94 100644
--- a/src/daemon/https/tls/gnutls_x509.c
+++ b/src/daemon/https/tls/gnutls_x509.c
@@ -50,7 +50,6 @@
50#include "x509.h" 50#include "x509.h"
51#include "verify.h" 51#include "verify.h"
52#include "mpi.h" 52#include "mpi.h"
53#include "pkcs7.h"
54#include "privkey.h" 53#include "privkey.h"
55 54
56 55
@@ -536,15 +535,6 @@ MHD__gnutls_x509_raw_privkey_to_gkey (MHD_gnutls_privkey * privkey,
536 } 535 }
537 536
538 ret = MHD_gnutls_x509_privkey_import (tmpkey, raw_key, type); 537 ret = MHD_gnutls_x509_privkey_import (tmpkey, raw_key, type);
539
540#ifdef ENABLE_PKI
541 /* If normal key decoding doesn't work try decoding a plain PKCS #8 key */
542 if (ret < 0)
543 ret =
544 MHD_gnutls_x509_privkey_import_pkcs8 (tmpkey, raw_key, type, NULL,
545 GNUTLS_PKCS_PLAIN);
546#endif
547
548 if (ret < 0) 538 if (ret < 0)
549 { 539 {
550 MHD_gnutls_assert (); 540 MHD_gnutls_assert ();
@@ -972,225 +962,3 @@ MHD__gnutls_certificate_set_x509_trust_mem (MHD_gtls_cert_credentials_t
972 return ret; 962 return ret;
973} 963}
974 964
975#ifdef ENABLE_PKI
976
977static int
978parse_pem_crl_mem (MHD_gnutls_x509_crl_t ** crl_list, unsigned *ncrls,
979 const opaque * input_crl, int input_crl_size)
980{
981 int size, i;
982 const opaque *ptr;
983 MHD_gnutls_datum_t tmp;
984 int ret, count;
985
986 /* move to the certificate
987 */
988 ptr = memmem (input_crl, input_crl_size,
989 PEM_CRL_SEP, sizeof (PEM_CRL_SEP) - 1);
990 if (ptr == NULL)
991 {
992 MHD_gnutls_assert ();
993 return GNUTLS_E_BASE64_DECODING_ERROR;
994 }
995
996 size = input_crl_size - (ptr - input_crl);
997
998 i = *ncrls + 1;
999 count = 0;
1000
1001 do
1002 {
1003
1004 *crl_list =
1005 (MHD_gnutls_x509_crl_t *) MHD_gtls_realloc_fast (*crl_list,
1006 i *
1007 sizeof
1008 (MHD_gnutls_x509_crl_t));
1009
1010 if (*crl_list == NULL)
1011 {
1012 MHD_gnutls_assert ();
1013 return GNUTLS_E_MEMORY_ERROR;
1014 }
1015
1016 ret = MHD_gnutls_x509_crl_init (&crl_list[0][i - 1]);
1017 if (ret < 0)
1018 {
1019 MHD_gnutls_assert ();
1020 return ret;
1021 }
1022
1023 tmp.data = (unsigned char *) ptr;
1024 tmp.size = size;
1025
1026 ret =
1027 MHD_gnutls_x509_crl_import (crl_list[0][i - 1],
1028 &tmp, GNUTLS_X509_FMT_PEM);
1029 if (ret < 0)
1030 {
1031 MHD_gnutls_assert ();
1032 return ret;
1033 }
1034
1035 /* now we move ptr after the pem header
1036 */
1037 ptr++;
1038 /* find the next certificate (if any)
1039 */
1040
1041 size = input_crl_size - (ptr - input_crl);
1042
1043 if (size > 0)
1044 ptr = memmem (ptr, size, PEM_CRL_SEP, sizeof (PEM_CRL_SEP) - 1);
1045 else
1046 ptr = NULL;
1047 i++;
1048 count++;
1049
1050 }
1051 while (ptr != NULL);
1052
1053 *ncrls = i - 1;
1054
1055 return count;
1056}
1057
1058/* Reads a DER encoded certificate list from memory and stores it to
1059 * a MHD_gnutls_cert structure.
1060 * returns the number of certificates parsed.
1061 */
1062static int
1063parse_der_crl_mem (MHD_gnutls_x509_crl_t ** crl_list, unsigned *ncrls,
1064 const void *input_crl, int input_crl_size)
1065{
1066 int i;
1067 MHD_gnutls_datum_t tmp;
1068 int ret;
1069
1070 i = *ncrls + 1;
1071
1072 *crl_list =
1073 (MHD_gnutls_x509_crl_t *) MHD_gtls_realloc_fast (*crl_list,
1074 i *
1075 sizeof
1076 (MHD_gnutls_x509_crl_t));
1077
1078 if (*crl_list == NULL)
1079 {
1080 MHD_gnutls_assert ();
1081 return GNUTLS_E_MEMORY_ERROR;
1082 }
1083
1084 tmp.data = (opaque *) input_crl;
1085 tmp.size = input_crl_size;
1086
1087 ret = MHD_gnutls_x509_crl_init (&crl_list[0][i - 1]);
1088 if (ret < 0)
1089 {
1090 MHD_gnutls_assert ();
1091 return ret;
1092 }
1093
1094 ret =
1095 MHD_gnutls_x509_crl_import (crl_list[0][i - 1], &tmp,
1096 GNUTLS_X509_FMT_DER);
1097 if (ret < 0)
1098 {
1099 MHD_gnutls_assert ();
1100 return ret;
1101 }
1102
1103 *ncrls = i;
1104
1105 return 1; /* one certificate parsed */
1106}
1107
1108
1109/* Reads a DER or PEM CRL from memory
1110 */
1111static int
1112read_crl_mem (MHD_gtls_cert_credentials_t res, const void *crl,
1113 int crl_size, MHD_gnutls_x509_crt_fmt_t type)
1114{
1115 int ret;
1116
1117 /* allocate space for the certificate to add
1118 */
1119 res->x509_crl_list = MHD_gtls_realloc_fast (res->x509_crl_list,
1120 (1 +
1121 res->x509_ncrls) *
1122 sizeof (MHD_gnutls_x509_crl_t));
1123 if (res->x509_crl_list == NULL)
1124 {
1125 MHD_gnutls_assert ();
1126 return GNUTLS_E_MEMORY_ERROR;
1127 }
1128
1129 if (type == GNUTLS_X509_FMT_DER)
1130 ret = parse_der_crl_mem (&res->x509_crl_list,
1131 &res->x509_ncrls, crl, crl_size);
1132 else
1133 ret = parse_pem_crl_mem (&res->x509_crl_list,
1134 &res->x509_ncrls, crl, crl_size);
1135
1136 if (ret < 0)
1137 {
1138 MHD_gnutls_assert ();
1139 return ret;
1140 }
1141
1142 return ret;
1143}
1144
1145/**
1146 * MHD__gnutls_certificate_set_x509_crl_mem - Used to add CRLs in a MHD_gtls_cert_credentials_t structure
1147 * @res: is an #MHD_gtls_cert_credentials_t structure.
1148 * @CRL: is a list of trusted CRLs. They should have been verified before.
1149 * @type: is DER or PEM
1150 *
1151 * This function adds the trusted CRLs in order to verify client or
1152 * server certificates. In case of a client this is not required to
1153 * be called if the certificates are not verified using
1154 * MHD_gtls_certificate_verify_peers2(). This function may be called
1155 * multiple times.
1156 *
1157 * Returns: number of CRLs processed, or a negative value on error.
1158 **/
1159int
1160MHD__gnutls_certificate_set_x509_crl_mem (MHD_gtls_cert_credentials_t
1161 res, const MHD_gnutls_datum_t * CRL,
1162 MHD_gnutls_x509_crt_fmt_t type)
1163{
1164 int ret;
1165
1166 if ((ret = read_crl_mem (res, CRL->data, CRL->size, type)) < 0)
1167 return ret;
1168
1169 return ret;
1170}
1171
1172/**
1173 * MHD__gnutls_certificate_free_crls - Used to free all the CRLs from a MHD_gtls_cert_credentials_t structure
1174 * @sc: is an #MHD_gtls_cert_credentials_t structure.
1175 *
1176 * This function will delete all the CRLs associated
1177 * with the given credentials.
1178 *
1179 **/
1180void
1181MHD__gnutls_certificate_free_crls (MHD_gtls_cert_credentials_t sc)
1182{
1183 unsigned j;
1184
1185 for (j = 0; j < sc->x509_ncrls; j++)
1186 {
1187 MHD_gnutls_x509_crl_deinit (sc->x509_crl_list[j]);
1188 }
1189
1190 sc->x509_ncrls = 0;
1191
1192 MHD_gnutls_free (sc->x509_crl_list);
1193 sc->x509_crl_list = NULL;
1194}
1195
1196#endif
diff --git a/src/daemon/https/x509/Makefile.am b/src/daemon/https/x509/Makefile.am
index 65d9594f..d1305b47 100644
--- a/src/daemon/https/x509/Makefile.am
+++ b/src/daemon/https/x509/Makefile.am
@@ -18,16 +18,12 @@ libx509_la_LDFLAGS = -lgcrypt
18 18
19libx509_la_SOURCES = \ 19libx509_la_SOURCES = \
20common.c common.h \ 20common.c common.h \
21crl.c \
22dn.c dn.h \ 21dn.c dn.h \
23extensions.c extensions.h \ 22extensions.c extensions.h \
24mpi.c mpi.h \ 23mpi.c mpi.h \
25pkcs12_encr.c pkcs12.h \ 24pkcs12.h \
26pkcs7.c pkcs7.h \
27x509_privkey.c privkey.h \ 25x509_privkey.c privkey.h \
28privkey_pkcs8.c \
29rfc2818_hostname.c rfc2818.h \ 26rfc2818_hostname.c rfc2818.h \
30sign.c sign.h \
31x509_verify.c verify.h \ 27x509_verify.c verify.h \
32x509.c x509.h 28x509.c x509.h
33 29
diff --git a/src/daemon/https/x509/crl.c b/src/daemon/https/x509/crl.c
deleted file mode 100644
index 98a9748b..00000000
--- a/src/daemon/https/x509/crl.c
+++ /dev/null
@@ -1,437 +0,0 @@
1/*
2 * Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25#include <gnutls_int.h>
26#include <libtasn1.h>
27
28#ifdef ENABLE_PKI
29
30#include <gnutls_datum.h>
31#include <gnutls_global.h>
32#include <gnutls_errors.h>
33#include <common.h>
34#include <x509_b64.h>
35#include <x509.h>
36#include <dn.h>
37
38/**
39 * MHD_gnutls_x509_crl_init - This function initializes a MHD_gnutls_x509_crl_t structure
40 * @crl: The structure to be initialized
41 *
42 * This function will initialize a CRL structure. CRL stands for
43 * Certificate Revocation List. A revocation list usually contains
44 * lists of certificate serial numbers that have been revoked
45 * by an Authority. The revocation lists are always signed with
46 * the authority's private key.
47 *
48 * Returns 0 on success.
49 *
50 **/
51int
52MHD_gnutls_x509_crl_init (MHD_gnutls_x509_crl_t * crl)
53{
54 *crl = MHD_gnutls_calloc (1, sizeof (MHD_gnutls_x509_crl_int));
55
56 if (*crl)
57 {
58 int result = MHD__asn1_create_element (MHD__gnutls_get_pkix (),
59 "PKIX1.CertificateList",
60 &(*crl)->crl);
61 if (result != ASN1_SUCCESS)
62 {
63 MHD_gnutls_assert ();
64 MHD_gnutls_free (*crl);
65 return MHD_gtls_asn2err (result);
66 }
67 return 0; /* success */
68 }
69 return GNUTLS_E_MEMORY_ERROR;
70}
71
72/**
73 * MHD_gnutls_x509_crl_deinit - This function deinitializes memory used by a MHD_gnutls_x509_crl_t structure
74 * @crl: The structure to be initialized
75 *
76 * This function will deinitialize a CRL structure.
77 *
78 **/
79void
80MHD_gnutls_x509_crl_deinit (MHD_gnutls_x509_crl_t crl)
81{
82 if (!crl)
83 return;
84
85 if (crl->crl)
86 MHD__asn1_delete_structure (&crl->crl);
87
88 MHD_gnutls_free (crl);
89}
90
91/**
92 * MHD_gnutls_x509_crl_import - This function will import a DER or PEM encoded CRL
93 * @crl: The structure to store the parsed CRL.
94 * @data: The DER or PEM encoded CRL.
95 * @format: One of DER or PEM
96 *
97 * This function will convert the given DER or PEM encoded CRL
98 * to the native MHD_gnutls_x509_crl_t format. The output will be stored in 'crl'.
99 *
100 * If the CRL is PEM encoded it should have a header of "X509 CRL".
101 *
102 * Returns 0 on success.
103 *
104 **/
105int
106MHD_gnutls_x509_crl_import (MHD_gnutls_x509_crl_t crl,
107 const MHD_gnutls_datum_t * data,
108 MHD_gnutls_x509_crt_fmt_t format)
109{
110 int result = 0, need_free = 0;
111 MHD_gnutls_datum_t _data;
112
113 _data.data = data->data;
114 _data.size = data->size;
115
116 if (crl == NULL)
117 {
118 MHD_gnutls_assert ();
119 return GNUTLS_E_INVALID_REQUEST;
120 }
121
122 /* If the CRL is in PEM format then decode it
123 */
124 if (format == GNUTLS_X509_FMT_PEM)
125 {
126 opaque *out;
127
128 result =
129 MHD__gnutls_fbase64_decode (PEM_CRL, data->data, data->size, &out);
130
131 if (result <= 0)
132 {
133 if (result == 0)
134 result = GNUTLS_E_INTERNAL_ERROR;
135 MHD_gnutls_assert ();
136 return result;
137 }
138
139 _data.data = out;
140 _data.size = result;
141
142 need_free = 1;
143 }
144
145
146 result = MHD__asn1_der_decoding (&crl->crl, _data.data, _data.size, NULL);
147 if (result != ASN1_SUCCESS)
148 {
149 result = MHD_gtls_asn2err (result);
150 MHD_gnutls_assert ();
151 goto cleanup;
152 }
153
154 if (need_free)
155 MHD__gnutls_free_datum (&_data);
156
157 return 0;
158
159cleanup:
160 if (need_free)
161 MHD__gnutls_free_datum (&_data);
162 return result;
163}
164
165
166/**
167 * MHD_gnutls_x509_crl_get_signature_algorithm - This function returns the CRL's signature algorithm
168 * @crl: should contain a MHD_gnutls_x509_crl_t structure
169 *
170 * This function will return a value of the MHD_gnutls_sign_algorithm_t enumeration that
171 * is the signature algorithm.
172 *
173 * Returns a negative value on error.
174 *
175 **/
176int
177MHD_gnutls_x509_crl_get_signature_algorithm (MHD_gnutls_x509_crl_t crl)
178{
179 int result;
180 MHD_gnutls_datum_t sa;
181
182 if (crl == NULL)
183 {
184 MHD_gnutls_assert ();
185 return GNUTLS_E_INVALID_REQUEST;
186 }
187
188 /* Read the signature algorithm. Note that parameters are not
189 * read. They will be read from the issuer's certificate if needed.
190 */
191
192 result =
193 MHD__gnutls_x509_read_value (crl->crl, "signatureAlgorithm.algorithm",
194 &sa, 0);
195
196 if (result < 0)
197 {
198 MHD_gnutls_assert ();
199 return result;
200 }
201
202 result = MHD_gtls_x509_oid2sign_algorithm ((const char *) sa.data);
203
204 MHD__gnutls_free_datum (&sa);
205
206 return result;
207}
208
209/**
210 * MHD_gnutls_x509_crl_get_signature - Returns the CRL's signature
211 * @crl: should contain a MHD_gnutls_x509_crl_t structure
212 * @sig: a pointer where the signature part will be copied (may be null).
213 * @sizeof_sig: initially holds the size of @sig
214 *
215 * This function will extract the signature field of a CRL.
216 *
217 * Returns 0 on success, and a negative value on error.
218 **/
219int
220MHD_gnutls_x509_crl_get_signature (MHD_gnutls_x509_crl_t crl,
221 char *sig, size_t * sizeof_sig)
222{
223 int result;
224 int bits, len;
225
226 if (crl == NULL)
227 {
228 MHD_gnutls_assert ();
229 return GNUTLS_E_INVALID_REQUEST;
230 }
231
232 bits = 0;
233 result = MHD__asn1_read_value (crl->crl, "signature", NULL, &bits);
234 if (result != ASN1_MEM_ERROR)
235 {
236 MHD_gnutls_assert ();
237 return MHD_gtls_asn2err (result);
238 }
239
240 if (bits % 8 != 0)
241 {
242 MHD_gnutls_assert ();
243 return GNUTLS_E_CERTIFICATE_ERROR;
244 }
245
246 len = bits / 8;
247
248 if (*sizeof_sig < len)
249 {
250 *sizeof_sig = bits / 8;
251 return GNUTLS_E_SHORT_MEMORY_BUFFER;
252 }
253
254 result = MHD__asn1_read_value (crl->crl, "signature", sig, &len);
255 if (result != ASN1_SUCCESS)
256 {
257 MHD_gnutls_assert ();
258 return MHD_gtls_asn2err (result);
259 }
260
261 return 0;
262}
263
264
265/**
266 * MHD_gnutls_x509_crl_get_crt_count - This function returns the number of revoked certificates in a CRL
267 * @crl: should contain a MHD_gnutls_x509_crl_t structure
268 *
269 * This function will return the number of revoked certificates in the
270 * given CRL.
271 *
272 * Returns a negative value on failure.
273 *
274 **/
275int
276MHD_gnutls_x509_crl_get_crt_count (MHD_gnutls_x509_crl_t crl)
277{
278
279 int count, result;
280
281 if (crl == NULL)
282 {
283 MHD_gnutls_assert ();
284 return GNUTLS_E_INVALID_REQUEST;
285 }
286
287 result =
288 MHD__asn1_number_of_elements (crl->crl,
289 "tbsCertList.revokedCertificates", &count);
290
291 if (result != ASN1_SUCCESS)
292 {
293 MHD_gnutls_assert ();
294 return 0; /* no certificates */
295 }
296
297 return count;
298}
299
300/**
301 * MHD_gnutls_x509_crl_get_crt_serial - This function returns the serial number of a revoked certificate
302 * @crl: should contain a MHD_gnutls_x509_crl_t structure
303 * @indx: the index of the certificate to extract (starting from 0)
304 * @serial: where the serial number will be copied
305 * @serial_size: initially holds the size of serial
306 * @t: if non null, will hold the time this certificate was revoked
307 *
308 * This function will return the serial number of the specified, by
309 * the index, revoked certificate.
310 *
311 * Returns a negative value on failure.
312 *
313 **/
314int
315MHD_gnutls_x509_crl_get_crt_serial (MHD_gnutls_x509_crl_t crl, int indx,
316 unsigned char *serial,
317 size_t * serial_size, time_t * t)
318{
319
320 int result, _serial_size;
321 char serial_name[MAX_NAME_SIZE];
322 char date_name[MAX_NAME_SIZE];
323
324 if (crl == NULL)
325 {
326 MHD_gnutls_assert ();
327 return GNUTLS_E_INVALID_REQUEST;
328 }
329
330 snprintf (serial_name, sizeof (serial_name),
331 "tbsCertList.revokedCertificates.?%u.userCertificate", indx + 1);
332 snprintf (date_name, sizeof (date_name),
333 "tbsCertList.revokedCertificates.?%u.revocationDate", indx + 1);
334
335 _serial_size = *serial_size;
336 result =
337 MHD__asn1_read_value (crl->crl, serial_name, serial, &_serial_size);
338
339 *serial_size = _serial_size;
340 if (result != ASN1_SUCCESS)
341 {
342 MHD_gnutls_assert ();
343 if (result == ASN1_ELEMENT_NOT_FOUND)
344 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
345 return MHD_gtls_asn2err (result);
346 }
347
348 if (t)
349 {
350 *t = MHD__gnutls_x509_get_time (crl->crl, date_name);
351 }
352
353 return 0;
354}
355
356/*-
357 * MHD__gnutls_x509_crl_get_raw_issuer_dn - This function returns the issuer's DN DER encoded
358 * @crl: should contain a MHD_gnutls_x509_crl_t structure
359 * @dn: will hold the starting point of the DN
360 *
361 * This function will return a pointer to the DER encoded DN structure and
362 * the length.
363 *
364 * Returns a negative value on error, and zero on success.
365 *
366 -*/
367int
368MHD__gnutls_x509_crl_get_raw_issuer_dn (MHD_gnutls_x509_crl_t crl,
369 MHD_gnutls_datum_t * dn)
370{
371 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
372 int result, len1;
373 int start1, end1;
374 MHD_gnutls_datum_t crl_signed_data;
375
376 if (crl == NULL)
377 {
378 MHD_gnutls_assert ();
379 return GNUTLS_E_INVALID_REQUEST;
380 }
381
382 /* get the issuer of 'crl'
383 */
384 if ((result =
385 MHD__asn1_create_element (MHD__gnutls_get_pkix (), "PKIX1.TBSCertList",
386 &c2)) != ASN1_SUCCESS)
387 {
388 MHD_gnutls_assert ();
389 return MHD_gtls_asn2err (result);
390 }
391
392 result =
393 MHD__gnutls_x509_get_signed_data (crl->crl, "tbsCertList",
394 &crl_signed_data);
395 if (result < 0)
396 {
397 MHD_gnutls_assert ();
398 goto cleanup;
399 }
400
401 result =
402 MHD__asn1_der_decoding (&c2, crl_signed_data.data, crl_signed_data.size,
403 NULL);
404 if (result != ASN1_SUCCESS)
405 {
406 /* couldn't decode DER */
407 MHD_gnutls_assert ();
408 MHD__asn1_delete_structure (&c2);
409 result = MHD_gtls_asn2err (result);
410 goto cleanup;
411 }
412
413 result =
414 MHD__asn1_der_decoding_startEnd (c2, crl_signed_data.data,
415 crl_signed_data.size, "issuer",
416 &start1, &end1);
417
418 if (result != ASN1_SUCCESS)
419 {
420 MHD_gnutls_assert ();
421 result = MHD_gtls_asn2err (result);
422 goto cleanup;
423 }
424
425 len1 = end1 - start1 + 1;
426
427 MHD__gnutls_set_datum (dn, &crl_signed_data.data[start1], len1);
428
429 result = 0;
430
431cleanup:
432 MHD__asn1_delete_structure (&c2);
433 MHD__gnutls_free_datum (&crl_signed_data);
434 return result;
435}
436
437#endif
diff --git a/src/daemon/https/x509/mpi.c b/src/daemon/https/x509/mpi.c
index 76995fdb..e8563967 100644
--- a/src/daemon/https/x509/mpi.c
+++ b/src/daemon/https/x509/mpi.c
@@ -83,126 +83,6 @@ MHD__gnutls_x509_read_rsa_params (opaque * der, int dersize, mpi_t * params)
83 83
84} 84}
85 85
86/* reads p,q and g
87 * from the certificate (subjectPublicKey BIT STRING).
88 * params[0-2]
89 */
90int
91MHD__gnutls_x509_read_dsa_params (opaque * der, int dersize, mpi_t * params)
92{
93 int result;
94 ASN1_TYPE spk = ASN1_TYPE_EMPTY;
95
96 if ((result =
97 MHD__asn1_create_element (MHD__gnutls_get_pkix (), "PKIX1.Dss-Parms",
98 &spk)) != ASN1_SUCCESS)
99 {
100 MHD_gnutls_assert ();
101 return MHD_gtls_asn2err (result);
102 }
103
104 result = MHD__asn1_der_decoding (&spk, der, dersize, NULL);
105
106 if (result != ASN1_SUCCESS)
107 {
108 MHD_gnutls_assert ();
109 MHD__asn1_delete_structure (&spk);
110 return MHD_gtls_asn2err (result);
111 }
112
113 /* FIXME: If the parameters are not included in the certificate
114 * then the issuer's parameters should be used. This is not
115 * done yet.
116 */
117
118 /* Read p */
119
120 if ((result = MHD__gnutls_x509_read_int (spk, "p", &params[0])) < 0)
121 {
122 MHD_gnutls_assert ();
123 MHD__asn1_delete_structure (&spk);
124 return GNUTLS_E_ASN1_GENERIC_ERROR;
125 }
126
127 /* Read q */
128
129 if ((result = MHD__gnutls_x509_read_int (spk, "q", &params[1])) < 0)
130 {
131 MHD_gnutls_assert ();
132 MHD__asn1_delete_structure (&spk);
133 MHD_gtls_mpi_release (&params[0]);
134 return GNUTLS_E_ASN1_GENERIC_ERROR;
135 }
136
137 /* Read g */
138
139 if ((result = MHD__gnutls_x509_read_int (spk, "g", &params[2])) < 0)
140 {
141 MHD_gnutls_assert ();
142 MHD__asn1_delete_structure (&spk);
143 MHD_gtls_mpi_release (&params[0]);
144 MHD_gtls_mpi_release (&params[1]);
145 return GNUTLS_E_ASN1_GENERIC_ERROR;
146 }
147
148 MHD__asn1_delete_structure (&spk);
149
150 return 0;
151
152}
153
154/* Reads an Integer from the DER encoded data
155 */
156
157int
158MHD__gnutls_x509_read_der_int (opaque * der, int dersize, mpi_t * out)
159{
160 int result;
161 ASN1_TYPE spk = ASN1_TYPE_EMPTY;
162
163 /* == INTEGER */
164 if ((result =
165 MHD__asn1_create_element (MHD__gnutls_getMHD__gnutls_asn (),
166 "GNUTLS.DSAPublicKey",
167 &spk)) != ASN1_SUCCESS)
168 {
169 MHD_gnutls_assert ();
170 return MHD_gtls_asn2err (result);
171 }
172
173 result = MHD__asn1_der_decoding (&spk, der, dersize, NULL);
174
175 if (result != ASN1_SUCCESS)
176 {
177 MHD_gnutls_assert ();
178 MHD__asn1_delete_structure (&spk);
179 return MHD_gtls_asn2err (result);
180 }
181
182 /* Read Y */
183
184 if ((result = MHD__gnutls_x509_read_int (spk, "", out)) < 0)
185 {
186 MHD_gnutls_assert ();
187 MHD__asn1_delete_structure (&spk);
188 return MHD_gtls_asn2err (result);
189 }
190
191 MHD__asn1_delete_structure (&spk);
192
193 return 0;
194
195}
196
197/* reads DSA's Y
198 * from the certificate
199 * only sets params[3]
200 */
201int
202MHD__gnutls_x509_read_dsa_pubkey (opaque * der, int dersize, mpi_t * params)
203{
204 return MHD__gnutls_x509_read_der_int (der, dersize, &params[3]);
205}
206 86
207/* Extracts DSA and RSA parameters from a certificate. 87/* Extracts DSA and RSA parameters from a certificate.
208 */ 88 */
@@ -331,181 +211,6 @@ cleanup:MHD__asn1_delete_structure (&spk);
331 return result; 211 return result;
332} 212}
333 213
334/*
335 * This function writes and encodes the parameters for DSS or RSA keys.
336 * This is the "signatureAlgorithm" fields.
337 */
338int
339MHD__gnutls_x509_write_sig_params (ASN1_TYPE dst,
340 const char *dst_name,
341 enum MHD_GNUTLS_PublicKeyAlgorithm
342 pk_algorithm,
343 enum MHD_GNUTLS_HashAlgorithm dig,
344 mpi_t * params, int params_size)
345{
346 int result;
347 char name[128];
348 const char *pk;
349
350 MHD_gtls_str_cpy (name, sizeof (name), dst_name);
351 MHD_gtls_str_cat (name, sizeof (name), ".algorithm");
352
353 pk = MHD_gtls_x509_sign_to_oid (pk_algorithm, HASH2MAC (dig));
354 if (pk == NULL)
355 {
356 MHD_gnutls_assert ();
357 return GNUTLS_E_INVALID_REQUEST;
358 }
359
360 /* write the OID.
361 */
362 result = MHD__asn1_write_value (dst, name, pk, 1);
363 if (result != ASN1_SUCCESS)
364 {
365 MHD_gnutls_assert ();
366 return MHD_gtls_asn2err (result);
367 }
368
369 MHD_gtls_str_cpy (name, sizeof (name), dst_name);
370 MHD_gtls_str_cat (name, sizeof (name), ".parameters");
371
372 if (pk_algorithm == MHD_GNUTLS_PK_RSA)
373 { /* RSA */
374 result = MHD__asn1_write_value (dst, name, NULL, 0);
375
376 if (result != ASN1_SUCCESS && result != ASN1_ELEMENT_NOT_FOUND)
377 {
378 /* Here we ignore the element not found error, since this
379 * may have been disabled before.
380 */
381 MHD_gnutls_assert ();
382 return MHD_gtls_asn2err (result);
383 }
384 }
385
386 return 0;
387}
388
389/*
390 * This function writes the parameters for DSS keys.
391 * Needs 3 parameters (p,q,g).
392 *
393 * Allocates the space used to store the DER data.
394 */
395int
396MHD__gnutls_x509_write_dsa_params (mpi_t * params,
397 int params_size, MHD_gnutls_datum_t * der)
398{
399 int result;
400 ASN1_TYPE spk = ASN1_TYPE_EMPTY;
401
402 der->data = NULL;
403 der->size = 0;
404
405 if (params_size < 3)
406 {
407 MHD_gnutls_assert ();
408 result = GNUTLS_E_INVALID_REQUEST;
409 goto cleanup;
410 }
411
412 if ((result =
413 MHD__asn1_create_element (MHD__gnutls_getMHD__gnutls_asn (),
414 "GNUTLS.DSAParameters",
415 &spk)) != ASN1_SUCCESS)
416 {
417 MHD_gnutls_assert ();
418 return MHD_gtls_asn2err (result);
419 }
420
421 result = MHD__gnutls_x509_write_int (spk, "p", params[0], 0);
422 if (result < 0)
423 {
424 MHD_gnutls_assert ();
425 goto cleanup;
426 }
427
428 result = MHD__gnutls_x509_write_int (spk, "q", params[1], 0);
429 if (result < 0)
430 {
431 MHD_gnutls_assert ();
432 goto cleanup;
433 }
434
435 result = MHD__gnutls_x509_write_int (spk, "g", params[2], 0);
436 if (result < 0)
437 {
438 MHD_gnutls_assert ();
439 goto cleanup;
440 }
441
442 result = MHD__gnutls_x509_der_encode (spk, "", der, 0);
443 if (result < 0)
444 {
445 MHD_gnutls_assert ();
446 goto cleanup;
447 }
448
449 result = 0;
450
451cleanup:MHD__asn1_delete_structure (&spk);
452 return result;
453}
454
455/*
456 * This function writes the public parameters for DSS keys.
457 * Needs 1 parameter (y).
458 *
459 * Allocates the space used to store the DER data.
460 */
461int
462MHD__gnutls_x509_write_dsa_public_key (mpi_t * params,
463 int params_size,
464 MHD_gnutls_datum_t * der)
465{
466 int result;
467 ASN1_TYPE spk = ASN1_TYPE_EMPTY;
468
469 der->data = NULL;
470 der->size = 0;
471
472 if (params_size < 3)
473 {
474 MHD_gnutls_assert ();
475 result = GNUTLS_E_INVALID_REQUEST;
476 goto cleanup;
477 }
478
479 if ((result =
480 MHD__asn1_create_element (MHD__gnutls_getMHD__gnutls_asn (),
481 "GNUTLS.DSAPublicKey",
482 &spk)) != ASN1_SUCCESS)
483 {
484 MHD_gnutls_assert ();
485 return MHD_gtls_asn2err (result);
486 }
487
488 result = MHD__gnutls_x509_write_int (spk, "", params[3], 0);
489 if (result < 0)
490 {
491 MHD_gnutls_assert ();
492 goto cleanup;
493 }
494
495 result = MHD__gnutls_x509_der_encode (spk, "", der, 0);
496 if (result < 0)
497 {
498 MHD_gnutls_assert ();
499 goto cleanup;
500 }
501
502 MHD__asn1_delete_structure (&spk);
503 return 0;
504
505cleanup:MHD__asn1_delete_structure (&spk);
506 return result;
507}
508
509/* this function reads a (small) unsigned integer 214/* this function reads a (small) unsigned integer
510 * from asn1 structs. Combines the read and the convertion 215 * from asn1 structs. Combines the read and the convertion
511 * steps. 216 * steps.
@@ -560,25 +265,3 @@ MHD__gnutls_x509_read_uint (ASN1_TYPE node, const char *value,
560 265
561 return 0; 266 return 0;
562} 267}
563
564/* Writes the specified integer into the specified node.
565 */
566int
567MHD__gnutls_x509_write_uint32 (ASN1_TYPE node, const char *value,
568 uint32_t num)
569{
570 opaque tmpstr[4];
571 int result;
572
573 MHD_gtls_write_uint32 (num, tmpstr);
574
575 result = MHD__asn1_write_value (node, value, tmpstr, 4);
576
577 if (result != ASN1_SUCCESS)
578 {
579 MHD_gnutls_assert ();
580 return MHD_gtls_asn2err (result);
581 }
582
583 return 0;
584}
diff --git a/src/daemon/https/x509/mpi.h b/src/daemon/https/x509/mpi.h
index edac2eee..8db519fd 100644
--- a/src/daemon/https/x509/mpi.h
+++ b/src/daemon/https/x509/mpi.h
@@ -29,32 +29,13 @@ int MHD__gnutls_x509_crt_get_mpis (MHD_gnutls_x509_crt_t cert,
29 mpi_t * params, int *params_size); 29 mpi_t * params, int *params_size);
30int MHD__gnutls_x509_read_rsa_params (opaque * der, int dersize, 30int MHD__gnutls_x509_read_rsa_params (opaque * der, int dersize,
31 mpi_t * params); 31 mpi_t * params);
32int MHD__gnutls_x509_read_dsa_pubkey (opaque * der, int dersize,
33 mpi_t * params);
34int MHD__gnutls_x509_read_dsa_params (opaque * der, int dersize,
35 mpi_t * params);
36
37int MHD__gnutls_x509_write_rsa_params (mpi_t * params, int params_size, 32int MHD__gnutls_x509_write_rsa_params (mpi_t * params, int params_size,
38 MHD_gnutls_datum_t * der); 33 MHD_gnutls_datum_t * der);
39int MHD__gnutls_x509_write_dsa_params (mpi_t * params, int params_size,
40 MHD_gnutls_datum_t * der);
41int MHD__gnutls_x509_write_dsa_public_key (mpi_t * params, int params_size,
42 MHD_gnutls_datum_t * der);
43
44int MHD__gnutls_x509_read_uint (ASN1_TYPE node, const char *value, 34int MHD__gnutls_x509_read_uint (ASN1_TYPE node, const char *value,
45 unsigned int *ret); 35 unsigned int *ret);
46 36
47int MHD__gnutls_x509_read_der_int (opaque * der, int dersize, mpi_t * out);
48
49int MHD__gnutls_x509_read_int (ASN1_TYPE node, const char *value, 37int MHD__gnutls_x509_read_int (ASN1_TYPE node, const char *value,
50 mpi_t * ret_mpi); 38 mpi_t * ret_mpi);
51int MHD__gnutls_x509_write_int (ASN1_TYPE node, const char *value, mpi_t mpi, 39int MHD__gnutls_x509_write_int (ASN1_TYPE node, const char *value, mpi_t mpi,
52 int lz); 40 int lz);
53int MHD__gnutls_x509_write_uint32 (ASN1_TYPE node, const char *value,
54 uint32_t num);
55 41
56int MHD__gnutls_x509_write_sig_params (ASN1_TYPE dst, const char *dst_name,
57 enum MHD_GNUTLS_PublicKeyAlgorithm
58 pk_algorithm,
59 enum MHD_GNUTLS_HashAlgorithm,
60 mpi_t * params, int params_size);
diff --git a/src/daemon/https/x509/pkcs12_encr.c b/src/daemon/https/x509/pkcs12_encr.c
deleted file mode 100644
index e534489c..00000000
--- a/src/daemon/https/x509/pkcs12_encr.c
+++ /dev/null
@@ -1,169 +0,0 @@
1/* minip12.c - A mini pkcs-12 implementation (modified for gnutls)
2 *
3 * Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
4 *
5 * This file is part of GNUTLS.
6 *
7 * The GNUTLS library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public License
9 * as published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
20 * USA
21 *
22 */
23
24#include <gnutls_int.h>
25
26#ifdef ENABLE_PKI
27
28#include <gcrypt.h>
29#include <gc.h>
30#include <gnutls_errors.h>
31
32/* Returns 0 if the password is ok, or a negative error
33 * code instead.
34 */
35static int
36MHD_pkcs12_check_pass (const char *pass, size_t plen)
37{
38 const char *p = pass;
39 unsigned int i;
40
41 for (i = 0; i < plen; i++)
42 {
43 if (isascii (p[i]))
44 continue;
45 return GNUTLS_E_INVALID_PASSWORD;
46 }
47
48 return 0;
49}
50
51/* ID should be:
52 * 3 for MAC
53 * 2 for IV
54 * 1 for encryption key
55 */
56int
57MHD_pkcs12_string_to_key (unsigned int id, const opaque * salt,
58 unsigned int salt_size, unsigned int iter,
59 const char *pw, unsigned int req_keylen,
60 opaque * keybuf)
61{
62 int rc;
63 unsigned int i, j;
64 MHD_gc_hash_handle md;
65 mpi_t num_b1 = NULL;
66 unsigned int pwlen;
67 opaque hash[20], buf_b[64], buf_i[128], *p;
68 size_t cur_keylen;
69 size_t n;
70
71 cur_keylen = 0;
72
73 if (pw == NULL)
74 pwlen = 0;
75 else
76 pwlen = strlen (pw);
77
78 if (pwlen > 63 / 2)
79 {
80 MHD_gnutls_assert ();
81 return GNUTLS_E_INVALID_REQUEST;
82 }
83
84 if ((rc = MHD_pkcs12_check_pass (pw, pwlen)) < 0)
85 {
86 MHD_gnutls_assert ();
87 return rc;
88 }
89
90 /* Store salt and password in BUF_I */
91 p = buf_i;
92 for (i = 0; i < 64; i++)
93 *p++ = salt[i % salt_size];
94 if (pw)
95 {
96 for (i = j = 0; i < 64; i += 2)
97 {
98 *p++ = 0;
99 *p++ = pw[j];
100 if (++j > pwlen) /* Note, that we include the trailing zero */
101 j = 0;
102 }
103 }
104 else
105 memset (p, 0, 64);
106
107 for (;;)
108 {
109 rc = MHD_gc_hash_open (GC_SHA1, 0, &md);
110 if (rc)
111 {
112 MHD_gnutls_assert ();
113 return GNUTLS_E_DECRYPTION_FAILED;
114 }
115 for (i = 0; i < 64; i++)
116 {
117 unsigned char lid = id & 0xFF;
118 MHD_gc_hash_write (md, 1, (const char *) &lid);
119 }
120 MHD_gc_hash_write (md, pw ? 128 : 64, (const char *) buf_i);
121 memcpy (hash, MHD_gc_hash_read (md), 20);
122 MHD_gc_hash_close (md);
123 for (i = 1; i < iter; i++)
124 MHD_gc_hash_buffer (GC_SHA1, hash, 20, (char *) hash);
125 for (i = 0; i < 20 && cur_keylen < req_keylen; i++)
126 keybuf[cur_keylen++] = hash[i];
127 if (cur_keylen == req_keylen)
128 {
129 gcry_mpi_release (num_b1);
130 return 0; /* ready */
131 }
132
133 /* need more bytes. */
134 for (i = 0; i < 64; i++)
135 buf_b[i] = hash[i % 20];
136 n = 64;
137 rc = MHD_gtls_mpi_scan (&num_b1, buf_b, &n);
138 if (rc < 0)
139 {
140 MHD_gnutls_assert ();
141 return rc;
142 }
143 gcry_mpi_add_ui (num_b1, num_b1, 1);
144 for (i = 0; i < 128; i += 64)
145 {
146 mpi_t num_ij;
147
148 n = 64;
149 rc = MHD_gtls_mpi_scan (&num_ij, buf_i + i, &n);
150 if (rc < 0)
151 {
152 MHD_gnutls_assert ();
153 return rc;
154 }
155 gcry_mpi_add (num_ij, num_ij, num_b1);
156 gcry_mpi_clear_highbit (num_ij, 64 * 8);
157 n = 64;
158 rc = MHD_gtls_mpi_print (buf_i + i, &n, num_ij);
159 if (rc < 0)
160 {
161 MHD_gnutls_assert ();
162 return rc;
163 }
164 gcry_mpi_release (num_ij);
165 }
166 }
167}
168
169#endif /* ENABLE_PKI */
diff --git a/src/daemon/https/x509/pkcs7.c b/src/daemon/https/x509/pkcs7.c
deleted file mode 100644
index 45f2b03c..00000000
--- a/src/daemon/https/x509/pkcs7.c
+++ /dev/null
@@ -1,1029 +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 PKCS7 certificate lists parsing.
26 */
27
28#include <gnutls_int.h>
29#include <libtasn1.h>
30
31#ifdef ENABLE_PKI
32
33#include <gnutls_datum.h>
34#include <gnutls_global.h>
35#include <gnutls_errors.h>
36#include <common.h>
37#include <x509_b64.h>
38#include <pkcs7.h>
39#include <dn.h>
40
41#define SIGNED_DATA_OID "1.2.840.113549.1.7.2"
42
43/* Decodes the PKCS #7 signed data, and returns an ASN1_TYPE,
44 * which holds them. If raw is non null then the raw decoded
45 * data are copied (they are locally allocated) there.
46 */
47static int
48_decode_pkcs7_signed_data (ASN1_TYPE pkcs7, ASN1_TYPE * sdata,
49 MHD_gnutls_datum_t * raw)
50{
51 char oid[128];
52 ASN1_TYPE c2;
53 opaque *tmp = NULL;
54 int tmp_size, len, result;
55
56 len = sizeof (oid) - 1;
57 result = MHD__asn1_read_value (pkcs7, "contentType", oid, &len);
58 if (result != ASN1_SUCCESS)
59 {
60 MHD_gnutls_assert ();
61 return MHD_gtls_asn2err (result);
62 }
63
64 if (strcmp (oid, SIGNED_DATA_OID) != 0)
65 {
66 MHD_gnutls_assert ();
67 MHD__gnutls_x509_log ("Unknown PKCS7 Content OID '%s'\n", oid);
68 return GNUTLS_E_UNKNOWN_PKCS_CONTENT_TYPE;
69 }
70
71 if ((result = MHD__asn1_create_element
72 (MHD__gnutls_get_pkix (), "PKIX1.pkcs-7-SignedData",
73 &c2)) != ASN1_SUCCESS)
74 {
75 MHD_gnutls_assert ();
76 return MHD_gtls_asn2err (result);
77 }
78
79 /* the Signed-data has been created, so
80 * decode them.
81 */
82 tmp_size = 0;
83 result = MHD__asn1_read_value (pkcs7, "content", NULL, &tmp_size);
84 if (result != ASN1_MEM_ERROR)
85 {
86 MHD_gnutls_assert ();
87 result = MHD_gtls_asn2err (result);
88 goto cleanup;
89 }
90
91 tmp = MHD_gnutls_malloc (tmp_size);
92 if (tmp == NULL)
93 {
94 MHD_gnutls_assert ();
95 result = GNUTLS_E_MEMORY_ERROR;
96 goto cleanup;
97 }
98
99 result = MHD__asn1_read_value (pkcs7, "content", tmp, &tmp_size);
100 if (result != ASN1_SUCCESS)
101 {
102 MHD_gnutls_assert ();
103 result = MHD_gtls_asn2err (result);
104 goto cleanup;
105 }
106
107 /* tmp, tmp_size hold the data and the size of the CertificateSet structure
108 * actually the ANY stuff.
109 */
110
111 /* Step 1. In case of a signed structure extract certificate set.
112 */
113
114 result = MHD__asn1_der_decoding (&c2, tmp, tmp_size, NULL);
115 if (result != ASN1_SUCCESS)
116 {
117 MHD_gnutls_assert ();
118 result = MHD_gtls_asn2err (result);
119 goto cleanup;
120 }
121
122 if (raw == NULL)
123 {
124 MHD_gnutls_free (tmp);
125 }
126 else
127 {
128 raw->data = tmp;
129 raw->size = tmp_size;
130 }
131
132 *sdata = c2;
133
134 return 0;
135
136cleanup:
137 if (c2)
138 MHD__asn1_delete_structure (&c2);
139 MHD_gnutls_free (tmp);
140 return result;
141}
142
143/**
144 * MHD_gnutls_pkcs7_init - This function initializes a MHD_gnutls_pkcs7_t structure
145 * @pkcs7: The structure to be initialized
146 *
147 * This function will initialize a PKCS7 structure. PKCS7 structures
148 * usually contain lists of X.509 Certificates and X.509 Certificate
149 * revocation lists.
150 *
151 * Returns 0 on success.
152 *
153 **/
154int
155MHD_gnutls_pkcs7_init (MHD_gnutls_pkcs7_t * pkcs7)
156{
157 *pkcs7 = MHD_gnutls_calloc (1, sizeof (MHD_gnutls_pkcs7_int));
158
159 if (*pkcs7)
160 {
161 int result = MHD__asn1_create_element (MHD__gnutls_get_pkix (),
162 "PKIX1.pkcs-7-ContentInfo",
163 &(*pkcs7)->pkcs7);
164 if (result != ASN1_SUCCESS)
165 {
166 MHD_gnutls_assert ();
167 MHD_gnutls_free (*pkcs7);
168 return MHD_gtls_asn2err (result);
169 }
170 return 0; /* success */
171 }
172 return GNUTLS_E_MEMORY_ERROR;
173}
174
175/**
176 * MHD_gnutls_pkcs7_deinit - This function deinitializes memory used by a MHD_gnutls_pkcs7_t structure
177 * @pkcs7: The structure to be initialized
178 *
179 * This function will deinitialize a PKCS7 structure.
180 *
181 **/
182void
183MHD_gnutls_pkcs7_deinit (MHD_gnutls_pkcs7_t pkcs7)
184{
185 if (!pkcs7)
186 return;
187
188 if (pkcs7->pkcs7)
189 MHD__asn1_delete_structure (&pkcs7->pkcs7);
190
191 MHD_gnutls_free (pkcs7);
192}
193
194/**
195 * MHD_gnutls_pkcs7_import - This function will import a DER or PEM encoded PKCS7
196 * @pkcs7: The structure to store the parsed PKCS7.
197 * @data: The DER or PEM encoded PKCS7.
198 * @format: One of DER or PEM
199 *
200 * This function will convert the given DER or PEM encoded PKCS7
201 * to the native MHD_gnutls_pkcs7_t format. The output will be stored in 'pkcs7'.
202 *
203 * If the PKCS7 is PEM encoded it should have a header of "PKCS7".
204 *
205 * Returns 0 on success.
206 *
207 **/
208int
209MHD_gnutls_pkcs7_import (MHD_gnutls_pkcs7_t pkcs7,
210 const MHD_gnutls_datum_t * data,
211 MHD_gnutls_x509_crt_fmt_t format)
212{
213 int result = 0, need_free = 0;
214 MHD_gnutls_datum_t _data;
215
216 if (pkcs7 == NULL)
217 return GNUTLS_E_INVALID_REQUEST;
218
219 _data.data = data->data;
220 _data.size = data->size;
221
222 /* If the PKCS7 is in PEM format then decode it
223 */
224 if (format == GNUTLS_X509_FMT_PEM)
225 {
226 opaque *out;
227
228 result = MHD__gnutls_fbase64_decode (PEM_PKCS7, data->data, data->size,
229 &out);
230
231 if (result <= 0)
232 {
233 if (result == 0)
234 result = GNUTLS_E_INTERNAL_ERROR;
235 MHD_gnutls_assert ();
236 return result;
237 }
238
239 _data.data = out;
240 _data.size = result;
241
242 need_free = 1;
243 }
244
245
246 result =
247 MHD__asn1_der_decoding (&pkcs7->pkcs7, _data.data, _data.size, NULL);
248 if (result != ASN1_SUCCESS)
249 {
250 result = MHD_gtls_asn2err (result);
251 MHD_gnutls_assert ();
252 goto cleanup;
253 }
254
255 if (need_free)
256 MHD__gnutls_free_datum (&_data);
257
258 return 0;
259
260cleanup:
261 if (need_free)
262 MHD__gnutls_free_datum (&_data);
263 return result;
264}
265
266/**
267 * MHD_gnutls_pkcs7_get_crt_raw - This function returns a certificate in a PKCS7 certificate set
268 * @pkcs7_struct: should contain a MHD_gnutls_pkcs7_t structure
269 * @indx: contains the index of the certificate to extract
270 * @certificate: the contents of the certificate will be copied there (may be null)
271 * @certificate_size: should hold the size of the certificate
272 *
273 * This function will return a certificate of the PKCS7 or RFC2630 certificate set.
274 * Returns 0 on success. If the provided buffer is not long enough,
275 * then @certificate_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER is returned.
276 *
277 * After the last certificate has been read GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
278 * will be returned.
279 *
280 **/
281int
282MHD_gnutls_pkcs7_get_crt_raw (MHD_gnutls_pkcs7_t pkcs7,
283 int indx, void *certificate,
284 size_t * certificate_size)
285{
286 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
287 int result, len;
288 char root2[MAX_NAME_SIZE];
289 char oid[128];
290 MHD_gnutls_datum_t tmp = { NULL, 0 };
291
292 if (certificate_size == NULL || pkcs7 == NULL)
293 return GNUTLS_E_INVALID_REQUEST;
294
295 /* Step 1. decode the signed data.
296 */
297 result = _decode_pkcs7_signed_data (pkcs7->pkcs7, &c2, &tmp);
298 if (result < 0)
299 {
300 MHD_gnutls_assert ();
301 return result;
302 }
303
304 /* Step 2. Parse the CertificateSet
305 */
306
307 snprintf (root2, sizeof (root2), "certificates.?%u", indx + 1);
308
309 len = sizeof (oid) - 1;
310
311 result = MHD__asn1_read_value (c2, root2, oid, &len);
312
313 if (result == ASN1_VALUE_NOT_FOUND)
314 {
315 result = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
316 goto cleanup;
317 }
318
319 if (result != ASN1_SUCCESS)
320 {
321 MHD_gnutls_assert ();
322 result = MHD_gtls_asn2err (result);
323 goto cleanup;
324 }
325
326 /* if 'Certificate' is the choice found:
327 */
328 if (strcmp (oid, "certificate") == 0)
329 {
330 int start, end;
331
332 result = MHD__asn1_der_decoding_startEnd (c2, tmp.data, tmp.size,
333 root2, &start, &end);
334
335 if (result != ASN1_SUCCESS)
336 {
337 MHD_gnutls_assert ();
338 result = MHD_gtls_asn2err (result);
339 goto cleanup;
340 }
341
342 end = end - start + 1;
343
344 if ((unsigned) end > *certificate_size)
345 {
346 *certificate_size = end;
347 result = GNUTLS_E_SHORT_MEMORY_BUFFER;
348 goto cleanup;
349 }
350
351 if (certificate)
352 memcpy (certificate, &tmp.data[start], end);
353
354 *certificate_size = end;
355
356 result = 0;
357
358 }
359 else
360 {
361 result = GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
362 }
363
364cleanup:
365 MHD__gnutls_free_datum (&tmp);
366 if (c2)
367 MHD__asn1_delete_structure (&c2);
368 return result;
369}
370
371/**
372 * MHD_gnutls_pkcs7_get_crt_count - This function returns the number of certificates in a PKCS7 certificate set
373 * @pkcs7_struct: should contain a MHD_gnutls_pkcs7_t structure
374 *
375 * This function will return the number of certifcates in the PKCS7 or
376 * RFC2630 certificate set.
377 *
378 * Returns a negative value on failure.
379 *
380 **/
381int
382MHD_gnutls_pkcs7_get_crt_count (MHD_gnutls_pkcs7_t pkcs7)
383{
384 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
385 int result, count;
386
387 if (pkcs7 == NULL)
388 return GNUTLS_E_INVALID_REQUEST;
389
390 /* Step 1. decode the signed data.
391 */
392 result = _decode_pkcs7_signed_data (pkcs7->pkcs7, &c2, NULL);
393 if (result < 0)
394 {
395 MHD_gnutls_assert ();
396 return result;
397 }
398
399 /* Step 2. Count the CertificateSet */
400
401 result = MHD__asn1_number_of_elements (c2, "certificates", &count);
402
403 MHD__asn1_delete_structure (&c2);
404
405 if (result != ASN1_SUCCESS)
406 {
407 MHD_gnutls_assert ();
408 return 0; /* no certificates */
409 }
410
411 return count;
412
413}
414
415/**
416 * MHD_gnutls_pkcs7_export - This function will export the pkcs7 structure
417 * @pkcs7: Holds the pkcs7 structure
418 * @format: the format of output params. One of PEM or DER.
419 * @output_data: will contain a structure PEM or DER encoded
420 * @output_data_size: holds the size of output_data (and will be
421 * replaced by the actual size of parameters)
422 *
423 * This function will export the pkcs7 structure to DER or PEM format.
424 *
425 * If the buffer provided is not long enough to hold the output, then
426 * *output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
427 * be returned.
428 *
429 * If the structure is PEM encoded, it will have a header
430 * of "BEGIN PKCS7".
431 *
432 * Return value: In case of failure a negative value will be
433 * returned, and 0 on success.
434 *
435 **/
436int
437MHD_gnutls_pkcs7_export (MHD_gnutls_pkcs7_t pkcs7,
438 MHD_gnutls_x509_crt_fmt_t format, void *output_data,
439 size_t * output_data_size)
440{
441 if (pkcs7 == NULL)
442 return GNUTLS_E_INVALID_REQUEST;
443
444 return MHD__gnutls_x509_export_int (pkcs7->pkcs7, format, PEM_PKCS7,
445 output_data, output_data_size);
446}
447
448/* Creates an empty signed data structure in the pkcs7
449 * structure and returns a handle to the signed data.
450 */
451static int
452create_empty_signed_data (ASN1_TYPE pkcs7, ASN1_TYPE * sdata)
453{
454 uint8_t one = 1;
455 int result;
456
457 *sdata = ASN1_TYPE_EMPTY;
458
459 if ((result = MHD__asn1_create_element
460 (MHD__gnutls_get_pkix (), "PKIX1.pkcs-7-SignedData",
461 sdata)) != ASN1_SUCCESS)
462 {
463 MHD_gnutls_assert ();
464 result = MHD_gtls_asn2err (result);
465 goto cleanup;
466 }
467
468 /* Use version 1
469 */
470 result = MHD__asn1_write_value (*sdata, "version", &one, 1);
471 if (result != ASN1_SUCCESS)
472 {
473 MHD_gnutls_assert ();
474 result = MHD_gtls_asn2err (result);
475 goto cleanup;
476 }
477
478 /* Use no digest algorithms
479 */
480
481 /* id-data */
482 result =
483 MHD__asn1_write_value (*sdata, "encapContentInfo.eContentType",
484 "1.2.840.113549.1.7.5", 1);
485 if (result != ASN1_SUCCESS)
486 {
487 MHD_gnutls_assert ();
488 result = MHD_gtls_asn2err (result);
489 goto cleanup;
490 }
491
492 result =
493 MHD__asn1_write_value (*sdata, "encapContentInfo.eContent", NULL, 0);
494 if (result != ASN1_SUCCESS)
495 {
496 MHD_gnutls_assert ();
497 result = MHD_gtls_asn2err (result);
498 goto cleanup;
499 }
500
501 /* Add no certificates.
502 */
503
504 /* Add no crls.
505 */
506
507 /* Add no signerInfos.
508 */
509
510 /* Write the content type of the signed data
511 */
512 result = MHD__asn1_write_value (pkcs7, "contentType", SIGNED_DATA_OID, 1);
513 if (result != ASN1_SUCCESS)
514 {
515 MHD_gnutls_assert ();
516 result = MHD_gtls_asn2err (result);
517 goto cleanup;
518 }
519
520 return 0;
521
522cleanup:
523 MHD__asn1_delete_structure (sdata);
524 return result;
525
526}
527
528/**
529 * MHD_gnutls_pkcs7_set_crt_raw - This function adds a certificate in a PKCS7 certificate set
530 * @pkcs7_struct: should contain a MHD_gnutls_pkcs7_t structure
531 * @crt: the DER encoded certificate to be added
532 *
533 * This function will add a certificate to the PKCS7 or RFC2630 certificate set.
534 * Returns 0 on success.
535 *
536 **/
537int
538MHD_gnutls_pkcs7_set_crt_raw (MHD_gnutls_pkcs7_t pkcs7,
539 const MHD_gnutls_datum_t * crt)
540{
541 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
542 int result;
543
544 if (pkcs7 == NULL)
545 return GNUTLS_E_INVALID_REQUEST;
546
547 /* Step 1. decode the signed data.
548 */
549 result = _decode_pkcs7_signed_data (pkcs7->pkcs7, &c2, NULL);
550 if (result < 0 && result != GNUTLS_E_ASN1_VALUE_NOT_FOUND)
551 {
552 MHD_gnutls_assert ();
553 return result;
554 }
555
556 /* If the signed data are uninitialized
557 * then create them.
558 */
559 if (result == GNUTLS_E_ASN1_VALUE_NOT_FOUND)
560 {
561 /* The pkcs7 structure is new, so create the
562 * signedData.
563 */
564 result = create_empty_signed_data (pkcs7->pkcs7, &c2);
565 if (result < 0)
566 {
567 MHD_gnutls_assert ();
568 return result;
569 }
570 }
571
572 /* Step 2. Append the new certificate.
573 */
574
575 result = MHD__asn1_write_value (c2, "certificates", "NEW", 1);
576 if (result != ASN1_SUCCESS)
577 {
578 MHD_gnutls_assert ();
579 result = MHD_gtls_asn2err (result);
580 goto cleanup;
581 }
582
583 result = MHD__asn1_write_value (c2, "certificates.?LAST", "certificate", 1);
584 if (result != ASN1_SUCCESS)
585 {
586 MHD_gnutls_assert ();
587 result = MHD_gtls_asn2err (result);
588 goto cleanup;
589 }
590
591 result =
592 MHD__asn1_write_value (c2, "certificates.?LAST.certificate", crt->data,
593 crt->size);
594 if (result != ASN1_SUCCESS)
595 {
596 MHD_gnutls_assert ();
597 result = MHD_gtls_asn2err (result);
598 goto cleanup;
599 }
600
601 /* Step 3. Replace the old content with the new
602 */
603 result =
604 MHD__gnutls_x509_der_encode_and_copy (c2, "", pkcs7->pkcs7, "content", 0);
605 if (result < 0)
606 {
607 MHD_gnutls_assert ();
608 goto cleanup;
609 }
610
611 MHD__asn1_delete_structure (&c2);
612
613 return 0;
614
615cleanup:
616 if (c2)
617 MHD__asn1_delete_structure (&c2);
618 return result;
619}
620
621/**
622 * MHD_gnutls_pkcs7_set_crt - This function adds a parsed certificate in a PKCS7 certificate set
623 * @pkcs7_struct: should contain a MHD_gnutls_pkcs7_t structure
624 * @crt: the certificate to be copied.
625 *
626 * This function will add a parsed certificate to the PKCS7 or RFC2630 certificate set.
627 * This is a wrapper function over MHD_gnutls_pkcs7_set_crt_raw() .
628 *
629 * Returns 0 on success.
630 *
631 **/
632int
633MHD_gnutls_pkcs7_set_crt (MHD_gnutls_pkcs7_t pkcs7, MHD_gnutls_x509_crt_t crt)
634{
635 int ret;
636 MHD_gnutls_datum_t data;
637
638 if (pkcs7 == NULL)
639 return GNUTLS_E_INVALID_REQUEST;
640
641 ret = MHD__gnutls_x509_der_encode (crt->cert, "", &data, 0);
642 if (ret < 0)
643 {
644 MHD_gnutls_assert ();
645 return ret;
646 }
647
648 ret = MHD_gnutls_pkcs7_set_crt_raw (pkcs7, &data);
649
650 MHD__gnutls_free_datum (&data);
651
652 if (ret < 0)
653 {
654 MHD_gnutls_assert ();
655 return ret;
656 }
657
658 return 0;
659}
660
661
662/**
663 * MHD_gnutls_pkcs7_delete_crt - This function deletes a certificate from a PKCS7 certificate set
664 * @pkcs7_struct: should contain a MHD_gnutls_pkcs7_t structure
665 * @indx: the index of the certificate to delete
666 *
667 * This function will delete a certificate from a PKCS7 or RFC2630 certificate set.
668 * Index starts from 0. Returns 0 on success.
669 *
670 **/
671int
672MHD_gnutls_pkcs7_delete_crt (MHD_gnutls_pkcs7_t pkcs7, int indx)
673{
674 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
675 int result;
676 char root2[MAX_NAME_SIZE];
677
678 if (pkcs7 == NULL)
679 return GNUTLS_E_INVALID_REQUEST;
680
681 /* Step 1. Decode the signed data.
682 */
683 result = _decode_pkcs7_signed_data (pkcs7->pkcs7, &c2, NULL);
684 if (result < 0)
685 {
686 MHD_gnutls_assert ();
687 return result;
688 }
689
690 /* Step 2. Delete the certificate.
691 */
692
693 snprintf (root2, sizeof (root2), "certificates.?%u", indx + 1);
694
695 result = MHD__asn1_write_value (c2, root2, NULL, 0);
696 if (result != ASN1_SUCCESS)
697 {
698 MHD_gnutls_assert ();
699 result = MHD_gtls_asn2err (result);
700 goto cleanup;
701 }
702
703 /* Step 3. Replace the old content with the new
704 */
705 result =
706 MHD__gnutls_x509_der_encode_and_copy (c2, "", pkcs7->pkcs7, "content", 0);
707 if (result < 0)
708 {
709 MHD_gnutls_assert ();
710 goto cleanup;
711 }
712
713 MHD__asn1_delete_structure (&c2);
714
715 return 0;
716
717cleanup:
718 if (c2)
719 MHD__asn1_delete_structure (&c2);
720 return result;
721}
722
723/* Read and write CRLs
724 */
725
726/**
727 * MHD_gnutls_pkcs7_get_crl_raw - This function returns a crl in a PKCS7 crl set
728 * @pkcs7_struct: should contain a MHD_gnutls_pkcs7_t structure
729 * @indx: contains the index of the crl to extract
730 * @crl: the contents of the crl will be copied there (may be null)
731 * @crl_size: should hold the size of the crl
732 *
733 * This function will return a crl of the PKCS7 or RFC2630 crl set.
734 * Returns 0 on success. If the provided buffer is not long enough,
735 * then @crl_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER is returned.
736 *
737 * After the last crl has been read GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
738 * will be returned.
739 *
740 **/
741int
742MHD_gnutls_pkcs7_get_crl_raw (MHD_gnutls_pkcs7_t pkcs7,
743 int indx, void *crl, size_t * crl_size)
744{
745 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
746 int result;
747 char root2[MAX_NAME_SIZE];
748 MHD_gnutls_datum_t tmp = { NULL, 0 };
749 int start, end;
750
751 if (pkcs7 == NULL || crl_size == NULL)
752 return GNUTLS_E_INVALID_REQUEST;
753
754 /* Step 1. decode the signed data.
755 */
756 result = _decode_pkcs7_signed_data (pkcs7->pkcs7, &c2, &tmp);
757 if (result < 0)
758 {
759 MHD_gnutls_assert ();
760 return result;
761 }
762
763 /* Step 2. Parse the CertificateSet
764 */
765
766 snprintf (root2, sizeof (root2), "crls.?%u", indx + 1);
767
768 /* Get the raw CRL
769 */
770 result = MHD__asn1_der_decoding_startEnd (c2, tmp.data, tmp.size,
771 root2, &start, &end);
772
773 if (result != ASN1_SUCCESS)
774 {
775 MHD_gnutls_assert ();
776 result = MHD_gtls_asn2err (result);
777 goto cleanup;
778 }
779
780 end = end - start + 1;
781
782 if ((unsigned) end > *crl_size)
783 {
784 *crl_size = end;
785 result = GNUTLS_E_SHORT_MEMORY_BUFFER;
786 goto cleanup;
787 }
788
789 if (crl)
790 memcpy (crl, &tmp.data[start], end);
791
792 *crl_size = end;
793
794 result = 0;
795
796cleanup:
797 MHD__gnutls_free_datum (&tmp);
798 if (c2)
799 MHD__asn1_delete_structure (&c2);
800 return result;
801}
802
803/**
804 * MHD_gnutls_pkcs7_get_crl_count - This function returns the number of crls in a PKCS7 crl set
805 * @pkcs7_struct: should contain a MHD_gnutls_pkcs7_t structure
806 *
807 * This function will return the number of certifcates in the PKCS7 or
808 * RFC2630 crl set.
809 *
810 * Returns a negative value on failure.
811 *
812 **/
813int
814MHD_gnutls_pkcs7_get_crl_count (MHD_gnutls_pkcs7_t pkcs7)
815{
816 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
817 int result, count;
818
819 if (pkcs7 == NULL)
820 return GNUTLS_E_INVALID_REQUEST;
821
822 /* Step 1. decode the signed data.
823 */
824 result = _decode_pkcs7_signed_data (pkcs7->pkcs7, &c2, NULL);
825 if (result < 0)
826 {
827 MHD_gnutls_assert ();
828 return result;
829 }
830
831 /* Step 2. Count the CertificateSet */
832
833 result = MHD__asn1_number_of_elements (c2, "crls", &count);
834
835 MHD__asn1_delete_structure (&c2);
836
837 if (result != ASN1_SUCCESS)
838 {
839 MHD_gnutls_assert ();
840 return 0; /* no crls */
841 }
842
843 return count;
844
845}
846
847/**
848 * MHD_gnutls_pkcs7_set_crl_raw - This function adds a crl in a PKCS7 crl set
849 * @pkcs7_struct: should contain a MHD_gnutls_pkcs7_t structure
850 * @crl: the DER encoded crl to be added
851 *
852 * This function will add a crl to the PKCS7 or RFC2630 crl set.
853 * Returns 0 on success.
854 *
855 **/
856int
857MHD_gnutls_pkcs7_set_crl_raw (MHD_gnutls_pkcs7_t pkcs7,
858 const MHD_gnutls_datum_t * crl)
859{
860 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
861 int result;
862
863 if (pkcs7 == NULL)
864 return GNUTLS_E_INVALID_REQUEST;
865
866 /* Step 1. decode the signed data.
867 */
868 result = _decode_pkcs7_signed_data (pkcs7->pkcs7, &c2, NULL);
869 if (result < 0 && result != GNUTLS_E_ASN1_VALUE_NOT_FOUND)
870 {
871 MHD_gnutls_assert ();
872 return result;
873 }
874
875 /* If the signed data are uninitialized
876 * then create them.
877 */
878 if (result == GNUTLS_E_ASN1_VALUE_NOT_FOUND)
879 {
880 /* The pkcs7 structure is new, so create the
881 * signedData.
882 */
883 result = create_empty_signed_data (pkcs7->pkcs7, &c2);
884 if (result < 0)
885 {
886 MHD_gnutls_assert ();
887 return result;
888 }
889 }
890
891 /* Step 2. Append the new crl.
892 */
893
894 result = MHD__asn1_write_value (c2, "crls", "NEW", 1);
895 if (result != ASN1_SUCCESS)
896 {
897 MHD_gnutls_assert ();
898 result = MHD_gtls_asn2err (result);
899 goto cleanup;
900 }
901
902 result = MHD__asn1_write_value (c2, "crls.?LAST", crl->data, crl->size);
903 if (result != ASN1_SUCCESS)
904 {
905 MHD_gnutls_assert ();
906 result = MHD_gtls_asn2err (result);
907 goto cleanup;
908 }
909
910 /* Step 3. Replace the old content with the new
911 */
912 result =
913 MHD__gnutls_x509_der_encode_and_copy (c2, "", pkcs7->pkcs7, "content", 0);
914 if (result < 0)
915 {
916 MHD_gnutls_assert ();
917 goto cleanup;
918 }
919
920 MHD__asn1_delete_structure (&c2);
921
922 return 0;
923
924cleanup:
925 if (c2)
926 MHD__asn1_delete_structure (&c2);
927 return result;
928}
929
930/**
931 * MHD_gnutls_pkcs7_set_crl - This function adds a parsed crl in a PKCS7 crl set
932 * @pkcs7_struct: should contain a MHD_gnutls_pkcs7_t structure
933 * @crl: the DER encoded crl to be added
934 *
935 * This function will add a parsed crl to the PKCS7 or RFC2630 crl set.
936 * Returns 0 on success.
937 *
938 **/
939int
940MHD_gnutls_pkcs7_set_crl (MHD_gnutls_pkcs7_t pkcs7, MHD_gnutls_x509_crl_t crl)
941{
942 int ret;
943 MHD_gnutls_datum_t data;
944
945 if (pkcs7 == NULL)
946 return GNUTLS_E_INVALID_REQUEST;
947
948 ret = MHD__gnutls_x509_der_encode (crl->crl, "", &data, 0);
949 if (ret < 0)
950 {
951 MHD_gnutls_assert ();
952 return ret;
953 }
954
955 ret = MHD_gnutls_pkcs7_set_crl_raw (pkcs7, &data);
956
957 MHD__gnutls_free_datum (&data);
958
959 if (ret < 0)
960 {
961 MHD_gnutls_assert ();
962 return ret;
963 }
964
965 return 0;
966}
967
968/**
969 * MHD_gnutls_pkcs7_delete_crl - This function deletes a crl from a PKCS7 crl set
970 * @pkcs7_struct: should contain a MHD_gnutls_pkcs7_t structure
971 * @indx: the index of the crl to delete
972 *
973 * This function will delete a crl from a PKCS7 or RFC2630 crl set.
974 * Index starts from 0. Returns 0 on success.
975 *
976 **/
977int
978MHD_gnutls_pkcs7_delete_crl (MHD_gnutls_pkcs7_t pkcs7, int indx)
979{
980 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
981 int result;
982 char root2[MAX_NAME_SIZE];
983
984 if (pkcs7 == NULL)
985 return GNUTLS_E_INVALID_REQUEST;
986
987 /* Step 1. Decode the signed data.
988 */
989 result = _decode_pkcs7_signed_data (pkcs7->pkcs7, &c2, NULL);
990 if (result < 0)
991 {
992 MHD_gnutls_assert ();
993 return result;
994 }
995
996 /* Step 2. Delete the crl.
997 */
998
999 snprintf (root2, sizeof (root2), "crls.?%u", indx + 1);
1000
1001 result = MHD__asn1_write_value (c2, root2, NULL, 0);
1002 if (result != ASN1_SUCCESS)
1003 {
1004 MHD_gnutls_assert ();
1005 result = MHD_gtls_asn2err (result);
1006 goto cleanup;
1007 }
1008
1009 /* Step 3. Replace the old content with the new
1010 */
1011 result =
1012 MHD__gnutls_x509_der_encode_and_copy (c2, "", pkcs7->pkcs7, "content", 0);
1013 if (result < 0)
1014 {
1015 MHD_gnutls_assert ();
1016 goto cleanup;
1017 }
1018
1019 MHD__asn1_delete_structure (&c2);
1020
1021 return 0;
1022
1023cleanup:
1024 if (c2)
1025 MHD__asn1_delete_structure (&c2);
1026 return result;
1027}
1028
1029#endif /* ENABLE_PKI */
diff --git a/src/daemon/https/x509/pkcs7.h b/src/daemon/https/x509/pkcs7.h
deleted file mode 100644
index 24e4a415..00000000
--- a/src/daemon/https/x509/pkcs7.h
+++ /dev/null
@@ -1,30 +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#include "x509.h"
26
27typedef struct MHD_gnutls_pkcs7_int
28{
29 ASN1_TYPE pkcs7;
30} MHD_gnutls_pkcs7_int;
diff --git a/src/daemon/https/x509/privkey_pkcs8.c b/src/daemon/https/x509/privkey_pkcs8.c
deleted file mode 100644
index 30f2caae..00000000
--- a/src/daemon/https/x509/privkey_pkcs8.c
+++ /dev/null
@@ -1,984 +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
27#ifdef ENABLE_PKI
28
29#include <gnutls_datum.h>
30#include <gnutls_global.h>
31#include <gnutls_errors.h>
32#include <gnutls_rsa_export.h>
33#include <common.h>
34#include <gnutls_x509.h>
35#include <x509_b64.h>
36#include <x509.h>
37#include <pkcs12.h>
38#include <dn.h>
39#include <privkey.h>
40#include <extensions.h>
41#include <mpi.h>
42#include <gnutls_algorithms.h>
43#include <gnutls_num.h>
44#include "gc.h"
45
46#define PBES2_OID "1.2.840.113549.1.5.13"
47#define PBKDF2_OID "1.2.840.113549.1.5.12"
48#define DES_EDE3_CBC_OID "1.2.840.113549.3.7"
49#define DES_CBC_OID "1.3.14.3.2.7"
50
51/* oid_pbeWithSHAAnd3_KeyTripleDES_CBC */
52#define PKCS12_PBE_3DES_SHA1_OID "1.2.840.113549.1.12.1.3"
53#define PKCS12_PBE_ARCFOUR_SHA1_OID "1.2.840.113549.1.12.1.1"
54#define PKCS12_PBE_RC2_40_SHA1_OID "1.2.840.113549.1.12.1.6"
55
56struct pbkdf2_params
57{
58 opaque salt[32];
59 int salt_size;
60 unsigned int iter_count;
61 unsigned int key_size;
62};
63
64struct pbe_enc_params
65{
66 enum MHD_GNUTLS_CipherAlgorithm cipher;
67 opaque iv[8];
68 int iv_size;
69};
70
71static int read_pbkdf2_params (ASN1_TYPE pbes2_asn,
72 const MHD_gnutls_datum_t * der,
73 struct pbkdf2_params *params);
74static int read_pbe_enc_params (ASN1_TYPE pbes2_asn,
75 const MHD_gnutls_datum_t * der,
76 struct pbe_enc_params *params);
77static int decrypt_data (schema_id, ASN1_TYPE pkcs8_asn, const char *root,
78 const char *password,
79 const struct pbkdf2_params *kdf_params,
80 const struct pbe_enc_params *enc_params,
81 MHD_gnutls_datum_t * decrypted_data);
82static int decode_private_key_info (const MHD_gnutls_datum_t * der,
83 MHD_gnutls_x509_privkey_t pkey);
84static int readMHD_pkcs12_kdf_params (ASN1_TYPE pbes2_asn,
85 struct pbkdf2_params *params);
86
87#define PEM_PKCS8 "ENCRYPTED PRIVATE KEY"
88#define PEM_UNENCRYPTED_PKCS8 "PRIVATE KEY"
89
90/* Returns a negative error code if the encryption schema in
91 * the OID is not supported. The schema ID is returned.
92 */
93static int
94check_schema (const char *oid)
95{
96
97 if (strcmp (oid, PBES2_OID) == 0)
98 return PBES2;
99
100 if (strcmp (oid, PKCS12_PBE_3DES_SHA1_OID) == 0)
101 return PKCS12_3DES_SHA1;
102
103 if (strcmp (oid, PKCS12_PBE_ARCFOUR_SHA1_OID) == 0)
104 return PKCS12_ARCFOUR_SHA1;
105
106 if (strcmp (oid, PKCS12_PBE_RC2_40_SHA1_OID) == 0)
107 return PKCS12_RC2_40_SHA1;
108
109 MHD__gnutls_x509_log ("PKCS encryption schema OID '%s' is unsupported.\n",
110 oid);
111
112 return GNUTLS_E_UNKNOWN_CIPHER_TYPE;
113}
114
115/* Read the parameters cipher, IV, salt etc using the given
116 * schema ID.
117 */
118static int
119read_pkcs_schema_params (schema_id schema, const char *password,
120 const opaque * data, int data_size,
121 struct pbkdf2_params *kdf_params,
122 struct pbe_enc_params *enc_params)
123{
124 ASN1_TYPE pbes2_asn = ASN1_TYPE_EMPTY;
125 int result;
126 MHD_gnutls_datum_t tmp;
127
128 switch (schema)
129 {
130
131 case PBES2:
132
133 /* Now check the key derivation and the encryption
134 * functions.
135 */
136 if ((result =
137 MHD__asn1_create_element (MHD__gnutls_get_pkix (),
138 "PKIX1.pkcs-5-PBES2-params",
139 &pbes2_asn)) != ASN1_SUCCESS)
140 {
141 MHD_gnutls_assert ();
142 result = MHD_gtls_asn2err (result);
143 goto error;
144 }
145
146 /* Decode the parameters.
147 */
148 result = MHD__asn1_der_decoding (&pbes2_asn, data, data_size, NULL);
149 if (result != ASN1_SUCCESS)
150 {
151 MHD_gnutls_assert ();
152 result = MHD_gtls_asn2err (result);
153 goto error;
154 }
155
156 tmp.data = (opaque *) data;
157 tmp.size = data_size;
158
159 result = read_pbkdf2_params (pbes2_asn, &tmp, kdf_params);
160 if (result < 0)
161 {
162 MHD_gnutls_assert ();
163 result = MHD_gtls_asn2err (result);
164 goto error;
165 }
166
167 result = read_pbe_enc_params (pbes2_asn, &tmp, enc_params);
168 if (result < 0)
169 {
170 MHD_gnutls_assert ();
171 result = MHD_gtls_asn2err (result);
172 goto error;
173 }
174
175 MHD__asn1_delete_structure (&pbes2_asn);
176 return 0;
177 break;
178
179 case PKCS12_3DES_SHA1:
180 case PKCS12_ARCFOUR_SHA1:
181 case PKCS12_RC2_40_SHA1:
182
183 if ((schema) == PKCS12_3DES_SHA1)
184 {
185 enc_params->cipher = MHD_GNUTLS_CIPHER_3DES_CBC;
186 enc_params->iv_size = 8;
187 }
188 else if ((schema) == PKCS12_ARCFOUR_SHA1)
189 {
190 enc_params->cipher = MHD_GNUTLS_CIPHER_ARCFOUR_128;
191 enc_params->iv_size = 0;
192 }
193 else if ((schema) == PKCS12_RC2_40_SHA1)
194 {
195 enc_params->cipher = MHD_GNUTLS_CIPHER_RC2_40_CBC;
196 enc_params->iv_size = 8;
197 }
198
199 if ((result =
200 MHD__asn1_create_element (MHD__gnutls_get_pkix (),
201 "PKIX1.pkcs-12-PbeParams",
202 &pbes2_asn)) != ASN1_SUCCESS)
203 {
204 MHD_gnutls_assert ();
205 result = MHD_gtls_asn2err (result);
206 goto error;
207 }
208
209 /* Decode the parameters.
210 */
211 result = MHD__asn1_der_decoding (&pbes2_asn, data, data_size, NULL);
212 if (result != ASN1_SUCCESS)
213 {
214 MHD_gnutls_assert ();
215 result = MHD_gtls_asn2err (result);
216 goto error;
217 }
218
219 result = readMHD_pkcs12_kdf_params (pbes2_asn, kdf_params);
220 if (result < 0)
221 {
222 MHD_gnutls_assert ();
223 goto error;
224 }
225
226 if (enc_params->iv_size)
227 {
228 result =
229 MHD_pkcs12_string_to_key (2 /*IV*/, kdf_params->salt,
230 kdf_params->salt_size,
231 kdf_params->iter_count, password,
232 enc_params->iv_size, enc_params->iv);
233 if (result < 0)
234 {
235 MHD_gnutls_assert ();
236 goto error;
237 }
238
239 }
240
241 MHD__asn1_delete_structure (&pbes2_asn);
242
243 return 0;
244 break;
245
246 } /* switch */
247
248 return GNUTLS_E_UNKNOWN_CIPHER_TYPE;
249
250error:
251 MHD__asn1_delete_structure (&pbes2_asn);
252 return result;
253}
254
255/* Converts a PKCS #8 key to
256 * an internal structure (MHD_gnutls_private_key)
257 * (normally a PKCS #1 encoded RSA key)
258 */
259static int
260decode_pkcs8_key (const MHD_gnutls_datum_t * raw_key,
261 const char *password, MHD_gnutls_x509_privkey_t pkey)
262{
263 int result, len;
264 char enc_oid[64];
265 MHD_gnutls_datum_t tmp;
266 ASN1_TYPE pbes2_asn = ASN1_TYPE_EMPTY, pkcs8_asn = ASN1_TYPE_EMPTY;
267 int params_start, params_end, params_len;
268 struct pbkdf2_params kdf_params;
269 struct pbe_enc_params enc_params;
270 schema_id schema;
271
272 if ((result =
273 MHD__asn1_create_element (MHD__gnutls_get_pkix (),
274 "PKIX1.pkcs-8-EncryptedPrivateKeyInfo",
275 &pkcs8_asn)) != ASN1_SUCCESS)
276 {
277 MHD_gnutls_assert ();
278 result = MHD_gtls_asn2err (result);
279 goto error;
280 }
281
282 result =
283 MHD__asn1_der_decoding (&pkcs8_asn, raw_key->data, raw_key->size, NULL);
284 if (result != ASN1_SUCCESS)
285 {
286 MHD_gnutls_assert ();
287 result = MHD_gtls_asn2err (result);
288 goto error;
289 }
290
291 /* Check the encryption schema OID
292 */
293 len = sizeof (enc_oid);
294 result =
295 MHD__asn1_read_value (pkcs8_asn, "encryptionAlgorithm.algorithm",
296 enc_oid, &len);
297 if (result != ASN1_SUCCESS)
298 {
299 MHD_gnutls_assert ();
300 goto error;
301 }
302
303 if ((result = check_schema (enc_oid)) < 0)
304 {
305 MHD_gnutls_assert ();
306 goto error;
307 }
308
309 schema = result;
310
311 /* Get the DER encoding of the parameters.
312 */
313 result =
314 MHD__asn1_der_decoding_startEnd (pkcs8_asn, raw_key->data,
315 raw_key->size,
316 "encryptionAlgorithm.parameters",
317 &params_start, &params_end);
318 if (result != ASN1_SUCCESS)
319 {
320 MHD_gnutls_assert ();
321 result = MHD_gtls_asn2err (result);
322 goto error;
323 }
324 params_len = params_end - params_start + 1;
325
326 result =
327 read_pkcs_schema_params (schema, password,
328 &raw_key->data[params_start],
329 params_len, &kdf_params, &enc_params);
330
331 /* Parameters have been decoded. Now
332 * decrypt the EncryptedData.
333 */
334 result =
335 decrypt_data (schema, pkcs8_asn, "encryptedData", password,
336 &kdf_params, &enc_params, &tmp);
337 if (result < 0)
338 {
339 MHD_gnutls_assert ();
340 goto error;
341 }
342
343 MHD__asn1_delete_structure (&pkcs8_asn);
344
345 result = decode_private_key_info (&tmp, pkey);
346 MHD__gnutls_free_datum (&tmp);
347
348 if (result < 0)
349 {
350 /* We've gotten this far. In the real world it's almost certain
351 * that we're dealing with a good file, but wrong password.
352 * Sadly like 90% of random data is somehow valid DER for the
353 * a first small number of bytes, so no easy way to guarantee. */
354 if (result == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND ||
355 result == GNUTLS_E_ASN1_IDENTIFIER_NOT_FOUND ||
356 result == GNUTLS_E_ASN1_DER_ERROR ||
357 result == GNUTLS_E_ASN1_VALUE_NOT_FOUND ||
358 result == GNUTLS_E_ASN1_GENERIC_ERROR ||
359 result == GNUTLS_E_ASN1_VALUE_NOT_VALID ||
360 result == GNUTLS_E_ASN1_TAG_ERROR ||
361 result == GNUTLS_E_ASN1_TAG_IMPLICIT ||
362 result == GNUTLS_E_ASN1_TYPE_ANY_ERROR ||
363 result == GNUTLS_E_ASN1_SYNTAX_ERROR ||
364 result == GNUTLS_E_ASN1_DER_OVERFLOW)
365 {
366 result = GNUTLS_E_DECRYPTION_FAILED;
367 }
368
369 MHD_gnutls_assert ();
370 goto error;
371 }
372
373 return 0;
374
375error:
376 MHD__asn1_delete_structure (&pbes2_asn);
377 MHD__asn1_delete_structure (&pkcs8_asn);
378 return result;
379}
380
381/* Decodes an RSA privateKey from a PKCS8 structure.
382 */
383static int
384_decode_pkcs8_rsa_key (ASN1_TYPE pkcs8_asn, MHD_gnutls_x509_privkey_t pkey)
385{
386 int ret;
387 MHD_gnutls_datum_t tmp;
388
389 ret = MHD__gnutls_x509_read_value (pkcs8_asn, "privateKey", &tmp, 0);
390 if (ret < 0)
391 {
392 MHD_gnutls_assert ();
393 goto error;
394 }
395
396 pkey->key = MHD__gnutls_privkey_decode_pkcs1_rsa_key (&tmp, pkey);
397 MHD__gnutls_free_datum (&tmp);
398 if (pkey->key == NULL)
399 {
400 MHD_gnutls_assert ();
401 goto error;
402 }
403
404 return 0;
405
406error:
407 MHD_gnutls_x509_privkey_deinit (pkey);
408 return ret;
409}
410
411static int
412decode_private_key_info (const MHD_gnutls_datum_t * der,
413 MHD_gnutls_x509_privkey_t pkey)
414{
415 int result, len;
416 opaque oid[64];
417 ASN1_TYPE pkcs8_asn = ASN1_TYPE_EMPTY;
418
419 if ((result =
420 MHD__asn1_create_element (MHD__gnutls_get_pkix (),
421 "PKIX1.pkcs-8-PrivateKeyInfo",
422 &pkcs8_asn)) != ASN1_SUCCESS)
423 {
424 MHD_gnutls_assert ();
425 result = MHD_gtls_asn2err (result);
426 goto error;
427 }
428
429 result = MHD__asn1_der_decoding (&pkcs8_asn, der->data, der->size, NULL);
430 if (result != ASN1_SUCCESS)
431 {
432 MHD_gnutls_assert ();
433 result = MHD_gtls_asn2err (result);
434 goto error;
435 }
436
437 /* Check the private key algorithm OID
438 */
439 len = sizeof (oid);
440 result =
441 MHD__asn1_read_value (pkcs8_asn, "privateKeyAlgorithm.algorithm", oid,
442 &len);
443 if (result != ASN1_SUCCESS)
444 {
445 MHD_gnutls_assert ();
446 result = MHD_gtls_asn2err (result);
447 goto error;
448 }
449
450 /* we only support RSA and DSA private keys.
451 */
452 if (strcmp ((const char *) oid, PK_PKIX1_RSA_OID) == 0)
453 pkey->pk_algorithm = MHD_GNUTLS_PK_RSA;
454 else
455 {
456 MHD_gnutls_assert ();
457 MHD__gnutls_x509_log
458 ("PKCS #8 private key OID '%s' is unsupported.\n", oid);
459 result = GNUTLS_E_UNKNOWN_PK_ALGORITHM;
460 goto error;
461 }
462
463 /* Get the DER encoding of the actual private key.
464 */
465
466 if (pkey->pk_algorithm == MHD_GNUTLS_PK_RSA)
467 result = _decode_pkcs8_rsa_key (pkcs8_asn, pkey);
468 if (result < 0)
469 {
470 MHD_gnutls_assert ();
471 return result;
472 }
473
474 result = 0;
475
476error:
477 MHD__asn1_delete_structure (&pkcs8_asn);
478
479 return result;
480
481}
482
483/**
484 * MHD_gnutls_x509_privkey_import_pkcs8 - This function will import a DER or PEM PKCS8 encoded key
485 * @key: The structure to store the parsed key
486 * @data: The DER or PEM encoded key.
487 * @format: One of DER or PEM
488 * @password: the password to decrypt the key (if it is encrypted).
489 * @flags: 0 if encrypted or GNUTLS_PKCS_PLAIN if not encrypted.
490 *
491 * This function will convert the given DER or PEM encoded PKCS8 2.0 encrypted key
492 * to the native MHD_gnutls_x509_privkey_t format. The output will be stored in @key.
493 * Both RSA and DSA keys can be imported, and flags can only be used to indicate
494 * an unencrypted key.
495 *
496 * The @password can be either ASCII or UTF-8 in the default PBES2
497 * encryption schemas, or ASCII for the PKCS12 schemas.
498 *
499 * If the Certificate is PEM encoded it should have a header of "ENCRYPTED PRIVATE KEY",
500 * or "PRIVATE KEY". You only need to specify the flags if the key is DER encoded, since
501 * in that case the encryption status cannot be auto-detected.
502 *
503 * Returns 0 on success.
504 *
505 **/
506int
507MHD_gnutls_x509_privkey_import_pkcs8 (MHD_gnutls_x509_privkey_t key,
508 const MHD_gnutls_datum_t * data,
509 MHD_gnutls_x509_crt_fmt_t format,
510 const char *password,
511 unsigned int flags)
512{
513 int result = 0, need_free = 0;
514 MHD_gnutls_datum_t _data;
515
516 if (key == NULL)
517 {
518 MHD_gnutls_assert ();
519 return GNUTLS_E_INVALID_REQUEST;
520 }
521
522 _data.data = data->data;
523 _data.size = data->size;
524
525 key->pk_algorithm = MHD_GNUTLS_PK_UNKNOWN;
526
527 /* If the Certificate is in PEM format then decode it
528 */
529 if (format == GNUTLS_X509_FMT_PEM)
530 {
531 opaque *out;
532
533 /* Try the first header
534 */
535 result =
536 MHD__gnutls_fbase64_decode (PEM_UNENCRYPTED_PKCS8,
537 data->data, data->size, &out);
538
539 if (result < 0)
540 { /* Try the encrypted header
541 */
542 result =
543 MHD__gnutls_fbase64_decode (PEM_PKCS8, data->data, data->size,
544 &out);
545
546 if (result <= 0)
547 {
548 if (result == 0)
549 result = GNUTLS_E_INTERNAL_ERROR;
550 MHD_gnutls_assert ();
551 return result;
552 }
553 }
554 else if (flags == 0)
555 flags |= GNUTLS_PKCS_PLAIN;
556
557 _data.data = out;
558 _data.size = result;
559
560 need_free = 1;
561 }
562
563 if (flags & GNUTLS_PKCS_PLAIN)
564 {
565 result = decode_private_key_info (&_data, key);
566 }
567 else
568 { /* encrypted. */
569 result = decode_pkcs8_key (&_data, password, key);
570 }
571
572 if (result < 0)
573 {
574 MHD_gnutls_assert ();
575 goto cleanup;
576 }
577
578 if (need_free)
579 MHD__gnutls_free_datum (&_data);
580
581 /* The key has now been decoded.
582 */
583
584 return 0;
585
586cleanup:
587 key->pk_algorithm = MHD_GNUTLS_PK_UNKNOWN;
588 if (need_free)
589 MHD__gnutls_free_datum (&_data);
590 return result;
591}
592
593/* Reads the PBKDF2 parameters.
594 */
595static int
596read_pbkdf2_params (ASN1_TYPE pbes2_asn,
597 const MHD_gnutls_datum_t * der,
598 struct pbkdf2_params *params)
599{
600 int params_start, params_end;
601 int params_len, len, result;
602 ASN1_TYPE pbkdf2_asn = ASN1_TYPE_EMPTY;
603 char oid[64];
604
605 memset (params, 0, sizeof (params));
606
607 /* Check the key derivation algorithm
608 */
609 len = sizeof (oid);
610 result =
611 MHD__asn1_read_value (pbes2_asn, "keyDerivationFunc.algorithm", oid,
612 &len);
613 if (result != ASN1_SUCCESS)
614 {
615 MHD_gnutls_assert ();
616 return MHD_gtls_asn2err (result);
617 }
618 MHD__gnutls_hard_log ("keyDerivationFunc.algorithm: %s\n", oid);
619
620 if (strcmp (oid, PBKDF2_OID) != 0)
621 {
622 MHD_gnutls_assert ();
623 MHD__gnutls_x509_log
624 ("PKCS #8 key derivation OID '%s' is unsupported.\n", oid);
625 return MHD_gtls_asn2err (result);
626 }
627
628 result =
629 MHD__asn1_der_decoding_startEnd (pbes2_asn, der->data, der->size,
630 "keyDerivationFunc.parameters",
631 &params_start, &params_end);
632 if (result != ASN1_SUCCESS)
633 {
634 MHD_gnutls_assert ();
635 return MHD_gtls_asn2err (result);
636 }
637 params_len = params_end - params_start + 1;
638
639 /* Now check the key derivation and the encryption
640 * functions.
641 */
642 if ((result =
643 MHD__asn1_create_element (MHD__gnutls_get_pkix (),
644 "PKIX1.pkcs-5-PBKDF2-params",
645 &pbkdf2_asn)) != ASN1_SUCCESS)
646 {
647 MHD_gnutls_assert ();
648 return MHD_gtls_asn2err (result);
649 }
650
651 result =
652 MHD__asn1_der_decoding (&pbkdf2_asn, &der->data[params_start],
653 params_len, NULL);
654 if (result != ASN1_SUCCESS)
655 {
656 MHD_gnutls_assert ();
657 result = MHD_gtls_asn2err (result);
658 goto error;
659 }
660
661 /* read the salt */
662 params->salt_size = sizeof (params->salt);
663 result =
664 MHD__asn1_read_value (pbkdf2_asn, "salt.specified", params->salt,
665 &params->salt_size);
666 if (result != ASN1_SUCCESS)
667 {
668 MHD_gnutls_assert ();
669 result = MHD_gtls_asn2err (result);
670 goto error;
671 }
672 MHD__gnutls_hard_log ("salt.specified.size: %d\n", params->salt_size);
673
674 /* read the iteration count
675 */
676 result =
677 MHD__gnutls_x509_read_uint (pbkdf2_asn, "iterationCount",
678 &params->iter_count);
679 if (result != ASN1_SUCCESS)
680 {
681 MHD_gnutls_assert ();
682 goto error;
683 }
684 MHD__gnutls_hard_log ("iterationCount: %d\n", params->iter_count);
685
686 /* read the keylength, if it is set.
687 */
688 result =
689 MHD__gnutls_x509_read_uint (pbkdf2_asn, "keyLength", &params->key_size);
690 if (result < 0)
691 {
692 params->key_size = 0;
693 }
694 MHD__gnutls_hard_log ("keyLength: %d\n", params->key_size);
695
696 /* We don't read the PRF. We only use the default.
697 */
698
699 return 0;
700
701error:
702 MHD__asn1_delete_structure (&pbkdf2_asn);
703 return result;
704
705}
706
707/* Reads the PBE parameters from PKCS-12 schemas (*&#%*&#% RSA).
708 */
709static int
710readMHD_pkcs12_kdf_params (ASN1_TYPE pbes2_asn, struct pbkdf2_params *params)
711{
712 int result;
713
714 memset (params, 0, sizeof (params));
715
716 /* read the salt */
717 params->salt_size = sizeof (params->salt);
718 result =
719 MHD__asn1_read_value (pbes2_asn, "salt", params->salt,
720 &params->salt_size);
721 if (result != ASN1_SUCCESS)
722 {
723 MHD_gnutls_assert ();
724 result = MHD_gtls_asn2err (result);
725 goto error;
726 }
727 MHD__gnutls_hard_log ("salt.size: %d\n", params->salt_size);
728
729 /* read the iteration count
730 */
731 result =
732 MHD__gnutls_x509_read_uint (pbes2_asn, "iterations", &params->iter_count);
733 if (result != ASN1_SUCCESS)
734 {
735 MHD_gnutls_assert ();
736 goto error;
737 }
738 MHD__gnutls_hard_log ("iterationCount: %d\n", params->iter_count);
739
740 params->key_size = 0;
741
742 return 0;
743
744error:
745 return result;
746
747}
748
749/* Converts an OID to a gnutls cipher type.
750 */
751static int
752oid2cipher (const char *oid, enum MHD_GNUTLS_CipherAlgorithm *algo)
753{
754
755 *algo = 0;
756
757 if (strcmp (oid, DES_EDE3_CBC_OID) == 0)
758 {
759 *algo = MHD_GNUTLS_CIPHER_3DES_CBC;
760 return 0;
761 }
762
763 if (strcmp (oid, DES_CBC_OID) == 0)
764 {
765 *algo = MHD_GNUTLS_CIPHER_DES_CBC;
766 return 0;
767 }
768
769 MHD__gnutls_x509_log ("PKCS #8 encryption OID '%s' is unsupported.\n", oid);
770 return GNUTLS_E_UNKNOWN_CIPHER_TYPE;
771}
772
773static int
774read_pbe_enc_params (ASN1_TYPE pbes2_asn,
775 const MHD_gnutls_datum_t * der,
776 struct pbe_enc_params *params)
777{
778 int params_start, params_end;
779 int params_len, len, result;
780 ASN1_TYPE pbe_asn = ASN1_TYPE_EMPTY;
781 char oid[64];
782
783 memset (params, 0, sizeof (params));
784
785 /* Check the encryption algorithm
786 */
787 len = sizeof (oid);
788 result =
789 MHD__asn1_read_value (pbes2_asn, "encryptionScheme.algorithm", oid, &len);
790 if (result != ASN1_SUCCESS)
791 {
792 MHD_gnutls_assert ();
793 goto error;
794 }
795 MHD__gnutls_hard_log ("encryptionScheme.algorithm: %s\n", oid);
796
797 if ((result = oid2cipher (oid, &params->cipher)) < 0)
798 {
799 MHD_gnutls_assert ();
800 goto error;
801 }
802
803 result =
804 MHD__asn1_der_decoding_startEnd (pbes2_asn, der->data, der->size,
805 "encryptionScheme.parameters",
806 &params_start, &params_end);
807 if (result != ASN1_SUCCESS)
808 {
809 MHD_gnutls_assert ();
810 return MHD_gtls_asn2err (result);
811 }
812 params_len = params_end - params_start + 1;
813
814 /* Now check the encryption parameters.
815 */
816 if ((result =
817 MHD__asn1_create_element (MHD__gnutls_get_pkix (),
818 "PKIX1.pkcs-5-des-EDE3-CBC-params",
819 &pbe_asn)) != ASN1_SUCCESS)
820 {
821 MHD_gnutls_assert ();
822 return MHD_gtls_asn2err (result);
823 }
824
825 result =
826 MHD__asn1_der_decoding (&pbe_asn, &der->data[params_start], params_len,
827 NULL);
828 if (result != ASN1_SUCCESS)
829 {
830 MHD_gnutls_assert ();
831 result = MHD_gtls_asn2err (result);
832 goto error;
833 }
834
835 /* read the IV */
836 params->iv_size = sizeof (params->iv);
837 result = MHD__asn1_read_value (pbe_asn, "", params->iv, &params->iv_size);
838 if (result != ASN1_SUCCESS)
839 {
840 MHD_gnutls_assert ();
841 result = MHD_gtls_asn2err (result);
842 goto error;
843 }
844 MHD__gnutls_hard_log ("IV.size: %d\n", params->iv_size);
845
846 return 0;
847
848error:
849 MHD__asn1_delete_structure (&pbe_asn);
850 return result;
851
852}
853
854static int
855decrypt_data (schema_id schema, ASN1_TYPE pkcs8_asn,
856 const char *root, const char *password,
857 const struct pbkdf2_params *kdf_params,
858 const struct pbe_enc_params *enc_params,
859 MHD_gnutls_datum_t * decrypted_data)
860{
861 int result;
862 int data_size;
863 opaque *data = NULL, *key = NULL;
864 MHD_gnutls_datum_t dkey, d_iv;
865 cipher_hd_t ch = NULL;
866 int key_size;
867
868 data_size = 0;
869 result = MHD__asn1_read_value (pkcs8_asn, root, NULL, &data_size);
870 if (result != ASN1_MEM_ERROR)
871 {
872 MHD_gnutls_assert ();
873 return MHD_gtls_asn2err (result);
874 }
875
876 data = MHD_gnutls_malloc (data_size);
877 if (data == NULL)
878 {
879 MHD_gnutls_assert ();
880 return GNUTLS_E_MEMORY_ERROR;
881 }
882
883 result = MHD__asn1_read_value (pkcs8_asn, root, data, &data_size);
884 if (result != ASN1_SUCCESS)
885 {
886 MHD_gnutls_assert ();
887 result = MHD_gtls_asn2err (result);
888 goto error;
889 }
890
891 if (kdf_params->key_size == 0)
892 {
893 key_size = MHD__gnutls_cipher_get_key_size (enc_params->cipher);
894 }
895 else
896 key_size = kdf_params->key_size;
897
898 key = MHD_gnutls_alloca (key_size);
899 if (key == NULL)
900 {
901 MHD_gnutls_assert ();
902 result = GNUTLS_E_MEMORY_ERROR;
903 goto error;
904 }
905
906 /* generate the key
907 */
908 if (schema == PBES2)
909 {
910 result = MHD_gc_pbkdf2_sha1 (password, strlen (password),
911 (const char *) kdf_params->salt,
912 kdf_params->salt_size,
913 kdf_params->iter_count, (char *) key,
914 key_size);
915
916 if (result != GC_OK)
917 {
918 MHD_gnutls_assert ();
919 result = GNUTLS_E_DECRYPTION_FAILED;
920 goto error;
921 }
922 }
923 else
924 {
925 result =
926 MHD_pkcs12_string_to_key (1 /*KEY*/, kdf_params->salt,
927 kdf_params->salt_size,
928 kdf_params->iter_count, password,
929 key_size, key);
930
931 if (result < 0)
932 {
933 MHD_gnutls_assert ();
934 goto error;
935 }
936 }
937
938 /* do the decryption.
939 */
940 dkey.data = key;
941 dkey.size = key_size;
942
943 d_iv.data = (opaque *) enc_params->iv;
944 d_iv.size = enc_params->iv_size;
945 ch = MHD_gtls_cipher_init (enc_params->cipher, &dkey, &d_iv);
946
947 MHD_gnutls_afree (key);
948 key = NULL;
949
950 if (ch == NULL)
951 {
952 MHD_gnutls_assert ();
953 result = GNUTLS_E_DECRYPTION_FAILED;
954 goto error;
955 }
956
957 result = MHD_gtls_cipher_decrypt (ch, data, data_size);
958 if (result < 0)
959 {
960 MHD_gnutls_assert ();
961 goto error;
962 }
963
964 decrypted_data->data = data;
965
966 if (MHD_gtls_cipher_get_block_size (enc_params->cipher) != 1)
967 decrypted_data->size = data_size - data[data_size - 1];
968 else
969 decrypted_data->size = data_size;
970
971 MHD_gnutls_cipher_deinit (ch);
972
973 return 0;
974
975error:
976 MHD_gnutls_free (data);
977 MHD_gnutls_afree (key);
978 if (ch != NULL)
979 MHD_gnutls_cipher_deinit (ch);
980 return result;
981}
982
983
984#endif
diff --git a/src/daemon/https/x509/sign.c b/src/daemon/https/x509/sign.c
deleted file mode 100644
index 1cc032be..00000000
--- a/src/daemon/https/x509/sign.c
+++ /dev/null
@@ -1,264 +0,0 @@
1/*
2 * Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25/* All functions which relate to X.509 certificate signing stuff are
26 * included here
27 */
28
29#include <gnutls_int.h>
30
31#ifdef ENABLE_PKI
32
33#include <gnutls_errors.h>
34#include <gnutls_cert.h>
35#include <libtasn1.h>
36#include <gnutls_global.h>
37#include <gnutls_num.h> /* MAX */
38#include <gnutls_sig.h>
39#include <gnutls_str.h>
40#include <gnutls_datum.h>
41#include <dn.h>
42#include <x509.h>
43#include <mpi.h>
44#include <sign.h>
45#include <common.h>
46#include <verify.h>
47
48/* Writes the digest information and the digest in a DER encoded
49 * structure. The digest info is allocated and stored into the info structure.
50 */
51static int
52encode_ber_digest_info (enum MHD_GNUTLS_HashAlgorithm hash,
53 const MHD_gnutls_datum_t * digest,
54 MHD_gnutls_datum_t * info)
55{
56 ASN1_TYPE dinfo = ASN1_TYPE_EMPTY;
57 int result;
58 const char *algo;
59
60 algo = MHD_gtls_x509_mac_to_oid ((enum MHD_GNUTLS_HashAlgorithm) hash);
61 if (algo == NULL)
62 {
63 MHD_gnutls_assert ();
64 MHD__gnutls_x509_log ("Hash algorithm: %d\n", hash);
65 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
66 }
67
68 if ((result = MHD__asn1_create_element (MHD__gnutls_getMHD__gnutls_asn (),
69 "GNUTLS.DigestInfo",
70 &dinfo)) != ASN1_SUCCESS)
71 {
72 MHD_gnutls_assert ();
73 return MHD_gtls_asn2err (result);
74 }
75
76 result =
77 MHD__asn1_write_value (dinfo, "digestAlgorithm.algorithm", algo, 1);
78 if (result != ASN1_SUCCESS)
79 {
80 MHD_gnutls_assert ();
81 MHD__asn1_delete_structure (&dinfo);
82 return MHD_gtls_asn2err (result);
83 }
84
85 /* Write an ASN.1 NULL in the parameters field. This matches RFC
86 3279 and RFC 4055, although is arguable incorrect from a historic
87 perspective (see those documents for more information).
88 Regardless of what is correct, this appears to be what most
89 implementations do. */
90 result = MHD__asn1_write_value (dinfo, "digestAlgorithm.parameters",
91 "\x05\x00", 2);
92 if (result != ASN1_SUCCESS)
93 {
94 MHD_gnutls_assert ();
95 MHD__asn1_delete_structure (&dinfo);
96 return MHD_gtls_asn2err (result);
97 }
98
99 result =
100 MHD__asn1_write_value (dinfo, "digest", digest->data, digest->size);
101 if (result != ASN1_SUCCESS)
102 {
103 MHD_gnutls_assert ();
104 MHD__asn1_delete_structure (&dinfo);
105 return MHD_gtls_asn2err (result);
106 }
107
108 info->size = 0;
109 MHD__asn1_der_coding (dinfo, "", NULL, (int *) &info->size, NULL);
110
111 info->data = MHD_gnutls_malloc (info->size);
112 if (info->data == NULL)
113 {
114 MHD_gnutls_assert ();
115 MHD__asn1_delete_structure (&dinfo);
116 return GNUTLS_E_MEMORY_ERROR;
117 }
118
119 result =
120 MHD__asn1_der_coding (dinfo, "", info->data, (int *) &info->size, NULL);
121 if (result != ASN1_SUCCESS)
122 {
123 MHD_gnutls_assert ();
124 MHD__asn1_delete_structure (&dinfo);
125 return MHD_gtls_asn2err (result);
126 }
127
128 MHD__asn1_delete_structure (&dinfo);
129
130 return 0;
131}
132
133/* if hash==MD5 then we do RSA-MD5
134 * if hash==SHA then we do RSA-SHA
135 * params[0] is modulus
136 * params[1] is public key
137 */
138static int
139pkcs1_rsa_sign (enum MHD_GNUTLS_HashAlgorithm hash,
140 const MHD_gnutls_datum_t * text, mpi_t * params,
141 int params_len, MHD_gnutls_datum_t * signature)
142{
143 int ret;
144 opaque _digest[MAX_HASH_SIZE];
145 GNUTLS_HASH_HANDLE hd;
146 MHD_gnutls_datum_t digest, info;
147
148 hd = MHD_gtls_hash_init (HASH2MAC (hash));
149 if (hd == NULL)
150 {
151 MHD_gnutls_assert ();
152 return GNUTLS_E_HASH_FAILED;
153 }
154
155 MHD_gnutls_hash (hd, text->data, text->size);
156 MHD_gnutls_hash_deinit (hd, _digest);
157
158 digest.data = _digest;
159 digest.size = MHD_gnutls_hash_get_algo_len (HASH2MAC (hash));
160
161 /* Encode the digest as a DigestInfo
162 */
163 if ((ret = encode_ber_digest_info (hash, &digest, &info)) != 0)
164 {
165 MHD_gnutls_assert ();
166 return ret;
167 }
168
169 if ((ret =
170 MHD_gtls_sign (MHD_GNUTLS_PK_RSA, params, params_len, &info,
171 signature)) < 0)
172 {
173 MHD_gnutls_assert ();
174 MHD__gnutls_free_datum (&info);
175 return ret;
176 }
177
178 MHD__gnutls_free_datum (&info);
179
180 return 0;
181}
182
183/* Signs the given data using the parameters from the signer's
184 * private key.
185 *
186 * returns 0 on success.
187 *
188 * 'tbs' is the data to be signed
189 * 'signature' will hold the signature!
190 * 'hash' is only used in PKCS1 RSA signing.
191 */
192static int
193MHD__gnutls_x509_sign (const MHD_gnutls_datum_t * tbs,
194 enum MHD_GNUTLS_HashAlgorithm hash,
195 MHD_gnutls_x509_privkey_t signer,
196 MHD_gnutls_datum_t * signature)
197{
198 int ret;
199
200 switch (signer->pk_algorithm)
201 {
202 case MHD_GNUTLS_PK_RSA:
203 ret =
204 pkcs1_rsa_sign (hash, tbs, signer->params, signer->params_size,
205 signature);
206 if (ret < 0)
207 {
208 MHD_gnutls_assert ();
209 return ret;
210 }
211 return 0;
212 break;
213 default:
214 MHD_gnutls_assert ();
215 return GNUTLS_E_INTERNAL_ERROR;
216 }
217
218}
219
220/* This is the same as the MHD__gnutls_x509_sign, but this one will decode
221 * the ASN1_TYPE given, and sign the DER data. Actually used to get the DER
222 * of the TBS and sign it on the fly.
223 */
224int
225MHD__gnutls_x509_sign_tbs (ASN1_TYPE cert, const char *tbs_name,
226 enum MHD_GNUTLS_HashAlgorithm hash,
227 MHD_gnutls_x509_privkey_t signer,
228 MHD_gnutls_datum_t * signature)
229{
230 int result;
231 opaque *buf;
232 int buf_size;
233 MHD_gnutls_datum_t tbs;
234
235 buf_size = 0;
236 MHD__asn1_der_coding (cert, tbs_name, NULL, &buf_size, NULL);
237
238 buf = MHD_gnutls_alloca (buf_size);
239 if (buf == NULL)
240 {
241 MHD_gnutls_assert ();
242 return GNUTLS_E_MEMORY_ERROR;
243 }
244
245 result = MHD__asn1_der_coding (cert, tbs_name, buf, &buf_size, NULL);
246
247 if (result != ASN1_SUCCESS)
248 {
249 MHD_gnutls_assert ();
250 MHD_gnutls_afree (buf);
251 return MHD_gtls_asn2err (result);
252 }
253
254 tbs.data = buf;
255 tbs.size = buf_size;
256
257 result = MHD__gnutls_x509_sign (&tbs, hash, signer, signature);
258 MHD_gnutls_afree (buf);
259
260 return result;
261}
262
263
264#endif
diff --git a/src/daemon/https/x509/sign.h b/src/daemon/https/x509/sign.h
deleted file mode 100644
index 51e51b92..00000000
--- a/src/daemon/https/x509/sign.h
+++ /dev/null
@@ -1,28 +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
25int MHD__gnutls_x509_sign_tbs (ASN1_TYPE cert, const char *tbs_name,
26 enum MHD_GNUTLS_HashAlgorithm hash,
27 MHD_gnutls_x509_privkey_t signer,
28 MHD_gnutls_datum_t * signature);
diff --git a/src/daemon/https/x509/x509.c b/src/daemon/https/x509/x509.c
index e64d34b2..21c27371 100644
--- a/src/daemon/https/x509/x509.c
+++ b/src/daemon/https/x509/x509.c
@@ -1111,113 +1111,3 @@ MHD_gnutls_x509_crt_export (MHD_gnutls_x509_crt_t cert,
1111 output_data, output_data_size); 1111 output_data, output_data_size);
1112} 1112}
1113 1113
1114#ifdef ENABLE_PKI
1115
1116/**
1117 * MHD_gnutls_x509_crt_check_revocation - This function checks if the given certificate is revoked
1118 * @cert: should contain a MHD_gnutls_x509_crt_t structure
1119 * @crl_list: should contain a list of MHD_gnutls_x509_crl_t structures
1120 * @crl_list_length: the length of the crl_list
1121 *
1122 * This function will return check if the given certificate is
1123 * revoked. It is assumed that the CRLs have been verified before.
1124 *
1125 * Returns: 0 if the certificate is NOT revoked, and 1 if it is. A
1126 * negative value is returned on error.
1127 **/
1128int
1129MHD_gnutls_x509_crt_check_revocation (MHD_gnutls_x509_crt_t cert,
1130 const MHD_gnutls_x509_crl_t * crl_list,
1131 int crl_list_length)
1132{
1133 opaque serial[64];
1134 opaque cert_serial[64];
1135 size_t serial_size, cert_serial_size;
1136 int ncerts, ret, i, j;
1137 MHD_gnutls_datum_t dn1, dn2;
1138
1139 if (cert == NULL)
1140 {
1141 MHD_gnutls_assert ();
1142 return GNUTLS_E_INVALID_REQUEST;
1143 }
1144
1145 for (j = 0; j < crl_list_length; j++)
1146 { /* do for all the crls */
1147
1148 /* Step 1. check if issuer's DN match
1149 */
1150 ret = MHD__gnutls_x509_crl_get_raw_issuer_dn (crl_list[j], &dn1);
1151 if (ret < 0)
1152 {
1153 MHD_gnutls_assert ();
1154 return ret;
1155 }
1156
1157 ret = MHD_gnutls_x509_crt_get_raw_issuer_dn (cert, &dn2);
1158 if (ret < 0)
1159 {
1160 MHD_gnutls_assert ();
1161 return ret;
1162 }
1163
1164 ret = MHD__gnutls_x509_compare_raw_dn (&dn1, &dn2);
1165 MHD__gnutls_free_datum (&dn1);
1166 MHD__gnutls_free_datum (&dn2);
1167 if (ret == 0)
1168 {
1169 /* issuers do not match so don't even
1170 * bother checking.
1171 */
1172 continue;
1173 }
1174
1175 /* Step 2. Read the certificate's serial number
1176 */
1177 cert_serial_size = sizeof (cert_serial);
1178 ret =
1179 MHD_gnutls_x509_crt_get_serial (cert, cert_serial, &cert_serial_size);
1180 if (ret < 0)
1181 {
1182 MHD_gnutls_assert ();
1183 return ret;
1184 }
1185
1186 /* Step 3. cycle through the CRL serials and compare with
1187 * certificate serial we have.
1188 */
1189
1190 ncerts = MHD_gnutls_x509_crl_get_crt_count (crl_list[j]);
1191 if (ncerts < 0)
1192 {
1193 MHD_gnutls_assert ();
1194 return ncerts;
1195 }
1196
1197 for (i = 0; i < ncerts; i++)
1198 {
1199 serial_size = sizeof (serial);
1200 ret = MHD_gnutls_x509_crl_get_crt_serial (crl_list[j], i, serial,
1201 &serial_size, NULL);
1202
1203 if (ret < 0)
1204 {
1205 MHD_gnutls_assert ();
1206 return ret;
1207 }
1208
1209 if (serial_size == cert_serial_size)
1210 {
1211 if (memcmp (serial, cert_serial, serial_size) == 0)
1212 {
1213 /* serials match */
1214 return 1; /* revoked! */
1215 }
1216 }
1217 }
1218
1219 }
1220 return 0; /* not revoked. */
1221}
1222
1223#endif
diff --git a/src/daemon/https/x509/x509_privkey.c b/src/daemon/https/x509/x509_privkey.c
index f151e329..473e8756 100644
--- a/src/daemon/https/x509/x509_privkey.c
+++ b/src/daemon/https/x509/x509_privkey.c
@@ -35,7 +35,6 @@
35#include <dn.h> 35#include <dn.h>
36#include <mpi.h> 36#include <mpi.h>
37#include <extensions.h> 37#include <extensions.h>
38#include <sign.h>
39#include <verify.h> 38#include <verify.h>
40 39
41static int MHD__gnutls_asn1_encode_rsa (ASN1_TYPE * c2, mpi_t * params); 40static int MHD__gnutls_asn1_encode_rsa (ASN1_TYPE * c2, mpi_t * params);
diff --git a/src/daemon/https/x509/x509_verify.c b/src/daemon/https/x509/x509_verify.c
index 35513810..3dc4c9f7 100644
--- a/src/daemon/https/x509/x509_verify.c
+++ b/src/daemon/https/x509/x509_verify.c
@@ -50,14 +50,6 @@ int MHD__gnutls_x509_verify_signature (const MHD_gnutls_datum_t * signed_data,
50 const MHD_gnutls_datum_t * signature, 50 const MHD_gnutls_datum_t * signature,
51 MHD_gnutls_x509_crt_t issuer); 51 MHD_gnutls_x509_crt_t issuer);
52 52
53static
54 int is_crl_issuer (MHD_gnutls_x509_crl_t crl,
55 MHD_gnutls_x509_crt_t issuer_cert);
56static int MHD__gnutls_verify_crl2 (MHD_gnutls_x509_crl_t crl,
57 const MHD_gnutls_x509_crt_t * trusted_cas,
58 int tcas_size, unsigned int flags,
59 unsigned int *output);
60
61/* Checks if the issuer of a certificate is a 53/* Checks if the issuer of a certificate is a
62 * Certificate Authority, or if the certificate is the same 54 * Certificate Authority, or if the certificate is the same
63 * as the issuer (and therefore it doesn't need to be a CA). 55 * as the issuer (and therefore it doesn't need to be a CA).
@@ -410,22 +402,6 @@ MHD__gnutls_x509_verify_certificate (const MHD_gnutls_x509_crt_t *
410 return status; 402 return status;
411 } 403 }
412 404
413 /* Check for revoked certificates in the chain
414 */
415#ifdef ENABLE_PKI
416 for (i = 0; i < clist_size; i++)
417 {
418 ret = MHD_gnutls_x509_crt_check_revocation (certificate_list[i],
419 CRLs, crls_size);
420 if (ret == 1)
421 { /* revoked */
422 status |= GNUTLS_CERT_REVOKED;
423 status |= GNUTLS_CERT_INVALID;
424 return status;
425 }
426 }
427#endif
428
429 /* Check if the last certificate in the path is self signed. 405 /* Check if the last certificate in the path is self signed.
430 * In that case ignore it (a certificate is trusted only if it 406 * In that case ignore it (a certificate is trusted only if it
431 * leads to a trusted party by us, not the server's). 407 * leads to a trusted party by us, not the server's).
@@ -795,224 +771,3 @@ MHD_gnutls_x509_crt_verify (MHD_gnutls_x509_crt_t cert,
795 return 0; 771 return 0;
796} 772}
797 773
798#ifdef ENABLE_PKI
799
800/**
801 * MHD_gnutls_x509_crl_check_issuer - This function checks if the CRL given has the given issuer
802 * @crl: is the CRL to be checked
803 * @issuer: is the certificate of a possible issuer
804 *
805 * This function will check if the given CRL was issued by the
806 * given issuer certificate. It will return true (1) if the given CRL was issued
807 * by the given issuer, and false (0) if not.
808 *
809 * A negative value is returned in case of an error.
810 *
811 **/
812int
813MHD_gnutls_x509_crl_check_issuer (MHD_gnutls_x509_crl_t cert,
814 MHD_gnutls_x509_crt_t issuer)
815{
816 return is_crl_issuer (cert, issuer);
817}
818
819/**
820 * MHD_gnutls_x509_crl_verify - This function verifies the given crl against a given trusted one
821 * @crl: is the crl to be verified
822 * @CA_list: is a certificate list that is considered to be trusted one
823 * @CA_list_length: holds the number of CA certificates in CA_list
824 * @flags: Flags that may be used to change the verification algorithm. Use OR of the MHD_gnutls_certificate_verify_flags enumerations.
825 * @verify: will hold the crl verification output.
826 *
827 * This function will try to verify the given crl and return its status.
828 * See MHD_gnutls_x509_crt_list_verify() for a detailed description of
829 * return values.
830 *
831 * Returns 0 on success and a negative value in case of an error.
832 *
833 **/
834int
835MHD_gnutls_x509_crl_verify (MHD_gnutls_x509_crl_t crl,
836 const MHD_gnutls_x509_crt_t * CA_list,
837 int CA_list_length, unsigned int flags,
838 unsigned int *verify)
839{
840 int ret;
841 /* Verify crl
842 */
843 ret = MHD__gnutls_verify_crl2 (crl, CA_list, CA_list_length, flags, verify);
844 if (ret < 0)
845 {
846 MHD_gnutls_assert ();
847 return ret;
848 }
849
850 return 0;
851}
852
853/* The same as above, but here we've got a CRL.
854 */
855static int
856is_crl_issuer (MHD_gnutls_x509_crl_t crl, MHD_gnutls_x509_crt_t issuer_cert)
857{
858 MHD_gnutls_datum_t dn1 = { NULL, 0 }, dn2 =
859 {
860 NULL, 0};
861 int ret;
862
863 ret = MHD__gnutls_x509_crl_get_raw_issuer_dn (crl, &dn1);
864 if (ret < 0)
865 {
866 MHD_gnutls_assert ();
867 goto cleanup;
868 }
869
870 ret = MHD_gnutls_x509_crt_get_raw_dn (issuer_cert, &dn2);
871 if (ret < 0)
872 {
873 MHD_gnutls_assert ();
874 return ret;
875 }
876
877 ret = MHD__gnutls_x509_compare_raw_dn (&dn1, &dn2);
878
879cleanup:
880 MHD__gnutls_free_datum (&dn1);
881 MHD__gnutls_free_datum (&dn2);
882
883 return ret;
884}
885
886static inline MHD_gnutls_x509_crt_t
887find_crl_issuer (MHD_gnutls_x509_crl_t crl,
888 const MHD_gnutls_x509_crt_t * trusted_cas, int tcas_size)
889{
890 int i;
891
892 /* this is serial search.
893 */
894
895 for (i = 0; i < tcas_size; i++)
896 {
897 if (is_crl_issuer (crl, trusted_cas[i]) == 1)
898 return trusted_cas[i];
899 }
900
901 MHD_gnutls_assert ();
902 return NULL;
903}
904
905/*
906 * Returns only 0 or 1. If 1 it means that the CRL
907 * was successfuly verified.
908 *
909 * 'flags': an OR of the MHD_gnutls_certificate_verify_flags enumeration.
910 *
911 * Output will hold information about the verification
912 * procedure.
913 */
914static int
915MHD__gnutls_verify_crl2 (MHD_gnutls_x509_crl_t crl,
916 const MHD_gnutls_x509_crt_t * trusted_cas,
917 int tcas_size, unsigned int flags,
918 unsigned int *output)
919{
920 /* CRL is ignored for now */
921 MHD_gnutls_datum_t crl_signed_data = { NULL, 0 };
922 MHD_gnutls_datum_t crl_signature = { NULL, 0 };
923 MHD_gnutls_x509_crt_t issuer;
924 int ret, result;
925
926 if (output)
927 *output = 0;
928
929 if (tcas_size >= 1)
930 issuer = find_crl_issuer (crl, trusted_cas, tcas_size);
931 else
932 {
933 MHD_gnutls_assert ();
934 if (output)
935 *output |= GNUTLS_CERT_SIGNER_NOT_FOUND | GNUTLS_CERT_INVALID;
936 return 0;
937 }
938
939 /* issuer is not in trusted certificate
940 * authorities.
941 */
942 if (issuer == NULL)
943 {
944 MHD_gnutls_assert ();
945 if (output)
946 *output |= GNUTLS_CERT_SIGNER_NOT_FOUND | GNUTLS_CERT_INVALID;
947 return 0;
948 }
949
950 if (!(flags & GNUTLS_VERIFY_DISABLE_CA_SIGN))
951 {
952 if (MHD_gnutls_x509_crt_get_ca_status (issuer, NULL) != 1)
953 {
954 MHD_gnutls_assert ();
955 if (output)
956 *output |= GNUTLS_CERT_SIGNER_NOT_CA | GNUTLS_CERT_INVALID;
957 return 0;
958 }
959 }
960
961 result =
962 MHD__gnutls_x509_get_signed_data (crl->crl, "tbsCertList",
963 &crl_signed_data);
964 if (result < 0)
965 {
966 MHD_gnutls_assert ();
967 goto cleanup;
968 }
969
970 result =
971 MHD__gnutls_x509_get_signature (crl->crl, "signature", &crl_signature);
972 if (result < 0)
973 {
974 MHD_gnutls_assert ();
975 goto cleanup;
976 }
977
978 ret =
979 MHD__gnutls_x509_verify_signature (&crl_signed_data, &crl_signature,
980 issuer);
981 if (ret < 0)
982 {
983 MHD_gnutls_assert ();
984 }
985 else if (ret == 0)
986 {
987 MHD_gnutls_assert ();
988 /* error. ignore it */
989 if (output)
990 *output |= GNUTLS_CERT_INVALID;
991 ret = 0;
992 }
993
994 {
995 int sigalg;
996
997 sigalg = MHD_gnutls_x509_crl_get_signature_algorithm (crl);
998
999 if (((sigalg == GNUTLS_SIGN_RSA_MD2) &&
1000 !(flags & GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD2)) ||
1001 ((sigalg == GNUTLS_SIGN_RSA_MD5) &&
1002 !(flags & GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5)))
1003 {
1004 if (output)
1005 *output |= GNUTLS_CERT_INSECURE_ALGORITHM | GNUTLS_CERT_INVALID;
1006 }
1007 }
1008
1009 result = ret;
1010
1011cleanup:
1012 MHD__gnutls_free_datum (&crl_signed_data);
1013 MHD__gnutls_free_datum (&crl_signature);
1014
1015 return result;
1016}
1017
1018#endif