Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/krb5/src/tests/gssapi/t_pcontok.c
34889 views
1
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
/* tests/gssapi/t_pcontok.c - gss_process_context_token tests */
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
/*
34
* This test program exercises krb5 gss_process_context_token. It first
35
* establishes a context to a named target. Then, if the resulting context
36
* uses RFC 1964, it creates a context deletion token from the acceptor to the
37
* initiator and passes it to the initiator using gss_process_context_token.
38
* If the established context uses RFC 4121, this program feeds a made-up
39
* context token to gss_process_context_token and checks for the expected
40
* error.
41
*/
42
43
#include "k5-int.h"
44
#include "common.h"
45
46
#define SGN_ALG_HMAC_SHA1_DES3_KD 0x04
47
#define SGN_ALG_HMAC_MD5 0x11
48
49
/*
50
* Create a valid RFC 1964 context deletion token using the information in *
51
* lctx. We must do this by hand since we no longer create context deletion
52
* tokens from gss_delete_sec_context.
53
*/
54
static void
55
make_delete_token(gss_krb5_lucid_context_v1_t *lctx, gss_buffer_desc *out)
56
{
57
krb5_error_code ret;
58
krb5_context context;
59
krb5_keyblock seqkb;
60
krb5_key seq;
61
krb5_checksum cksum;
62
krb5_cksumtype cktype;
63
krb5_keyusage ckusage;
64
krb5_crypto_iov iov;
65
krb5_data d;
66
size_t cksize, tlen;
67
unsigned char *token, *ptr, iv[8];
68
gss_krb5_lucid_key_t *lkey = &lctx->rfc1964_kd.ctx_key;
69
int signalg = lctx->rfc1964_kd.sign_alg;
70
71
ret = krb5_init_context(&context);
72
check_k5err(context, "krb5_init_context", ret);
73
74
seqkb.enctype = lkey->type;
75
seqkb.length = lkey->length;
76
seqkb.contents = lkey->data;
77
ret = krb5_k_create_key(context, &seqkb, &seq);
78
check_k5err(context, "krb5_k_create_key", ret);
79
80
if (signalg == SGN_ALG_HMAC_SHA1_DES3_KD) {
81
cktype = CKSUMTYPE_HMAC_SHA1_DES3;
82
cksize = 20;
83
ckusage = 23;
84
} else if (signalg == SGN_ALG_HMAC_MD5) {
85
cktype = CKSUMTYPE_HMAC_MD5_ARCFOUR;
86
cksize = 8;
87
ckusage = 15;
88
} else {
89
abort();
90
}
91
92
tlen = 20 + mech_krb5.length + cksize;
93
token = malloc(tlen);
94
assert(token != NULL);
95
96
/* Create the ASN.1 wrapper (4 + mech_krb5.length bytes). Assume the ASN.1
97
* lengths fit in one byte since deletion tokens are short. */
98
ptr = token;
99
*ptr++ = 0x60;
100
*ptr++ = tlen - 2;
101
*ptr++ = 0x06;
102
*ptr++ = mech_krb5.length;
103
memcpy(ptr, mech_krb5.elements, mech_krb5.length);
104
ptr += mech_krb5.length;
105
106
/* Create the RFC 1964 token header (8 bytes). */
107
*ptr++ = 0x01;
108
*ptr++ = 0x02;
109
store_16_le(signalg, ptr);
110
ptr += 2;
111
*ptr++ = 0xFF;
112
*ptr++ = 0xFF;
113
*ptr++ = 0xFF;
114
*ptr++ = 0xFF;
115
116
/* Create the checksum (cksize bytes at offset 8 from the header). */
117
d = make_data(ptr - 8, 8);
118
ret = krb5_k_make_checksum(context, cktype, seq, ckusage, &d, &cksum);
119
check_k5err(context, "krb5_k_make_checksum", ret);
120
memcpy(ptr + 8, cksum.contents, cksize);
121
122
/* Create the sequence number (8 bytes). */
123
iov.flags = KRB5_CRYPTO_TYPE_DATA;
124
iov.data = make_data(ptr, 8);
125
ptr[4] = ptr[5] = ptr[6] = ptr[7] = lctx->initiate ? 0 : 0xFF;
126
memcpy(iv, ptr + 8, 8);
127
d = make_data(iv, 8);
128
if (signalg == SGN_ALG_HMAC_MD5) {
129
store_32_be(lctx->send_seq, ptr);
130
ret = krb5int_arcfour_gsscrypt(&seq->keyblock, 0, &d, &iov, 1);
131
check_k5err(context, "krb5int_arcfour_gsscrypt(seq)", ret);
132
} else {
133
store_32_le(lctx->send_seq, ptr);
134
ret = krb5_k_encrypt_iov(context, seq, 24, &d, &iov, 1);
135
check_k5err(context, "krb5_k_encrypt_iov(seq)", ret);
136
}
137
138
krb5_free_checksum_contents(context, &cksum);
139
krb5_k_free_key(context, seq);
140
krb5_free_context(context);
141
142
out->length = tlen;
143
out->value = token;
144
}
145
146
int
147
main(int argc, char *argv[])
148
{
149
OM_uint32 minor, major, flags;
150
gss_name_t tname;
151
gss_buffer_desc token, in = GSS_C_EMPTY_BUFFER, out;
152
gss_ctx_id_t ictx, actx;
153
gss_krb5_lucid_context_v1_t *lctx;
154
void *lptr;
155
156
assert(argc == 2);
157
tname = import_name(argv[1]);
158
159
flags = GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG;
160
establish_contexts(&mech_krb5, GSS_C_NO_CREDENTIAL, GSS_C_NO_CREDENTIAL,
161
tname, flags, &ictx, &actx, NULL, NULL, NULL);
162
163
/* Export the acceptor context to a lucid context so we can look inside. */
164
major = gss_krb5_export_lucid_sec_context(&minor, &actx, 1, &lptr);
165
check_gsserr("gss_export_lucid_sec_context", major, minor);
166
lctx = lptr;
167
if (!lctx->protocol) {
168
/* Make an RFC 1964 context deletion token and pass it to
169
* gss_process_context_token. */
170
make_delete_token(lctx, &token);
171
major = gss_process_context_token(&minor, ictx, &token);
172
free(token.value);
173
check_gsserr("gss_process_context_token", major, minor);
174
/* Check for the appropriate major code from gss_wrap. */
175
major = gss_wrap(&minor, ictx, 1, GSS_C_QOP_DEFAULT, &in, NULL, &out);
176
assert(major == GSS_S_NO_CONTEXT);
177
} else {
178
/* RFC 4121 defines no context deletion token, so try passing something
179
* arbitrary and check for the appropriate major code. */
180
token.value = "abcd";
181
token.length = 4;
182
major = gss_process_context_token(&minor, ictx, &token);
183
assert(major == GSS_S_DEFECTIVE_TOKEN);
184
}
185
186
(void)gss_release_name(&minor, &tname);
187
(void)gss_delete_sec_context(&minor, &ictx, NULL);
188
(void)gss_krb5_free_lucid_sec_context(&minor, lptr);
189
return 0;
190
}
191
192