Fix various API doc issues and typos
[strongswan.git] / src / libpttls / pt_tls.c
1 /*
2 * Copyright (C) 2012 Martin Willi
3 * Copyright (C) 2012 revosec AG
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #include "pt_tls.h"
17
18 #include <utils/debug.h>
19
20 /*
21 * PT-TNC Message format:
22 * 1 2 3
23 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
24 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
25 * | Reserved | Message Type Vendor ID |
26 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
27 * | Message Type |
28 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
29 * | Message Length |
30 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
31 * | Message Identifier |
32 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
33 * | Message Value (e.g. PB-TNC Batch) . . . |
34 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
35 */
36
37 /**
38 * Read a chunk of data from TLS, returning a reader for it
39 */
40 static bio_reader_t* read_tls(tls_socket_t *tls, size_t len)
41 {
42 ssize_t got, total = 0;
43 char *buf;
44
45 buf = malloc(len);
46 while (total < len)
47 {
48 got = tls->read(tls, buf + total, len - total, TRUE);
49 if (got <= 0)
50 {
51 free(buf);
52 return NULL;
53 }
54 total += got;
55 }
56 return bio_reader_create_own(chunk_create(buf, len));
57 }
58
59 /**
60 * Read a PT-TLS message, return header data
61 */
62 bio_reader_t* pt_tls_read(tls_socket_t *tls, u_int32_t *vendor,
63 u_int32_t *type, u_int32_t *identifier)
64 {
65 bio_reader_t *reader;
66 u_int32_t len;
67 u_int8_t reserved;
68
69 reader = read_tls(tls, PT_TLS_HEADER_LEN);
70 if (!reader)
71 {
72 return NULL;
73 }
74 if (!reader->read_uint8(reader, &reserved) ||
75 !reader->read_uint24(reader, vendor) ||
76 !reader->read_uint32(reader, type) ||
77 !reader->read_uint32(reader, &len) ||
78 !reader->read_uint32(reader, identifier))
79 {
80 reader->destroy(reader);
81 return NULL;
82 }
83 reader->destroy(reader);
84
85 if (len < PT_TLS_HEADER_LEN)
86 {
87 DBG1(DBG_TNC, "received short PT-TLS header (%d bytes)", len);
88 return NULL;
89 }
90 return read_tls(tls, len - PT_TLS_HEADER_LEN);
91 }
92
93 /**
94 * Prepend a PT-TLS header to a writer, send data, destroy writer
95 */
96 bool pt_tls_write(tls_socket_t *tls, bio_writer_t *writer,
97 pt_tls_message_type_t type, u_int32_t identifier)
98 {
99 bio_writer_t *header;
100 ssize_t len;
101 chunk_t data;
102
103 data = writer->get_buf(writer);
104 len = PT_TLS_HEADER_LEN + data.len;
105 header = bio_writer_create(len);
106 header->write_uint8(header, 0);
107 header->write_uint24(header, 0);
108 header->write_uint32(header, type);
109 header->write_uint32(header, len);
110 header->write_uint32(header, identifier);
111
112 header->write_data(header, data);
113 writer->destroy(writer);
114
115 data = header->get_buf(header);
116 len = tls->write(tls, data.ptr, data.len);
117 header->destroy(header);
118
119 return len == data.len;
120 }