1/* 2 * Copyright (c) 1997 - 2010 Kungliga Tekniska Högskolan 3 * (Royal Institute of Technology, Stockholm, Sweden). 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 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * 3. Neither the name of the Institute nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34#define HC_DEPRECATED_CRYPTO 35 36#include "mech_locl.h" 37 38#include <krb5.h> 39#include <roken.h> 40 41#include "crypto-headers.h" 42 43 44OM_uint32 45gss_mg_gen_cb(OM_uint32 *minor_status, 46 const gss_channel_bindings_t b, 47 uint8_t p[16], gss_buffer_t buffer) 48{ 49 krb5_error_code ret; 50 krb5_ssize_t sret; 51 krb5_storage *sp; 52 krb5_data data; 53 54 krb5_data_zero(&data); 55 56 sp = krb5_storage_emem(); 57 if (sp == NULL) { 58 *minor_status = ENOMEM; 59 goto out; 60 } 61 krb5_storage_set_byteorder(sp, KRB5_STORAGE_BYTEORDER_LE); 62 63 ret = krb5_store_uint32(sp, b->initiator_addrtype); 64 if (ret) { 65 *minor_status = ret; 66 goto out; 67 } 68 ret = krb5_store_uint32(sp, (uint32_t)b->initiator_address.length); 69 if (ret) { 70 *minor_status = ret; 71 goto out; 72 } 73 sret = krb5_storage_write(sp, b->initiator_address.value, 74 (uint32_t)b->initiator_address.length); 75 if (sret < 0 || (size_t)sret != b->initiator_address.length) { 76 *minor_status = ENOMEM; 77 goto out; 78 } 79 80 ret = krb5_store_uint32(sp, b->acceptor_addrtype); 81 if (ret) { 82 *minor_status = ret; 83 goto out; 84 } 85 ret = krb5_store_uint32(sp, (uint32_t)b->acceptor_address.length); 86 if (ret) { 87 *minor_status = ret; 88 goto out; 89 } 90 sret = krb5_storage_write(sp, b->acceptor_address.value, 91 b->acceptor_address.length); 92 if (sret < 0 || (size_t)sret != b->acceptor_address.length) { 93 *minor_status = ENOMEM; 94 goto out; 95 } 96 97 ret = krb5_store_uint32(sp, (uint32_t)b->application_data.length); 98 if (ret) { 99 *minor_status = ret; 100 goto out; 101 } 102 sret = krb5_storage_write(sp, b->application_data.value, 103 b->application_data.length); 104 if (sret < 0 || (size_t)sret != b->application_data.length) { 105 *minor_status = ENOMEM; 106 goto out; 107 } 108 109 ret = krb5_storage_to_data(sp, &data); 110 if (ret) { 111 *minor_status = ret; 112 goto out; 113 } 114 115 CCDigest(kCCDigestMD5, data.data, data.length, p); 116 117 if (buffer) { 118 buffer->value = data.data; 119 buffer->length = data.length; 120 } else { 121 krb5_data_free(&data); 122 } 123 124 *minor_status = 0; 125 return GSS_S_COMPLETE; 126 127 out: 128 if (sp) 129 krb5_storage_free(sp); 130 return GSS_S_FAILURE; 131} 132 133OM_uint32 134gss_mg_validate_cb(OM_uint32 *minor_status, 135 const gss_channel_bindings_t b, 136 const uint8_t p[16], 137 gss_buffer_t buffer) 138{ 139 static uint8_t zeros[16] = { 0 }; 140 OM_uint32 major_status, junk; 141 uint8_t hash[16]; 142 143 if (b != GSS_C_NO_CHANNEL_BINDINGS 144 && memcmp(p, zeros, sizeof(zeros)) != 0) { 145 146 major_status = gss_mg_gen_cb(minor_status, b, hash, buffer); 147 if (major_status) 148 return major_status; 149 150 if(ct_memcmp(hash, p, sizeof(hash)) != 0) { 151 gss_release_buffer(&junk, buffer); 152 *minor_status = 0; 153 return GSS_S_BAD_BINDINGS; 154 } 155 } else { 156 buffer->length = 0; 157 buffer->value = NULL; 158 } 159 160 return GSS_S_COMPLETE; 161} 162