*** empty log message ***
[gnutls.git] / lib / auth_rsa.c
blob69206aab1f662f3ee34c5cc82ff47f24a08fb3c6
1 /*
2 * Copyright (C) 2000,2001,2002 Nikos Mavroyanopoulos
4 * This file is part of GNUTLS.
6 * The GNUTLS library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library 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 GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 * */
21 #include "gnutls_int.h"
22 #include "gnutls_auth_int.h"
23 #include "gnutls_errors.h"
24 #include "gnutls_dh.h"
25 #include "gnutls_num.h"
26 #include "x509_asn1.h"
27 #include "x509_der.h"
28 #include "gnutls_datum.h"
29 #include "auth_cert.h"
30 #include <gnutls_random.h>
31 #include <gnutls_pk.h>
32 #include <gnutls_algorithms.h>
33 #include <gnutls_global.h>
34 #include <x509_verify.h>
35 #include "debug.h"
36 #include <gnutls_sig.h>
37 #include <gnutls_x509.h>
38 #include <gnutls_extra.h>
40 int gen_rsa_client_kx(GNUTLS_STATE, opaque **);
41 int proc_rsa_client_kx(GNUTLS_STATE, opaque *, int);
44 const MOD_AUTH_STRUCT rsa_auth_struct = {
45 "RSA",
46 _gnutls_gen_cert_server_certificate,
47 _gnutls_gen_cert_client_certificate,
48 NULL, /* gen server kx */
49 NULL, /* gen server kx2 */
50 NULL, /* gen client kx0 */
51 gen_rsa_client_kx,
52 _gnutls_gen_cert_client_cert_vrfy, /* gen client cert vrfy */
53 _gnutls_gen_cert_server_cert_req, /* server cert request */
55 _gnutls_proc_cert_server_certificate,
56 _gnutls_proc_cert_client_certificate,
57 NULL, /* proc server kx */
58 NULL, /* proc server kx2 */
59 NULL, /* proc client kx0 */
60 proc_rsa_client_kx, /* proc client kx */
61 _gnutls_proc_cert_client_cert_vrfy, /* proc client cert vrfy */
62 _gnutls_proc_cert_cert_req /* proc server cert request */
65 /* in auth_dhe.c */
66 extern OPENPGP_CERT2GNUTLS_CERT _E_gnutls_openpgp_cert2gnutls_cert;
68 /* This function reads the RSA parameters from peer's certificate;
70 static int _gnutls_get_public_rsa_params(GNUTLS_STATE state, GNUTLS_MPI params[MAX_PARAMS_SIZE], int* params_len)
72 int ret;
73 CERTIFICATE_AUTH_INFO info = _gnutls_get_auth_info( state);
74 gnutls_cert peer_cert;
75 int i;
76 if (info==NULL || info->ncerts==0) {
77 gnutls_assert();
78 return GNUTLS_E_UNKNOWN_ERROR;
81 switch( state->security_parameters.cert_type) {
82 case GNUTLS_CRT_X509:
83 if ((ret =
84 _gnutls_x509_cert2gnutls_cert( &peer_cert,
85 info->raw_certificate_list[0])) < 0) {
86 gnutls_assert();
87 return ret;
89 break;
91 case GNUTLS_CRT_OPENPGP:
92 if (_E_gnutls_openpgp_cert2gnutls_cert==NULL) {
93 gnutls_assert();
94 return GNUTLS_E_INVALID_REQUEST;
96 if ((ret =
97 _E_gnutls_openpgp_cert2gnutls_cert( &peer_cert,
98 info->raw_certificate_list[0])) < 0) {
99 gnutls_assert();
100 return ret;
102 break;
104 default:
105 gnutls_assert();
106 return GNUTLS_E_INTERNAL_ERROR;
109 if (*params_len < peer_cert.params_size) {
110 gnutls_assert();
111 return GNUTLS_E_INTERNAL_ERROR;
113 *params_len = peer_cert.params_size;
115 for (i=0;i<*params_len;i++) {
116 params[i] = _gnutls_mpi_copy(peer_cert.params[i]);
118 _gnutls_free_cert( peer_cert);
120 return 0;
123 /* This function reads the RSA parameters from the private key
125 static int _gnutls_get_private_rsa_params(GNUTLS_STATE state, GNUTLS_MPI **params, int* params_size)
127 int index;
128 const GNUTLS_CERTIFICATE_CREDENTIALS cred;
130 cred = _gnutls_get_cred(state->gnutls_key, GNUTLS_CRD_CERTIFICATE, NULL);
131 if (cred == NULL) {
132 gnutls_assert();
133 return GNUTLS_E_INSUFICIENT_CRED;
136 if ( (index=state->gnutls_internals.selected_cert_index) < 0) {
137 gnutls_assert();
138 return GNUTLS_E_UNKNOWN_ERROR;
141 *params_size = cred->pkey[index].params_size;
142 *params = cred->pkey[index].params;
144 return 0;
149 #define RANDOMIZE_KEY(x, galloc, rand) x.size=TLS_MASTER_SIZE; x.data=galloc(x.size); \
150 if (x.data==NULL) return GNUTLS_E_MEMORY_ERROR; \
151 if (_gnutls_get_random( x.data, x.size, rand) < 0) { \
152 gnutls_assert(); \
153 return GNUTLS_E_MEMORY_ERROR; \
156 int proc_rsa_client_kx(GNUTLS_STATE state, opaque * data, int data_size)
158 gnutls_sdatum plaintext;
159 gnutls_datum ciphertext;
160 int ret, dsize;
161 GNUTLS_MPI *params;
162 int params_len;
164 if (gnutls_protocol_get_version(state) == GNUTLS_SSL3) {
165 /* SSL 3.0 */
166 ciphertext.data = data;
167 ciphertext.size = data_size;
168 } else { /* TLS 1 */
169 DECR_LEN( data_size, 2);
170 ciphertext.data = &data[2];
171 dsize = _gnutls_read_uint16(data);
173 if (dsize != data_size) {
174 gnutls_assert();
175 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
177 ciphertext.size = dsize;
180 ret = _gnutls_get_private_rsa_params(state, &params, &params_len);
181 if (ret < 0) {
182 gnutls_assert();
183 return ret;
186 ret = _gnutls_pkcs1_rsa_decrypt(&plaintext, ciphertext, params,
187 params_len, 2); /* btype==2 */
189 if (ret < 0 || plaintext.size != TLS_MASTER_SIZE) {
190 /* in case decryption fails then don't inform
191 * the peer. Just use a random key. (in order to avoid
192 * attack against pkcs-1 formating).
194 ret = 0;
195 gnutls_assert();
197 _gnutls_log("RSA_AUTH: Possible PKCS-1 format attack\n");
199 RANDOMIZE_KEY(state->gnutls_key->key,
200 gnutls_secure_malloc, GNUTLS_WEAK_RANDOM);
201 } else {
202 ret = 0;
203 if (state->gnutls_internals.rsa_pms_check==0)
204 if (_gnutls_get_adv_version_major(state) !=
205 plaintext.data[0]
206 || _gnutls_get_adv_version_minor(state) !=
207 plaintext.data[1]) {
208 gnutls_assert();
209 ret = GNUTLS_E_DECRYPTION_FAILED;
212 state->gnutls_key->key.data = plaintext.data;
213 state->gnutls_key->key.size = plaintext.size;
216 return ret;
221 /* return RSA(random) using the peers public key
223 int gen_rsa_client_kx(GNUTLS_STATE state, opaque ** data)
225 CERTIFICATE_AUTH_INFO auth = state->gnutls_key->auth_info;
226 gnutls_datum sdata; /* data to send */
227 GNUTLS_MPI params[MAX_PARAMS_SIZE];
228 int params_len = MAX_PARAMS_SIZE;
229 int ret, i;
230 GNUTLS_Version ver;
232 if (auth == NULL) {
233 /* this shouldn't have happened. The proc_certificate
234 * function should have detected that.
236 gnutls_assert();
237 return GNUTLS_E_INSUFICIENT_CRED;
239 RANDOMIZE_KEY(state->gnutls_key->key, gnutls_secure_malloc, GNUTLS_STRONG_RANDOM);
241 ver = _gnutls_get_adv_version(state);
243 state->gnutls_key->key.data[0] = _gnutls_version_get_major(ver);
244 state->gnutls_key->key.data[1] = _gnutls_version_get_minor(ver);
246 /* move RSA parameters to gnutls_key (state).
248 if ((ret =
249 _gnutls_get_public_rsa_params(state, params, &params_len)) < 0) {
250 gnutls_assert();
251 return ret;
254 if ((ret =
255 _gnutls_pkcs1_rsa_encrypt(&sdata, state->gnutls_key->key,
256 params, params_len, 2)) < 0) {
257 gnutls_assert();
258 return ret;
261 for (i=0;i<params_len;i++)
262 _gnutls_mpi_release( &params[i]);
264 if (gnutls_protocol_get_version( state) == GNUTLS_SSL3) {
265 /* SSL 3.0 */
266 *data = sdata.data;
267 return sdata.size;
268 } else { /* TLS 1 */
269 *data = gnutls_malloc(sdata.size + 2);
270 if (*data == NULL) {
271 gnutls_free_datum(&sdata);
272 return GNUTLS_E_MEMORY_ERROR;
274 _gnutls_write_datum16( *data, sdata);
275 ret = sdata.size + 2;
276 gnutls_free_datum(&sdata);
277 return ret;