blob: d200ed20534e76c2f9bed640165ec4d84408e4ab [file] [log] [blame]
Neels Hofmeyrf06046b2015-10-12 11:57:35 +02001/* Test Osmocom Authentication Protocol */
2/*
3 * (C) 2015 by sysmocom s.f.m.c. GmbH
4 * All Rights Reserved
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Affero General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Affero General Public License for more details.
15 *
16 * You should have received a copy of the GNU Affero General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 *
19 */
20
21#include <osmocom/core/application.h>
22
23#include <openbsc/debug.h>
24
25#include <openbsc/oap.h>
26#include <openbsc/oap_messages.h>
27
28#include <stdio.h>
Harald Welte31760a12016-04-27 15:17:14 +020029#include <string.h>
Neels Hofmeyrf06046b2015-10-12 11:57:35 +020030
Neels Hofmeyr89ef3242015-10-12 11:57:36 +020031static void test_oap_api(void)
Neels Hofmeyrf06046b2015-10-12 11:57:35 +020032{
Neels Hofmeyr89ef3242015-10-12 11:57:36 +020033 printf("Testing OAP API\n - Config parsing\n");
34
35 struct oap_config _config;
36 struct oap_config *config = &_config;
37
38 struct oap_state _state;
39 struct oap_state *state = &_state;
40
41 memset(config, 0, sizeof(*config));
42 memset(state, 0, sizeof(*state));
43
44 OSMO_ASSERT(osmo_hexparse("0102030405060708090a0b0c0d0e0f10", config->secret_k, 16) == 16);
45 OSMO_ASSERT(osmo_hexparse("1112131415161718191a1b1c1d1e1f20", config->secret_opc, 16) == 16);
46
47 /* make sure filling with zeros means uninitialized */
48 OSMO_ASSERT(state->state == OAP_UNINITIALIZED);
49
50 /* invalid client_id and shared secret */
51 config->client_id = 0;
52 config->secret_k_present = 0;
53 config->secret_opc_present = 0;
54 OSMO_ASSERT( oap_init(config, state) == 0 );
55 OSMO_ASSERT(state->state == OAP_DISABLED);
56
57 /* reset state */
58 memset(state, 0, sizeof(*state));
59
60 /* only client_id is invalid */
61 config->client_id = 0;
62 config->secret_k_present = 1;
63 config->secret_opc_present = 1;
64 OSMO_ASSERT( oap_init(config, state) == 0 );
65 OSMO_ASSERT(state->state == OAP_DISABLED);
66
67 memset(state, 0, sizeof(*state));
68
69 /* valid id, but omitted shared_secret (1/2) */
70 config->client_id = 12345;
71 config->secret_k_present = 0;
72 config->secret_opc_present = 1;
73 OSMO_ASSERT( oap_init(config, state) == 0 );
74 OSMO_ASSERT(state->state == OAP_DISABLED);
75
76 memset(state, 0, sizeof(*state));
77
78 /* valid id, but omitted shared_secret (2/2) */
79 config->client_id = 12345;
80 config->secret_k_present = 1;
81 config->secret_opc_present = 0;
82 OSMO_ASSERT( oap_init(config, state) == 0 );
83 OSMO_ASSERT(state->state == OAP_DISABLED);
84
85 memset(state, 0, sizeof(*state));
86
87
88 /* mint configuration */
89 config->client_id = 12345;
90 config->secret_k_present = 1;
91 config->secret_opc_present = 1;
92 /*config->secret_* buffers are still set from the top */
93 OSMO_ASSERT( oap_init(config, state) == 0 );
94 OSMO_ASSERT(state->state == OAP_INITIALIZED);
95
96 printf(" - AUTN failures\n");
97
Harald Welte564c0652016-04-27 18:14:14 +020098 struct osmo_oap_message oap_rx;
99 struct osmo_oap_message oap_tx;
Neels Hofmeyr89ef3242015-10-12 11:57:36 +0200100 struct msgb *msg_rx;
101 struct msgb *msg_tx;
102
103 memset(&oap_rx, 0, sizeof(oap_rx));
104
105 /* Missing challenge data */
106 oap_rx.message_type = OAP_MSGT_CHALLENGE_REQUEST;
107 oap_rx.rand_present = 0;
108 oap_rx.autn_present = 0;
109 msg_rx = oap_encoded(&oap_rx);
110 OSMO_ASSERT(oap_handle(state, msg_rx, &msg_tx) == -2);
111 msgb_free(msg_rx);
112 OSMO_ASSERT(!msg_tx);
113
114 /* AUTN missing */
115 osmo_hexparse("0102030405060708090a0b0c0d0e0f10",
116 oap_rx.rand, 16);
117 oap_rx.rand_present = 1;
118 msg_rx = oap_encoded(&oap_rx);
119 OSMO_ASSERT(oap_handle(state, msg_rx, &msg_tx) == -2);
120 msgb_free(msg_rx);
121 OSMO_ASSERT(!msg_tx);
122
123 /* RAND missing */
124 oap_rx.rand_present = 0;
125 osmo_hexparse("cec4e3848a33000086781158ca40f136",
126 oap_rx.autn, 16);
127 oap_rx.autn_present = 1;
128 msg_rx = oap_encoded(&oap_rx);
129 OSMO_ASSERT(oap_handle(state, msg_rx, &msg_tx) == -2);
130 msgb_free(msg_rx);
131 OSMO_ASSERT(!msg_tx);
132
133 /* wrong autn (by one bit) */
134 osmo_hexparse("0102030405060708090a0b0c0d0e0f10",
135 oap_rx.rand, 16);
136 osmo_hexparse("dec4e3848a33000086781158ca40f136",
137 oap_rx.autn, 16);
138 oap_rx.rand_present = 1;
139 oap_rx.autn_present = 1;
140 msg_rx = oap_encoded(&oap_rx);
141 OSMO_ASSERT(oap_handle(state, msg_rx, &msg_tx) == -2);
142 msgb_free(msg_rx);
143 OSMO_ASSERT(!msg_tx);
144
145 /* all data correct */
146 osmo_hexparse("cec4e3848a33000086781158ca40f136",
147 oap_rx.autn, 16);
148 msg_rx = oap_encoded(&oap_rx);
149
150 /* but refuse to evaluate in uninitialized state */
151 OSMO_ASSERT(state->state == OAP_INITIALIZED);
152
153 state->state = OAP_UNINITIALIZED;
154 OSMO_ASSERT(oap_handle(state, msg_rx, &msg_tx) == -1);
155 OSMO_ASSERT(!msg_tx);
156
157 state->state = OAP_DISABLED;
158 OSMO_ASSERT(oap_handle(state, msg_rx, &msg_tx) == -1);
159 OSMO_ASSERT(!msg_tx);
160
161 state->state = OAP_INITIALIZED;
162
163 /* now everything is correct */
164 printf(" - AUTN success\n");
165 /* a successful return value here indicates correct autn */
166 OSMO_ASSERT(oap_handle(state, msg_rx, &msg_tx) == 0);
167 msgb_free(msg_rx);
168
169 /* Expect the challenge response in msg_tx */
170 OSMO_ASSERT(msg_tx);
Harald Welte5d547a42016-04-27 18:21:16 +0200171 OSMO_ASSERT(osmo_oap_decode(&oap_tx, msg_tx->data, msg_tx->len) == 0);
Neels Hofmeyr89ef3242015-10-12 11:57:36 +0200172 OSMO_ASSERT(oap_tx.message_type == OAP_MSGT_CHALLENGE_RESULT);
173 OSMO_ASSERT(strcmp("e2d05b598c61d9ba",
174 osmo_hexdump_nospc(oap_tx.xres, sizeof(oap_tx.xres)))
175 == 0);
176 OSMO_ASSERT(state->state == OAP_SENT_CHALLENGE_RESULT);
177 msgb_free(msg_tx);
178 msg_tx = 0;
179
180 struct oap_state saved_state = _state;
181
182 printf(" - Registration failure\n");
183
184 memset(&oap_rx, 0, sizeof(oap_rx));
185 oap_rx.message_type = OAP_MSGT_REGISTER_ERROR;
186 oap_rx.cause = GMM_CAUSE_PROTO_ERR_UNSPEC;
187 msg_rx = oap_encoded(&oap_rx);
188
189 /* Receive registration error for the first time. */
190 OSMO_ASSERT(state->registration_failures == 0);
191 OSMO_ASSERT(oap_handle(state, msg_rx, &msg_tx) == 0);
192 OSMO_ASSERT(state->registration_failures == 1);
193 OSMO_ASSERT(msg_tx);
Harald Welte5d547a42016-04-27 18:21:16 +0200194 OSMO_ASSERT(osmo_oap_decode(&oap_tx, msg_tx->data, msg_tx->len) == 0);
Neels Hofmeyr89ef3242015-10-12 11:57:36 +0200195 OSMO_ASSERT(oap_tx.message_type == OAP_MSGT_REGISTER_REQUEST);
196 OSMO_ASSERT(state->state == OAP_REQUESTED_CHALLENGE);
197 msgb_free(msg_tx);
198 msg_tx = 0;
199
200 /* Receive registration error for the Nth time. */
201 state->registration_failures = 999;
202 OSMO_ASSERT(oap_handle(state, msg_rx, &msg_tx) == -11);
203 OSMO_ASSERT(!msg_tx);
204 OSMO_ASSERT(state->state == OAP_INITIALIZED);
205 msgb_free(msg_tx);
206 msg_tx = 0;
207
208 msgb_free(msg_rx);
209
210 printf(" - Registration success\n");
211
212 _state = saved_state;
213 memset(&oap_rx, 0, sizeof(oap_rx));
214 oap_rx.message_type = OAP_MSGT_REGISTER_RESULT;
215 msg_rx = oap_encoded(&oap_rx);
216 OSMO_ASSERT(oap_handle(state, msg_rx, &msg_tx) == 0);
217 OSMO_ASSERT(!msg_tx);
218 OSMO_ASSERT(state->state == OAP_REGISTERED);
219 msgb_free(msg_rx);
Neels Hofmeyrf06046b2015-10-12 11:57:35 +0200220}
221
222static struct log_info_cat gprs_categories[] = {
223 [DGPRS] = {
224 .name = "DGPRS",
225 .description = "GPRS Packet Service",
226 .enabled = 1, .loglevel = LOGL_DEBUG,
227 },
228};
229
230static struct log_info info = {
231 .cat = gprs_categories,
232 .num_cat = ARRAY_SIZE(gprs_categories),
233};
234
235int main(int argc, char **argv)
236{
Neels Hofmeyr4c2d4ab2016-09-16 02:31:17 +0200237 msgb_talloc_ctx_init(NULL, 0);
Neels Hofmeyrf06046b2015-10-12 11:57:35 +0200238 osmo_init_logging(&info);
239
Neels Hofmeyr89ef3242015-10-12 11:57:36 +0200240 test_oap_api();
Neels Hofmeyrf06046b2015-10-12 11:57:35 +0200241 printf("Done\n");
242
243 return 0;
244}
245