added support for DSS certificates.
[gnutls.git] / lib / auth_rsa.c
blob8ac3e5064c311110ab2820144d42df3ee60edda6
1 /*
2 * Copyright (C) 2000,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_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_x509.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>
39 int gen_rsa_client_kx(GNUTLS_STATE, opaque **);
40 int proc_rsa_client_kx(GNUTLS_STATE, opaque *, int);
43 MOD_AUTH_STRUCT rsa_auth_struct =
45 "RSA",
46 _gnutls_gen_x509_server_certificate,
47 _gnutls_gen_x509_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_x509_client_cert_vrfy, /* gen client cert vrfy */
53 _gnutls_gen_x509_server_cert_req, /* server cert request */
55 _gnutls_proc_x509_server_certificate,
56 _gnutls_proc_x509_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_x509_client_cert_vrfy, /* proc client cert vrfy */
62 _gnutls_proc_x509_cert_req /* proc server cert request */
70 #define RANDOMIZE_KEY(x, galloc) x.size=TLS_MASTER_SIZE; x.data=galloc(x.size); \
71 if (x.data==NULL) return GNUTLS_E_MEMORY_ERROR; \
72 if (_gnutls_get_random( x.data, x.size, GNUTLS_WEAK_RANDOM) < 0) { \
73 gnutls_assert(); \
74 return GNUTLS_E_MEMORY_ERROR; \
77 int proc_rsa_client_kx(GNUTLS_STATE state, opaque * data, int data_size)
79 gnutls_sdatum plaintext;
80 gnutls_datum ciphertext;
81 int ret, dsize;
82 MPI params[2];
84 if ( gnutls_protocol_get_version(state) == GNUTLS_SSL3) {
85 /* SSL 3.0 */
86 ciphertext.data = data;
87 ciphertext.size = data_size;
88 } else { /* TLS 1 */
89 ciphertext.data = &data[2];
90 dsize = READuint16(data);
92 if (dsize != data_size - 2) {
93 gnutls_assert();
94 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
96 ciphertext.size = dsize;
99 params[0] = state->gnutls_key->A;
100 params[1] = state->gnutls_key->u;
101 ret =
102 _gnutls_pkcs1_rsa_decrypt(&plaintext, ciphertext, params, 2); /* btype==2 */
104 if (ret < 0) {
105 /* in case decryption fails then don't inform
106 * the peer. Just use a random key. (in order to avoid
107 * attack against pkcs-1 formating).
110 gnutls_assert();
112 _gnutls_log( "RSA_auth: Possible PKCS-1 format attack\n");
114 RANDOMIZE_KEY(state->gnutls_key->key, gnutls_secure_malloc);
115 } else {
116 ret = 0;
117 if (plaintext.size != TLS_MASTER_SIZE) { /* WOW */
118 RANDOMIZE_KEY(state->gnutls_key->key, gnutls_secure_malloc);
119 } else {
120 if (_gnutls_get_adv_version_major( state) != plaintext.data[0]
121 || _gnutls_get_adv_version_minor( state) != plaintext.data[1]) {
122 gnutls_assert();
123 ret = GNUTLS_E_DECRYPTION_FAILED;
125 if (ret != 0) {
126 _gnutls_mpi_release(&state->gnutls_key->B);
127 _gnutls_mpi_release(&state->gnutls_key->u);
128 _gnutls_mpi_release(&state->gnutls_key->A);
129 gnutls_assert();
130 return ret;
132 state->gnutls_key->key.data = plaintext.data;
133 state->gnutls_key->key.size = plaintext.size;
137 _gnutls_mpi_release(&state->gnutls_key->A);
138 _gnutls_mpi_release(&state->gnutls_key->B);
139 _gnutls_mpi_release(&state->gnutls_key->u);
140 return 0;
145 /* return RSA(random) using the peers public key
147 int gen_rsa_client_kx(GNUTLS_STATE state, opaque ** data)
149 X509PKI_AUTH_INFO auth = state->gnutls_key->auth_info;
150 gnutls_datum sdata; /* data to send */
151 MPI params[RSA_PARAMS];
152 int ret;
153 GNUTLS_Version ver;
155 if (auth == NULL) {
156 /* this shouldn't have happened. The proc_certificate
157 * function should have detected that.
159 gnutls_assert();
160 return GNUTLS_E_INSUFICIENT_CRED;
162 RANDOMIZE_KEY(state->gnutls_key->key, gnutls_secure_malloc);
164 ver = _gnutls_get_adv_version( state);
166 state->gnutls_key->key.data[0] = _gnutls_version_get_major(ver);
167 state->gnutls_key->key.data[1] = _gnutls_version_get_minor(ver);
169 params[0] = state->gnutls_key->a;
170 params[1] = state->gnutls_key->x;
171 if ((ret =
172 _gnutls_pkcs1_rsa_encrypt(&sdata, state->gnutls_key->key, params, 2)) < 0) {
173 gnutls_assert();
174 return ret;
176 _gnutls_mpi_release(&state->gnutls_key->a);
177 _gnutls_mpi_release(&state->gnutls_key->x);
179 if ( ver == GNUTLS_SSL3) {
180 /* SSL 3.0 */
181 *data = sdata.data;
182 return sdata.size;
183 } else { /* TLS 1 */
184 *data = gnutls_malloc(sdata.size + 2);
185 if (*data == NULL) {
186 gnutls_free_datum(&sdata);
187 return GNUTLS_E_MEMORY_ERROR;
189 WRITEuint16(sdata.size, *data);
190 memcpy(&(*data)[2], sdata.data, sdata.size);
191 ret = sdata.size + 2;
192 gnutls_free_datum(&sdata);
193 return ret;