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
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_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>
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
= {
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 */
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 */
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
)
73 CERTIFICATE_AUTH_INFO info
= _gnutls_get_auth_info( state
);
74 gnutls_cert peer_cert
;
76 if (info
==NULL
|| info
->ncerts
==0) {
78 return GNUTLS_E_UNKNOWN_ERROR
;
81 switch( state
->security_parameters
.cert_type
) {
84 _gnutls_x509_cert2gnutls_cert( &peer_cert
,
85 info
->raw_certificate_list
[0])) < 0) {
91 case GNUTLS_CRT_OPENPGP
:
92 if (_E_gnutls_openpgp_cert2gnutls_cert
==NULL
) {
94 return GNUTLS_E_INVALID_REQUEST
;
97 _E_gnutls_openpgp_cert2gnutls_cert( &peer_cert
,
98 info
->raw_certificate_list
[0])) < 0) {
106 return GNUTLS_E_INTERNAL_ERROR
;
109 if (*params_len
< peer_cert
.params_size
) {
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
);
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
)
128 const GNUTLS_CERTIFICATE_CREDENTIALS cred
;
130 cred
= _gnutls_get_cred(state
->gnutls_key
, GNUTLS_CRD_CERTIFICATE
, NULL
);
133 return GNUTLS_E_INSUFICIENT_CRED
;
136 if ( (index
=state
->gnutls_internals
.selected_cert_index
) < 0) {
138 return GNUTLS_E_UNKNOWN_ERROR
;
141 *params_size
= cred
->pkey
[index
].params_size
;
142 *params
= cred
->pkey
[index
].params
;
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) { \
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
;
164 if (gnutls_protocol_get_version(state
) == GNUTLS_SSL3
) {
166 ciphertext
.data
= data
;
167 ciphertext
.size
= data_size
;
169 DECR_LEN( data_size
, 2);
170 ciphertext
.data
= &data
[2];
171 dsize
= _gnutls_read_uint16(data
);
173 if (dsize
!= data_size
) {
175 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH
;
177 ciphertext
.size
= dsize
;
180 ret
= _gnutls_get_private_rsa_params(state
, ¶ms
, ¶ms_len
);
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).
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
);
203 if (state
->gnutls_internals
.rsa_pms_check
==0)
204 if (_gnutls_get_adv_version_major(state
) !=
206 || _gnutls_get_adv_version_minor(state
) !=
209 ret
= GNUTLS_E_DECRYPTION_FAILED
;
212 state
->gnutls_key
->key
.data
= plaintext
.data
;
213 state
->gnutls_key
->key
.size
= plaintext
.size
;
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
;
233 /* this shouldn't have happened. The proc_certificate
234 * function should have detected that.
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).
249 _gnutls_get_public_rsa_params(state
, params
, ¶ms_len
)) < 0) {
255 _gnutls_pkcs1_rsa_encrypt(&sdata
, state
->gnutls_key
->key
,
256 params
, params_len
, 2)) < 0) {
261 for (i
=0;i
<params_len
;i
++)
262 _gnutls_mpi_release( ¶ms
[i
]);
264 if (gnutls_protocol_get_version( state
) == GNUTLS_SSL3
) {
269 *data
= gnutls_malloc(sdata
.size
+ 2);
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
);