2 * Copyright (C) 2007, 2010 Free Software Foundation, Inc.
4 * Author: Simon Josefsson
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 /* Implementation of Opaque PRF Input:
26 * http://tools.ietf.org/id/draft-rescorla-tls-opaque-prf-input-00.txt
30 #include <ext_oprfi.h>
32 #include <gnutls_errors.h>
33 #include <gnutls_num.h>
36 oprfi_recv_server (gnutls_session_t session
,
37 const opaque
* data
, size_t _data_size
)
39 ssize_t data_size
= _data_size
;
43 if (!session
->internals
.oprfi_cb
)
49 DECR_LEN (data_size
, 2);
50 len
= _gnutls_read_uint16 (data
);
56 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH
;
59 /* Store incoming data. */
60 session
->security_parameters
.extensions
.oprfi_client_len
= len
;
61 session
->security_parameters
.extensions
.oprfi_client
= gnutls_malloc (len
);
62 if (!session
->security_parameters
.extensions
.oprfi_client
)
65 return GNUTLS_E_MEMORY_ERROR
;
67 memcpy (session
->security_parameters
.extensions
.oprfi_client
, data
, len
);
73 oprfi_recv_client (gnutls_session_t session
,
74 const opaque
* data
, size_t _data_size
)
76 ssize_t data_size
= _data_size
;
80 if (session
->security_parameters
.extensions
.oprfi_client
== NULL
)
86 DECR_LEN (data_size
, 2);
87 len
= _gnutls_read_uint16 (data
);
93 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH
;
96 if (len
!= session
->security_parameters
.extensions
.oprfi_client_len
)
99 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER
;
102 /* Store incoming data. */
103 session
->security_parameters
.extensions
.oprfi_server_len
= len
;
104 session
->security_parameters
.extensions
.oprfi_server
= gnutls_malloc (len
);
105 if (!session
->security_parameters
.extensions
.oprfi_server
)
108 return GNUTLS_E_MEMORY_ERROR
;
110 memcpy (session
->security_parameters
.extensions
.oprfi_server
, data
, len
);
116 _gnutls_oprfi_recv_params (gnutls_session_t session
,
117 const opaque
* data
, size_t data_size
)
119 if (session
->security_parameters
.entity
== GNUTLS_CLIENT
)
120 return oprfi_recv_client (session
, data
, data_size
);
122 return oprfi_recv_server (session
, data
, data_size
);
126 oprfi_send_client (gnutls_session_t session
, opaque
* data
, size_t _data_size
)
129 ssize_t data_size
= _data_size
;
130 int oprf_size
= session
->security_parameters
.extensions
.oprfi_client_len
;
135 DECR_LENGTH_RET (data_size
, 2, GNUTLS_E_SHORT_MEMORY_BUFFER
);
136 _gnutls_write_uint16 (oprf_size
, p
);
139 DECR_LENGTH_RET (data_size
, oprf_size
, GNUTLS_E_SHORT_MEMORY_BUFFER
);
141 memcpy (p
, session
->security_parameters
.extensions
.oprfi_client
, oprf_size
);
143 return 2 + oprf_size
;
147 oprfi_send_server (gnutls_session_t session
, opaque
* data
, size_t _data_size
)
151 ssize_t data_size
= _data_size
;
154 if (!session
->security_parameters
.extensions
.oprfi_client
||
155 !session
->internals
.oprfi_cb
)
158 /* Allocate buffer for outgoing data. */
159 session
->security_parameters
.extensions
.oprfi_server_len
=
160 session
->security_parameters
.extensions
.oprfi_client_len
;
161 session
->security_parameters
.extensions
.oprfi_server
=
162 gnutls_malloc (session
->security_parameters
.extensions
.oprfi_server_len
);
163 if (!session
->security_parameters
.extensions
.oprfi_server
)
166 return GNUTLS_E_MEMORY_ERROR
;
169 /* Get outgoing data. */
170 ret
= session
->internals
.oprfi_cb
171 (session
, session
->internals
.oprfi_userdata
,
172 session
->security_parameters
.extensions
.oprfi_client_len
,
173 session
->security_parameters
.extensions
.oprfi_client
,
174 session
->security_parameters
.extensions
.oprfi_server
);
178 gnutls_free (session
->security_parameters
.extensions
.oprfi_server
);
182 DECR_LENGTH_RET (data_size
, 2, GNUTLS_E_SHORT_MEMORY_BUFFER
);
183 _gnutls_write_uint16 (session
->security_parameters
.
184 extensions
.oprfi_server_len
, p
);
187 DECR_LENGTH_RET (data_size
,
188 session
->security_parameters
.extensions
.oprfi_server_len
,
189 GNUTLS_E_SHORT_MEMORY_BUFFER
);
191 memcpy (p
, session
->security_parameters
.extensions
.oprfi_server
,
192 session
->security_parameters
.extensions
.oprfi_server_len
);
194 return 2 + session
->security_parameters
.extensions
.oprfi_server_len
;
198 _gnutls_oprfi_send_params (gnutls_session_t session
,
199 opaque
* data
, size_t data_size
)
201 if (session
->security_parameters
.entity
== GNUTLS_CLIENT
)
202 return oprfi_send_client (session
, data
, data_size
);
204 return oprfi_send_server (session
, data
, data_size
);
208 * gnutls_oprfi_enable_client:
209 * @session: is a #gnutls_session_t structure.
210 * @len: length of Opaque PRF data to use in client.
211 * @data: Opaque PRF data to use in client.
213 * Request that the client should attempt to negotiate the Opaque PRF
214 * Input TLS extension, using the given data as the client's Opaque
217 * The data is copied into the session context after this call, so you
218 * may de-allocate it immediately after calling this function.
221 gnutls_oprfi_enable_client (gnutls_session_t session
,
222 size_t len
, unsigned char *data
)
224 session
->security_parameters
.extensions
.oprfi_client_len
= len
;
225 session
->security_parameters
.extensions
.oprfi_client
= data
;
229 * gnutls_oprfi_enable_server:
230 * @session: is a #gnutls_session_t structure.
231 * @cb: function pointer to Opaque PRF extension server callback.
232 * @userdata: hook passed to callback function for passing application state.
234 * Request that the server should attempt to accept the Opaque PRF
235 * Input TLS extension. If the client requests the extension, the
236 * provided callback @cb will be invoked. The callback must have the
237 * following prototype:
239 * int callback (gnutls_session_t session, void *userdata,
240 * size_t oprfi_len, const unsigned char *in_oprfi,
241 * unsigned char *out_oprfi);
243 * The callback can inspect the client-provided data in the input
244 * parameters, and specify its own opaque prf input data in the output
245 * variable. The function must return 0 on success, otherwise the
246 * handshake will be aborted.
249 gnutls_oprfi_enable_server (gnutls_session_t session
,
250 gnutls_oprfi_callback_func cb
, void *userdata
)
252 session
->internals
.oprfi_cb
= cb
;
253 session
->internals
.oprfi_userdata
= userdata
;