]> git.ipfire.org Git - thirdparty/strongswan.git/blob - src/libcharon/sa/ikev1/authenticators/psk_v1_authenticator.c
diffie-hellman: Add a bool return value to get_my_public_value()
[thirdparty/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 if (!this->dh->get_my_public_value(this->dh, &dh))
78 {
79 return FAILED;
80 }
81 keymat = (keymat_v1_t*)this->ike_sa->get_keymat(this->ike_sa);
82 if (!keymat->get_hash(keymat, this->initiator, dh, this->dh_value,
83 this->ike_sa->get_id(this->ike_sa), this->sa_payload,
84 this->id_payload, &hash))
85 {
86 free(dh.ptr);
87 return FAILED;
88 }
89 free(dh.ptr);
90
91 hash_payload = hash_payload_create(PLV1_HASH);
92 hash_payload->set_hash(hash_payload, hash);
93 message->add_payload(message, &hash_payload->payload_interface);
94 free(hash.ptr);
95
96 return SUCCESS;
97 }
98
99 METHOD(authenticator_t, process, status_t,
100 private_psk_v1_authenticator_t *this, message_t *message)
101 {
102 hash_payload_t *hash_payload;
103 keymat_v1_t *keymat;
104 chunk_t hash, dh;
105 auth_cfg_t *auth;
106
107 hash_payload = (hash_payload_t*)message->get_payload(message, PLV1_HASH);
108 if (!hash_payload)
109 {
110 DBG1(DBG_IKE, "HASH payload missing in message");
111 return FAILED;
112 }
113
114 if (!this->dh->get_my_public_value(this->dh, &dh))
115 {
116 return FAILED;
117 }
118 keymat = (keymat_v1_t*)this->ike_sa->get_keymat(this->ike_sa);
119 if (!keymat->get_hash(keymat, !this->initiator, this->dh_value, dh,
120 this->ike_sa->get_id(this->ike_sa), this->sa_payload,
121 this->id_payload, &hash))
122 {
123 free(dh.ptr);
124 return FAILED;
125 }
126 free(dh.ptr);
127 if (chunk_equals(hash, hash_payload->get_hash(hash_payload)))
128 {
129 free(hash.ptr);
130 if (!this->hybrid)
131 {
132 auth = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE);
133 auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PSK);
134 }
135 return SUCCESS;
136 }
137 free(hash.ptr);
138 DBG1(DBG_IKE, "calculated HASH does not match HASH payload");
139 return FAILED;
140 }
141
142 METHOD(authenticator_t, destroy, void,
143 private_psk_v1_authenticator_t *this)
144 {
145 chunk_free(&this->id_payload);
146 free(this);
147 }
148
149 /*
150 * Described in header.
151 */
152 psk_v1_authenticator_t *psk_v1_authenticator_create(ike_sa_t *ike_sa,
153 bool initiator, diffie_hellman_t *dh,
154 chunk_t dh_value, chunk_t sa_payload,
155 chunk_t id_payload, bool hybrid)
156 {
157 private_psk_v1_authenticator_t *this;
158
159 INIT(this,
160 .public = {
161 .authenticator = {
162 .build = _build,
163 .process = _process,
164 .is_mutual = (void*)return_false,
165 .destroy = _destroy,
166 },
167 },
168 .ike_sa = ike_sa,
169 .initiator = initiator,
170 .dh = dh,
171 .dh_value = dh_value,
172 .sa_payload = sa_payload,
173 .id_payload = id_payload,
174 .hybrid = hybrid,
175 );
176
177 return &this->public;
178 }