2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007 Free Software Foundation
4 * Author: Nikos Mavrogiannopoulos
6 * This file is part of GNUTLS.
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
25 /* This file contains the RSA key exchange part of the certificate
29 #include "gnutls_int.h"
30 #include "gnutls_auth_int.h"
31 #include "gnutls_errors.h"
32 #include "gnutls_dh.h"
33 #include "gnutls_num.h"
35 #include "gnutls_datum.h"
36 #include "auth_cert.h"
37 #include <gnutls_pk.h>
38 #include <gnutls_algorithms.h>
39 #include <gnutls_global.h>
41 #include <gnutls_sig.h>
42 #include <gnutls_x509.h>
43 #include <gnutls_rsa_export.h>
44 #include <gnutls_state.h>
46 int _gnutls_gen_rsa_client_kx (gnutls_session_t
, opaque
**);
47 int _gnutls_proc_rsa_client_kx (gnutls_session_t
, opaque
*, size_t);
48 static int gen_rsa_export_server_kx (gnutls_session_t
, opaque
**);
49 static int proc_rsa_export_server_kx (gnutls_session_t
, opaque
*, size_t);
51 const mod_auth_st rsa_export_auth_struct
= {
53 _gnutls_gen_cert_server_certificate
,
54 _gnutls_gen_cert_client_certificate
,
55 gen_rsa_export_server_kx
,
56 _gnutls_gen_rsa_client_kx
,
57 _gnutls_gen_cert_client_cert_vrfy
, /* gen client cert vrfy */
58 _gnutls_gen_cert_server_cert_req
, /* server cert request */
60 _gnutls_proc_cert_server_certificate
,
61 _gnutls_proc_cert_client_certificate
,
62 proc_rsa_export_server_kx
,
63 _gnutls_proc_rsa_client_kx
, /* proc client kx */
64 _gnutls_proc_cert_client_cert_vrfy
, /* proc client cert vrfy */
65 _gnutls_proc_cert_cert_req
/* proc server cert request */
69 gen_rsa_export_server_kx (gnutls_session_t session
, opaque
** data
)
71 gnutls_rsa_params_t rsa_params
;
72 const mpi_t
*rsa_mpis
;
74 uint8_t *data_e
, *data_m
;
75 int ret
= 0, data_size
;
76 gnutls_cert
*apr_cert_list
;
77 gnutls_privkey
*apr_pkey
;
78 int apr_cert_list_length
;
79 gnutls_datum_t signature
, ddata
;
80 cert_auth_info_t info
;
81 gnutls_certificate_credentials_t cred
;
83 cred
= (gnutls_certificate_credentials_t
)
84 _gnutls_get_cred (session
->key
, GNUTLS_CRD_CERTIFICATE
, NULL
);
88 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
91 /* find the appropriate certificate */
93 _gnutls_get_selected_cert (session
, &apr_cert_list
,
94 &apr_cert_list_length
, &apr_pkey
)) < 0)
100 /* abort sending this message if we have a certificate
101 * of 512 bits or less.
103 if (apr_pkey
&& _gnutls_mpi_get_nbits (apr_pkey
->params
[0]) <= 512)
106 return GNUTLS_E_INT_RET_0
;
110 _gnutls_certificate_get_rsa_params (cred
->rsa_params
, cred
->params_func
,
112 rsa_mpis
= _gnutls_rsa_params_to_mpi (rsa_params
);
113 if (rsa_mpis
== NULL
)
116 return GNUTLS_E_NO_TEMPORARY_RSA_PARAMS
;
119 if ((ret
= _gnutls_auth_info_set (session
, GNUTLS_CRD_CERTIFICATE
,
120 sizeof (cert_auth_info_st
), 0)) < 0)
126 info
= _gnutls_get_auth_info (session
);
127 _gnutls_rsa_export_set_pubkey (session
, rsa_mpis
[1], rsa_mpis
[0]);
129 _gnutls_mpi_print (NULL
, &n_m
, rsa_mpis
[0]);
130 _gnutls_mpi_print (NULL
, &n_e
, rsa_mpis
[1]);
132 (*data
) = gnutls_malloc (n_e
+ n_m
+ 4);
135 return GNUTLS_E_MEMORY_ERROR
;
138 data_m
= &(*data
)[0];
139 _gnutls_mpi_print (&data_m
[2], &n_m
, rsa_mpis
[0]);
141 _gnutls_write_uint16 (n_m
, data_m
);
143 data_e
= &data_m
[2 + n_m
];
144 _gnutls_mpi_print (&data_e
[2], &n_e
, rsa_mpis
[1]);
146 _gnutls_write_uint16 (n_e
, data_e
);
148 data_size
= n_m
+ n_e
+ 4;
151 /* Generate the signature. */
154 ddata
.size
= data_size
;
156 if (apr_cert_list_length
> 0)
159 _gnutls_tls_sign_params (session
, &apr_cert_list
[0],
160 apr_pkey
, &ddata
, &signature
)) < 0)
171 return data_size
; /* do not put a signature - ILLEGAL! */
174 *data
= gnutls_realloc_fast (*data
, data_size
+ signature
.size
+ 2);
177 _gnutls_free_datum (&signature
);
179 return GNUTLS_E_MEMORY_ERROR
;
182 _gnutls_write_datum16 (&((*data
)[data_size
]), signature
);
183 data_size
+= signature
.size
+ 2;
185 _gnutls_free_datum (&signature
);
190 /* if the peer's certificate is of 512 bits or less, returns non zero.
193 _gnutls_peers_cert_less_512 (gnutls_session_t session
)
195 gnutls_cert peer_cert
;
197 cert_auth_info_t info
= _gnutls_get_auth_info (session
);
199 if (info
== NULL
|| info
->ncerts
== 0)
202 /* we need this in order to get peer's certificate */
207 _gnutls_get_auth_info_gcert (&peer_cert
,
208 session
->security_parameters
.cert_type
,
209 info
, CERT_NO_COPY
)) < 0)
215 if (peer_cert
.subject_pk_algorithm
!= GNUTLS_PK_RSA
)
218 _gnutls_gcert_deinit (&peer_cert
);
222 if (_gnutls_mpi_get_nbits (peer_cert
.params
[0]) <= 512)
224 _gnutls_gcert_deinit (&peer_cert
);
228 _gnutls_gcert_deinit (&peer_cert
);
234 proc_rsa_export_server_kx (gnutls_session_t session
,
235 opaque
* data
, size_t _data_size
)
242 gnutls_datum_t vparams
, signature
;
244 ssize_t data_size
= _data_size
;
245 cert_auth_info_t info
;
246 gnutls_cert peer_cert
;
248 info
= _gnutls_get_auth_info (session
);
249 if (info
== NULL
|| info
->ncerts
== 0)
252 /* we need this in order to get peer's certificate */
253 return GNUTLS_E_INTERNAL_ERROR
;
259 DECR_LEN (data_size
, 2);
260 n_m
= _gnutls_read_uint16 (&data
[i
]);
263 DECR_LEN (data_size
, n_m
);
267 DECR_LEN (data_size
, 2);
268 n_e
= _gnutls_read_uint16 (&data
[i
]);
271 DECR_LEN (data_size
, n_e
);
278 if (_gnutls_mpi_scan_nz (&session
->key
->rsa
[0], data_m
, &_n_m
) != 0)
281 return GNUTLS_E_MPI_SCAN_FAILED
;
284 if (_gnutls_mpi_scan_nz (&session
->key
->rsa
[1], data_e
, &_n_e
) != 0)
287 return GNUTLS_E_MPI_SCAN_FAILED
;
290 _gnutls_rsa_export_set_pubkey (session
, session
->key
->rsa
[1],
291 session
->key
->rsa
[0]);
293 /* VERIFY SIGNATURE */
295 vparams
.size
= n_m
+ n_e
+ 4;
298 DECR_LEN (data_size
, 2);
299 sigsize
= _gnutls_read_uint16 (&data
[vparams
.size
]);
301 DECR_LEN (data_size
, sigsize
);
302 signature
.data
= &data
[vparams
.size
+ 2];
303 signature
.size
= sigsize
;
306 _gnutls_get_auth_info_gcert (&peer_cert
,
307 session
->security_parameters
.cert_type
,
308 info
, CERT_NO_COPY
)) < 0)
314 ret
= _gnutls_verify_sig_params (session
, &peer_cert
, &vparams
, &signature
);
316 _gnutls_gcert_deinit (&peer_cert
);