Tizen 2.0 Release
[external/libgnutls26.git] / lib / x509 / sign.c
1 /*
2  * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2010 Free Software
3  * 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 /* All functions which relate to X.509 certificate signing stuff are
27  * included here
28  */
29
30 #include <gnutls_int.h>
31
32 #ifdef ENABLE_PKI
33
34 #include <gnutls_errors.h>
35 #include <gnutls_cert.h>
36 #include <libtasn1.h>
37 #include <gnutls_global.h>
38 #include <gnutls_num.h>         /* MAX */
39 #include <gnutls_sig.h>
40 #include <gnutls_str.h>
41 #include <gnutls_datum.h>
42 #include <x509_int.h>
43 #include <common.h>
44 #include <gnutls/abstract.h>
45
46 /* This is the same as the _gnutls_x509_sign, but this one will decode
47  * the ASN1_TYPE given, and sign the DER data. Actually used to get the DER
48  * of the TBS and sign it on the fly.
49  */
50 int
51 _gnutls_x509_get_tbs (ASN1_TYPE cert, const char *tbs_name,
52                       gnutls_datum_t * tbs)
53 {
54   int result;
55   opaque *buf;
56   int buf_size;
57
58   buf_size = 0;
59   asn1_der_coding (cert, tbs_name, NULL, &buf_size, NULL);
60
61   buf = gnutls_malloc (buf_size);
62   if (buf == NULL)
63     {
64       gnutls_assert ();
65       return GNUTLS_E_MEMORY_ERROR;
66     }
67
68   result = asn1_der_coding (cert, tbs_name, buf, &buf_size, NULL);
69
70   if (result != ASN1_SUCCESS)
71     {
72       gnutls_assert ();
73       gnutls_free (buf);
74       return _gnutls_asn2err (result);
75     }
76
77   tbs->data = buf;
78   tbs->size = buf_size;
79
80   return 0;
81 }
82
83 /*-
84  * _gnutls_x509_pkix_sign - This function will sign a CRL or a certificate with a key
85  * @src: should contain an ASN1_TYPE
86  * @issuer: is the certificate of the certificate issuer
87  * @issuer_key: holds the issuer's private key
88  *
89  * This function will sign a CRL or a certificate with the issuer's private key, and
90  * will copy the issuer's information into the CRL or certificate.
91  *
92  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
93  *   negative error value.
94  -*/
95 int
96 _gnutls_x509_pkix_sign (ASN1_TYPE src, const char *src_name,
97                         gnutls_digest_algorithm_t dig,
98                         gnutls_x509_crt_t issuer, gnutls_privkey_t issuer_key)
99 {
100   int result;
101   gnutls_datum_t signature;
102   gnutls_datum_t tbs;
103   char name[128];
104
105   /* Step 1. Copy the issuer's name into the certificate.
106    */
107   _gnutls_str_cpy (name, sizeof (name), src_name);
108   _gnutls_str_cat (name, sizeof (name), ".issuer");
109
110   result = asn1_copy_node (src, name, issuer->cert, "tbsCertificate.subject");
111   if (result != ASN1_SUCCESS)
112     {
113       gnutls_assert ();
114       return _gnutls_asn2err (result);
115     }
116
117   /* Step 1.5. Write the signature stuff in the tbsCertificate.
118    */
119   _gnutls_str_cpy (name, sizeof (name), src_name);
120   _gnutls_str_cat (name, sizeof (name), ".signature");
121
122   result = _gnutls_x509_write_sig_params (src, name,
123                                           gnutls_privkey_get_pk_algorithm
124                                           (issuer_key, NULL), dig);
125   if (result < 0)
126     {
127       gnutls_assert ();
128       return result;
129     }
130
131   /* Step 2. Sign the certificate.
132    */
133   result = _gnutls_x509_get_tbs (src, src_name, &tbs);
134
135   if (result < 0)
136     {
137       gnutls_assert ();
138       return result;
139     }
140
141   result = gnutls_privkey_sign_data (issuer_key, dig, 0, &tbs, &signature);
142   gnutls_free (tbs.data);
143
144   if (result < 0)
145     {
146       gnutls_assert ();
147       return result;
148     }
149
150   /* write the signature (bits)
151    */
152   result =
153     asn1_write_value (src, "signature", signature.data, signature.size * 8);
154
155   _gnutls_free_datum (&signature);
156
157   if (result != ASN1_SUCCESS)
158     {
159       gnutls_assert ();
160       return _gnutls_asn2err (result);
161     }
162
163   /* Step 3. Move up and write the AlgorithmIdentifier, which is also
164    * the same. 
165    */
166
167   result = _gnutls_x509_write_sig_params (src, "signatureAlgorithm",
168                                           gnutls_privkey_get_pk_algorithm
169                                           (issuer_key, NULL), dig);
170   if (result < 0)
171     {
172       gnutls_assert ();
173       return result;
174     }
175
176   return 0;
177 }
178
179 #endif