1 /*	$NetBSD: data.c,v 1.2 2017/01/28 21:31:49 christos Exp $	*/
2 
3 /*
4  * Copyright (c) 1997 - 2007 Kungliga Tekniska Högskolan
5  * (Royal Institute of Technology, Stockholm, Sweden).
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * 3. Neither the name of the Institute nor the names of its contributors
20  *    may be used to endorse or promote products derived from this software
21  *    without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  */
35 
36 #include "krb5_locl.h"
37 
38 /**
39  * Reset the (potentially uninitalized) krb5_data structure.
40  *
41  * @param p krb5_data to reset.
42  *
43  * @ingroup krb5
44  */
45 
46 KRB5_LIB_FUNCTION void KRB5_LIB_CALL
krb5_data_zero(krb5_data * p)47 krb5_data_zero(krb5_data *p)
48 {
49     p->length = 0;
50     p->data   = NULL;
51 }
52 
53 /**
54  * Free the content of krb5_data structure, its ok to free a zeroed
55  * structure (with memset() or krb5_data_zero()). When done, the
56  * structure will be zeroed. The same function is called
57  * krb5_free_data_contents() in MIT Kerberos.
58  *
59  * @param p krb5_data to free.
60  *
61  * @ingroup krb5
62  */
63 
64 KRB5_LIB_FUNCTION void KRB5_LIB_CALL
krb5_data_free(krb5_data * p)65 krb5_data_free(krb5_data *p)
66 {
67     free(p->data);
68     krb5_data_zero(p);
69 }
70 
71 /**
72  * Free krb5_data (and its content).
73  *
74  * @param context Kerberos 5 context.
75  * @param p krb5_data to free.
76  *
77  * @ingroup krb5
78  */
79 
80 KRB5_LIB_FUNCTION void KRB5_LIB_CALL
krb5_free_data(krb5_context context,krb5_data * p)81 krb5_free_data(krb5_context context,
82 	       krb5_data *p)
83 {
84     krb5_data_free(p);
85     free(p);
86 }
87 
88 /**
89  * Allocate data of and krb5_data.
90  *
91  * @param p krb5_data to allocate.
92  * @param len size to allocate.
93  *
94  * @return Returns 0 to indicate success. Otherwise an kerberos et
95  * error code is returned.
96  *
97  * @ingroup krb5
98  */
99 
100 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_data_alloc(krb5_data * p,int len)101 krb5_data_alloc(krb5_data *p, int len)
102 {
103     p->data = malloc(len);
104     if(len && p->data == NULL)
105 	return ENOMEM;
106     p->length = len;
107     return 0;
108 }
109 
110 /**
111  * Grow (or shrink) the content of krb5_data to a new size.
112  *
113  * @param p krb5_data to free.
114  * @param len new size.
115  *
116  * @return Returns 0 to indicate success. Otherwise an kerberos et
117  * error code is returned.
118  *
119  * @ingroup krb5
120  */
121 
122 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_data_realloc(krb5_data * p,int len)123 krb5_data_realloc(krb5_data *p, int len)
124 {
125     void *tmp;
126     tmp = realloc(p->data, len);
127     if(len && !tmp)
128 	return ENOMEM;
129     p->data = tmp;
130     p->length = len;
131     return 0;
132 }
133 
134 /**
135  * Copy the data of len into the krb5_data.
136  *
137  * @param p krb5_data to copy into.
138  * @param data data to copy..
139  * @param len new size.
140  *
141  * @return Returns 0 to indicate success. Otherwise an kerberos et
142  * error code is returned.
143  *
144  * @ingroup krb5
145  */
146 
147 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_data_copy(krb5_data * p,const void * data,size_t len)148 krb5_data_copy(krb5_data *p, const void *data, size_t len)
149 {
150     if (len) {
151 	if(krb5_data_alloc(p, len))
152 	    return ENOMEM;
153 	memmove(p->data, data, len);
154     } else
155 	p->data = NULL;
156     p->length = len;
157     return 0;
158 }
159 
160 /**
161  * Copy the data into a newly allocated krb5_data.
162  *
163  * @param context Kerberos 5 context.
164  * @param indata the krb5_data data to copy
165  * @param outdata new krb5_date to copy too. Free with krb5_free_data().
166  *
167  * @return Returns 0 to indicate success. Otherwise an kerberos et
168  * error code is returned.
169  *
170  * @ingroup krb5
171  */
172 
173 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_copy_data(krb5_context context,const krb5_data * indata,krb5_data ** outdata)174 krb5_copy_data(krb5_context context,
175 	       const krb5_data *indata,
176 	       krb5_data **outdata)
177 {
178     krb5_error_code ret;
179     ALLOC(*outdata, 1);
180     if(*outdata == NULL)
181 	return krb5_enomem(context);
182     ret = der_copy_octet_string(indata, *outdata);
183     if(ret) {
184 	krb5_clear_error_message (context);
185 	free(*outdata);
186 	*outdata = NULL;
187     }
188     return ret;
189 }
190 
191 /**
192  * Compare to data.
193  *
194  * @param data1 krb5_data to compare
195  * @param data2 krb5_data to compare
196  *
197  * @return return the same way as memcmp(), useful when sorting.
198  *
199  * @ingroup krb5
200  */
201 
202 KRB5_LIB_FUNCTION int KRB5_LIB_CALL
krb5_data_cmp(const krb5_data * data1,const krb5_data * data2)203 krb5_data_cmp(const krb5_data *data1, const krb5_data *data2)
204 {
205     if (data1->length != data2->length)
206 	return data1->length - data2->length;
207     return memcmp(data1->data, data2->data, data1->length);
208 }
209 
210 /**
211  * Compare to data not exposing timing information from the checksum data
212  *
213  * @param data1 krb5_data to compare
214  * @param data2 krb5_data to compare
215  *
216  * @return returns zero for same data, otherwise non zero.
217  *
218  * @ingroup krb5
219  */
220 
221 KRB5_LIB_FUNCTION int KRB5_LIB_CALL
krb5_data_ct_cmp(const krb5_data * data1,const krb5_data * data2)222 krb5_data_ct_cmp(const krb5_data *data1, const krb5_data *data2)
223 {
224     if (data1->length != data2->length)
225 	return data1->length - data2->length;
226     return ct_memcmp(data1->data, data2->data, data1->length);
227 }
228