Use the new asn1_read_node_value()
[gnutls.git] / lib / x509 / crl_write.c
blobec758ea8069f85fcb512763c0f868c9596af6438
1 /*
2 * Copyright (C) 2003-2012 Free Software Foundation, Inc.
4 * Author: Nikos Mavrogiannopoulos
6 * This file is part of GnuTLS.
8 * The GnuTLS 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 3 of
11 * the License, or (at your option) any later version.
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.
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>
23 /* This file contains functions to handle CRL generation.
26 #include <gnutls_int.h>
28 #include <gnutls_datum.h>
29 #include <gnutls_global.h>
30 #include <gnutls_errors.h>
31 #include <common.h>
32 #include <gnutls_x509.h>
33 #include <x509_b64.h>
34 #include <x509_int.h>
35 #include <libtasn1.h>
37 static void disable_optional_stuff (gnutls_x509_crl_t crl);
39 /**
40 * gnutls_x509_crl_set_version:
41 * @crl: should contain a gnutls_x509_crl_t structure
42 * @version: holds the version number. For CRLv1 crls must be 1.
44 * This function will set the version of the CRL. This
45 * must be one for CRL version 1, and so on. The CRLs generated
46 * by gnutls should have a version number of 2.
48 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
49 * negative error value.
50 **/
51 int
52 gnutls_x509_crl_set_version (gnutls_x509_crl_t crl, unsigned int version)
54 int result;
55 uint8_t null = version & 0xFF;
57 if (crl == NULL)
59 gnutls_assert ();
60 return GNUTLS_E_INVALID_REQUEST;
63 if (null > 0)
64 null -= 1;
66 result = asn1_write_value (crl->crl, "tbsCertList.version", &null, 1);
67 if (result != ASN1_SUCCESS)
69 gnutls_assert ();
70 return _gnutls_asn2err (result);
73 return 0;
76 /**
77 * gnutls_x509_crl_sign2:
78 * @crl: should contain a gnutls_x509_crl_t structure
79 * @issuer: is the certificate of the certificate issuer
80 * @issuer_key: holds the issuer's private key
81 * @dig: The message digest to use. GNUTLS_DIG_SHA1 is the safe choice unless you know what you're doing.
82 * @flags: must be 0
84 * This function will sign the CRL with the issuer's private key, and
85 * will copy the issuer's information into the CRL.
87 * This must be the last step in a certificate CRL since all
88 * the previously set parameters are now signed.
90 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
91 * negative error value.
93 **/
94 int
95 gnutls_x509_crl_sign2 (gnutls_x509_crl_t crl, gnutls_x509_crt_t issuer,
96 gnutls_x509_privkey_t issuer_key,
97 gnutls_digest_algorithm_t dig, unsigned int flags)
99 int result;
100 gnutls_privkey_t privkey;
102 if (crl == NULL || issuer == NULL)
104 gnutls_assert ();
105 return GNUTLS_E_INVALID_REQUEST;
108 result = gnutls_privkey_init (&privkey);
109 if (result < 0)
111 gnutls_assert ();
112 return result;
115 result = gnutls_privkey_import_x509 (privkey, issuer_key, 0);
116 if (result < 0)
118 gnutls_assert ();
119 goto fail;
122 result = gnutls_x509_crl_privkey_sign (crl, issuer, privkey, dig, flags);
123 if (result < 0)
125 gnutls_assert ();
126 goto fail;
129 result = 0;
131 fail:
132 gnutls_privkey_deinit (privkey);
134 return result;
138 * gnutls_x509_crl_sign:
139 * @crl: should contain a gnutls_x509_crl_t structure
140 * @issuer: is the certificate of the certificate issuer
141 * @issuer_key: holds the issuer's private key
143 * This function is the same a gnutls_x509_crl_sign2() with no flags, and
144 * SHA1 as the hash algorithm.
146 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
147 * negative error value.
149 * Deprecated: Use gnutls_x509_crl_privkey_sign().
152 gnutls_x509_crl_sign (gnutls_x509_crl_t crl, gnutls_x509_crt_t issuer,
153 gnutls_x509_privkey_t issuer_key)
155 return gnutls_x509_crl_sign2 (crl, issuer, issuer_key, GNUTLS_DIG_SHA1, 0);
159 * gnutls_x509_crl_set_this_update:
160 * @crl: should contain a gnutls_x509_crl_t structure
161 * @act_time: The actual time
163 * This function will set the time this CRL was issued.
165 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
166 * negative error value.
169 gnutls_x509_crl_set_this_update (gnutls_x509_crl_t crl, time_t act_time)
171 if (crl == NULL)
173 gnutls_assert ();
174 return GNUTLS_E_INVALID_REQUEST;
177 return _gnutls_x509_set_time (crl->crl, "tbsCertList.thisUpdate", act_time, 0);
181 * gnutls_x509_crl_set_next_update:
182 * @crl: should contain a gnutls_x509_crl_t structure
183 * @exp_time: The actual time
185 * This function will set the time this CRL will be updated.
187 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
188 * negative error value.
191 gnutls_x509_crl_set_next_update (gnutls_x509_crl_t crl, time_t exp_time)
193 if (crl == NULL)
195 gnutls_assert ();
196 return GNUTLS_E_INVALID_REQUEST;
198 return _gnutls_x509_set_time (crl->crl, "tbsCertList.nextUpdate", exp_time, 0);
202 * gnutls_x509_crl_set_crt_serial:
203 * @crl: should contain a gnutls_x509_crl_t structure
204 * @serial: The revoked certificate's serial number
205 * @serial_size: Holds the size of the serial field.
206 * @revocation_time: The time this certificate was revoked
208 * This function will set a revoked certificate's serial number to the CRL.
210 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
211 * negative error value.
214 gnutls_x509_crl_set_crt_serial (gnutls_x509_crl_t crl,
215 const void *serial, size_t serial_size,
216 time_t revocation_time)
218 int ret;
220 if (crl == NULL)
222 gnutls_assert ();
223 return GNUTLS_E_INVALID_REQUEST;
226 ret =
227 asn1_write_value (crl->crl, "tbsCertList.revokedCertificates", "NEW", 1);
228 if (ret != ASN1_SUCCESS)
230 gnutls_assert ();
231 return _gnutls_asn2err (ret);
234 ret =
235 asn1_write_value (crl->crl,
236 "tbsCertList.revokedCertificates.?LAST.userCertificate",
237 serial, serial_size);
238 if (ret != ASN1_SUCCESS)
240 gnutls_assert ();
241 return _gnutls_asn2err (ret);
244 ret =
245 _gnutls_x509_set_time (crl->crl,
246 "tbsCertList.revokedCertificates.?LAST.revocationDate",
247 revocation_time, 0);
248 if (ret < 0)
250 gnutls_assert ();
251 return ret;
254 ret =
255 asn1_write_value (crl->crl,
256 "tbsCertList.revokedCertificates.?LAST.crlEntryExtensions",
257 NULL, 0);
258 if (ret != ASN1_SUCCESS)
260 gnutls_assert ();
261 return _gnutls_asn2err (ret);
264 return 0;
268 * gnutls_x509_crl_set_crt:
269 * @crl: should contain a gnutls_x509_crl_t structure
270 * @crt: a certificate of type #gnutls_x509_crt_t with the revoked certificate
271 * @revocation_time: The time this certificate was revoked
273 * This function will set a revoked certificate's serial number to the CRL.
275 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
276 * negative error value.
279 gnutls_x509_crl_set_crt (gnutls_x509_crl_t crl, gnutls_x509_crt_t crt,
280 time_t revocation_time)
282 int ret;
283 uint8_t serial[128];
284 size_t serial_size;
286 if (crl == NULL || crt == NULL)
288 gnutls_assert ();
289 return GNUTLS_E_INVALID_REQUEST;
292 serial_size = sizeof (serial);
293 ret = gnutls_x509_crt_get_serial (crt, serial, &serial_size);
294 if (ret < 0)
296 gnutls_assert ();
297 return ret;
300 ret =
301 gnutls_x509_crl_set_crt_serial (crl, serial, serial_size,
302 revocation_time);
303 if (ret < 0)
305 gnutls_assert ();
306 return _gnutls_asn2err (ret);
309 return 0;
313 /* If OPTIONAL fields have not been initialized then
314 * disable them.
316 static void
317 disable_optional_stuff (gnutls_x509_crl_t crl)
320 if (crl->use_extensions == 0)
322 asn1_write_value (crl->crl, "tbsCertList.crlExtensions", NULL, 0);
325 return;
329 * gnutls_x509_crl_set_authority_key_id:
330 * @crl: a CRL of type #gnutls_x509_crl_t
331 * @id: The key ID
332 * @id_size: Holds the size of the serial field.
334 * This function will set the CRL's authority key ID extension. Only
335 * the keyIdentifier field can be set with this function. This may
336 * be used by an authority that holds multiple private keys, to distinguish
337 * the used key.
339 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
340 * negative error value.
342 * Since: 2.8.0
345 gnutls_x509_crl_set_authority_key_id (gnutls_x509_crl_t crl,
346 const void *id, size_t id_size)
348 int result;
349 gnutls_datum_t old_id, der_data;
350 unsigned int critical;
352 if (crl == NULL)
354 gnutls_assert ();
355 return GNUTLS_E_INVALID_REQUEST;
358 /* Check if the extension already exists.
360 result =
361 _gnutls_x509_crl_get_extension (crl, "2.5.29.35", 0, &old_id, &critical);
363 if (result >= 0)
364 _gnutls_free_datum (&old_id);
365 if (result != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
367 gnutls_assert ();
368 return GNUTLS_E_INVALID_REQUEST;
371 /* generate the extension.
373 result = _gnutls_x509_ext_gen_auth_key_id (id, id_size, &der_data);
374 if (result < 0)
376 gnutls_assert ();
377 return result;
380 result = _gnutls_x509_crl_set_extension (crl, "2.5.29.35", &der_data, 0);
382 _gnutls_free_datum (&der_data);
384 if (result < 0)
386 gnutls_assert ();
387 return result;
390 crl->use_extensions = 1;
392 return 0;
396 * gnutls_x509_crl_set_number:
397 * @crl: a CRL of type #gnutls_x509_crl_t
398 * @nr: The CRL number
399 * @nr_size: Holds the size of the nr field.
401 * This function will set the CRL's number extension. This
402 * is to be used as a unique and monotonic number assigned to
403 * the CRL by the authority.
405 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
406 * negative error value.
408 * Since: 2.8.0
411 gnutls_x509_crl_set_number (gnutls_x509_crl_t crl,
412 const void *nr, size_t nr_size)
414 int result;
415 gnutls_datum_t old_id, der_data;
416 unsigned int critical;
418 if (crl == NULL)
420 gnutls_assert ();
421 return GNUTLS_E_INVALID_REQUEST;
424 /* Check if the extension already exists.
426 result =
427 _gnutls_x509_crl_get_extension (crl, "2.5.29.20", 0, &old_id, &critical);
429 if (result >= 0)
430 _gnutls_free_datum (&old_id);
431 if (result != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
433 gnutls_assert ();
434 return GNUTLS_E_INVALID_REQUEST;
437 /* generate the extension.
439 result = _gnutls_x509_ext_gen_number (nr, nr_size, &der_data);
440 if (result < 0)
442 gnutls_assert ();
443 return result;
446 result = _gnutls_x509_crl_set_extension (crl, "2.5.29.20", &der_data, 0);
448 _gnutls_free_datum (&der_data);
450 if (result < 0)
452 gnutls_assert ();
453 return result;
456 crl->use_extensions = 1;
458 return 0;
462 * gnutls_x509_crl_privkey_sign:
463 * @crl: should contain a gnutls_x509_crl_t structure
464 * @issuer: is the certificate of the certificate issuer
465 * @issuer_key: holds the issuer's private key
466 * @dig: The message digest to use. GNUTLS_DIG_SHA1 is the safe choice unless you know what you're doing.
467 * @flags: must be 0
469 * This function will sign the CRL with the issuer's private key, and
470 * will copy the issuer's information into the CRL.
472 * This must be the last step in a certificate CRL since all
473 * the previously set parameters are now signed.
475 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
476 * negative error value.
478 * Since 2.12.0
481 gnutls_x509_crl_privkey_sign (gnutls_x509_crl_t crl, gnutls_x509_crt_t issuer,
482 gnutls_privkey_t issuer_key,
483 gnutls_digest_algorithm_t dig,
484 unsigned int flags)
486 int result;
488 if (crl == NULL || issuer == NULL)
490 gnutls_assert ();
491 return GNUTLS_E_INVALID_REQUEST;
494 /* disable all the unneeded OPTIONAL fields.
496 disable_optional_stuff (crl);
498 result = _gnutls_x509_pkix_sign (crl->crl, "tbsCertList",
499 dig, issuer, issuer_key);
500 if (result < 0)
502 gnutls_assert ();
503 return result;
506 return 0;