1 /* 2 * Copyright (c) 1997 - 2000 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 "der_locl.h" 35 36 RCSID("$Id: der_get.c,v 1.28 2000/04/06 17:19:53 assar Exp $"); 37 38 #include <version.h> 39 40 /* 41 * All decoding functions take a pointer `p' to first position in 42 * which to read, from the left, `len' which means the maximum number 43 * of characters we are able to read, `ret' were the value will be 44 * returned and `size' where the number of used bytes is stored. 45 * Either 0 or an error code is returned. 46 */ 47 48 static int 49 der_get_unsigned (const unsigned char *p, size_t len, 50 unsigned *ret, size_t *size) 51 { 52 unsigned val = 0; 53 size_t oldlen = len; 54 55 while (len--) 56 val = val * 256 + *p++; 57 *ret = val; 58 if(size) *size = oldlen; 59 return 0; 60 } 61 62 int 63 der_get_int (const unsigned char *p, size_t len, 64 int *ret, size_t *size) 65 { 66 int val = 0; 67 size_t oldlen = len; 68 69 if (len--) 70 val = (signed char)*p++; 71 while (len--) 72 val = val * 256 + *p++; 73 *ret = val; 74 if(size) *size = oldlen; 75 return 0; 76 } 77 78 int 79 der_get_length (const unsigned char *p, size_t len, 80 size_t *val, size_t *size) 81 { 82 size_t v; 83 84 if (len <= 0) 85 return ASN1_OVERRUN; 86 --len; 87 v = *p++; 88 if (v < 128) { 89 *val = v; 90 if(size) *size = 1; 91 } else { 92 int e; 93 size_t l; 94 unsigned tmp; 95 96 if(v == 0x80){ 97 *val = ASN1_INDEFINITE; 98 if(size) *size = 1; 99 return 0; 100 } 101 v &= 0x7F; 102 if (len < v) 103 return ASN1_OVERRUN; 104 e = der_get_unsigned (p, v, &tmp, &l); 105 if(e) return e; 106 *val = tmp; 107 if(size) *size = l + 1; 108 } 109 return 0; 110 } 111 112 int 113 der_get_general_string (const unsigned char *p, size_t len, 114 general_string *str, size_t *size) 115 { 116 char *s; 117 118 s = malloc (len + 1); 119 if (s == NULL) 120 return ENOMEM; 121 memcpy (s, p, len); 122 s[len] = '\0'; 123 *str = s; 124 if(size) *size = len; 125 return 0; 126 } 127 128 int 129 der_get_octet_string (const unsigned char *p, size_t len, 130 octet_string *data, size_t *size) 131 { 132 data->length = len; 133 data->data = malloc(len); 134 if (data->data == NULL && data->length != 0) 135 return ENOMEM; 136 memcpy (data->data, p, len); 137 if(size) *size = len; 138 return 0; 139 } 140 141 int 142 der_get_tag (const unsigned char *p, size_t len, 143 Der_class *class, Der_type *type, 144 int *tag, size_t *size) 145 { 146 if (len < 1) 147 return ASN1_OVERRUN; 148 *class = (Der_class)(((*p) >> 6) & 0x03); 149 *type = (Der_type)(((*p) >> 5) & 0x01); 150 *tag = (*p) & 0x1F; 151 if(size) *size = 1; 152 return 0; 153 } 154 155 int 156 der_match_tag (const unsigned char *p, size_t len, 157 Der_class class, Der_type type, 158 int tag, size_t *size) 159 { 160 size_t l; 161 Der_class thisclass; 162 Der_type thistype; 163 int thistag; 164 int e; 165 166 e = der_get_tag (p, len, &thisclass, &thistype, &thistag, &l); 167 if (e) return e; 168 if (class != thisclass || type != thistype) 169 return ASN1_BAD_ID; 170 if(tag > thistag) 171 return ASN1_MISPLACED_FIELD; 172 if(tag < thistag) 173 return ASN1_MISSING_FIELD; 174 if(size) *size = l; 175 return 0; 176 } 177 178 int 179 der_match_tag_and_length (const unsigned char *p, size_t len, 180 Der_class class, Der_type type, int tag, 181 size_t *length_ret, size_t *size) 182 { 183 size_t l, ret = 0; 184 int e; 185 186 e = der_match_tag (p, len, class, type, tag, &l); 187 if (e) return e; 188 p += l; 189 len -= l; 190 ret += l; 191 e = der_get_length (p, len, length_ret, &l); 192 if (e) return e; 193 p += l; 194 len -= l; 195 ret += l; 196 if(size) *size = ret; 197 return 0; 198 } 199 200 int 201 decode_integer (const unsigned char *p, size_t len, 202 int *num, size_t *size) 203 { 204 size_t ret = 0; 205 size_t l, reallen; 206 int e; 207 208 e = der_match_tag (p, len, UNIV, PRIM, UT_Integer, &l); 209 if (e) return e; 210 p += l; 211 len -= l; 212 ret += l; 213 e = der_get_length (p, len, &reallen, &l); 214 if (e) return e; 215 p += l; 216 len -= l; 217 ret += l; 218 e = der_get_int (p, reallen, num, &l); 219 if (e) return e; 220 p += l; 221 len -= l; 222 ret += l; 223 if(size) *size = ret; 224 return 0; 225 } 226 227 int 228 decode_unsigned (const unsigned char *p, size_t len, 229 unsigned *num, size_t *size) 230 { 231 size_t ret = 0; 232 size_t l, reallen; 233 int e; 234 235 e = der_match_tag (p, len, UNIV, PRIM, UT_Integer, &l); 236 if (e) return e; 237 p += l; 238 len -= l; 239 ret += l; 240 e = der_get_length (p, len, &reallen, &l); 241 if (e) return e; 242 p += l; 243 len -= l; 244 ret += l; 245 e = der_get_unsigned (p, reallen, num, &l); 246 if (e) return e; 247 p += l; 248 len -= l; 249 ret += l; 250 if(size) *size = ret; 251 return 0; 252 } 253 254 int 255 decode_general_string (const unsigned char *p, size_t len, 256 general_string *str, size_t *size) 257 { 258 size_t ret = 0; 259 size_t l; 260 int e; 261 size_t slen; 262 263 e = der_match_tag (p, len, UNIV, PRIM, UT_GeneralString, &l); 264 if (e) return e; 265 p += l; 266 len -= l; 267 ret += l; 268 269 e = der_get_length (p, len, &slen, &l); 270 if (e) return e; 271 p += l; 272 len -= l; 273 ret += l; 274 if (len < slen) 275 return ASN1_OVERRUN; 276 277 e = der_get_general_string (p, slen, str, &l); 278 if (e) return e; 279 p += l; 280 len -= l; 281 ret += l; 282 if(size) *size = ret; 283 return 0; 284 } 285 286 int 287 decode_octet_string (const unsigned char *p, size_t len, 288 octet_string *k, size_t *size) 289 { 290 size_t ret = 0; 291 size_t l; 292 int e; 293 size_t slen; 294 295 e = der_match_tag (p, len, UNIV, PRIM, UT_OctetString, &l); 296 if (e) return e; 297 p += l; 298 len -= l; 299 ret += l; 300 301 e = der_get_length (p, len, &slen, &l); 302 if (e) return e; 303 p += l; 304 len -= l; 305 ret += l; 306 if (len < slen) 307 return ASN1_OVERRUN; 308 309 e = der_get_octet_string (p, slen, k, &l); 310 if (e) return e; 311 p += l; 312 len -= l; 313 ret += l; 314 if(size) *size = ret; 315 return 0; 316 } 317 318 static void 319 generalizedtime2time (const char *s, time_t *t) 320 { 321 struct tm tm; 322 323 memset(&tm, 0, sizeof(tm)); 324 sscanf (s, "%04d%02d%02d%02d%02d%02dZ", 325 &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, 326 &tm.tm_min, &tm.tm_sec); 327 tm.tm_year -= 1900; 328 tm.tm_mon -= 1; 329 *t = timegm (&tm); 330 } 331 332 int 333 decode_generalized_time (const unsigned char *p, size_t len, 334 time_t *t, size_t *size) 335 { 336 octet_string k; 337 char *times; 338 size_t ret = 0; 339 size_t l; 340 int e; 341 size_t slen; 342 343 e = der_match_tag (p, len, UNIV, PRIM, UT_GeneralizedTime, &l); 344 if (e) return e; 345 p += l; 346 len -= l; 347 ret += l; 348 349 e = der_get_length (p, len, &slen, &l); 350 if (e) return e; 351 p += l; 352 len -= l; 353 ret += l; 354 if (len < slen) 355 return ASN1_OVERRUN; 356 e = der_get_octet_string (p, slen, &k, &l); 357 if (e) return e; 358 p += l; 359 len -= l; 360 ret += l; 361 times = realloc(k.data, k.length + 1); 362 if (times == NULL){ 363 free(k.data); 364 return ENOMEM; 365 } 366 times[k.length] = 0; 367 generalizedtime2time (times, t); 368 free (times); 369 if(size) *size = ret; 370 return 0; 371 } 372 373 374 int 375 fix_dce(size_t reallen, size_t *len) 376 { 377 if(reallen == ASN1_INDEFINITE) 378 return 1; 379 if(*len < reallen) 380 return -1; 381 *len = reallen; 382 return 0; 383 } 384