Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/krb5/src/lib/gssapi/generic/t_seqstate.c
39563 views
1
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
/* lib/gssapi/generic/t_seqstate.c - Test program for sequence number state */
3
/*
4
* Copyright (C) 2014 by the Massachusetts Institute of Technology.
5
* All rights reserved.
6
*
7
* Redistribution and use in source and binary forms, with or without
8
* modification, are permitted provided that the following conditions
9
* are met:
10
*
11
* * Redistributions of source code must retain the above copyright
12
* notice, this list of conditions and the following disclaimer.
13
*
14
* * Redistributions in binary form must reproduce the above copyright
15
* notice, this list of conditions and the following disclaimer in
16
* the documentation and/or other materials provided with the
17
* distribution.
18
*
19
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
24
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
28
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
30
* OF THE POSSIBILITY OF SUCH DAMAGE.
31
*/
32
33
#include "gssapiP_generic.h"
34
35
enum resultcode {
36
NOERR = GSS_S_COMPLETE,
37
GAP = GSS_S_GAP_TOKEN,
38
UNSEQ = GSS_S_UNSEQ_TOKEN,
39
OLD = GSS_S_OLD_TOKEN,
40
REPLAY = GSS_S_DUPLICATE_TOKEN
41
};
42
43
enum replayflag { NO_REPLAY = 0, DO_REPLAY = 1 };
44
enum sequenceflag { NO_SEQUENCE = 0, DO_SEQUENCE = 1 };
45
enum width { NARROW = 0, WIDE = 1, BOTH = 2 };
46
47
struct test {
48
uint64_t initial;
49
enum replayflag do_replay;
50
enum sequenceflag do_sequence;
51
enum width wide_seqnums;
52
size_t nseqs;
53
struct {
54
uint64_t seqnum;
55
enum resultcode result;
56
} seqs[10];
57
} tests[] = {
58
/* No replay or sequence checking. */
59
{
60
10, NO_REPLAY, NO_SEQUENCE, BOTH,
61
4, { { 11, NOERR }, { 10, NOERR }, { 10, NOERR }, { 9, NOERR } }
62
},
63
64
/* Basic sequence checking, no wraparound. */
65
{
66
100, NO_REPLAY, DO_SEQUENCE, BOTH,
67
4, { { 100, NOERR }, { 102, GAP }, { 103, NOERR }, { 101, UNSEQ } }
68
},
69
70
/* Initial gap sequence checking, no wraparound. */
71
{
72
200, NO_REPLAY, DO_SEQUENCE, BOTH,
73
4, { { 201, GAP }, { 202, NOERR }, { 200, UNSEQ }, { 203, NOERR } }
74
},
75
76
/* Sequence checking with wraparound. */
77
{
78
UINT32_MAX - 1, NO_REPLAY, DO_SEQUENCE, NARROW,
79
4, { { UINT32_MAX - 1, NOERR }, { UINT32_MAX, NOERR }, { 0, NOERR },
80
{ 1, NOERR } }
81
},
82
{
83
UINT32_MAX - 1, NO_REPLAY, DO_SEQUENCE, NARROW,
84
4, { { UINT32_MAX - 1, NOERR }, { 0, GAP }, { UINT32_MAX, UNSEQ },
85
{ 1, NOERR } }
86
},
87
{
88
UINT64_MAX - 1, NO_REPLAY, DO_SEQUENCE, WIDE,
89
4, { { UINT64_MAX - 1, NOERR }, { UINT64_MAX, NOERR }, { 0, NOERR },
90
{ 1, NOERR } }
91
},
92
{
93
UINT64_MAX - 1, NO_REPLAY, DO_SEQUENCE, WIDE,
94
4, { { UINT64_MAX - 1, NOERR }, { 0, GAP }, { UINT64_MAX, UNSEQ },
95
{ 1, NOERR } }
96
},
97
98
/* 64-bit sequence checking beyond 32-bit range */
99
{
100
UINT32_MAX - 1, NO_REPLAY, DO_SEQUENCE, WIDE,
101
4, { { UINT32_MAX - 1, NOERR },
102
{ UINT32_MAX, NOERR },
103
{ (uint64_t)UINT32_MAX + 1, NOERR },
104
{ (uint64_t)UINT32_MAX + 2, NOERR } }
105
},
106
{
107
UINT32_MAX - 1, NO_REPLAY, DO_SEQUENCE, WIDE,
108
4, { { UINT32_MAX - 1, NOERR },
109
{ (uint64_t)UINT32_MAX + 1, GAP },
110
{ UINT32_MAX, UNSEQ },
111
{ (uint64_t)UINT32_MAX + 2, NOERR } }
112
},
113
{
114
UINT32_MAX - 1, NO_REPLAY, DO_SEQUENCE, WIDE,
115
3, { { UINT32_MAX - 1, NOERR }, { UINT32_MAX, NOERR }, { 0, GAP } }
116
},
117
118
/* Replay without the replay flag set. */
119
{
120
250, NO_REPLAY, DO_SEQUENCE, BOTH,
121
2, { { 250, NOERR }, { 250, UNSEQ } }
122
},
123
124
/* Basic replay detection with and without sequence checking. */
125
{
126
0, DO_REPLAY, DO_SEQUENCE, BOTH,
127
10, { { 5, GAP }, { 3, UNSEQ }, { 8, GAP }, { 3, REPLAY },
128
{ 0, UNSEQ }, { 0, REPLAY }, { 5, REPLAY }, { 3, REPLAY },
129
{ 8, REPLAY }, { 9, NOERR } }
130
},
131
{
132
0, DO_REPLAY, NO_SEQUENCE, BOTH,
133
10, { { 5, NOERR }, { 3, NOERR }, { 8, NOERR }, { 3, REPLAY },
134
{ 0, NOERR }, { 0, REPLAY }, { 5, REPLAY }, { 3, REPLAY },
135
{ 8, REPLAY }, { 9, NOERR } }
136
},
137
138
/* Replay and sequence detection with wraparound. The last seqnum produces
139
* GAP because it is before the initial sequence number. */
140
{
141
UINT64_MAX - 5, DO_REPLAY, DO_SEQUENCE, WIDE,
142
10, { { UINT64_MAX, GAP }, { UINT64_MAX - 2, UNSEQ }, { 0, NOERR },
143
{ UINT64_MAX, REPLAY }, { UINT64_MAX, REPLAY },
144
{ 2, GAP }, { 0, REPLAY }, { 1, UNSEQ },
145
{ UINT64_MAX - 2, REPLAY }, { UINT64_MAX - 6, GAP } }
146
},
147
{
148
UINT32_MAX - 5, DO_REPLAY, DO_SEQUENCE, NARROW,
149
10, { { UINT32_MAX, GAP }, { UINT32_MAX - 2, UNSEQ }, { 0, NOERR },
150
{ UINT32_MAX, REPLAY }, { UINT32_MAX, REPLAY },
151
{ 2, GAP }, { 0, REPLAY }, { 1, UNSEQ },
152
{ UINT32_MAX - 2, REPLAY }, { UINT32_MAX - 6, GAP } }
153
},
154
155
/* Old token edge cases. The current code can detect replays up to 64
156
* numbers behind the expected sequence number (1164 in this case). */
157
{
158
1000, DO_REPLAY, NO_SEQUENCE, BOTH,
159
10, { { 1163, NOERR }, { 1100, NOERR }, { 1100, REPLAY },
160
{ 1163, REPLAY }, { 1099, OLD }, { 1100, REPLAY },
161
{ 1150, NOERR }, { 1150, REPLAY }, { 1000, OLD },
162
{ 999, NOERR } }
163
},
164
};
165
166
int
167
main(void)
168
{
169
size_t i, j;
170
enum width w;
171
struct test *t;
172
g_seqnum_state seqstate;
173
OM_uint32 status;
174
175
for (i = 0; i < sizeof(tests) / sizeof(*tests); i++) {
176
t = &tests[i];
177
/* Try both widths if t->wide_seqnums is both, otherwise just one. */
178
for (w = NARROW; w <= WIDE; w++) {
179
if (t->wide_seqnums != BOTH && t->wide_seqnums != w)
180
continue;
181
if (g_seqstate_init(&seqstate, t->initial, t->do_replay,
182
t->do_sequence, w))
183
abort();
184
for (j = 0; j < t->nseqs; j++) {
185
status = g_seqstate_check(seqstate, t->seqs[j].seqnum);
186
if (status != t->seqs[j].result) {
187
fprintf(stderr, "Test %d seq %d failed: %d != %d\n",
188
(int)i, (int)j, status, t->seqs[j].result);
189
return 1;
190
}
191
}
192
g_seqstate_free(seqstate);
193
}
194
}
195
196
return 0;
197
}
198
199