2 * Copyright (C) 2002, 2003, 2004, 2005, 2010 Free Software Foundation,
5 * Author: Nikos Mavrogiannopoulos
7 * This file is part of GnuTLS.
9 * The GnuTLS is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 2.1 of
12 * the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
26 /* This file contains the code the Certificate Type TLS extension.
27 * This extension is currently gnutls specific.
30 #include "gnutls_int.h"
31 #include "gnutls_errors.h"
32 #include "gnutls_num.h"
33 #include "ext_cert_type.h"
34 #include <gnutls_state.h>
35 #include <gnutls_num.h>
37 /* Maps record size to numbers according to the
40 inline static int _gnutls_num2cert_type (int num
);
41 inline static int _gnutls_cert_type2num (int record_size
);
42 static int _gnutls_cert_type_recv_params (gnutls_session_t session
,
45 static int _gnutls_cert_type_send_params (gnutls_session_t session
,
46 gnutls_buffer_st
* extdata
);
48 extension_entry_st ext_mod_cert_type
= {
50 .type
= GNUTLS_EXTENSION_CERT_TYPE
,
51 .parse_type
= GNUTLS_EXT_TLS
,
53 .recv_func
= _gnutls_cert_type_recv_params
,
54 .send_func
= _gnutls_cert_type_send_params
,
61 * In case of a server: if a CERT_TYPE extension type is received then it stores
62 * into the session security parameters the new value. The server may use gnutls_session_certificate_type_get(),
65 * In case of a client: If a cert_types have been specified then we send the extension.
70 _gnutls_cert_type_recv_params (gnutls_session_t session
,
71 const opaque
* data
, size_t _data_size
)
73 int new_type
= -1, ret
, i
;
74 ssize_t data_size
= _data_size
;
76 if (session
->security_parameters
.entity
== GNUTLS_CLIENT
)
83 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH
;
86 new_type
= _gnutls_num2cert_type (data
[0]);
94 /* Check if we support this cert_type */
96 _gnutls_session_cert_type_supported (session
, new_type
)) < 0)
102 _gnutls_session_cert_type_set (session
, new_type
);
106 { /* SERVER SIDE - we must check if the sent cert type is the right one
112 DECR_LEN (data_size
, 1);
114 DECR_LEN (data_size
, len
);
116 for (i
= 0; i
< len
; i
++)
118 new_type
= _gnutls_num2cert_type (data
[i
+ 1]);
123 /* Check if we support this cert_type */
125 _gnutls_session_cert_type_supported (session
,
139 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER
;
143 _gnutls_session_cert_type_supported (session
, new_type
)) < 0)
146 /* The peer has requested unsupported certificate
147 * types. Instead of failing, procceed normally.
148 * (the ciphersuite selection would fail, or a
149 * non certificate ciphersuite will be selected).
154 _gnutls_session_cert_type_set (session
, new_type
);
161 /* returns data_size or a negative number on failure
164 _gnutls_cert_type_send_params (gnutls_session_t session
, gnutls_buffer_st
* extdata
)
170 /* this function sends the client extension data (dnsname) */
171 if (session
->security_parameters
.entity
== GNUTLS_CLIENT
)
174 if (session
->internals
.priorities
.cert_type
.algorithms
> 0)
177 len
= session
->internals
.priorities
.cert_type
.algorithms
;
180 session
->internals
.priorities
.cert_type
.priority
[0] ==
183 /* We don't use this extension if X.509 certificates
192 ret
= _gnutls_buffer_append_data(extdata
, &p
, 1);
194 return gnutls_assert_val(ret
);
196 for (i
= 0; i
< len
; i
++)
199 _gnutls_cert_type2num (session
->internals
.priorities
.
200 cert_type
.priority
[i
]);
201 ret
= _gnutls_buffer_append_data(extdata
, &p
, 1);
203 return gnutls_assert_val(ret
);
211 if (session
->security_parameters
.cert_type
!= DEFAULT_CERT_TYPE
)
216 _gnutls_cert_type2num (session
->security_parameters
.cert_type
);
217 ret
= _gnutls_buffer_append_data(extdata
, &p
, 1);
219 return gnutls_assert_val(ret
);
230 /* Maps numbers to record sizes according to the
234 _gnutls_num2cert_type (int num
)
239 return GNUTLS_CRT_X509
;
241 return GNUTLS_CRT_OPENPGP
;
243 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER
;
247 /* Maps record size to numbers according to the
251 _gnutls_cert_type2num (int cert_type
)
255 case GNUTLS_CRT_X509
:
257 case GNUTLS_CRT_OPENPGP
:
260 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER
;