1c19800e8SDoug Rabson /*
2ae771770SStanislav Sedov  * Copyright (c) 1997 - 2003 Kungliga Tekniska Högskolan
3c19800e8SDoug Rabson  * (Royal Institute of Technology, Stockholm, Sweden).
4c19800e8SDoug Rabson  * All rights reserved.
5c19800e8SDoug Rabson  *
6c19800e8SDoug Rabson  * Redistribution and use in source and binary forms, with or without
7c19800e8SDoug Rabson  * modification, are permitted provided that the following conditions
8c19800e8SDoug Rabson  * are met:
9c19800e8SDoug Rabson  *
10c19800e8SDoug Rabson  * 1. Redistributions of source code must retain the above copyright
11c19800e8SDoug Rabson  *    notice, this list of conditions and the following disclaimer.
12c19800e8SDoug Rabson  *
13c19800e8SDoug Rabson  * 2. Redistributions in binary form must reproduce the above copyright
14c19800e8SDoug Rabson  *    notice, this list of conditions and the following disclaimer in the
15c19800e8SDoug Rabson  *    documentation and/or other materials provided with the distribution.
16c19800e8SDoug Rabson  *
17c19800e8SDoug Rabson  * 3. Neither the name of the Institute nor the names of its contributors
18c19800e8SDoug Rabson  *    may be used to endorse or promote products derived from this software
19c19800e8SDoug Rabson  *    without specific prior written permission.
20c19800e8SDoug Rabson  *
21c19800e8SDoug Rabson  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22c19800e8SDoug Rabson  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23c19800e8SDoug Rabson  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24c19800e8SDoug Rabson  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25c19800e8SDoug Rabson  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26c19800e8SDoug Rabson  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27c19800e8SDoug Rabson  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28c19800e8SDoug Rabson  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29c19800e8SDoug Rabson  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30c19800e8SDoug Rabson  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31c19800e8SDoug Rabson  * SUCH DAMAGE.
32c19800e8SDoug Rabson  */
33c19800e8SDoug Rabson 
34ae771770SStanislav Sedov #include "gsskrb5_locl.h"
35c19800e8SDoug Rabson 
36ae771770SStanislav Sedov #ifdef HEIM_WEAK_CRYPTO
37c19800e8SDoug Rabson 
38c19800e8SDoug Rabson static OM_uint32
verify_mic_des(OM_uint32 * minor_status,const gsskrb5_ctx context_handle,krb5_context context,const gss_buffer_t message_buffer,const gss_buffer_t token_buffer,gss_qop_t * qop_state,krb5_keyblock * key,const char * type)39c19800e8SDoug Rabson verify_mic_des
40c19800e8SDoug Rabson            (OM_uint32 * minor_status,
41c19800e8SDoug Rabson             const gsskrb5_ctx context_handle,
42c19800e8SDoug Rabson 	    krb5_context context,
43c19800e8SDoug Rabson             const gss_buffer_t message_buffer,
44c19800e8SDoug Rabson             const gss_buffer_t token_buffer,
45c19800e8SDoug Rabson             gss_qop_t * qop_state,
46c19800e8SDoug Rabson 	    krb5_keyblock *key,
47ae771770SStanislav Sedov 	    const char *type
48c19800e8SDoug Rabson 	    )
49c19800e8SDoug Rabson {
50c19800e8SDoug Rabson   u_char *p;
51ae771770SStanislav Sedov   EVP_MD_CTX *md5;
52c19800e8SDoug Rabson   u_char hash[16], *seq;
53c19800e8SDoug Rabson   DES_key_schedule schedule;
54e4456411SJohn Baldwin   EVP_CIPHER_CTX *des_ctx;
55c19800e8SDoug Rabson   DES_cblock zero;
56c19800e8SDoug Rabson   DES_cblock deskey;
57c19800e8SDoug Rabson   uint32_t seq_number;
58c19800e8SDoug Rabson   OM_uint32 ret;
59c19800e8SDoug Rabson   int cmp;
60c19800e8SDoug Rabson 
61c19800e8SDoug Rabson   p = token_buffer->value;
62c19800e8SDoug Rabson   ret = _gsskrb5_verify_header (&p,
63c19800e8SDoug Rabson 				   token_buffer->length,
64c19800e8SDoug Rabson 				   type,
65c19800e8SDoug Rabson 				   GSS_KRB5_MECHANISM);
66c19800e8SDoug Rabson   if (ret)
67c19800e8SDoug Rabson       return ret;
68c19800e8SDoug Rabson 
69c19800e8SDoug Rabson   if (memcmp(p, "\x00\x00", 2) != 0)
70c19800e8SDoug Rabson       return GSS_S_BAD_SIG;
71c19800e8SDoug Rabson   p += 2;
72c19800e8SDoug Rabson   if (memcmp (p, "\xff\xff\xff\xff", 4) != 0)
73c19800e8SDoug Rabson     return GSS_S_BAD_MIC;
74c19800e8SDoug Rabson   p += 4;
75c19800e8SDoug Rabson   p += 16;
76c19800e8SDoug Rabson 
77c19800e8SDoug Rabson   /* verify checksum */
78ae771770SStanislav Sedov   md5 = EVP_MD_CTX_create();
79ae771770SStanislav Sedov   EVP_DigestInit_ex(md5, EVP_md5(), NULL);
80ae771770SStanislav Sedov   EVP_DigestUpdate(md5, p - 24, 8);
81ae771770SStanislav Sedov   EVP_DigestUpdate(md5, message_buffer->value, message_buffer->length);
82ae771770SStanislav Sedov   EVP_DigestFinal_ex(md5, hash, NULL);
83ae771770SStanislav Sedov   EVP_MD_CTX_destroy(md5);
84c19800e8SDoug Rabson 
85c19800e8SDoug Rabson   memset (&zero, 0, sizeof(zero));
86c19800e8SDoug Rabson   memcpy (&deskey, key->keyvalue.data, sizeof(deskey));
87c19800e8SDoug Rabson 
88ae771770SStanislav Sedov   DES_set_key_unchecked (&deskey, &schedule);
89c19800e8SDoug Rabson   DES_cbc_cksum ((void *)hash, (void *)hash, sizeof(hash),
90c19800e8SDoug Rabson 		 &schedule, &zero);
91ae771770SStanislav Sedov   if (ct_memcmp (p - 8, hash, 8) != 0) {
92c19800e8SDoug Rabson     memset (deskey, 0, sizeof(deskey));
93c19800e8SDoug Rabson     memset (&schedule, 0, sizeof(schedule));
94c19800e8SDoug Rabson     return GSS_S_BAD_MIC;
95c19800e8SDoug Rabson   }
96c19800e8SDoug Rabson 
97c19800e8SDoug Rabson   /* verify sequence number */
98c19800e8SDoug Rabson 
99e4456411SJohn Baldwin   des_ctx = EVP_CIPHER_CTX_new();
100e4456411SJohn Baldwin   if (des_ctx == NULL) {
101e4456411SJohn Baldwin     memset (deskey, 0, sizeof(deskey));
102e4456411SJohn Baldwin     memset (&schedule, 0, sizeof(schedule));
103e4456411SJohn Baldwin     *minor_status = ENOMEM;
104e4456411SJohn Baldwin     return GSS_S_FAILURE;
105e4456411SJohn Baldwin   }
106e4456411SJohn Baldwin 
107c19800e8SDoug Rabson   HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
108c19800e8SDoug Rabson 
109c19800e8SDoug Rabson   p -= 16;
110ae771770SStanislav Sedov 
111e4456411SJohn Baldwin   EVP_CipherInit_ex(des_ctx, EVP_des_cbc(), NULL, key->keyvalue.data, hash, 0);
112e4456411SJohn Baldwin   EVP_Cipher(des_ctx, p, p, 8);
113e4456411SJohn Baldwin   EVP_CIPHER_CTX_free(des_ctx);
114c19800e8SDoug Rabson 
115c19800e8SDoug Rabson   memset (deskey, 0, sizeof(deskey));
116c19800e8SDoug Rabson   memset (&schedule, 0, sizeof(schedule));
117c19800e8SDoug Rabson 
118c19800e8SDoug Rabson   seq = p;
119c19800e8SDoug Rabson   _gsskrb5_decode_om_uint32(seq, &seq_number);
120c19800e8SDoug Rabson 
121c19800e8SDoug Rabson   if (context_handle->more_flags & LOCAL)
122ae771770SStanislav Sedov       cmp = ct_memcmp(&seq[4], "\xff\xff\xff\xff", 4);
123c19800e8SDoug Rabson   else
124ae771770SStanislav Sedov       cmp = ct_memcmp(&seq[4], "\x00\x00\x00\x00", 4);
125c19800e8SDoug Rabson 
126c19800e8SDoug Rabson   if (cmp != 0) {
127c19800e8SDoug Rabson     HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
128c19800e8SDoug Rabson     return GSS_S_BAD_MIC;
129c19800e8SDoug Rabson   }
130c19800e8SDoug Rabson 
131c19800e8SDoug Rabson   ret = _gssapi_msg_order_check(context_handle->order, seq_number);
132c19800e8SDoug Rabson   if (ret) {
133c19800e8SDoug Rabson       HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
134c19800e8SDoug Rabson       return ret;
135c19800e8SDoug Rabson   }
136c19800e8SDoug Rabson 
137c19800e8SDoug Rabson   HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
138c19800e8SDoug Rabson 
139c19800e8SDoug Rabson   return GSS_S_COMPLETE;
140c19800e8SDoug Rabson }
141ae771770SStanislav Sedov #endif
142c19800e8SDoug Rabson 
143c19800e8SDoug Rabson static OM_uint32
verify_mic_des3(OM_uint32 * minor_status,const gsskrb5_ctx context_handle,krb5_context context,const gss_buffer_t message_buffer,const gss_buffer_t token_buffer,gss_qop_t * qop_state,krb5_keyblock * key,const char * type)144c19800e8SDoug Rabson verify_mic_des3
145c19800e8SDoug Rabson            (OM_uint32 * minor_status,
146c19800e8SDoug Rabson             const gsskrb5_ctx context_handle,
147c19800e8SDoug Rabson 	    krb5_context context,
148c19800e8SDoug Rabson             const gss_buffer_t message_buffer,
149c19800e8SDoug Rabson             const gss_buffer_t token_buffer,
150c19800e8SDoug Rabson             gss_qop_t * qop_state,
151c19800e8SDoug Rabson 	    krb5_keyblock *key,
152ae771770SStanislav Sedov 	    const char *type
153c19800e8SDoug Rabson 	    )
154c19800e8SDoug Rabson {
155c19800e8SDoug Rabson   u_char *p;
156c19800e8SDoug Rabson   u_char *seq;
157c19800e8SDoug Rabson   uint32_t seq_number;
158c19800e8SDoug Rabson   OM_uint32 ret;
159c19800e8SDoug Rabson   krb5_crypto crypto;
160c19800e8SDoug Rabson   krb5_data seq_data;
161c19800e8SDoug Rabson   int cmp, docompat;
162c19800e8SDoug Rabson   Checksum csum;
163c19800e8SDoug Rabson   char *tmp;
164c19800e8SDoug Rabson   char ivec[8];
165c19800e8SDoug Rabson 
166c19800e8SDoug Rabson   p = token_buffer->value;
167c19800e8SDoug Rabson   ret = _gsskrb5_verify_header (&p,
168c19800e8SDoug Rabson 				   token_buffer->length,
169c19800e8SDoug Rabson 				   type,
170c19800e8SDoug Rabson 				   GSS_KRB5_MECHANISM);
171c19800e8SDoug Rabson   if (ret)
172c19800e8SDoug Rabson       return ret;
173c19800e8SDoug Rabson 
174c19800e8SDoug Rabson   if (memcmp(p, "\x04\x00", 2) != 0) /* SGN_ALG = HMAC SHA1 DES3-KD */
175c19800e8SDoug Rabson       return GSS_S_BAD_SIG;
176c19800e8SDoug Rabson   p += 2;
177c19800e8SDoug Rabson   if (memcmp (p, "\xff\xff\xff\xff", 4) != 0)
178c19800e8SDoug Rabson     return GSS_S_BAD_MIC;
179c19800e8SDoug Rabson   p += 4;
180c19800e8SDoug Rabson 
181c19800e8SDoug Rabson   ret = krb5_crypto_init(context, key,
182c19800e8SDoug Rabson 			 ETYPE_DES3_CBC_NONE, &crypto);
183c19800e8SDoug Rabson   if (ret){
184c19800e8SDoug Rabson       *minor_status = ret;
185c19800e8SDoug Rabson       return GSS_S_FAILURE;
186c19800e8SDoug Rabson   }
187c19800e8SDoug Rabson 
188c19800e8SDoug Rabson   /* verify sequence number */
189c19800e8SDoug Rabson   docompat = 0;
190c19800e8SDoug Rabson retry:
191c19800e8SDoug Rabson   if (docompat)
192c19800e8SDoug Rabson       memset(ivec, 0, 8);
193c19800e8SDoug Rabson   else
194c19800e8SDoug Rabson       memcpy(ivec, p + 8, 8);
195c19800e8SDoug Rabson 
196c19800e8SDoug Rabson   ret = krb5_decrypt_ivec (context,
197c19800e8SDoug Rabson 			   crypto,
198c19800e8SDoug Rabson 			   KRB5_KU_USAGE_SEQ,
199c19800e8SDoug Rabson 			   p, 8, &seq_data, ivec);
200c19800e8SDoug Rabson   if (ret) {
201c19800e8SDoug Rabson       if (docompat++) {
202c19800e8SDoug Rabson 	  krb5_crypto_destroy (context, crypto);
203c19800e8SDoug Rabson 	  *minor_status = ret;
204c19800e8SDoug Rabson 	  return GSS_S_FAILURE;
205c19800e8SDoug Rabson       } else
206c19800e8SDoug Rabson 	  goto retry;
207c19800e8SDoug Rabson   }
208c19800e8SDoug Rabson 
209c19800e8SDoug Rabson   if (seq_data.length != 8) {
210c19800e8SDoug Rabson       krb5_data_free (&seq_data);
211c19800e8SDoug Rabson       if (docompat++) {
212c19800e8SDoug Rabson 	  krb5_crypto_destroy (context, crypto);
213c19800e8SDoug Rabson 	  return GSS_S_BAD_MIC;
214c19800e8SDoug Rabson       } else
215c19800e8SDoug Rabson 	  goto retry;
216c19800e8SDoug Rabson   }
217c19800e8SDoug Rabson 
218c19800e8SDoug Rabson   HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
219c19800e8SDoug Rabson 
220c19800e8SDoug Rabson   seq = seq_data.data;
221c19800e8SDoug Rabson   _gsskrb5_decode_om_uint32(seq, &seq_number);
222c19800e8SDoug Rabson 
223c19800e8SDoug Rabson   if (context_handle->more_flags & LOCAL)
224ae771770SStanislav Sedov       cmp = ct_memcmp(&seq[4], "\xff\xff\xff\xff", 4);
225c19800e8SDoug Rabson   else
226ae771770SStanislav Sedov       cmp = ct_memcmp(&seq[4], "\x00\x00\x00\x00", 4);
227c19800e8SDoug Rabson 
228c19800e8SDoug Rabson   krb5_data_free (&seq_data);
229c19800e8SDoug Rabson   if (cmp != 0) {
230c19800e8SDoug Rabson       krb5_crypto_destroy (context, crypto);
231c19800e8SDoug Rabson       *minor_status = 0;
232c19800e8SDoug Rabson       HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
233c19800e8SDoug Rabson       return GSS_S_BAD_MIC;
234c19800e8SDoug Rabson   }
235c19800e8SDoug Rabson 
236c19800e8SDoug Rabson   ret = _gssapi_msg_order_check(context_handle->order, seq_number);
237c19800e8SDoug Rabson   if (ret) {
238c19800e8SDoug Rabson       krb5_crypto_destroy (context, crypto);
239c19800e8SDoug Rabson       *minor_status = 0;
240c19800e8SDoug Rabson       HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
241c19800e8SDoug Rabson       return ret;
242c19800e8SDoug Rabson   }
243c19800e8SDoug Rabson 
244c19800e8SDoug Rabson   /* verify checksum */
245c19800e8SDoug Rabson 
246c19800e8SDoug Rabson   tmp = malloc (message_buffer->length + 8);
247c19800e8SDoug Rabson   if (tmp == NULL) {
248c19800e8SDoug Rabson       krb5_crypto_destroy (context, crypto);
249c19800e8SDoug Rabson       HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
250c19800e8SDoug Rabson       *minor_status = ENOMEM;
251c19800e8SDoug Rabson       return GSS_S_FAILURE;
252c19800e8SDoug Rabson   }
253c19800e8SDoug Rabson 
254c19800e8SDoug Rabson   memcpy (tmp, p - 8, 8);
255c19800e8SDoug Rabson   memcpy (tmp + 8, message_buffer->value, message_buffer->length);
256c19800e8SDoug Rabson 
257c19800e8SDoug Rabson   csum.cksumtype = CKSUMTYPE_HMAC_SHA1_DES3;
258c19800e8SDoug Rabson   csum.checksum.length = 20;
259c19800e8SDoug Rabson   csum.checksum.data   = p + 8;
260c19800e8SDoug Rabson 
261cf771f22SStanislav Sedov   krb5_crypto_destroy (context, crypto);
262cf771f22SStanislav Sedov   ret = krb5_crypto_init(context, key,
263cf771f22SStanislav Sedov 			 ETYPE_DES3_CBC_SHA1, &crypto);
264cf771f22SStanislav Sedov   if (ret){
265cf771f22SStanislav Sedov       *minor_status = ret;
266cf771f22SStanislav Sedov       return GSS_S_FAILURE;
267cf771f22SStanislav Sedov   }
268cf771f22SStanislav Sedov 
269c19800e8SDoug Rabson   ret = krb5_verify_checksum (context, crypto,
270c19800e8SDoug Rabson 			      KRB5_KU_USAGE_SIGN,
271c19800e8SDoug Rabson 			      tmp, message_buffer->length + 8,
272c19800e8SDoug Rabson 			      &csum);
273c19800e8SDoug Rabson   free (tmp);
274c19800e8SDoug Rabson   if (ret) {
275c19800e8SDoug Rabson       krb5_crypto_destroy (context, crypto);
276c19800e8SDoug Rabson       *minor_status = ret;
277c19800e8SDoug Rabson       HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
278c19800e8SDoug Rabson       return GSS_S_BAD_MIC;
279c19800e8SDoug Rabson   }
280c19800e8SDoug Rabson   HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
281c19800e8SDoug Rabson 
282c19800e8SDoug Rabson   krb5_crypto_destroy (context, crypto);
283c19800e8SDoug Rabson   return GSS_S_COMPLETE;
284c19800e8SDoug Rabson }
285c19800e8SDoug Rabson 
286c19800e8SDoug Rabson OM_uint32
_gsskrb5_verify_mic_internal(OM_uint32 * minor_status,const gsskrb5_ctx ctx,krb5_context context,const gss_buffer_t message_buffer,const gss_buffer_t token_buffer,gss_qop_t * qop_state,const char * type)287c19800e8SDoug Rabson _gsskrb5_verify_mic_internal
288c19800e8SDoug Rabson            (OM_uint32 * minor_status,
289ae771770SStanislav Sedov             const gsskrb5_ctx ctx,
290c19800e8SDoug Rabson 	    krb5_context context,
291c19800e8SDoug Rabson             const gss_buffer_t message_buffer,
292c19800e8SDoug Rabson             const gss_buffer_t token_buffer,
293c19800e8SDoug Rabson             gss_qop_t * qop_state,
294ae771770SStanislav Sedov 	    const char * type
295c19800e8SDoug Rabson 	    )
296c19800e8SDoug Rabson {
297c19800e8SDoug Rabson     krb5_keyblock *key;
298c19800e8SDoug Rabson     OM_uint32 ret;
299c19800e8SDoug Rabson     krb5_keytype keytype;
300c19800e8SDoug Rabson 
301ae771770SStanislav Sedov     if (ctx->more_flags & IS_CFX)
302ae771770SStanislav Sedov         return _gssapi_verify_mic_cfx (minor_status, ctx,
303ae771770SStanislav Sedov 				       context, message_buffer, token_buffer,
304ae771770SStanislav Sedov 				       qop_state);
305ae771770SStanislav Sedov 
306ae771770SStanislav Sedov     HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
307ae771770SStanislav Sedov     ret = _gsskrb5i_get_token_key(ctx, context, &key);
308ae771770SStanislav Sedov     HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
309c19800e8SDoug Rabson     if (ret) {
310c19800e8SDoug Rabson 	*minor_status = ret;
311c19800e8SDoug Rabson 	return GSS_S_FAILURE;
312c19800e8SDoug Rabson     }
313c19800e8SDoug Rabson     *minor_status = 0;
314c19800e8SDoug Rabson     krb5_enctype_to_keytype (context, key->keytype, &keytype);
315c19800e8SDoug Rabson     switch (keytype) {
316c19800e8SDoug Rabson     case KEYTYPE_DES :
317ae771770SStanislav Sedov #ifdef HEIM_WEAK_CRYPTO
318ae771770SStanislav Sedov 	ret = verify_mic_des (minor_status, ctx, context,
319c19800e8SDoug Rabson 			      message_buffer, token_buffer, qop_state, key,
320c19800e8SDoug Rabson 			      type);
321ae771770SStanislav Sedov #else
322ae771770SStanislav Sedov       ret = GSS_S_FAILURE;
323ae771770SStanislav Sedov #endif
324c19800e8SDoug Rabson 	break;
325c19800e8SDoug Rabson     case KEYTYPE_DES3 :
326ae771770SStanislav Sedov 	ret = verify_mic_des3 (minor_status, ctx, context,
327c19800e8SDoug Rabson 			       message_buffer, token_buffer, qop_state, key,
328c19800e8SDoug Rabson 			       type);
329c19800e8SDoug Rabson 	break;
330c19800e8SDoug Rabson     case KEYTYPE_ARCFOUR :
331c19800e8SDoug Rabson     case KEYTYPE_ARCFOUR_56 :
332ae771770SStanislav Sedov 	ret = _gssapi_verify_mic_arcfour (minor_status, ctx,
333c19800e8SDoug Rabson 					  context,
334c19800e8SDoug Rabson 					  message_buffer, token_buffer,
335c19800e8SDoug Rabson 					  qop_state, key, type);
336c19800e8SDoug Rabson 	break;
337c19800e8SDoug Rabson     default :
338ae771770SStanislav Sedov         abort();
339c19800e8SDoug Rabson     }
340c19800e8SDoug Rabson     krb5_free_keyblock (context, key);
341c19800e8SDoug Rabson 
342c19800e8SDoug Rabson     return ret;
343c19800e8SDoug Rabson }
344c19800e8SDoug Rabson 
345ae771770SStanislav Sedov OM_uint32 GSSAPI_CALLCONV
_gsskrb5_verify_mic(OM_uint32 * minor_status,const gss_ctx_id_t context_handle,const gss_buffer_t message_buffer,const gss_buffer_t token_buffer,gss_qop_t * qop_state)346c19800e8SDoug Rabson _gsskrb5_verify_mic
347c19800e8SDoug Rabson            (OM_uint32 * minor_status,
348c19800e8SDoug Rabson             const gss_ctx_id_t context_handle,
349c19800e8SDoug Rabson             const gss_buffer_t message_buffer,
350c19800e8SDoug Rabson             const gss_buffer_t token_buffer,
351c19800e8SDoug Rabson             gss_qop_t * qop_state
352c19800e8SDoug Rabson 	    )
353c19800e8SDoug Rabson {
354c19800e8SDoug Rabson     krb5_context context;
355c19800e8SDoug Rabson     OM_uint32 ret;
356c19800e8SDoug Rabson 
357c19800e8SDoug Rabson     GSSAPI_KRB5_INIT (&context);
358c19800e8SDoug Rabson 
359c19800e8SDoug Rabson     if (qop_state != NULL)
360c19800e8SDoug Rabson 	*qop_state = GSS_C_QOP_DEFAULT;
361c19800e8SDoug Rabson 
362c19800e8SDoug Rabson     ret = _gsskrb5_verify_mic_internal(minor_status,
363c19800e8SDoug Rabson 				       (gsskrb5_ctx)context_handle,
364c19800e8SDoug Rabson 				       context,
365c19800e8SDoug Rabson 				       message_buffer, token_buffer,
366ae771770SStanislav Sedov 				       qop_state, (void *)(intptr_t)"\x01\x01");
367c19800e8SDoug Rabson 
368c19800e8SDoug Rabson     return ret;
369c19800e8SDoug Rabson }
370