Line data Source code
1 : /* 2 : * Copyright (C) 2017 Red Hat, Inc. 3 : * 4 : * Author: Nikos Mavrogiannopoulos 5 : * 6 : * This file is part of GnuTLS. 7 : * 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 2.1 of 11 : * the License, or (at your option) any later version. 12 : * 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. 17 : * 18 : * You should have received a copy of the GNU Lesser General Public License 19 : * along with this program. If not, see <https://www.gnu.org/licenses/> 20 : * 21 : */ 22 : 23 : #ifndef GNUTLS_LIB_EXTV_H 24 : #define GNUTLS_LIB_EXTV_H 25 : 26 : #include <gnutls/gnutls.h> 27 : #include "str.h" 28 : 29 : /* Iterates through all TLS-type extensions in data, and 30 : * calls the callback function for each of them. The ctx, flags 31 : * and parse_type are passed verbatim to callback. */ 32 : int _gnutls_extv_parse(void *ctx, 33 : gnutls_ext_raw_process_func cb, 34 : const uint8_t * data, int data_size); 35 : 36 : inline static 37 32145 : int _gnutls_extv_append_init(gnutls_buffer_st *buf) 38 : { 39 32145 : unsigned pos; 40 32145 : int ret; 41 : 42 32145 : pos = buf->length; 43 : 44 32145 : ret = _gnutls_buffer_append_prefix(buf, 16, 0); 45 32145 : if (ret < 0) 46 0 : return gnutls_assert_val(ret); 47 : 48 32145 : return pos; 49 : } 50 : 51 : /* its input is the buffer and the return value of _gnutls_extv_append_init() 52 : * @is_hello: should be true for client and server hello messages. 53 : */ 54 : inline static 55 31989 : int _gnutls_extv_append_final(gnutls_buffer_st *buf, unsigned init, unsigned is_hello) 56 : { 57 31989 : unsigned size = buf->length - init - 2; 58 : 59 31989 : if (size > UINT16_MAX) /* sent too many extensions */ 60 0 : return gnutls_assert_val(GNUTLS_E_HANDSHAKE_TOO_LARGE); 61 : 62 31989 : if (size > 0) 63 21575 : _gnutls_write_uint16(size, &buf->data[init]); 64 10414 : else if (is_hello && size == 0) { 65 : /* there is no point to send empty extension bytes, and 66 : * they are known to break certain clients */ 67 465 : buf->length -= 2; 68 : } 69 : 70 : return 0; 71 : } 72 : 73 : typedef int (*extv_append_func)(void *ctx, gnutls_buffer_st *buf); 74 : 75 : int _gnutls_extv_append(gnutls_buffer_st *buf, 76 : uint16_t tls_id, 77 : void *ctx, 78 : extv_append_func cb); 79 : 80 : 81 : #endif /* GNUTLS_LIB_EXTV_H */