payload: Use common prefixes for all payload type identifiers
[strongswan.git] / src / libcharon / encoding / payloads / nonce_payload.c
1 /*
2 * Copyright (C) 2005-2010 Martin Willi
3 * Copyright (C) 2010 revosec AG
4 * Copyright (C) 2005 Jan Hutter
5 * Hochschule fuer Technik Rapperswil
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 * for more details.
16 */
17
18 #include <stddef.h>
19
20 #include "nonce_payload.h"
21
22 #include <daemon.h>
23 #include <encoding/payloads/encodings.h>
24
25 typedef struct private_nonce_payload_t private_nonce_payload_t;
26
27 /**
28 * Private data of an nonce_payload_t object.
29 */
30 struct private_nonce_payload_t {
31
32 /**
33 * Public nonce_payload_t interface.
34 */
35 nonce_payload_t public;
36
37 /**
38 * Next payload type.
39 */
40 u_int8_t next_payload;
41
42 /**
43 * Critical flag.
44 */
45 bool critical;
46
47 /**
48 * Reserved bits
49 */
50 bool reserved[7];
51
52 /**
53 * Length of this payload.
54 */
55 u_int16_t payload_length;
56
57 /**
58 * The contained nonce value.
59 */
60 chunk_t nonce;
61
62 /**
63 * Payload type, PLV2_NONCE or PLV1_NONCE
64 */
65 payload_type_t type;
66 };
67
68 /**
69 * Encoding rules to parse or generate a nonce payload
70 *
71 * The defined offsets are the positions in a object of type
72 * private_nonce_payload_t.
73 */
74 static encoding_rule_t encodings[] = {
75 /* 1 Byte next payload type, stored in the field next_payload */
76 { U_INT_8, offsetof(private_nonce_payload_t, next_payload) },
77 /* the critical bit */
78 { FLAG, offsetof(private_nonce_payload_t, critical) },
79 /* 7 Bit reserved bits */
80 { RESERVED_BIT, offsetof(private_nonce_payload_t, reserved[0]) },
81 { RESERVED_BIT, offsetof(private_nonce_payload_t, reserved[1]) },
82 { RESERVED_BIT, offsetof(private_nonce_payload_t, reserved[2]) },
83 { RESERVED_BIT, offsetof(private_nonce_payload_t, reserved[3]) },
84 { RESERVED_BIT, offsetof(private_nonce_payload_t, reserved[4]) },
85 { RESERVED_BIT, offsetof(private_nonce_payload_t, reserved[5]) },
86 { RESERVED_BIT, offsetof(private_nonce_payload_t, reserved[6]) },
87 /* Length of the whole nonce payload*/
88 { PAYLOAD_LENGTH, offsetof(private_nonce_payload_t, payload_length) },
89 /* some nonce bytes, lenth is defined in PAYLOAD_LENGTH */
90 { CHUNK_DATA, offsetof(private_nonce_payload_t, nonce) },
91 };
92
93 /* 1 2 3
94 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
95 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
96 ! Next Payload !C! RESERVED ! Payload Length !
97 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
98 ! !
99 ~ Nonce Data ~
100 ! !
101 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
102 */
103
104 METHOD(payload_t, verify, status_t,
105 private_nonce_payload_t *this)
106 {
107 bool bad_length = FALSE;
108
109 if (this->nonce.len > 256)
110 {
111 bad_length = TRUE;
112 }
113 if (this->type == PLV2_NONCE &&
114 this->nonce.len < 16)
115 {
116 bad_length = TRUE;
117 }
118 if (this->type == PLV1_NONCE &&
119 this->nonce.len < 8)
120 {
121 bad_length = TRUE;
122 }
123 if (bad_length)
124 {
125 DBG1(DBG_ENC, "%N payload has invalid length (%d bytes)",
126 payload_type_names, this->type, this->nonce.len);
127 return FAILED;
128 }
129 return SUCCESS;
130 }
131
132 METHOD(payload_t, get_encoding_rules, int,
133 private_nonce_payload_t *this, encoding_rule_t **rules)
134 {
135 *rules = encodings;
136 return countof(encodings);
137 }
138
139 METHOD(payload_t, get_header_length, int,
140 private_nonce_payload_t *this)
141 {
142 return 4;
143 }
144
145 METHOD(payload_t, get_type, payload_type_t,
146 private_nonce_payload_t *this)
147 {
148 return this->type;
149 }
150
151 METHOD(payload_t, get_next_type, payload_type_t,
152 private_nonce_payload_t *this)
153 {
154 return this->next_payload;
155 }
156
157 METHOD(payload_t, set_next_type, void,
158 private_nonce_payload_t *this, payload_type_t type)
159 {
160 this->next_payload = type;
161 }
162
163 METHOD(payload_t, get_length, size_t,
164 private_nonce_payload_t *this)
165 {
166 return this->payload_length;
167 }
168
169 METHOD(nonce_payload_t, set_nonce, void,
170 private_nonce_payload_t *this, chunk_t nonce)
171 {
172 this->nonce = chunk_clone(nonce);
173 this->payload_length = get_header_length(this) + nonce.len;
174 }
175
176 METHOD(nonce_payload_t, get_nonce, chunk_t,
177 private_nonce_payload_t *this)
178 {
179 return chunk_clone(this->nonce);
180 }
181
182 METHOD2(payload_t, nonce_payload_t, destroy, void,
183 private_nonce_payload_t *this)
184 {
185 free(this->nonce.ptr);
186 free(this);
187 }
188
189 /*
190 * Described in header
191 */
192 nonce_payload_t *nonce_payload_create(payload_type_t type)
193 {
194 private_nonce_payload_t *this;
195
196 INIT(this,
197 .public = {
198 .payload_interface = {
199 .verify = _verify,
200 .get_encoding_rules = _get_encoding_rules,
201 .get_header_length = _get_header_length,
202 .get_length = _get_length,
203 .get_next_type = _get_next_type,
204 .set_next_type = _set_next_type,
205 .get_type = _get_type,
206 .destroy = _destroy,
207 },
208 .set_nonce = _set_nonce,
209 .get_nonce = _get_nonce,
210 .destroy = _destroy,
211 },
212 .next_payload = PL_NONE,
213 .payload_length = get_header_length(this),
214 .type = type,
215 );
216 return &this->public;
217 }