2 * Copyright (C) 2002-2012 Free Software Foundation, Inc.
4 * Author: Nikos Mavrogiannopoulos
6 * This file is part of GnuTLS.
8 * The GnuTLS 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 3 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 License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>
23 /* This file contains the code the Certificate Type TLS extension.
24 * This extension is currently gnutls specific.
27 #include "gnutls_int.h"
28 #include "gnutls_errors.h"
29 #include "gnutls_num.h"
30 #include <ext/cert_type.h>
31 #include <gnutls_state.h>
32 #include <gnutls_num.h>
34 /* Maps record size to numbers according to the
37 inline static int _gnutls_num2cert_type (int num
);
38 inline static int _gnutls_cert_type2num (int record_size
);
39 static int _gnutls_cert_type_recv_params (gnutls_session_t session
,
42 static int _gnutls_cert_type_send_params (gnutls_session_t session
,
43 gnutls_buffer_st
* extdata
);
45 extension_entry_st ext_mod_cert_type
= {
47 .type
= GNUTLS_EXTENSION_CERT_TYPE
,
48 .parse_type
= GNUTLS_EXT_TLS
,
50 .recv_func
= _gnutls_cert_type_recv_params
,
51 .send_func
= _gnutls_cert_type_send_params
,
58 * In case of a server: if a CERT_TYPE extension type is received then it stores
59 * into the session security parameters the new value. The server may use gnutls_session_certificate_type_get(),
62 * In case of a client: If a cert_types have been specified then we send the extension.
67 _gnutls_cert_type_recv_params (gnutls_session_t session
,
68 const uint8_t * data
, size_t _data_size
)
70 int new_type
= -1, ret
, i
;
71 ssize_t data_size
= _data_size
;
73 if (session
->security_parameters
.entity
== GNUTLS_CLIENT
)
80 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH
;
83 new_type
= _gnutls_num2cert_type (data
[0]);
91 /* Check if we support this cert_type */
93 _gnutls_session_cert_type_supported (session
, new_type
)) < 0)
99 _gnutls_session_cert_type_set (session
, new_type
);
103 { /* SERVER SIDE - we must check if the sent cert type is the right one
109 DECR_LEN (data_size
, 1);
111 DECR_LEN (data_size
, len
);
113 for (i
= 0; i
< len
; i
++)
115 new_type
= _gnutls_num2cert_type (data
[i
+ 1]);
120 /* Check if we support this cert_type */
122 _gnutls_session_cert_type_supported (session
,
136 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER
;
140 _gnutls_session_cert_type_supported (session
, new_type
)) < 0)
143 /* The peer has requested unsupported certificate
144 * types. Instead of failing, procceed normally.
145 * (the ciphersuite selection would fail, or a
146 * non certificate ciphersuite will be selected).
151 _gnutls_session_cert_type_set (session
, new_type
);
158 /* returns data_size or a negative number on failure
161 _gnutls_cert_type_send_params (gnutls_session_t session
, gnutls_buffer_st
* extdata
)
167 /* this function sends the client extension data (dnsname) */
168 if (session
->security_parameters
.entity
== GNUTLS_CLIENT
)
171 if (session
->internals
.priorities
.cert_type
.algorithms
> 0)
174 len
= session
->internals
.priorities
.cert_type
.algorithms
;
177 session
->internals
.priorities
.cert_type
.priority
[0] ==
180 /* We don't use this extension if X.509 certificates
189 ret
= _gnutls_buffer_append_data(extdata
, &p
, 1);
191 return gnutls_assert_val(ret
);
193 for (i
= 0; i
< len
; i
++)
196 _gnutls_cert_type2num (session
->internals
.priorities
.
197 cert_type
.priority
[i
]);
198 ret
= _gnutls_buffer_append_data(extdata
, &p
, 1);
200 return gnutls_assert_val(ret
);
208 if (session
->security_parameters
.cert_type
!= DEFAULT_CERT_TYPE
)
213 _gnutls_cert_type2num (session
->security_parameters
.cert_type
);
214 ret
= _gnutls_buffer_append_data(extdata
, &p
, 1);
216 return gnutls_assert_val(ret
);
227 /* Maps numbers to record sizes according to the
231 _gnutls_num2cert_type (int num
)
236 return GNUTLS_CRT_X509
;
238 return GNUTLS_CRT_OPENPGP
;
240 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER
;
244 /* Maps record size to numbers according to the
248 _gnutls_cert_type2num (int cert_type
)
252 case GNUTLS_CRT_X509
:
254 case GNUTLS_CRT_OPENPGP
:
257 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER
;