xref: /freebsd/crypto/krb5/src/lib/gssapi/spnego/gssapiP_negoex.h (revision 7f2fe78b9dd5f51c821d771b63d2e096f6fd49e9)
1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /*
3  * Copyright (C) 2011-2018 PADL Software Pty Ltd.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * * Redistributions of source code must retain the above copyright
11  *   notice, this list of conditions and the following disclaimer.
12  *
13  * * Redistributions in binary form must reproduce the above copyright
14  *   notice, this list of conditions and the following disclaimer in
15  *   the documentation and/or other materials provided with the
16  *   distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22  * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
23  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
29  * OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #include "k5-int.h"
33 
34 /*
35  * { iso(1) identified-organization(3) dod(6) internet(1) private(4)
36  *   enterprise(1) microsoft (311) security(2) mechanisms(2) negoex(30) }
37  */
38 #define NEGOEX_OID_LENGTH 10
39 #define NEGOEX_OID "\x2b\x06\x01\x04\x01\x82\x37\x02\x02\x1e"
40 
41 #define MESSAGE_SIGNATURE   0x535458454F47454EULL
42 
43 #define EXTENSION_LENGTH                    12
44 
45 #define EXTENSION_FLAG_CRITICAL             0x80000000
46 
47 #define CHECKSUM_SCHEME_RFC3961             1
48 
49 #define NEGOEX_KEYUSAGE_INITIATOR_CHECKSUM  23
50 #define NEGOEX_KEYUSAGE_ACCEPTOR_CHECKSUM   25
51 
52 #define CHECKSUM_HEADER_LENGTH              20
53 
54 #define GUID_LENGTH                         16
55 
56 typedef uint8_t auth_scheme[GUID_LENGTH];
57 typedef uint8_t conversation_id[GUID_LENGTH];
58 #define GUID_EQ(a, b) (memcmp(a, b, GUID_LENGTH) == 0)
59 
60 #define NEGO_MESSAGE_HEADER_LENGTH          96
61 #define EXCHANGE_MESSAGE_HEADER_LENGTH      64
62 #define VERIFY_MESSAGE_HEADER_LENGTH        80
63 #define ALERT_MESSAGE_HEADER_LENGTH         72
64 #define ALERT_LENGTH                        12
65 #define ALERT_PULSE_LENGTH                  8
66 
67 #define ALERT_TYPE_PULSE                    1
68 #define ALERT_VERIFY_NO_KEY                 1
69 
70 enum message_type {
71     INITIATOR_NEGO = 0,         /* NEGO_MESSAGE */
72     ACCEPTOR_NEGO,              /* NEGO_MESSAGE */
73     INITIATOR_META_DATA,        /* EXCHANGE_MESSAGE */
74     ACCEPTOR_META_DATA,         /* EXCHANGE_MESSAGE */
75     CHALLENGE,                  /* EXCHANGE_MESSAGE */
76     AP_REQUEST,                 /* EXCHANGE_MESSAGE */
77     VERIFY,                     /* VERIFY_MESSAGE */
78     ALERT,                      /* ALERT */
79 };
80 
81 struct nego_message {
82     uint8_t random[32];
83     const uint8_t *schemes;
84     uint16_t nschemes;
85 };
86 
87 struct exchange_message {
88     auth_scheme scheme;
89     gss_buffer_desc token;
90 };
91 
92 struct verify_message {
93     auth_scheme scheme;
94     uint32_t cksum_type;
95     const uint8_t *cksum;
96     size_t cksum_len;
97     size_t offset_in_token;
98 };
99 
100 struct alert_message {
101     auth_scheme scheme;
102     int verify_no_key;
103 };
104 
105 struct negoex_message {
106     uint32_t type;
107     union {
108         struct nego_message n;
109         struct exchange_message e;
110         struct verify_message v;
111         struct alert_message a;
112     } u;
113 };
114 
115 struct negoex_auth_mech {
116     K5_TAILQ_ENTRY(negoex_auth_mech) links;
117     gss_OID oid;
118     auth_scheme scheme;
119     gss_ctx_id_t mech_context;
120     gss_buffer_desc metadata;
121     krb5_keyblock key;
122     krb5_keyblock verify_key;
123     int complete;
124     int sent_checksum;
125     int verified_checksum;
126 };
127 
128 /* negoex_util.c */
129 
130 OM_uint32
131 negoex_parse_token(OM_uint32 *minor, spnego_gss_ctx_id_t ctx,
132                    gss_const_buffer_t token,
133                    struct negoex_message **messages_out, size_t *count_out);
134 
135 
136 struct nego_message *
137 negoex_locate_nego_message(struct negoex_message *messages, size_t nmessages,
138                            enum message_type type);
139 struct exchange_message *
140 negoex_locate_exchange_message(struct negoex_message *messages,
141                                size_t nmessages, enum message_type type);
142 struct verify_message *
143 negoex_locate_verify_message(struct negoex_message *messages,
144                              size_t nmessages);
145 struct alert_message *
146 negoex_locate_alert_message(struct negoex_message *messages, size_t nmessages);
147 
148 void
149 negoex_add_nego_message(spnego_gss_ctx_id_t ctx, enum message_type type,
150                         uint8_t random[32]);
151 void
152 negoex_add_exchange_message(spnego_gss_ctx_id_t ctx, enum message_type type,
153                             const auth_scheme scheme, gss_buffer_t token);
154 void
155 negoex_add_verify_message(spnego_gss_ctx_id_t ctx, const auth_scheme scheme,
156                           uint32_t cksum_type, const uint8_t *cksum,
157                           uint32_t cksum_len);
158 
159 void
160 negoex_add_verify_no_key_alert(spnego_gss_ctx_id_t ctx,
161                                const auth_scheme scheme);
162 
163 OM_uint32
164 negoex_random(OM_uint32 *minor, spnego_gss_ctx_id_t ctx,
165               unsigned char *data, size_t length);
166 
167 void
168 negoex_prep_context_for_spnego(spnego_gss_ctx_id_t ctx);
169 
170 OM_uint32
171 negoex_prep_context_for_negoex(OM_uint32 *minor, spnego_gss_ctx_id_t ctx);
172 
173 void
174 negoex_release_context(spnego_gss_ctx_id_t ctx);
175 
176 OM_uint32
177 negoex_add_auth_mech(OM_uint32 *minor, spnego_gss_ctx_id_t ctx,
178                      gss_const_OID oid, auth_scheme scheme);
179 
180 void
181 negoex_delete_auth_mech(spnego_gss_ctx_id_t ctx,
182                         struct negoex_auth_mech *mech);
183 
184 void
185 negoex_select_auth_mech(spnego_gss_ctx_id_t ctx,
186                         struct negoex_auth_mech *mech);
187 
188 struct negoex_auth_mech *
189 negoex_locate_auth_scheme(spnego_gss_ctx_id_t ctx, const auth_scheme scheme);
190 
191 void
192 negoex_common_auth_schemes(spnego_gss_ctx_id_t ctx,
193                            const uint8_t *schemes, uint16_t nschemes);
194 
195 void
196 negoex_restrict_auth_schemes(spnego_gss_ctx_id_t ctx,
197                              const uint8_t *schemes, uint16_t nschemes);
198 
199 /* negoex_ctx.c */
200 
201 OM_uint32
202 negoex_init(OM_uint32 *minor, spnego_gss_ctx_id_t ctx, gss_cred_id_t cred,
203             gss_name_t target_name, OM_uint32 req_flags, OM_uint32 time_req,
204             gss_buffer_t input_token, gss_channel_bindings_t bindings,
205             gss_buffer_t output_token, OM_uint32 *time_rec);
206 
207 OM_uint32
208 negoex_accept(OM_uint32 *minor, spnego_gss_ctx_id_t ctx, gss_cred_id_t cred,
209               gss_buffer_t input_token, gss_channel_bindings_t bindings,
210               gss_buffer_t output_token, OM_uint32 *time_rec);
211