payload: Use common prefixes for all payload type identifiers
[strongswan.git] / src / libcharon / sa / ikev1 / authenticators / psk_v1_authenticator.c
1 /*
2 * Copyright (C) 2011 Martin Willi
3 * Copyright (C) 2011 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 "psk_v1_authenticator.h"
17
18 #include <daemon.h>
19 #include <sa/ikev1/keymat_v1.h>
20 #include <encoding/payloads/hash_payload.h>
21
22 typedef struct private_psk_v1_authenticator_t private_psk_v1_authenticator_t;
23
24 /**
25 * Private data of an psk_v1_authenticator_t object.
26 */
27 struct private_psk_v1_authenticator_t {
28
29 /**
30 * Public authenticator_t interface.
31 */
32 psk_v1_authenticator_t public;
33
34 /**
35 * Assigned IKE_SA
36 */
37 ike_sa_t *ike_sa;
38
39 /**
40 * TRUE if we are initiator
41 */
42 bool initiator;
43
44 /**
45 * DH key exchange
46 */
47 diffie_hellman_t *dh;
48
49 /**
50 * Others DH public value
51 */
52 chunk_t dh_value;
53
54 /**
55 * Encoded SA payload, without fixed header
56 */
57 chunk_t sa_payload;
58
59 /**
60 * Encoded ID payload, without fixed header
61 */
62 chunk_t id_payload;
63
64 /**
65 * Used for Hybrid authentication to build hash without PSK?
66 */
67 bool hybrid;
68 };
69
70 METHOD(authenticator_t, build, status_t,
71 private_psk_v1_authenticator_t *this, message_t *message)
72 {
73 hash_payload_t *hash_payload;
74 keymat_v1_t *keymat;
75 chunk_t hash, dh;
76
77 this->dh->get_my_public_value(this->dh, &dh);
78 keymat = (keymat_v1_t*)this->ike_sa->get_keymat(this->ike_sa);
79 if (!keymat->get_hash(keymat, this->initiator, dh, this->dh_value,
80 this->ike_sa->get_id(this->ike_sa), this->sa_payload,
81 this->id_payload, &hash))
82 {
83 free(dh.ptr);
84 return FAILED;
85 }
86 free(dh.ptr);
87
88 hash_payload = hash_payload_create(PLV1_HASH);
89 hash_payload->set_hash(hash_payload, hash);
90 message->add_payload(message, &hash_payload->payload_interface);
91 free(hash.ptr);
92
93 return SUCCESS;
94 }
95
96 METHOD(authenticator_t, process, status_t,
97 private_psk_v1_authenticator_t *this, message_t *message)
98 {
99 hash_payload_t *hash_payload;
100 keymat_v1_t *keymat;
101 chunk_t hash, dh;
102 auth_cfg_t *auth;
103
104 hash_payload = (hash_payload_t*)message->get_payload(message, PLV1_HASH);
105 if (!hash_payload)
106 {
107 DBG1(DBG_IKE, "HASH payload missing in message");
108 return FAILED;
109 }
110
111 this->dh->get_my_public_value(this->dh, &dh);
112 keymat = (keymat_v1_t*)this->ike_sa->get_keymat(this->ike_sa);
113 if (!keymat->get_hash(keymat, !this->initiator, this->dh_value, dh,
114 this->ike_sa->get_id(this->ike_sa), this->sa_payload,
115 this->id_payload, &hash))
116 {
117 free(dh.ptr);
118 return FAILED;
119 }
120 free(dh.ptr);
121 if (chunk_equals(hash, hash_payload->get_hash(hash_payload)))
122 {
123 free(hash.ptr);
124 if (!this->hybrid)
125 {
126 auth = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE);
127 auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PSK);
128 }
129 return SUCCESS;
130 }
131 free(hash.ptr);
132 DBG1(DBG_IKE, "calculated HASH does not match HASH payload");
133 return FAILED;
134 }
135
136 METHOD(authenticator_t, destroy, void,
137 private_psk_v1_authenticator_t *this)
138 {
139 chunk_free(&this->id_payload);
140 free(this);
141 }
142
143 /*
144 * Described in header.
145 */
146 psk_v1_authenticator_t *psk_v1_authenticator_create(ike_sa_t *ike_sa,
147 bool initiator, diffie_hellman_t *dh,
148 chunk_t dh_value, chunk_t sa_payload,
149 chunk_t id_payload, bool hybrid)
150 {
151 private_psk_v1_authenticator_t *this;
152
153 INIT(this,
154 .public = {
155 .authenticator = {
156 .build = _build,
157 .process = _process,
158 .is_mutual = (void*)return_false,
159 .destroy = _destroy,
160 },
161 },
162 .ike_sa = ike_sa,
163 .initiator = initiator,
164 .dh = dh,
165 .dh_value = dh_value,
166 .sa_payload = sa_payload,
167 .id_payload = id_payload,
168 .hybrid = hybrid,
169 );
170
171 return &this->public;
172 }