Added stuff for DSS certificates (not ready yet)
[gnutls.git] / lib / gnutls_sig.c
bloba2502705f6b29dcdf648e22cb36bcf483170f0e0
1 /*
2 * Copyright (C) 2001 Nikos Mavroyanopoulos
4 * This file is part of GNUTLS.
6 * GNUTLS is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * GNUTLS is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
21 #include <gnutls_int.h>
22 #include <gnutls_errors.h>
23 #include <x509_b64.h>
24 #include <auth_x509.h>
25 #include <gnutls_cert.h>
26 #include <x509_asn1.h>
27 #include <x509_der.h>
28 #include <gnutls_datum.h>
29 #include <gnutls_gcry.h>
30 #include <gnutls_privkey.h>
31 #include <gnutls_global.h>
32 #include <gnutls_pk.h>
33 #include <debug.h>
34 #include <gnutls_buffers.h>
35 #include <gnutls_sig.h>
39 /* Generates a signature of all the previous sent packets in the
40 * handshake procedure.
42 int _gnutls_generate_sig_from_hdata( GNUTLS_STATE state, gnutls_cert* cert, gnutls_private_key *pkey, gnutls_datum *signature) {
43 gnutls_datum dconcat;
44 int ret;
45 opaque concat[36];
46 GNUTLS_MAC_HANDLE td_md5;
47 GNUTLS_MAC_HANDLE td_sha;
49 td_md5 = gnutls_hash_copy( state->gnutls_internals.handshake_mac_handle_md5);
50 if (td_md5 == NULL) {
51 gnutls_assert();
52 return GNUTLS_E_HASH_FAILED;
55 td_sha = gnutls_hash_copy( state->gnutls_internals.handshake_mac_handle_sha);
56 if (td_sha == NULL) {
57 gnutls_assert();
58 gnutls_hash_deinit( td_md5, NULL);
59 return GNUTLS_E_HASH_FAILED;
62 gnutls_hash_deinit(td_md5, concat);
63 gnutls_hash_deinit(td_sha, &concat[16]);
65 dconcat.data = concat;
66 dconcat.size = 36;
68 ret = _gnutls_generate_sig( cert, pkey, &dconcat, signature);
69 if (ret < 0)
70 gnutls_assert();
72 return ret;
76 /* Generates a signature of all the random data and the parameters.
77 * Used in DHE_* ciphersuites.
79 int _gnutls_generate_sig_params( GNUTLS_STATE state, gnutls_cert* cert, gnutls_private_key *pkey, gnutls_datum* params, gnutls_datum *signature)
81 gnutls_datum dconcat;
82 int ret;
83 GNUTLS_MAC_HANDLE td_md5;
84 GNUTLS_MAC_HANDLE td_sha;
85 opaque concat[36];
87 td_md5 = gnutls_hash_init( GNUTLS_MAC_MD5);
88 if (td_md5 == NULL) {
89 gnutls_assert();
90 return GNUTLS_E_HASH_FAILED;
93 td_sha = gnutls_hash_init( GNUTLS_MAC_SHA);
94 if (td_sha == NULL) {
95 gnutls_assert();
96 gnutls_hash_deinit( td_md5, NULL);
97 return GNUTLS_E_HASH_FAILED;
100 gnutls_hash( td_md5, state->security_parameters.client_random, TLS_RANDOM_SIZE);
101 gnutls_hash( td_md5, state->security_parameters.server_random, TLS_RANDOM_SIZE);
102 gnutls_hash( td_md5, params->data, params->size);
104 gnutls_hash( td_sha, state->security_parameters.client_random, TLS_RANDOM_SIZE);
105 gnutls_hash( td_sha, state->security_parameters.server_random, TLS_RANDOM_SIZE);
106 gnutls_hash( td_sha, params->data, params->size);
108 gnutls_hash_deinit(td_md5, concat);
109 gnutls_hash_deinit(td_sha, &concat[16]);
111 dconcat.data = concat;
112 dconcat.size = 36;
114 ret = _gnutls_generate_sig( cert, pkey, &dconcat, signature);
115 if (ret < 0)
116 gnutls_assert();
118 return ret;
123 /* This will create a PKCS1 or DSA signature, as defined in the TLS protocol.
124 * Cert is the certificate of the corresponding private key. It is only checked if
125 * it supports signing.
127 int _gnutls_generate_sig( gnutls_cert* cert, gnutls_private_key *pkey, const gnutls_datum* hash_concat, gnutls_datum *signature)
129 int ret;
130 gnutls_datum tmpdata;
132 /* If our certificate supports signing
135 if ( cert != NULL)
136 if ( cert->keyUsage != 0)
137 if ( !(cert->keyUsage & GNUTLS_X509KEY_DIGITAL_SIGNATURE)) {
138 gnutls_assert();
139 return GNUTLS_E_X509_KEY_USAGE_VIOLATION;
142 switch(pkey->pk_algorithm) {
143 case GNUTLS_PK_RSA:
144 tmpdata.data = hash_concat->data;
145 tmpdata.size = hash_concat->size; /* md5 + sha */
147 /* encrypt */
148 if ((ret=_gnutls_pkcs1_rsa_encrypt( signature, tmpdata, pkey->params[0], pkey->params[1], 1)) < 0) {
149 gnutls_assert();
150 return ret;
153 break;
154 case GNUTLS_PK_DSA:
155 /* Ok this is silly. We have calculated
156 * md5 also!
158 tmpdata.data = &hash_concat->data[16];
159 tmpdata.size = 20; /* sha */
161 /* sign */
162 if ((ret=_gnutls_dsa_sign( signature, tmpdata, pkey->params[0], pkey->params[1], pkey->params[2], pkey->params[3])) < 0) {
163 gnutls_assert();
164 return ret;
166 break;
167 default:
168 gnutls_assert();
169 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
170 break;
175 return 0;
180 int _gnutls_pkcs1_rsa_verify_sig( gnutls_cert *cert, const gnutls_datum *hash_concat, gnutls_datum *signature) {
181 int ret;
182 gnutls_datum vdata;
184 if (cert->version == 0 || cert==NULL) { /* this is the only way to check
185 * if it is initialized
187 gnutls_assert();
188 return GNUTLS_E_X509_CERTIFICATE_ERROR;
191 /* If the certificate supports signing continue.
193 if ( cert != NULL)
194 if ( cert->keyUsage != 0)
195 if ( !(cert->keyUsage & GNUTLS_X509KEY_DIGITAL_SIGNATURE)) {
196 gnutls_assert();
197 return GNUTLS_E_X509_KEY_USAGE_VIOLATION;
200 switch(cert->subject_pk_algorithm) {
201 case GNUTLS_PK_RSA:
203 vdata.data = hash_concat->data;
204 vdata.size = hash_concat->size;
206 /* verify signature */
207 if ( (ret=_gnutls_rsa_verify( &vdata, signature, cert->params[1], cert->params[0], 1)) < 0) {
208 gnutls_assert();
209 return ret;
212 break;
213 case GNUTLS_PK_DSA:
215 vdata.data = &hash_concat->data[16];
216 vdata.size = 20; /* sha1 */
218 /* decrypt signature */
219 if ( (ret=_gnutls_dsa_verify( &vdata, *signature, cert->params[0],
220 cert->params[1], cert->params[2], cert->params[3])) < 0) {
221 gnutls_assert();
222 return ret;
225 break;
226 default:
227 gnutls_assert();
228 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
233 return 0;
237 /* Verifies a TLS signature (like the one in the client certificate
238 * verify message). ubuffer_size is a buffer to remove from the hash buffer
239 * in order to avoid hashing the last message.
241 int _gnutls_verify_sig_hdata( GNUTLS_STATE state, gnutls_cert *cert, gnutls_datum* signature, int ubuffer_size) {
242 int ret;
243 opaque concat[36];
244 GNUTLS_MAC_HANDLE td_md5;
245 GNUTLS_MAC_HANDLE td_sha;
246 gnutls_datum dconcat;
248 td_md5 = gnutls_hash_copy( state->gnutls_internals.handshake_mac_handle_md5);
249 if (td_md5 == NULL) {
250 gnutls_assert();
251 return GNUTLS_E_HASH_FAILED;
254 td_sha = gnutls_hash_copy( state->gnutls_internals.handshake_mac_handle_sha);
255 if (td_sha == NULL) {
256 gnutls_assert();
257 gnutls_hash_deinit( td_md5, NULL);
258 return GNUTLS_E_HASH_FAILED;
261 gnutls_hash_deinit(td_md5, concat);
262 gnutls_hash_deinit(td_sha, &concat[16]);
264 dconcat.data = concat;
265 dconcat.size = 20+16; /* md5+ sha */
267 ret = _gnutls_pkcs1_rsa_verify_sig( cert, &dconcat, signature);
268 if (ret < 0) {
269 gnutls_assert();
270 return ret;
273 return ret;
277 /* Generates a signature of all the random data and the parameters.
278 * Used in DHE_* ciphersuites.
280 int _gnutls_verify_sig_params( GNUTLS_STATE state, gnutls_cert *cert, const gnutls_datum* params, gnutls_datum *signature)
282 gnutls_datum dconcat;
283 int ret;
284 GNUTLS_MAC_HANDLE td_md5;
285 GNUTLS_MAC_HANDLE td_sha;
286 opaque concat[36];
288 td_md5 = gnutls_hash_init( GNUTLS_MAC_MD5);
289 if (td_md5 == NULL) {
290 gnutls_assert();
291 return GNUTLS_E_HASH_FAILED;
294 td_sha = gnutls_hash_init( GNUTLS_MAC_SHA);
295 if (td_sha == NULL) {
296 gnutls_assert();
297 gnutls_hash_deinit( td_md5, NULL);
298 return GNUTLS_E_HASH_FAILED;
301 gnutls_hash( td_md5, state->security_parameters.client_random, TLS_RANDOM_SIZE);
302 gnutls_hash( td_md5, state->security_parameters.server_random, TLS_RANDOM_SIZE);
303 gnutls_hash( td_md5, params->data, params->size);
305 gnutls_hash( td_sha, state->security_parameters.client_random, TLS_RANDOM_SIZE);
306 gnutls_hash( td_sha, state->security_parameters.server_random, TLS_RANDOM_SIZE);
307 gnutls_hash( td_sha, params->data, params->size);
309 gnutls_hash_deinit(td_md5, concat);
310 gnutls_hash_deinit(td_sha, &concat[16]);
312 dconcat.data = concat;
313 dconcat.size = 36;
315 ret = _gnutls_pkcs1_rsa_verify_sig( cert, &dconcat, signature);
316 if (ret < 0) {
317 gnutls_assert();
318 return ret;
321 return ret;