Use the new asn1_read_node_value()
[gnutls.git] / lib / x509 / sign.c
blobcd9d1be0e826f066a5ed040912741ee50650298c
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 /* All functions which relate to X.509 certificate signing stuff are
24 * included here
27 #include <gnutls_int.h>
29 #include <gnutls_errors.h>
30 #include <libtasn1.h>
31 #include <gnutls_global.h>
32 #include <gnutls_num.h> /* MAX */
33 #include <gnutls_sig.h>
34 #include <gnutls_str.h>
35 #include <gnutls_datum.h>
36 #include <x509_int.h>
37 #include <common.h>
38 #include <gnutls/abstract.h>
40 /* This is the same as the _gnutls_x509_sign, but this one will decode
41 * the ASN1_TYPE given, and sign the DER data. Actually used to get the DER
42 * of the TBS and sign it on the fly.
44 int
45 _gnutls_x509_get_tbs (ASN1_TYPE cert, const char *tbs_name,
46 gnutls_datum_t * tbs)
48 int result;
49 uint8_t *buf;
50 int buf_size;
52 buf_size = 0;
53 asn1_der_coding (cert, tbs_name, NULL, &buf_size, NULL);
55 buf = gnutls_malloc (buf_size);
56 if (buf == NULL)
58 gnutls_assert ();
59 return GNUTLS_E_MEMORY_ERROR;
62 result = asn1_der_coding (cert, tbs_name, buf, &buf_size, NULL);
64 if (result != ASN1_SUCCESS)
66 gnutls_assert ();
67 gnutls_free (buf);
68 return _gnutls_asn2err (result);
71 tbs->data = buf;
72 tbs->size = buf_size;
74 return 0;
77 /*-
78 * _gnutls_x509_pkix_sign - This function will sign a CRL or a certificate with a key
79 * @src: should contain an ASN1_TYPE
80 * @issuer: is the certificate of the certificate issuer
81 * @issuer_key: holds the issuer's private key
83 * This function will sign a CRL or a certificate with the issuer's private key, and
84 * will copy the issuer's information into the CRL or certificate.
86 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
87 * negative error value.
88 -*/
89 int
90 _gnutls_x509_pkix_sign (ASN1_TYPE src, const char *src_name,
91 gnutls_digest_algorithm_t dig,
92 gnutls_x509_crt_t issuer, gnutls_privkey_t issuer_key)
94 int result;
95 gnutls_datum_t signature;
96 gnutls_datum_t tbs;
97 char name[128];
99 /* Step 1. Copy the issuer's name into the certificate.
101 _gnutls_str_cpy (name, sizeof (name), src_name);
102 _gnutls_str_cat (name, sizeof (name), ".issuer");
104 result = asn1_copy_node (src, name, issuer->cert, "tbsCertificate.subject");
105 if (result != ASN1_SUCCESS)
107 gnutls_assert ();
108 return _gnutls_asn2err (result);
111 /* Step 1.5. Write the signature stuff in the tbsCertificate.
113 _gnutls_str_cpy (name, sizeof (name), src_name);
114 _gnutls_str_cat (name, sizeof (name), ".signature");
116 result = _gnutls_x509_write_sig_params (src, name,
117 gnutls_privkey_get_pk_algorithm
118 (issuer_key, NULL), dig);
119 if (result < 0)
121 gnutls_assert ();
122 return result;
125 /* Step 2. Sign the certificate.
127 result = _gnutls_x509_get_tbs (src, src_name, &tbs);
129 if (result < 0)
131 gnutls_assert ();
132 return result;
135 result = gnutls_privkey_sign_data (issuer_key, dig, 0, &tbs, &signature);
136 gnutls_free (tbs.data);
138 if (result < 0)
140 gnutls_assert ();
141 return result;
144 /* write the signature (bits)
146 result =
147 asn1_write_value (src, "signature", signature.data, signature.size * 8);
149 _gnutls_free_datum (&signature);
151 if (result != ASN1_SUCCESS)
153 gnutls_assert ();
154 return _gnutls_asn2err (result);
157 /* Step 3. Move up and write the AlgorithmIdentifier, which is also
158 * the same.
161 result = _gnutls_x509_write_sig_params (src, "signatureAlgorithm",
162 gnutls_privkey_get_pk_algorithm
163 (issuer_key, NULL), dig);
164 if (result < 0)
166 gnutls_assert ();
167 return result;
170 return 0;