1 /* 2 * Copyright (c) 1997 - 2007 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 #include "krb5_locl.h" 35 36 /** 37 * Reset the (potentially uninitalized) krb5_data structure. 38 * 39 * @param p krb5_data to reset. 40 * 41 * @ingroup krb5 42 */ 43 44 KRB5_LIB_FUNCTION void KRB5_LIB_CALL 45 krb5_data_zero(krb5_data *p) 46 { 47 p->length = 0; 48 p->data = NULL; 49 } 50 51 /** 52 * Free the content of krb5_data structure, its ok to free a zeroed 53 * structure (with memset() or krb5_data_zero()). When done, the 54 * structure will be zeroed. The same function is called 55 * krb5_free_data_contents() in MIT Kerberos. 56 * 57 * @param p krb5_data to free. 58 * 59 * @ingroup krb5 60 */ 61 62 KRB5_LIB_FUNCTION void KRB5_LIB_CALL 63 krb5_data_free(krb5_data *p) 64 { 65 if(p->data != NULL) 66 free(p->data); 67 krb5_data_zero(p); 68 } 69 70 /** 71 * Free krb5_data (and its content). 72 * 73 * @param context Kerberos 5 context. 74 * @param p krb5_data to free. 75 * 76 * @ingroup krb5 77 */ 78 79 KRB5_LIB_FUNCTION void KRB5_LIB_CALL 80 krb5_free_data(krb5_context context, 81 krb5_data *p) 82 { 83 krb5_data_free(p); 84 free(p); 85 } 86 87 /** 88 * Allocate data of and krb5_data. 89 * 90 * @param p krb5_data to allocate. 91 * @param len size to allocate. 92 * 93 * @return Returns 0 to indicate success. Otherwise an kerberos et 94 * error code is returned. 95 * 96 * @ingroup krb5 97 */ 98 99 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 100 krb5_data_alloc(krb5_data *p, int len) 101 { 102 p->data = malloc(len); 103 if(len && p->data == NULL) 104 return ENOMEM; 105 p->length = len; 106 return 0; 107 } 108 109 /** 110 * Grow (or shrink) the content of krb5_data to a new size. 111 * 112 * @param p krb5_data to free. 113 * @param len new size. 114 * 115 * @return Returns 0 to indicate success. Otherwise an kerberos et 116 * error code is returned. 117 * 118 * @ingroup krb5 119 */ 120 121 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 122 krb5_data_realloc(krb5_data *p, int len) 123 { 124 void *tmp; 125 tmp = realloc(p->data, len); 126 if(len && !tmp) 127 return ENOMEM; 128 p->data = tmp; 129 p->length = len; 130 return 0; 131 } 132 133 /** 134 * Copy the data of len into the krb5_data. 135 * 136 * @param p krb5_data to copy into. 137 * @param data data to copy.. 138 * @param len new size. 139 * 140 * @return Returns 0 to indicate success. Otherwise an kerberos et 141 * error code is returned. 142 * 143 * @ingroup krb5 144 */ 145 146 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 147 krb5_data_copy(krb5_data *p, const void *data, size_t len) 148 { 149 if (len) { 150 if(krb5_data_alloc(p, len)) 151 return ENOMEM; 152 memmove(p->data, data, len); 153 } else 154 p->data = NULL; 155 p->length = len; 156 return 0; 157 } 158 159 /** 160 * Copy the data into a newly allocated krb5_data. 161 * 162 * @param context Kerberos 5 context. 163 * @param indata the krb5_data data to copy 164 * @param outdata new krb5_date to copy too. Free with krb5_free_data(). 165 * 166 * @return Returns 0 to indicate success. Otherwise an kerberos et 167 * error code is returned. 168 * 169 * @ingroup krb5 170 */ 171 172 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 173 krb5_copy_data(krb5_context context, 174 const krb5_data *indata, 175 krb5_data **outdata) 176 { 177 krb5_error_code ret; 178 ALLOC(*outdata, 1); 179 if(*outdata == NULL) { 180 krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); 181 return ENOMEM; 182 } 183 ret = der_copy_octet_string(indata, *outdata); 184 if(ret) { 185 krb5_clear_error_message (context); 186 free(*outdata); 187 *outdata = NULL; 188 } 189 return ret; 190 } 191 192 /** 193 * Compare to data. 194 * 195 * @param data1 krb5_data to compare 196 * @param data2 krb5_data to compare 197 * 198 * @return return the same way as memcmp(), useful when sorting. 199 * 200 * @ingroup krb5 201 */ 202 203 KRB5_LIB_FUNCTION int KRB5_LIB_CALL 204 krb5_data_cmp(const krb5_data *data1, const krb5_data *data2) 205 { 206 if (data1->length != data2->length) 207 return data1->length - data2->length; 208 return memcmp(data1->data, data2->data, data1->length); 209 } 210 211 /** 212 * Compare to data not exposing timing information from the checksum data 213 * 214 * @param data1 krb5_data to compare 215 * @param data2 krb5_data to compare 216 * 217 * @return returns zero for same data, otherwise non zero. 218 * 219 * @ingroup krb5 220 */ 221 222 KRB5_LIB_FUNCTION int KRB5_LIB_CALL 223 krb5_data_ct_cmp(const krb5_data *data1, const krb5_data *data2) 224 { 225 if (data1->length != data2->length) 226 return data1->length - data2->length; 227 return ct_memcmp(data1->data, data2->data, data1->length); 228 } 229