Tizen 2.0 Release
[external/libgnutls26.git] / lib / x509 / x509_write.c
1 /*
2  * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free
3  * Software Foundation, 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 X.509 certificate 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_crt_t cert);
43
44 /**
45  * gnutls_x509_crt_set_dn_by_oid:
46  * @crt: a certificate of type #gnutls_x509_crt_t
47  * @oid: holds an Object Identifier in a null terminated string
48  * @raw_flag: must be 0, or 1 if the data are DER encoded
49  * @name: a pointer to the name
50  * @sizeof_name: holds the size of @name
51  *
52  * This function will set the part of the name of the Certificate
53  * subject, specified by the given OID. The input string should be
54  * ASCII or UTF-8 encoded.
55  *
56  * Some helper macros with popular OIDs can be found in gnutls/x509.h
57  * With this function you can only set the known OIDs. You can test
58  * for known OIDs using gnutls_x509_dn_oid_known(). For OIDs that are
59  * not known (by gnutls) you should properly DER encode your data,
60  * and call this function with @raw_flag set.
61  *
62  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
63  *   negative error value.
64  **/
65 int
66 gnutls_x509_crt_set_dn_by_oid (gnutls_x509_crt_t crt, const char *oid,
67                                unsigned int raw_flag, const void *name,
68                                unsigned int sizeof_name)
69 {
70   if (sizeof_name == 0 || name == NULL || crt == NULL)
71     {
72       return GNUTLS_E_INVALID_REQUEST;
73     }
74
75   return _gnutls_x509_set_dn_oid (crt->cert, "tbsCertificate.subject",
76                                   oid, raw_flag, name, sizeof_name);
77 }
78
79 /**
80  * gnutls_x509_crt_set_issuer_dn_by_oid:
81  * @crt: a certificate of type #gnutls_x509_crt_t
82  * @oid: holds an Object Identifier in a null terminated string
83  * @raw_flag: must be 0, or 1 if the data are DER encoded
84  * @name: a pointer to the name
85  * @sizeof_name: holds the size of @name
86  *
87  * This function will set the part of the name of the Certificate
88  * issuer, specified by the given OID.  The input string should be
89  * ASCII or UTF-8 encoded.
90  *
91  * Some helper macros with popular OIDs can be found in gnutls/x509.h
92  * With this function you can only set the known OIDs. You can test
93  * for known OIDs using gnutls_x509_dn_oid_known(). For OIDs that are
94  * not known (by gnutls) you should properly DER encode your data,
95  * and call this function with @raw_flag set.
96  *
97  * Normally you do not need to call this function, since the signing
98  * operation will copy the signer's name as the issuer of the
99  * certificate.
100  *
101  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
102  *   negative error value.
103  **/
104 int
105 gnutls_x509_crt_set_issuer_dn_by_oid (gnutls_x509_crt_t crt,
106                                       const char *oid,
107                                       unsigned int raw_flag,
108                                       const void *name,
109                                       unsigned int sizeof_name)
110 {
111   if (sizeof_name == 0 || name == NULL || crt == NULL)
112     {
113       return GNUTLS_E_INVALID_REQUEST;
114     }
115
116   return _gnutls_x509_set_dn_oid (crt->cert, "tbsCertificate.issuer", oid,
117                                   raw_flag, name, sizeof_name);
118 }
119
120 /**
121  * gnutls_x509_crt_set_proxy_dn:
122  * @crt: a gnutls_x509_crt_t structure with the new proxy cert
123  * @eecrt: the end entity certificate that will be issuing the proxy
124  * @raw_flag: must be 0, or 1 if the CN is DER encoded
125  * @name: a pointer to the CN name, may be NULL (but MUST then be added later)
126  * @sizeof_name: holds the size of @name
127  *
128  * This function will set the subject in @crt to the end entity's
129  * @eecrt subject name, and add a single Common Name component @name
130  * of size @sizeof_name.  This corresponds to the required proxy
131  * certificate naming style.  Note that if @name is %NULL, you MUST
132  * set it later by using gnutls_x509_crt_set_dn_by_oid() or similar.
133  *
134  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
135  *   negative error value.
136  **/
137 int
138 gnutls_x509_crt_set_proxy_dn (gnutls_x509_crt_t crt, gnutls_x509_crt_t eecrt,
139                               unsigned int raw_flag, const void *name,
140                               unsigned int sizeof_name)
141 {
142   int result;
143
144   if (crt == NULL || eecrt == NULL)
145     {
146       return GNUTLS_E_INVALID_REQUEST;
147     }
148
149   result = asn1_copy_node (crt->cert, "tbsCertificate.subject",
150                            eecrt->cert, "tbsCertificate.subject");
151   if (result != ASN1_SUCCESS)
152     {
153       gnutls_assert ();
154       return _gnutls_asn2err (result);
155     }
156
157   if (name && sizeof_name)
158     {
159       return _gnutls_x509_set_dn_oid (crt->cert, "tbsCertificate.subject",
160                                       GNUTLS_OID_X520_COMMON_NAME,
161                                       raw_flag, name, sizeof_name);
162     }
163
164   return 0;
165 }
166
167 /**
168  * gnutls_x509_crt_set_version:
169  * @crt: a certificate of type #gnutls_x509_crt_t
170  * @version: holds the version number. For X.509v1 certificates must be 1.
171  *
172  * This function will set the version of the certificate.  This must
173  * be one for X.509 version 1, and so on.  Plain certificates without
174  * extensions must have version set to one.
175  *
176  * To create well-formed certificates, you must specify version 3 if
177  * you use any certificate extensions.  Extensions are created by
178  * functions such as gnutls_x509_crt_set_subject_alt_name()
179  * or gnutls_x509_crt_set_key_usage().
180  *
181  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
182  *   negative error value.
183  **/
184 int
185 gnutls_x509_crt_set_version (gnutls_x509_crt_t crt, unsigned int version)
186 {
187   int result;
188   unsigned char null = version;
189
190   if (crt == NULL)
191     {
192       gnutls_assert ();
193       return GNUTLS_E_INVALID_REQUEST;
194     }
195
196   if (null > 0)
197     null--;
198
199   result = asn1_write_value (crt->cert, "tbsCertificate.version", &null, 1);
200   if (result != ASN1_SUCCESS)
201     {
202       gnutls_assert ();
203       return _gnutls_asn2err (result);
204     }
205
206   return 0;
207 }
208
209 /**
210  * gnutls_x509_crt_set_key:
211  * @crt: a certificate of type #gnutls_x509_crt_t
212  * @key: holds a private key
213  *
214  * This function will set the public parameters from the given
215  * private key to the certificate. Only RSA keys are currently
216  * supported.
217  *
218  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
219  *   negative error value.
220  *
221  **/
222 int
223 gnutls_x509_crt_set_key (gnutls_x509_crt_t crt, gnutls_x509_privkey_t key)
224 {
225   int result;
226
227   if (crt == NULL)
228     {
229       gnutls_assert ();
230       return GNUTLS_E_INVALID_REQUEST;
231     }
232
233   result = _gnutls_x509_encode_and_copy_PKI_params (crt->cert,
234                                                     "tbsCertificate.subjectPublicKeyInfo",
235                                                     key->pk_algorithm,
236                                                     key->params,
237                                                     key->params_size);
238
239   if (result < 0)
240     {
241       gnutls_assert ();
242       return result;
243     }
244
245   return 0;
246 }
247
248 /**
249  * gnutls_x509_crt_set_crq:
250  * @crt: a certificate of type #gnutls_x509_crt_t
251  * @crq: holds a certificate request
252  *
253  * This function will set the name and public parameters as well as
254  * the extensions from the given certificate request to the certificate. 
255  * Only RSA keys are currently supported.
256  *
257  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
258  *   negative error value.
259  **/
260 int
261 gnutls_x509_crt_set_crq (gnutls_x509_crt_t crt, gnutls_x509_crq_t crq)
262 {
263   int result;
264
265   if (crt == NULL || crq == NULL)
266     {
267       gnutls_assert ();
268       return GNUTLS_E_INVALID_REQUEST;
269     }
270
271   result = gnutls_x509_crq_verify(crq, 0);
272   if (result < 0)
273     return gnutls_assert_val(result);
274
275   result = asn1_copy_node (crt->cert, "tbsCertificate.subject",
276                            crq->crq, "certificationRequestInfo.subject");
277   if (result != ASN1_SUCCESS)
278     {
279       gnutls_assert ();
280       return _gnutls_asn2err (result);
281     }
282
283   result =
284     asn1_copy_node (crt->cert, "tbsCertificate.subjectPublicKeyInfo",
285                     crq->crq, "certificationRequestInfo.subjectPKInfo");
286   if (result != ASN1_SUCCESS)
287     {
288       gnutls_assert ();
289       return _gnutls_asn2err (result);
290     }
291
292   return 0;
293 }
294
295 /**
296  * gnutls_x509_crt_set_crq_extensions:
297  * @crt: a certificate of type #gnutls_x509_crt_t
298  * @crq: holds a certificate request
299  *
300  * This function will set extensions from the given request to the
301  * certificate.
302  *
303  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
304  *   negative error value.
305  *
306  * Since: 2.8.0
307  **/
308 int
309 gnutls_x509_crt_set_crq_extensions (gnutls_x509_crt_t crt,
310                                     gnutls_x509_crq_t crq)
311 {
312   size_t i;
313
314   if (crt == NULL || crq == NULL)
315     {
316       gnutls_assert ();
317       return GNUTLS_E_INVALID_REQUEST;
318     }
319
320   for (i = 0;; i++)
321     {
322       int result;
323       char oid[MAX_OID_SIZE];
324       size_t oid_size;
325       opaque *extensions;
326       size_t extensions_size;
327       unsigned int critical;
328       gnutls_datum_t ext;
329
330       oid_size = sizeof (oid);
331       result = gnutls_x509_crq_get_extension_info (crq, i, oid,
332                                                    &oid_size, &critical);
333       if (result < 0)
334         {
335           if (result == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
336             break;
337
338           gnutls_assert ();
339           return result;
340         }
341
342       extensions_size = 0;
343       result = gnutls_x509_crq_get_extension_data (crq, i, NULL,
344                                                    &extensions_size);
345       if (result < 0)
346         {
347           gnutls_assert ();
348           return result;
349         }
350
351       extensions = gnutls_malloc (extensions_size);
352       if (extensions == NULL)
353         {
354           gnutls_assert ();
355           return GNUTLS_E_MEMORY_ERROR;
356         }
357
358       result = gnutls_x509_crq_get_extension_data (crq, i, extensions,
359                                                    &extensions_size);
360       if (result < 0)
361         {
362           gnutls_assert ();
363           gnutls_free (extensions);
364           return result;
365         }
366
367       ext.data = extensions;
368       ext.size = extensions_size;
369
370       result = _gnutls_x509_crt_set_extension (crt, oid, &ext, critical);
371       gnutls_free (extensions);
372       if (result < 0)
373         {
374           gnutls_assert ();
375           return result;
376         }
377     }
378
379   if (i > 0)
380     crt->use_extensions = 1;
381
382   return 0;
383 }
384
385 /**
386  * gnutls_x509_crt_set_extension_by_oid:
387  * @crt: a certificate of type #gnutls_x509_crt_t
388  * @oid: holds an Object Identified in null terminated string
389  * @buf: a pointer to a DER encoded data
390  * @sizeof_buf: holds the size of @buf
391  * @critical: should be non zero if the extension is to be marked as critical
392  *
393  * This function will set an the extension, by the specified OID, in
394  * the certificate.  The extension data should be binary data DER
395  * encoded.
396  *
397  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
398  *   negative error value.
399  **/
400 int
401 gnutls_x509_crt_set_extension_by_oid (gnutls_x509_crt_t crt,
402                                       const char *oid, const void *buf,
403                                       size_t sizeof_buf,
404                                       unsigned int critical)
405 {
406   int result;
407   gnutls_datum_t der_data;
408
409   der_data.data = (void *) buf;
410   der_data.size = sizeof_buf;
411
412   if (crt == NULL)
413     {
414       gnutls_assert ();
415       return GNUTLS_E_INVALID_REQUEST;
416     }
417
418   result = _gnutls_x509_crt_set_extension (crt, oid, &der_data, critical);
419   if (result < 0)
420     {
421       gnutls_assert ();
422       return result;
423     }
424
425   crt->use_extensions = 1;
426
427   return 0;
428
429 }
430
431 /**
432  * gnutls_x509_crt_set_basic_constraints:
433  * @crt: a certificate of type #gnutls_x509_crt_t
434  * @ca: true(1) or false(0). Depending on the Certificate authority status.
435  * @pathLenConstraint: non-negative values indicate maximum length of path,
436  *   and negative values indicate that the pathLenConstraints field should
437  *   not be present.
438  *
439  * This function will set the basicConstraints certificate extension.
440  *
441  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
442  *   negative error value.
443  **/
444 int
445 gnutls_x509_crt_set_basic_constraints (gnutls_x509_crt_t crt,
446                                        unsigned int ca, int pathLenConstraint)
447 {
448   int result;
449   gnutls_datum_t der_data;
450
451   if (crt == NULL)
452     {
453       gnutls_assert ();
454       return GNUTLS_E_INVALID_REQUEST;
455     }
456
457   /* generate the extension.
458    */
459   result = _gnutls_x509_ext_gen_basicConstraints (ca, pathLenConstraint,
460                                                   &der_data);
461   if (result < 0)
462     {
463       gnutls_assert ();
464       return result;
465     }
466
467   result = _gnutls_x509_crt_set_extension (crt, "2.5.29.19", &der_data, 1);
468
469   _gnutls_free_datum (&der_data);
470
471   if (result < 0)
472     {
473       gnutls_assert ();
474       return result;
475     }
476
477   crt->use_extensions = 1;
478
479   return 0;
480 }
481
482 /**
483  * gnutls_x509_crt_set_ca_status:
484  * @crt: a certificate of type #gnutls_x509_crt_t
485  * @ca: true(1) or false(0). Depending on the Certificate authority status.
486  *
487  * This function will set the basicConstraints certificate extension.
488  * Use gnutls_x509_crt_set_basic_constraints() if you want to control
489  * the pathLenConstraint field too.
490  *
491  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
492  *   negative error value.
493  **/
494 int
495 gnutls_x509_crt_set_ca_status (gnutls_x509_crt_t crt, unsigned int ca)
496 {
497   return gnutls_x509_crt_set_basic_constraints (crt, ca, -1);
498 }
499
500 /**
501  * gnutls_x509_crt_set_key_usage:
502  * @crt: a certificate of type #gnutls_x509_crt_t
503  * @usage: an ORed sequence of the GNUTLS_KEY_* elements.
504  *
505  * This function will set the keyUsage certificate extension.
506  *
507  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
508  *   negative error value.
509  **/
510 int
511 gnutls_x509_crt_set_key_usage (gnutls_x509_crt_t crt, unsigned int usage)
512 {
513   int result;
514   gnutls_datum_t der_data;
515
516   if (crt == NULL)
517     {
518       gnutls_assert ();
519       return GNUTLS_E_INVALID_REQUEST;
520     }
521
522   /* generate the extension.
523    */
524   result = _gnutls_x509_ext_gen_keyUsage ((uint16_t) usage, &der_data);
525   if (result < 0)
526     {
527       gnutls_assert ();
528       return result;
529     }
530
531   result = _gnutls_x509_crt_set_extension (crt, "2.5.29.15", &der_data, 1);
532
533   _gnutls_free_datum (&der_data);
534
535   if (result < 0)
536     {
537       gnutls_assert ();
538       return result;
539     }
540
541   crt->use_extensions = 1;
542
543   return 0;
544 }
545
546 /**
547  * gnutls_x509_crt_set_subject_alternative_name:
548  * @crt: a certificate of type #gnutls_x509_crt_t
549  * @type: is one of the gnutls_x509_subject_alt_name_t enumerations
550  * @data_string: The data to be set, a zero terminated string
551  *
552  * This function will set the subject alternative name certificate
553  * extension. This function assumes that data can be expressed as a null
554  * terminated string.
555  *
556  * The name of the function is unfortunate since it is incosistent with
557  * gnutls_x509_crt_get_subject_alt_name().
558  *
559  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
560  *   negative error value.
561  **/
562 int
563 gnutls_x509_crt_set_subject_alternative_name (gnutls_x509_crt_t crt,
564                                               gnutls_x509_subject_alt_name_t
565                                               type, const char *data_string)
566 {
567   if (crt == NULL)
568     {
569       gnutls_assert ();
570       return GNUTLS_E_INVALID_REQUEST;
571     }
572
573   /* only handle text extensions */
574   if (type != GNUTLS_SAN_DNSNAME && type != GNUTLS_SAN_RFC822NAME &&
575       type != GNUTLS_SAN_URI)
576     {
577       gnutls_assert ();
578       return GNUTLS_E_INVALID_REQUEST;
579     }
580
581   return gnutls_x509_crt_set_subject_alt_name (crt, type, data_string,
582                                                strlen (data_string),
583                                                GNUTLS_FSAN_SET);
584 }
585
586 /**
587  * gnutls_x509_crt_set_subject_alt_name:
588  * @crt: a certificate of type #gnutls_x509_crt_t
589  * @type: is one of the gnutls_x509_subject_alt_name_t enumerations
590  * @data: The data to be set
591  * @data_size: The size of data to be set
592  * @flags: GNUTLS_FSAN_SET to clear previous data or GNUTLS_FSAN_APPEND to append. 
593  *
594  * This function will set the subject alternative name certificate
595  * extension. It can set the following types:
596  *
597  * &GNUTLS_SAN_DNSNAME: as a text string
598  *
599  * &GNUTLS_SAN_RFC822NAME: as a text string
600  *
601  * &GNUTLS_SAN_URI: as a text string
602  *
603  * &GNUTLS_SAN_IPADDRESS: as a binary IP address (4 or 16 bytes)
604  * 
605  * Other values can be set as binary values with the proper DER encoding.
606  *
607  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
608  *   negative error value.
609  *
610  * Since: 2.6.0
611  **/
612 int
613 gnutls_x509_crt_set_subject_alt_name (gnutls_x509_crt_t crt,
614                                       gnutls_x509_subject_alt_name_t type,
615                                       const void *data,
616                                       unsigned int data_size,
617                                       unsigned int flags)
618 {
619   int result;
620   gnutls_datum_t der_data = { NULL, 0 };
621   gnutls_datum_t prev_der_data = { NULL, 0 };
622   unsigned int critical = 0;
623
624   if (crt == NULL)
625     {
626       gnutls_assert ();
627       return GNUTLS_E_INVALID_REQUEST;
628     }
629
630   /* Check if the extension already exists.
631    */
632
633   if (flags == GNUTLS_FSAN_APPEND)
634     {
635       result = _gnutls_x509_crt_get_extension (crt, "2.5.29.17", 0,
636                                                &prev_der_data, &critical);
637       if (result < 0 && result != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
638         {
639           gnutls_assert ();
640           return result;
641         }
642     }
643
644   /* generate the extension.
645    */
646   result = _gnutls_x509_ext_gen_subject_alt_name (type, data, data_size,
647                                                   &prev_der_data, &der_data);
648
649   if (flags == GNUTLS_FSAN_APPEND)
650     _gnutls_free_datum (&prev_der_data);
651
652   if (result < 0)
653     {
654       gnutls_assert ();
655       goto finish;
656     }
657
658   result = _gnutls_x509_crt_set_extension (crt, "2.5.29.17", &der_data,
659                                            critical);
660
661   _gnutls_free_datum (&der_data);
662
663   if (result < 0)
664     {
665       gnutls_assert ();
666       return result;
667     }
668
669   crt->use_extensions = 1;
670
671   return 0;
672
673 finish:
674   _gnutls_free_datum (&prev_der_data);
675   return result;
676 }
677
678 /**
679  * gnutls_x509_crt_set_proxy:
680  * @crt: a certificate of type #gnutls_x509_crt_t
681  * @pathLenConstraint: non-negative values indicate maximum length of path,
682  *   and negative values indicate that the pathLenConstraints field should
683  *   not be present.
684  * @policyLanguage: OID describing the language of @policy.
685  * @policy: opaque byte array with policy language, can be %NULL
686  * @sizeof_policy: size of @policy.
687  *
688  * This function will set the proxyCertInfo extension.
689  *
690  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
691  *   negative error value.
692  **/
693 int
694 gnutls_x509_crt_set_proxy (gnutls_x509_crt_t crt,
695                            int pathLenConstraint,
696                            const char *policyLanguage,
697                            const char *policy, size_t sizeof_policy)
698 {
699   int result;
700   gnutls_datum_t der_data;
701
702   if (crt == NULL)
703     {
704       gnutls_assert ();
705       return GNUTLS_E_INVALID_REQUEST;
706     }
707
708   /* generate the extension.
709    */
710   result = _gnutls_x509_ext_gen_proxyCertInfo (pathLenConstraint,
711                                                policyLanguage,
712                                                policy, sizeof_policy,
713                                                &der_data);
714   if (result < 0)
715     {
716       gnutls_assert ();
717       return result;
718     }
719
720   result = _gnutls_x509_crt_set_extension (crt, "1.3.6.1.5.5.7.1.14",
721                                            &der_data, 1);
722
723   _gnutls_free_datum (&der_data);
724
725   if (result < 0)
726     {
727       gnutls_assert ();
728       return result;
729     }
730
731   crt->use_extensions = 1;
732
733   return 0;
734 }
735
736 /**
737  * gnutls_x509_crt_sign2:
738  * @crt: a certificate of type #gnutls_x509_crt_t
739  * @issuer: is the certificate of the certificate issuer
740  * @issuer_key: holds the issuer's private key
741  * @dig: The message digest to use, %GNUTLS_DIG_SHA1 is a safe choice
742  * @flags: must be 0
743  *
744  * This function will sign the certificate with the issuer's private key, and
745  * will copy the issuer's information into the certificate.
746  *
747  * This must be the last step in a certificate generation since all
748  * the previously set parameters are now signed.
749  *
750  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
751  *   negative error value.
752  **/
753 int
754 gnutls_x509_crt_sign2 (gnutls_x509_crt_t crt, gnutls_x509_crt_t issuer,
755                        gnutls_x509_privkey_t issuer_key,
756                        gnutls_digest_algorithm_t dig, unsigned int flags)
757 {
758   int result;
759   gnutls_privkey_t privkey;
760
761   if (crt == NULL || issuer == NULL || issuer_key == NULL)
762     {
763       gnutls_assert ();
764       return GNUTLS_E_INVALID_REQUEST;
765     }
766
767   result = gnutls_privkey_init (&privkey);
768   if (result < 0)
769     {
770       gnutls_assert ();
771       return result;
772     }
773
774   result = gnutls_privkey_import_x509 (privkey, issuer_key, 0);
775   if (result < 0)
776     {
777       gnutls_assert ();
778       goto fail;
779     }
780
781   result = gnutls_x509_crt_privkey_sign (crt, issuer, privkey, dig, flags);
782   if (result < 0)
783     {
784       gnutls_assert ();
785       goto fail;
786     }
787
788   result = 0;
789
790 fail:
791   gnutls_privkey_deinit (privkey);
792
793   return result;
794 }
795
796 /**
797  * gnutls_x509_crt_sign:
798  * @crt: a certificate of type #gnutls_x509_crt_t
799  * @issuer: is the certificate of the certificate issuer
800  * @issuer_key: holds the issuer's private key
801  *
802  * This function is the same a gnutls_x509_crt_sign2() with no flags,
803  * and SHA1 as the hash algorithm.
804  *
805  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
806  *   negative error value.
807  **/
808 int
809 gnutls_x509_crt_sign (gnutls_x509_crt_t crt, gnutls_x509_crt_t issuer,
810                       gnutls_x509_privkey_t issuer_key)
811 {
812   return gnutls_x509_crt_sign2 (crt, issuer, issuer_key, GNUTLS_DIG_SHA1, 0);
813 }
814
815 /**
816  * gnutls_x509_crt_set_activation_time:
817  * @cert: a certificate of type #gnutls_x509_crt_t
818  * @act_time: The actual time
819  *
820  * This function will set the time this Certificate was or will be
821  * activated.
822  *
823  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
824  *   negative error value.
825  **/
826 int
827 gnutls_x509_crt_set_activation_time (gnutls_x509_crt_t cert, time_t act_time)
828 {
829   if (cert == NULL)
830     {
831       gnutls_assert ();
832       return GNUTLS_E_INVALID_REQUEST;
833     }
834
835   return _gnutls_x509_set_time (cert->cert,
836                                 "tbsCertificate.validity.notBefore",
837                                 act_time);
838 }
839
840 /**
841  * gnutls_x509_crt_set_expiration_time:
842  * @cert: a certificate of type #gnutls_x509_crt_t
843  * @exp_time: The actual time
844  *
845  * This function will set the time this Certificate will expire.
846  *
847  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
848  *   negative error value.
849  **/
850 int
851 gnutls_x509_crt_set_expiration_time (gnutls_x509_crt_t cert, time_t exp_time)
852 {
853   if (cert == NULL)
854     {
855       gnutls_assert ();
856       return GNUTLS_E_INVALID_REQUEST;
857     }
858   return _gnutls_x509_set_time (cert->cert,
859                                 "tbsCertificate.validity.notAfter", exp_time);
860 }
861
862 /**
863  * gnutls_x509_crt_set_serial:
864  * @cert: a certificate of type #gnutls_x509_crt_t
865  * @serial: The serial number
866  * @serial_size: Holds the size of the serial field.
867  *
868  * This function will set the X.509 certificate's serial number.
869  * Serial is not always a 32 or 64bit number.  Some CAs use large
870  * serial numbers, thus it may be wise to handle it as something
871  * opaque.
872  *
873  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
874  *   negative error value.
875  **/
876 int
877 gnutls_x509_crt_set_serial (gnutls_x509_crt_t cert, const void *serial,
878                             size_t serial_size)
879 {
880   int ret;
881
882   if (cert == NULL)
883     {
884       gnutls_assert ();
885       return GNUTLS_E_INVALID_REQUEST;
886     }
887
888   ret =
889     asn1_write_value (cert->cert, "tbsCertificate.serialNumber", serial,
890                       serial_size);
891   if (ret != ASN1_SUCCESS)
892     {
893       gnutls_assert ();
894       return _gnutls_asn2err (ret);
895     }
896
897   return 0;
898
899 }
900
901 /* If OPTIONAL fields have not been initialized then
902  * disable them.
903  */
904 static void
905 disable_optional_stuff (gnutls_x509_crt_t cert)
906 {
907
908   asn1_write_value (cert->cert, "tbsCertificate.issuerUniqueID", NULL, 0);
909
910   asn1_write_value (cert->cert, "tbsCertificate.subjectUniqueID", NULL, 0);
911
912   if (cert->use_extensions == 0)
913     {
914       _gnutls_x509_log ("Disabling X.509 extensions.\n");
915       asn1_write_value (cert->cert, "tbsCertificate.extensions", NULL, 0);
916     }
917
918   return;
919 }
920
921 /**
922  * gnutls_x509_crt_set_crl_dist_points:
923  * @crt: a certificate of type #gnutls_x509_crt_t
924  * @type: is one of the gnutls_x509_subject_alt_name_t enumerations
925  * @data_string: The data to be set
926  * @reason_flags: revocation reasons
927  *
928  * This function will set the CRL distribution points certificate extension.
929  *
930  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
931  *   negative error value.
932  **/
933 int
934 gnutls_x509_crt_set_crl_dist_points (gnutls_x509_crt_t crt,
935                                      gnutls_x509_subject_alt_name_t type,
936                                      const void *data_string,
937                                      unsigned int reason_flags)
938 {
939   return gnutls_x509_crt_set_crl_dist_points2 (crt, type, data_string,
940                                                strlen (data_string),
941                                                reason_flags);
942 }
943
944 /**
945  * gnutls_x509_crt_set_crl_dist_points2:
946  * @crt: a certificate of type #gnutls_x509_crt_t
947  * @type: is one of the gnutls_x509_subject_alt_name_t enumerations
948  * @data: The data to be set
949  * @data_size: The data size
950  * @reason_flags: revocation reasons
951  *
952  * This function will set the CRL distribution points certificate extension.
953  *
954  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
955  *   negative error value.
956  *
957  * Since: 2.6.0
958  **/
959 int
960 gnutls_x509_crt_set_crl_dist_points2 (gnutls_x509_crt_t crt,
961                                       gnutls_x509_subject_alt_name_t type,
962                                       const void *data,
963                                       unsigned int data_size,
964                                       unsigned int reason_flags)
965 {
966   int result;
967   gnutls_datum_t der_data = { NULL, 0 };
968   gnutls_datum_t oldname = { NULL, 0 };
969   unsigned int critical;
970
971   if (crt == NULL)
972     {
973       gnutls_assert ();
974       return GNUTLS_E_INVALID_REQUEST;
975     }
976
977   /* Check if the extension already exists.
978    */
979   result =
980     _gnutls_x509_crt_get_extension (crt, "2.5.29.31", 0, &oldname, &critical);
981
982   _gnutls_free_datum (&oldname);
983
984   if (result != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
985     {
986       gnutls_assert ();
987       return GNUTLS_E_INVALID_REQUEST;
988     }
989
990   /* generate the extension.
991    */
992   result =
993     _gnutls_x509_ext_gen_crl_dist_points (type, data, data_size,
994                                           reason_flags, &der_data);
995   if (result < 0)
996     {
997       gnutls_assert ();
998       return result;
999     }
1000
1001   result = _gnutls_x509_crt_set_extension (crt, "2.5.29.31", &der_data, 0);
1002
1003   _gnutls_free_datum (&der_data);
1004
1005   if (result < 0)
1006     {
1007       gnutls_assert ();
1008       return result;
1009     }
1010
1011   crt->use_extensions = 1;
1012
1013   return 0;
1014
1015 }
1016
1017 /**
1018  * gnutls_x509_crt_cpy_crl_dist_points:
1019  * @dst: a certificate of type #gnutls_x509_crt_t
1020  * @src: the certificate where the dist points will be copied from
1021  *
1022  * This function will copy the CRL distribution points certificate
1023  * extension, from the source to the destination certificate.
1024  * This may be useful to copy from a CA certificate to issued ones.
1025  *
1026  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
1027  *   negative error value.
1028  **/
1029 int
1030 gnutls_x509_crt_cpy_crl_dist_points (gnutls_x509_crt_t dst,
1031                                      gnutls_x509_crt_t src)
1032 {
1033   int result;
1034   gnutls_datum_t der_data;
1035   unsigned int critical;
1036
1037   if (dst == NULL || src == NULL)
1038     {
1039       gnutls_assert ();
1040       return GNUTLS_E_INVALID_REQUEST;
1041     }
1042
1043   /* Check if the extension already exists.
1044    */
1045   result =
1046     _gnutls_x509_crt_get_extension (src, "2.5.29.31", 0, &der_data,
1047                                     &critical);
1048   if (result < 0)
1049     {
1050       gnutls_assert ();
1051       return result;
1052     }
1053
1054   result =
1055     _gnutls_x509_crt_set_extension (dst, "2.5.29.31", &der_data, critical);
1056   _gnutls_free_datum (&der_data);
1057
1058   if (result < 0)
1059     {
1060       gnutls_assert ();
1061       return result;
1062     }
1063
1064   dst->use_extensions = 1;
1065
1066   return 0;
1067 }
1068
1069 /**
1070  * gnutls_x509_crt_set_subject_key_id:
1071  * @cert: a certificate of type #gnutls_x509_crt_t
1072  * @id: The key ID
1073  * @id_size: Holds the size of the serial field.
1074  *
1075  * This function will set the X.509 certificate's subject key ID
1076  * extension.
1077  *
1078  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
1079  *   negative error value.
1080  **/
1081 int
1082 gnutls_x509_crt_set_subject_key_id (gnutls_x509_crt_t cert,
1083                                     const void *id, size_t id_size)
1084 {
1085   int result;
1086   gnutls_datum_t old_id, der_data;
1087   unsigned int critical;
1088
1089   if (cert == NULL)
1090     {
1091       gnutls_assert ();
1092       return GNUTLS_E_INVALID_REQUEST;
1093     }
1094
1095   /* Check if the extension already exists.
1096    */
1097   result =
1098     _gnutls_x509_crt_get_extension (cert, "2.5.29.14", 0, &old_id, &critical);
1099
1100   if (result >= 0)
1101     _gnutls_free_datum (&old_id);
1102   if (result != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
1103     {
1104       gnutls_assert ();
1105       return GNUTLS_E_INVALID_REQUEST;
1106     }
1107
1108   /* generate the extension.
1109    */
1110   result = _gnutls_x509_ext_gen_key_id (id, id_size, &der_data);
1111   if (result < 0)
1112     {
1113       gnutls_assert ();
1114       return result;
1115     }
1116
1117   result = _gnutls_x509_crt_set_extension (cert, "2.5.29.14", &der_data, 0);
1118
1119   _gnutls_free_datum (&der_data);
1120
1121   if (result < 0)
1122     {
1123       gnutls_assert ();
1124       return result;
1125     }
1126
1127   cert->use_extensions = 1;
1128
1129   return 0;
1130 }
1131
1132 /**
1133  * gnutls_x509_crt_set_authority_key_id:
1134  * @cert: a certificate of type #gnutls_x509_crt_t
1135  * @id: The key ID
1136  * @id_size: Holds the size of the serial field.
1137  *
1138  * This function will set the X.509 certificate's authority key ID extension.
1139  * Only the keyIdentifier field can be set with this function.
1140  *
1141  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
1142  *   negative error value.
1143  **/
1144 int
1145 gnutls_x509_crt_set_authority_key_id (gnutls_x509_crt_t cert,
1146                                       const void *id, size_t id_size)
1147 {
1148   int result;
1149   gnutls_datum_t old_id, der_data;
1150   unsigned int critical;
1151
1152   if (cert == NULL)
1153     {
1154       gnutls_assert ();
1155       return GNUTLS_E_INVALID_REQUEST;
1156     }
1157
1158   /* Check if the extension already exists.
1159    */
1160   result =
1161     _gnutls_x509_crt_get_extension (cert, "2.5.29.35", 0, &old_id, &critical);
1162
1163   if (result >= 0)
1164     _gnutls_free_datum (&old_id);
1165   if (result != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
1166     {
1167       gnutls_assert ();
1168       return GNUTLS_E_INVALID_REQUEST;
1169     }
1170
1171   /* generate the extension.
1172    */
1173   result = _gnutls_x509_ext_gen_auth_key_id (id, id_size, &der_data);
1174   if (result < 0)
1175     {
1176       gnutls_assert ();
1177       return result;
1178     }
1179
1180   result = _gnutls_x509_crt_set_extension (cert, "2.5.29.35", &der_data, 0);
1181
1182   _gnutls_free_datum (&der_data);
1183
1184   if (result < 0)
1185     {
1186       gnutls_assert ();
1187       return result;
1188     }
1189
1190   cert->use_extensions = 1;
1191
1192   return 0;
1193 }
1194
1195 /**
1196  * gnutls_x509_crt_set_key_purpose_oid:
1197  * @cert: a certificate of type #gnutls_x509_crt_t
1198  * @oid: a pointer to a null terminated string that holds the OID
1199  * @critical: Whether this extension will be critical or not
1200  *
1201  * This function will set the key purpose OIDs of the Certificate.
1202  * These are stored in the Extended Key Usage extension (2.5.29.37)
1203  * See the GNUTLS_KP_* definitions for human readable names.
1204  *
1205  * Subsequent calls to this function will append OIDs to the OID list.
1206  *
1207  * Returns: On success, %GNUTLS_E_SUCCESS (zero) is returned,
1208  *   otherwise an error code is returned.
1209  **/
1210 int
1211 gnutls_x509_crt_set_key_purpose_oid (gnutls_x509_crt_t cert,
1212                                      const void *oid, unsigned int critical)
1213 {
1214   int result;
1215   gnutls_datum_t old_id, der_data;
1216   ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
1217
1218   if (cert == NULL)
1219     {
1220       gnutls_assert ();
1221       return GNUTLS_E_INVALID_REQUEST;
1222     }
1223
1224   result = asn1_create_element
1225     (_gnutls_get_pkix (), "PKIX1.ExtKeyUsageSyntax", &c2);
1226   if (result != ASN1_SUCCESS)
1227     {
1228       gnutls_assert ();
1229       return _gnutls_asn2err (result);
1230     }
1231
1232   /* Check if the extension already exists.
1233    */
1234   result =
1235     _gnutls_x509_crt_get_extension (cert, "2.5.29.37", 0, &old_id, NULL);
1236
1237   if (result >= 0)
1238     {
1239       /* decode it.
1240        */
1241       result = asn1_der_decoding (&c2, old_id.data, old_id.size, NULL);
1242       _gnutls_free_datum (&old_id);
1243
1244       if (result != ASN1_SUCCESS)
1245         {
1246           gnutls_assert ();
1247           asn1_delete_structure (&c2);
1248           return _gnutls_asn2err (result);
1249         }
1250
1251     }
1252
1253   /* generate the extension.
1254    */
1255   /* 1. create a new element.
1256    */
1257   result = asn1_write_value (c2, "", "NEW", 1);
1258   if (result != ASN1_SUCCESS)
1259     {
1260       gnutls_assert ();
1261       asn1_delete_structure (&c2);
1262       return _gnutls_asn2err (result);
1263     }
1264
1265   /* 2. Add the OID.
1266    */
1267   result = asn1_write_value (c2, "?LAST", oid, 1);
1268   if (result != ASN1_SUCCESS)
1269     {
1270       gnutls_assert ();
1271       asn1_delete_structure (&c2);
1272       return _gnutls_asn2err (result);
1273     }
1274
1275   result = _gnutls_x509_der_encode (c2, "", &der_data, 0);
1276   asn1_delete_structure (&c2);
1277
1278   if (result != ASN1_SUCCESS)
1279     {
1280       gnutls_assert ();
1281       return _gnutls_asn2err (result);
1282     }
1283
1284   result = _gnutls_x509_crt_set_extension (cert, "2.5.29.37",
1285                                            &der_data, critical);
1286
1287   _gnutls_free_datum (&der_data);
1288
1289   if (result < 0)
1290     {
1291       gnutls_assert ();
1292       return result;
1293     }
1294
1295   cert->use_extensions = 1;
1296
1297   return 0;
1298
1299 }
1300
1301 /**
1302  * gnutls_x509_crt_privkey_sign:
1303  * @crt: a certificate of type #gnutls_x509_crt_t
1304  * @issuer: is the certificate of the certificate issuer
1305  * @issuer_key: holds the issuer's private key
1306  * @dig: The message digest to use, %GNUTLS_DIG_SHA1 is a safe choice
1307  * @flags: must be 0
1308  *
1309  * This function will sign the certificate with the issuer's private key, and
1310  * will copy the issuer's information into the certificate.
1311  *
1312  * This must be the last step in a certificate generation since all
1313  * the previously set parameters are now signed.
1314  *
1315  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
1316  *   negative error value.
1317  **/
1318 int
1319 gnutls_x509_crt_privkey_sign (gnutls_x509_crt_t crt, gnutls_x509_crt_t issuer,
1320                               gnutls_privkey_t issuer_key,
1321                               gnutls_digest_algorithm_t dig,
1322                               unsigned int flags)
1323 {
1324   int result;
1325
1326   if (crt == NULL || issuer == NULL || issuer_key == NULL)
1327     {
1328       gnutls_assert ();
1329       return GNUTLS_E_INVALID_REQUEST;
1330     }
1331
1332   /* disable all the unneeded OPTIONAL fields.
1333    */
1334   disable_optional_stuff (crt);
1335
1336   result = _gnutls_x509_pkix_sign (crt->cert, "tbsCertificate",
1337                                    dig, issuer, issuer_key);
1338   if (result < 0)
1339     {
1340       gnutls_assert ();
1341       return result;
1342     }
1343
1344   return 0;
1345 }
1346
1347
1348 #endif /* ENABLE_PKI */