hdb: export length_hdb_keyset and encode_hdb_keyset symbols
[metze/heimdal/wip.git] / wrap_ex_ntlm.diff
1 Index: lib/gssapi/ntlm/crypto.c
2 ===================================================================
3 --- lib/gssapi/ntlm/crypto.c    (revision 796)
4 +++ lib/gssapi/ntlm/crypto.c    (working copy)
5 @@ -1,6 +1,7 @@
6  /*
7   * Copyright (c) 2006 Kungliga Tekniska Högskolan
8   * (Royal Institute of Technology, Stockholm, Sweden). 
9 + * Copyright (c) 2008 Red Hat Inc.
10   * All rights reserved. 
11   *
12   * Redistribution and use in source and binary forms, with or without 
13 @@ -194,10 +195,12 @@
14  v2_seal_message(const gss_buffer_t in,
15                 unsigned char signkey[16],
16                 uint32_t seq,
17 +               RC4_KEY *signsealkey,
18                 RC4_KEY *sealkey,
19                 gss_buffer_t out)
20  {
21      unsigned char *p;
22 +    unsigned char sealed_sig[16];
23      OM_uint32 ret;
24  
25      if (in->length + 16 < in->length)
26 @@ -207,14 +210,21 @@
27      if (p == NULL)
28         return ENOMEM;
29  
30 -    RC4(sealkey, in->length, in->value, p);
31 -
32 -    ret = v2_sign_message(in, signkey, sealkey, seq, &p[in->length]);
33 +    /* Must encrypt signature after encrypting the data, so don't specify signseal key here */
34 +    ret = v2_sign_message(in, signkey, NULL, seq, &p[in->length]);
35      if (ret) {
36         free(p);
37         return ret;
38      }
39  
40 +    RC4(sealkey, in->length, in->value, p);
41 +
42 +    /* Instead deal with it here */
43 +    if (signsealkey) {
44 +           RC4(sealkey, 16, &p[in->length], sealed_sig);
45 +           memcpy(&p[in->length], sealed_sig, 16);
46 +    }
47 +
48      out->value = p;
49      out->length = in->length + 16;
50  
51 @@ -225,6 +235,7 @@
52  v2_unseal_message(gss_buffer_t in,
53                   unsigned char signkey[16],
54                   uint32_t seq,
55 +                 RC4_KEY *signsealkey,
56                   RC4_KEY *sealkey,
57                   gss_buffer_t out)
58  {
59 @@ -240,7 +251,7 @@
60  
61      RC4(sealkey, out->length, in->value, out->value);
62  
63 -    ret = v2_verify_message(out, signkey, sealkey, seq,
64 +    ret = v2_verify_message(out, signkey, signsealkey, seq,
65                             ((const unsigned char *)in->value) + out->length);
66      if (ret) {
67         OM_uint32 junk;
68 @@ -249,6 +260,103 @@
69      return ret;
70  }
71  
72 +static OM_uint32
73 +v2_seal_message_ex(const gss_buffer_t in_to_sign,
74 +                  const gss_buffer_t in_to_seal,
75 +                  unsigned char signkey[16],
76 +                  uint32_t seq,
77 +                  RC4_KEY *signsealkey,
78 +                  RC4_KEY *sealkey,
79 +                  gss_buffer_t out_signature,
80 +                  gss_buffer_t out_sealed)
81 +{
82 +    unsigned char *p;
83 +    unsigned char sealed_sig[16];
84 +    OM_uint32 ret;
85 +
86 +    out_sealed->value = malloc(in_to_seal->length);
87 +    if (out_sealed->value == NULL)
88 +       return ENOMEM;
89 +
90 +    out_signature->value = malloc(16);
91 +    if (out_signature->value == NULL) {
92 +       free(out_sealed->value);
93 +       return ENOMEM;
94 +    }
95 +
96 +    /* Must encrypt signature after encrypting the data, so don't specify signseal key here */
97 +    ret = v2_sign_message(in_to_sign, signkey, NULL, seq, out_signature->value);
98 +    if (ret) {
99 +       free(p);
100 +       return ret;
101 +    }
102 +
103 +    out_signature->length = 16;
104 +
105 +    RC4(sealkey, in_to_seal->length, in_to_seal->value, out_sealed->value);
106 +
107 +    out_sealed->length = in_to_sign->length;
108 +
109 +    /* Instead deal with it here */
110 +    if (signsealkey) {
111 +           RC4(sealkey, 16, out_signature->value, sealed_sig);
112 +           memcpy(out_signature->value, sealed_sig, 16);
113 +    }
114 +
115 +    return 0;
116 +}
117 +
118 +static OM_uint32
119 +v2_unseal_message_ex(gss_buffer_t in_signed,
120 +                    gss_buffer_t in_sealed,
121 +                    gss_buffer_t in_signature,
122 +                    unsigned char signkey[16],
123 +                    uint32_t seq,
124 +                    RC4_KEY *signsealkey,
125 +                    RC4_KEY *sealkey,
126 +                    gss_buffer_t out_unsealed)
127 +{
128 +    OM_uint32 ret;
129 +    gss_buffer_desc unsealed_with_aead;
130 +       
131 +    if (in_sealed->value < in_signed->value) {
132 +       return GSS_S_BAD_MIC;
133 +    }
134 +
135 +    if (&((char *)in_sealed->value)[in_sealed->length] > &((char *)in_signed->value)[in_signed->length]) {
136 +       return GSS_S_BAD_MIC;
137 +    }
138 +
139 +    if (in_signature->length < 16) 
140 +       return GSS_S_BAD_MIC;
141 +
142 +    unsealed_with_aead.value = malloc(in_signed->length);
143 +    if (unsealed_with_aead.value == NULL) 
144 +       return ENOMEM;
145 +
146 +    out_unsealed->length = in_sealed->length;
147 +    out_unsealed->value = malloc(out_unsealed->length);
148 +    if (out_unsealed->value == NULL) {
149 +       free(unsealed_with_aead.value);
150 +       return GSS_S_BAD_MIC;
151 +    }
152 +
153 +    RC4(sealkey, out_unsealed->length, in_sealed->value, out_unsealed->value);
154 +
155 +    memcpy(unsealed_with_aead.value, in_signed->value, in_signed->length);
156 +
157 +    /* Someone please check this is doing the right thing... */
158 +    memcpy(&((char *)unsealed_with_aead.value)[(char *)in_sealed->value - (char *)in_signed->value], 
159 +          out_unsealed->value, out_unsealed->length);
160 +
161 +    ret = v2_verify_message(&unsealed_with_aead, signkey, sealkey, seq, in_signature->value);
162 +    if (ret) {
163 +       OM_uint32 junk;
164 +       gss_release_buffer(&junk, out_unsealed);
165 +    }
166 +    return ret;
167 +}
168 +
169  /*
170   *
171   */
172 @@ -482,6 +590,7 @@
173         return v2_seal_message(input_message_buffer,
174                                ctx->u.v2.send.signkey,
175                                ctx->u.v2.send.seq++,
176 +                              ctx->u.v2.send.signsealkey,
177                                &ctx->u.v2.send.sealkey,
178                                output_message_buffer);
179  
180 @@ -555,6 +664,7 @@
181         return v2_unseal_message(input_message_buffer,
182                                  ctx->u.v2.recv.signkey,
183                                  ctx->u.v2.recv.seq++,
184 +                                ctx->u.v2.send.signsealkey,
185                                  &ctx->u.v2.recv.sealkey,
186                                  output_message_buffer);
187  
188 @@ -593,3 +703,134 @@
189  
190      return GSS_S_UNAVAILABLE;
191  }
192 +/*
193 + *
194 + */
195 +
196 +OM_uint32 _gss_ntlm_wrap_ex
197 +(OM_uint32 * minor_status,
198 + const gss_ctx_id_t context_handle,
199 + int conf_req_flag,
200 + gss_qop_t qop_req,
201 + const gss_buffer_t associated_data_buffer,
202 + const gss_buffer_t input_message_buffer,
203 + int * conf_state,
204 + gss_buffer_t output_token_buffer,
205 + gss_buffer_t output_message_buffer
206 +    )
207 +{
208 +    ntlm_ctx ctx = (ntlm_ctx)context_handle;
209 +    OM_uint32 ret;
210 +
211 +    if (minor_status)
212 +       *minor_status = 0;
213 +    if (conf_state)
214 +       *conf_state = 0;
215 +    if (output_message_buffer == GSS_C_NO_BUFFER)
216 +       return GSS_S_FAILURE;
217 +
218 +    
219 +    if (CTX_FLAGS_ISSET(ctx, NTLM_NEG_SEAL|NTLM_NEG_NTLM2_SESSION)) {
220 +
221 +           return v2_seal_message_ex(associated_data_buffer,
222 +                                     input_message_buffer,
223 +                                     ctx->u.v2.send.signkey,
224 +                                     ctx->u.v2.send.seq++,
225 +                                     ctx->u.v2.send.signsealkey,
226 +                                     &ctx->u.v2.send.sealkey,
227 +                                     output_token_buffer,
228 +                                     output_message_buffer);
229 +
230 +    } else if (CTX_FLAGS_ISSET(ctx, NTLM_NEG_SEAL)) {
231 +       OM_uint32 junk;
232 +
233 +       output_message_buffer->length = input_message_buffer->length;
234 +       output_message_buffer->value = malloc(output_message_buffer->length);
235 +       if (output_message_buffer->value == NULL) {
236 +           output_message_buffer->length = 0;
237 +           return GSS_S_FAILURE;
238 +       }
239 +
240 +
241 +       RC4(&ctx->u.v1.crypto_send.key, input_message_buffer->length,
242 +           input_message_buffer->value, output_message_buffer->value);
243 +       
244 +       ret = _gss_ntlm_get_mic(minor_status, context_handle,
245 +                               0, input_message_buffer,
246 +                               output_token_buffer);
247 +       if (ret) {
248 +           gss_release_buffer(&junk, output_message_buffer);
249 +           return ret;
250 +       }
251 +       return GSS_S_COMPLETE;
252 +    }
253 +
254 +    return GSS_S_UNAVAILABLE;
255 +}
256 +
257 +/*
258 + *
259 + */
260 +
261 +OM_uint32 _gss_ntlm_unwrap_ex
262 +(OM_uint32 * minor_status,
263 + const gss_ctx_id_t context_handle,
264 + const gss_buffer_t token_header_buffer,
265 + const gss_buffer_t associated_data_buffer,
266 + const gss_buffer_t input_message_buffer,
267 + gss_buffer_t output_message_buffer,
268 + int * conf_state,
269 + gss_qop_t * qop_state
270 +       )
271 +{
272 +    ntlm_ctx ctx = (ntlm_ctx)context_handle;
273 +    OM_uint32 ret;
274 +
275 +    if (minor_status)
276 +       *minor_status = 0;
277 +    if (output_message_buffer) {
278 +       output_message_buffer->value = NULL;
279 +       output_message_buffer->length = 0;
280 +    }
281 +    if (conf_state)
282 +       *conf_state = 0;
283 +    if (qop_state)
284 +       *qop_state = 0;
285 +
286 +    if (CTX_FLAGS_ISSET(ctx, NTLM_NEG_SEAL|NTLM_NEG_NTLM2_SESSION)) {
287 +
288 +           return v2_unseal_message_ex(associated_data_buffer,
289 +                                       input_message_buffer,
290 +                                       token_header_buffer,
291 +                                       ctx->u.v2.recv.signkey,
292 +                                       ctx->u.v2.recv.seq++,
293 +                                       ctx->u.v2.recv.signsealkey,
294 +                                       &ctx->u.v2.recv.sealkey,
295 +                                       output_message_buffer);
296 +           
297 +    } else if (CTX_FLAGS_ISSET(ctx, NTLM_NEG_SEAL)) {
298 +       OM_uint32 junk;
299 +
300 +       output_message_buffer->length = input_message_buffer->length;
301 +       output_message_buffer->value = malloc(output_message_buffer->length);
302 +       if (output_message_buffer->value == NULL) {
303 +           output_message_buffer->length = 0;
304 +           return GSS_S_FAILURE;
305 +       }
306 +       
307 +       RC4(&ctx->u.v1.crypto_recv.key, output_message_buffer->length,
308 +           input_message_buffer->value, output_message_buffer->value);
309 +       
310 +       ret = _gss_ntlm_verify_mic(minor_status, context_handle,
311 +                                  output_message_buffer,
312 +                                  token_header_buffer, NULL);
313 +       if (ret) {
314 +           gss_release_buffer(&junk, output_message_buffer);
315 +           return ret;
316 +       }
317 +
318 +       return GSS_S_COMPLETE;
319 +    }
320 +
321 +    return GSS_S_UNAVAILABLE;
322 +}
323 Index: lib/gssapi/ntlm/external.c
324 ===================================================================
325 --- lib/gssapi/ntlm/external.c  (revision 796)
326 +++ lib/gssapi/ntlm/external.c  (working copy)
327 @@ -50,6 +50,8 @@
328      _gss_ntlm_verify_mic,
329      _gss_ntlm_wrap,
330      _gss_ntlm_unwrap,
331 +    _gss_ntlm_wrap_ex,
332 +    _gss_ntlm_unwrap_ex,
333      _gss_ntlm_display_status,
334      NULL,
335      _gss_ntlm_compare_name,