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"
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>
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
=
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 */
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) { \
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
;
84 if ( gnutls_protocol_get_version(state
) == GNUTLS_SSL3
) {
86 ciphertext
.data
= data
;
87 ciphertext
.size
= data_size
;
89 ciphertext
.data
= &data
[2];
90 dsize
= READuint16(data
);
92 if (dsize
!= data_size
- 2) {
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
;
102 _gnutls_pkcs1_rsa_decrypt(&plaintext
, ciphertext
, params
, 2); /* btype==2 */
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).
112 _gnutls_log( "RSA_auth: Possible PKCS-1 format attack\n");
114 RANDOMIZE_KEY(state
->gnutls_key
->key
, gnutls_secure_malloc
);
117 if (plaintext
.size
!= TLS_MASTER_SIZE
) { /* WOW */
118 RANDOMIZE_KEY(state
->gnutls_key
->key
, gnutls_secure_malloc
);
120 if (_gnutls_get_adv_version_major( state
) != plaintext
.data
[0]
121 || _gnutls_get_adv_version_minor( state
) != plaintext
.data
[1]) {
123 ret
= GNUTLS_E_DECRYPTION_FAILED
;
126 _gnutls_mpi_release(&state
->gnutls_key
->B
);
127 _gnutls_mpi_release(&state
->gnutls_key
->u
);
128 _gnutls_mpi_release(&state
->gnutls_key
->A
);
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
);
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
];
156 /* this shouldn't have happened. The proc_certificate
157 * function should have detected that.
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
;
172 _gnutls_pkcs1_rsa_encrypt(&sdata
, state
->gnutls_key
->key
, params
, 2)) < 0) {
176 _gnutls_mpi_release(&state
->gnutls_key
->a
);
177 _gnutls_mpi_release(&state
->gnutls_key
->x
);
179 if ( ver
== GNUTLS_SSL3
) {
184 *data
= gnutls_malloc(sdata
.size
+ 2);
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
);