|
|
1.1 misho 1: /*
2: * Copyright (C) 2005-2010 Martin Willi
3: * Copyright (C) 2010 revosec AG
4: * Copyright (C) 2005 Jan Hutter
5: * HSR 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: uint8_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: uint16_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, length 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: }