Export new ABIs. Doc fixes for new APIs.
[gnutls.git] / lib / ext_cert_type.c
blobb144dd51d80442f60fcc8891171dab82a28eac31
1 /*
2 * Copyright (C) 2002, 2003, 2004, 2005, 2010 Free Software Foundation,
3 * Inc.
5 * Author: Nikos Mavrogiannopoulos
7 * This file is part of GNUTLS.
9 * The GNUTLS library 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,
22 * USA
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 inline static int _gnutls_num2cert_type (int num);
38 inline static int _gnutls_cert_type2num (int record_size);
40 /*
41 * In case of a server: if a CERT_TYPE extension type is received then it stores
42 * into the session security parameters the new value. The server may use gnutls_session_certificate_type_get(),
43 * to access it.
45 * In case of a client: If a cert_types have been specified then we send the extension.
49 int
50 _gnutls_cert_type_recv_params (gnutls_session_t session,
51 const opaque * data, size_t _data_size)
53 int new_type = -1, ret, i;
54 ssize_t data_size = _data_size;
56 if (session->security_parameters.entity == GNUTLS_CLIENT)
58 if (data_size > 0)
60 if (data_size != 1)
62 gnutls_assert ();
63 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
66 new_type = _gnutls_num2cert_type (data[0]);
68 if (new_type < 0)
70 gnutls_assert ();
71 return new_type;
74 /* Check if we support this cert_type */
75 if ((ret =
76 _gnutls_session_cert_type_supported (session, new_type)) < 0)
78 gnutls_assert ();
79 return ret;
82 _gnutls_session_cert_type_set (session, new_type);
85 else
86 { /* SERVER SIDE - we must check if the sent cert type is the right one
88 if (data_size > 1)
90 uint8_t len;
92 DECR_LEN (data_size, 1);
93 len = data[0];
94 DECR_LEN (data_size, len);
96 for (i = 0; i < len; i++)
98 new_type = _gnutls_num2cert_type (data[i + 1]);
100 if (new_type < 0)
101 continue;
103 /* Check if we support this cert_type */
104 if ((ret =
105 _gnutls_session_cert_type_supported (session,
106 new_type)) < 0)
108 gnutls_assert ();
109 continue;
111 else
112 break;
113 /* new_type is ok */
116 if (new_type < 0)
118 gnutls_assert ();
119 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
122 if ((ret =
123 _gnutls_session_cert_type_supported (session, new_type)) < 0)
125 gnutls_assert ();
126 /* The peer has requested unsupported certificate
127 * types. Instead of failing, procceed normally.
128 * (the ciphersuite selection would fail, or a
129 * non certificate ciphersuite will be selected).
131 return 0;
134 _gnutls_session_cert_type_set (session, new_type);
140 return 0;
143 /* returns data_size or a negative number on failure
146 _gnutls_cert_type_send_params (gnutls_session_t session, opaque * data,
147 size_t data_size)
149 unsigned len, i;
151 /* this function sends the client extension data (dnsname) */
152 if (session->security_parameters.entity == GNUTLS_CLIENT)
155 if (session->internals.priorities.cert_type.algorithms > 0)
158 len = session->internals.priorities.cert_type.algorithms;
160 if (len == 1 &&
161 session->internals.priorities.cert_type.priority[0] ==
162 GNUTLS_CRT_X509)
164 /* We don't use this extension if X.509 certificates
165 * are used.
167 return 0;
170 if (data_size < len + 1)
172 gnutls_assert ();
173 return GNUTLS_E_SHORT_MEMORY_BUFFER;
176 /* this is a vector!
178 data[0] = (uint8_t) len;
180 for (i = 0; i < len; i++)
182 data[i + 1] =
183 _gnutls_cert_type2num (session->internals.
184 priorities.cert_type.priority[i]);
186 return len + 1;
190 else
191 { /* server side */
192 if (session->security_parameters.cert_type != DEFAULT_CERT_TYPE)
194 len = 1;
195 if (data_size < len)
197 gnutls_assert ();
198 return GNUTLS_E_SHORT_MEMORY_BUFFER;
201 data[0] =
202 _gnutls_cert_type2num (session->security_parameters.cert_type);
203 return len;
209 return 0;
212 /* Maps numbers to record sizes according to the
213 * extensions draft.
215 inline static int
216 _gnutls_num2cert_type (int num)
218 switch (num)
220 case 0:
221 return GNUTLS_CRT_X509;
222 case 1:
223 return GNUTLS_CRT_OPENPGP;
224 default:
225 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
229 /* Maps record size to numbers according to the
230 * extensions draft.
232 inline static int
233 _gnutls_cert_type2num (int cert_type)
235 switch (cert_type)
237 case GNUTLS_CRT_X509:
238 return 0;
239 case GNUTLS_CRT_OPENPGP:
240 return 1;
241 default:
242 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;