Tizen 2.0 Release
[external/libgnutls26.git] / lib / x509 / crl_write.c
1 /*
2  * Copyright (C) 2003, 2004, 2005, 2008, 2010 Free Software Foundation,
3  * Inc.
4  *
5  * Author: Nikos Mavrogiannopoulos
6  *
7  * This file is part of GnuTLS.
8  *
9  * The GnuTLS is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public License
11  * as published by the Free Software Foundation; either version 2.1 of
12  * the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
22  * USA
23  *
24  */
25
26 /* This file contains functions to handle CRL generation.
27  */
28
29 #include <gnutls_int.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 <gnutls_x509.h>
38 #include <x509_b64.h>
39 #include <x509_int.h>
40 #include <libtasn1.h>
41
42 static void disable_optional_stuff (gnutls_x509_crl_t crl);
43
44 /**
45  * gnutls_x509_crl_set_version:
46  * @crl: should contain a gnutls_x509_crl_t structure
47  * @version: holds the version number. For CRLv1 crls must be 1.
48  *
49  * This function will set the version of the CRL. This
50  * must be one for CRL version 1, and so on. The CRLs generated
51  * by gnutls should have a version number of 2.
52  *
53  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
54  *   negative error value.
55  **/
56 int
57 gnutls_x509_crl_set_version (gnutls_x509_crl_t crl, unsigned int version)
58 {
59   int result;
60   uint8_t null = version & 0xFF;
61
62   if (crl == NULL)
63     {
64       gnutls_assert ();
65       return GNUTLS_E_INVALID_REQUEST;
66     }
67
68   if (null > 0)
69     null -= 1;
70
71   result = asn1_write_value (crl->crl, "tbsCertList.version", &null, 1);
72   if (result != ASN1_SUCCESS)
73     {
74       gnutls_assert ();
75       return _gnutls_asn2err (result);
76     }
77
78   return 0;
79 }
80
81 /**
82  * gnutls_x509_crl_sign2:
83  * @crl: should contain a gnutls_x509_crl_t structure
84  * @issuer: is the certificate of the certificate issuer
85  * @issuer_key: holds the issuer's private key
86  * @dig: The message digest to use. GNUTLS_DIG_SHA1 is the safe choice unless you know what you're doing.
87  * @flags: must be 0
88  *
89  * This function will sign the CRL with the issuer's private key, and
90  * will copy the issuer's information into the CRL.
91  *
92  * This must be the last step in a certificate CRL since all
93  * the previously set parameters are now signed.
94  *
95  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
96  *   negative error value.
97  *
98  * Deprecated: Use gnutls_x509_crl_privkey_sign() instead.
99  **/
100 int
101 gnutls_x509_crl_sign2 (gnutls_x509_crl_t crl, gnutls_x509_crt_t issuer,
102                        gnutls_x509_privkey_t issuer_key,
103                        gnutls_digest_algorithm_t dig, unsigned int flags)
104 {
105   int result;
106   gnutls_privkey_t privkey;
107
108   if (crl == NULL || issuer == NULL)
109     {
110       gnutls_assert ();
111       return GNUTLS_E_INVALID_REQUEST;
112     }
113
114   result = gnutls_privkey_init (&privkey);
115   if (result < 0)
116     {
117       gnutls_assert ();
118       return result;
119     }
120
121   result = gnutls_privkey_import_x509 (privkey, issuer_key, 0);
122   if (result < 0)
123     {
124       gnutls_assert ();
125       goto fail;
126     }
127
128   result = gnutls_x509_crl_privkey_sign (crl, issuer, privkey, dig, flags);
129   if (result < 0)
130     {
131       gnutls_assert ();
132       goto fail;
133     }
134
135   result = 0;
136
137 fail:
138   gnutls_privkey_deinit (privkey);
139
140   return result;
141 }
142
143 /**
144  * gnutls_x509_crl_sign:
145  * @crl: should contain a gnutls_x509_crl_t structure
146  * @issuer: is the certificate of the certificate issuer
147  * @issuer_key: holds the issuer's private key
148  *
149  * This function is the same a gnutls_x509_crl_sign2() with no flags, and
150  * SHA1 as the hash algorithm.
151  *
152  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
153  *   negative error value.
154  *
155  * Deprecated: Use gnutls_x509_crl_privkey_sign().
156  */
157 int
158 gnutls_x509_crl_sign (gnutls_x509_crl_t crl, gnutls_x509_crt_t issuer,
159                       gnutls_x509_privkey_t issuer_key)
160 {
161   return gnutls_x509_crl_sign2 (crl, issuer, issuer_key, GNUTLS_DIG_SHA1, 0);
162 }
163
164 /**
165  * gnutls_x509_crl_set_this_update:
166  * @crl: should contain a gnutls_x509_crl_t structure
167  * @act_time: The actual time
168  *
169  * This function will set the time this CRL was issued.
170  *
171  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
172  *   negative error value.
173  **/
174 int
175 gnutls_x509_crl_set_this_update (gnutls_x509_crl_t crl, time_t act_time)
176 {
177   if (crl == NULL)
178     {
179       gnutls_assert ();
180       return GNUTLS_E_INVALID_REQUEST;
181     }
182
183   return _gnutls_x509_set_time (crl->crl, "tbsCertList.thisUpdate", act_time);
184 }
185
186 /**
187  * gnutls_x509_crl_set_next_update:
188  * @crl: should contain a gnutls_x509_crl_t structure
189  * @exp_time: The actual time
190  *
191  * This function will set the time this CRL will be updated.
192  *
193  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
194  *   negative error value.
195  **/
196 int
197 gnutls_x509_crl_set_next_update (gnutls_x509_crl_t crl, time_t exp_time)
198 {
199   if (crl == NULL)
200     {
201       gnutls_assert ();
202       return GNUTLS_E_INVALID_REQUEST;
203     }
204   return _gnutls_x509_set_time (crl->crl, "tbsCertList.nextUpdate", exp_time);
205 }
206
207 /**
208  * gnutls_x509_crl_set_crt_serial:
209  * @crl: should contain a gnutls_x509_crl_t structure
210  * @serial: The revoked certificate's serial number
211  * @serial_size: Holds the size of the serial field.
212  * @revocation_time: The time this certificate was revoked
213  *
214  * This function will set a revoked certificate's serial number to the CRL.
215  *
216  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
217  *   negative error value.
218  **/
219 int
220 gnutls_x509_crl_set_crt_serial (gnutls_x509_crl_t crl,
221                                 const void *serial, size_t serial_size,
222                                 time_t revocation_time)
223 {
224   int ret;
225
226   if (crl == NULL)
227     {
228       gnutls_assert ();
229       return GNUTLS_E_INVALID_REQUEST;
230     }
231
232   ret =
233     asn1_write_value (crl->crl, "tbsCertList.revokedCertificates", "NEW", 1);
234   if (ret != ASN1_SUCCESS)
235     {
236       gnutls_assert ();
237       return _gnutls_asn2err (ret);
238     }
239
240   ret =
241     asn1_write_value (crl->crl,
242                       "tbsCertList.revokedCertificates.?LAST.userCertificate",
243                       serial, serial_size);
244   if (ret != ASN1_SUCCESS)
245     {
246       gnutls_assert ();
247       return _gnutls_asn2err (ret);
248     }
249
250   ret =
251     _gnutls_x509_set_time (crl->crl,
252                            "tbsCertList.revokedCertificates.?LAST.revocationDate",
253                            revocation_time);
254   if (ret < 0)
255     {
256       gnutls_assert ();
257       return ret;
258     }
259
260   ret =
261     asn1_write_value (crl->crl,
262                       "tbsCertList.revokedCertificates.?LAST.crlEntryExtensions",
263                       NULL, 0);
264   if (ret != ASN1_SUCCESS)
265     {
266       gnutls_assert ();
267       return _gnutls_asn2err (ret);
268     }
269
270   return 0;
271 }
272
273 /**
274  * gnutls_x509_crl_set_crt:
275  * @crl: should contain a gnutls_x509_crl_t structure
276  * @crt: a certificate of type #gnutls_x509_crt_t with the revoked certificate
277  * @revocation_time: The time this certificate was revoked
278  *
279  * This function will set a revoked certificate's serial number to the CRL.
280  *
281  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
282  *   negative error value.
283  **/
284 int
285 gnutls_x509_crl_set_crt (gnutls_x509_crl_t crl, gnutls_x509_crt_t crt,
286                          time_t revocation_time)
287 {
288   int ret;
289   opaque serial[128];
290   size_t serial_size;
291
292   if (crl == NULL || crt == NULL)
293     {
294       gnutls_assert ();
295       return GNUTLS_E_INVALID_REQUEST;
296     }
297
298   serial_size = sizeof (serial);
299   ret = gnutls_x509_crt_get_serial (crt, serial, &serial_size);
300   if (ret < 0)
301     {
302       gnutls_assert ();
303       return ret;
304     }
305
306   ret =
307     gnutls_x509_crl_set_crt_serial (crl, serial, serial_size,
308                                     revocation_time);
309   if (ret < 0)
310     {
311       gnutls_assert ();
312       return _gnutls_asn2err (ret);
313     }
314
315   return 0;
316 }
317
318
319 /* If OPTIONAL fields have not been initialized then
320  * disable them.
321  */
322 static void
323 disable_optional_stuff (gnutls_x509_crl_t crl)
324 {
325
326   if (crl->use_extensions == 0)
327     {
328       asn1_write_value (crl->crl, "tbsCertList.crlExtensions", NULL, 0);
329     }
330
331   return;
332 }
333
334 /**
335  * gnutls_x509_crl_set_authority_key_id:
336  * @crl: a CRL of type #gnutls_x509_crl_t
337  * @id: The key ID
338  * @id_size: Holds the size of the serial field.
339  *
340  * This function will set the CRL's authority key ID extension.  Only
341  * the keyIdentifier field can be set with this function.
342  *
343  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
344  *   negative error value.
345  *
346  * Since: 2.8.0
347  **/
348 int
349 gnutls_x509_crl_set_authority_key_id (gnutls_x509_crl_t crl,
350                                       const void *id, size_t id_size)
351 {
352   int result;
353   gnutls_datum_t old_id, der_data;
354   unsigned int critical;
355
356   if (crl == NULL)
357     {
358       gnutls_assert ();
359       return GNUTLS_E_INVALID_REQUEST;
360     }
361
362   /* Check if the extension already exists.
363    */
364   result =
365     _gnutls_x509_crl_get_extension (crl, "2.5.29.35", 0, &old_id, &critical);
366
367   if (result >= 0)
368     _gnutls_free_datum (&old_id);
369   if (result != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
370     {
371       gnutls_assert ();
372       return GNUTLS_E_INVALID_REQUEST;
373     }
374
375   /* generate the extension.
376    */
377   result = _gnutls_x509_ext_gen_auth_key_id (id, id_size, &der_data);
378   if (result < 0)
379     {
380       gnutls_assert ();
381       return result;
382     }
383
384   result = _gnutls_x509_crl_set_extension (crl, "2.5.29.35", &der_data, 0);
385
386   _gnutls_free_datum (&der_data);
387
388   if (result < 0)
389     {
390       gnutls_assert ();
391       return result;
392     }
393
394   crl->use_extensions = 1;
395
396   return 0;
397 }
398
399 /**
400  * gnutls_x509_crl_set_number:
401  * @crl: a CRL of type #gnutls_x509_crl_t
402  * @nr: The CRL number
403  * @nr_size: Holds the size of the nr field.
404  *
405  * This function will set the CRL's number extension.
406  *
407  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
408  *   negative error value.
409  *
410  * Since: 2.8.0
411  **/
412 int
413 gnutls_x509_crl_set_number (gnutls_x509_crl_t crl,
414                             const void *nr, size_t nr_size)
415 {
416   int result;
417   gnutls_datum_t old_id, der_data;
418   unsigned int critical;
419
420   if (crl == NULL)
421     {
422       gnutls_assert ();
423       return GNUTLS_E_INVALID_REQUEST;
424     }
425
426   /* Check if the extension already exists.
427    */
428   result =
429     _gnutls_x509_crl_get_extension (crl, "2.5.29.20", 0, &old_id, &critical);
430
431   if (result >= 0)
432     _gnutls_free_datum (&old_id);
433   if (result != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
434     {
435       gnutls_assert ();
436       return GNUTLS_E_INVALID_REQUEST;
437     }
438
439   /* generate the extension.
440    */
441   result = _gnutls_x509_ext_gen_number (nr, nr_size, &der_data);
442   if (result < 0)
443     {
444       gnutls_assert ();
445       return result;
446     }
447
448   result = _gnutls_x509_crl_set_extension (crl, "2.5.29.20", &der_data, 0);
449
450   _gnutls_free_datum (&der_data);
451
452   if (result < 0)
453     {
454       gnutls_assert ();
455       return result;
456     }
457
458   crl->use_extensions = 1;
459
460   return 0;
461 }
462
463 /**
464  * gnutls_x509_crl_privkey_sign:
465  * @crl: should contain a gnutls_x509_crl_t structure
466  * @issuer: is the certificate of the certificate issuer
467  * @issuer_key: holds the issuer's private key
468  * @dig: The message digest to use. GNUTLS_DIG_SHA1 is the safe choice unless you know what you're doing.
469  * @flags: must be 0
470  *
471  * This function will sign the CRL with the issuer's private key, and
472  * will copy the issuer's information into the CRL.
473  *
474  * This must be the last step in a certificate CRL since all
475  * the previously set parameters are now signed.
476  *
477  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
478  *   negative error value.
479  **/
480 int
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)
485 {
486   int result;
487
488   if (crl == NULL || issuer == NULL)
489     {
490       gnutls_assert ();
491       return GNUTLS_E_INVALID_REQUEST;
492     }
493
494   /* disable all the unneeded OPTIONAL fields.
495    */
496   disable_optional_stuff (crl);
497
498   result = _gnutls_x509_pkix_sign (crl->crl, "tbsCertList",
499                                    dig, issuer, issuer_key);
500   if (result < 0)
501     {
502       gnutls_assert ();
503       return result;
504     }
505
506   return 0;
507 }
508
509 #endif /* ENABLE_PKI */