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 "der_locl.h" 35 36 RCSID("$Id: der_get.c 21369 2007-06-27 10:14:39Z lha $"); 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 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 if (len == sizeof(unsigned) + 1 && p[0] == 0) 56 ; 57 else if (len > sizeof(unsigned)) 58 return ASN1_OVERRUN; 59 60 while (len--) 61 val = val * 256 + *p++; 62 *ret = val; 63 if(size) *size = oldlen; 64 return 0; 65 } 66 67 int 68 der_get_integer (const unsigned char *p, size_t len, 69 int *ret, size_t *size) 70 { 71 int val = 0; 72 size_t oldlen = len; 73 74 if (len > sizeof(int)) 75 return ASN1_OVERRUN; 76 77 if (len > 0) { 78 val = (signed char)*p++; 79 while (--len) 80 val = val * 256 + *p++; 81 } 82 *ret = val; 83 if(size) *size = oldlen; 84 return 0; 85 } 86 87 int 88 der_get_length (const unsigned char *p, size_t len, 89 size_t *val, size_t *size) 90 { 91 size_t v; 92 93 if (len <= 0) 94 return ASN1_OVERRUN; 95 --len; 96 v = *p++; 97 if (v < 128) { 98 *val = v; 99 if(size) *size = 1; 100 } else { 101 int e; 102 size_t l; 103 unsigned tmp; 104 105 if(v == 0x80){ 106 *val = ASN1_INDEFINITE; 107 if(size) *size = 1; 108 return 0; 109 } 110 v &= 0x7F; 111 if (len < v) 112 return ASN1_OVERRUN; 113 e = der_get_unsigned (p, v, &tmp, &l); 114 if(e) return e; 115 *val = tmp; 116 if(size) *size = l + 1; 117 } 118 return 0; 119 } 120 121 int 122 der_get_boolean(const unsigned char *p, size_t len, int *data, size_t *size) 123 { 124 if(len < 1) 125 return ASN1_OVERRUN; 126 if(*p != 0) 127 *data = 1; 128 else 129 *data = 0; 130 *size = 1; 131 return 0; 132 } 133 134 int 135 der_get_general_string (const unsigned char *p, size_t len, 136 heim_general_string *str, size_t *size) 137 { 138 const unsigned char *p1; 139 char *s; 140 141 p1 = memchr(p, 0, len); 142 if (p1 != NULL) { 143 /* 144 * Allow trailing NULs. We allow this since MIT Kerberos sends 145 * an strings in the NEED_PREAUTH case that includes a 146 * trailing NUL. 147 */ 148 while (p1 - p < len && *p1 == '\0') 149 p1++; 150 if (p1 - p != len) 151 return ASN1_BAD_CHARACTER; 152 } 153 if (len > len + 1) 154 return ASN1_BAD_LENGTH; 155 156 s = malloc (len + 1); 157 if (s == NULL) 158 return ENOMEM; 159 memcpy (s, p, len); 160 s[len] = '\0'; 161 *str = s; 162 if(size) *size = len; 163 return 0; 164 } 165 166 int 167 der_get_utf8string (const unsigned char *p, size_t len, 168 heim_utf8_string *str, size_t *size) 169 { 170 return der_get_general_string(p, len, str, size); 171 } 172 173 int 174 der_get_printable_string (const unsigned char *p, size_t len, 175 heim_printable_string *str, size_t *size) 176 { 177 return der_get_general_string(p, len, str, size); 178 } 179 180 int 181 der_get_ia5_string (const unsigned char *p, size_t len, 182 heim_ia5_string *str, size_t *size) 183 { 184 return der_get_general_string(p, len, str, size); 185 } 186 187 int 188 der_get_bmp_string (const unsigned char *p, size_t len, 189 heim_bmp_string *data, size_t *size) 190 { 191 size_t i; 192 193 if (len & 1) 194 return ASN1_BAD_FORMAT; 195 data->length = len / 2; 196 if (data->length > UINT_MAX/sizeof(data->data[0])) 197 return ERANGE; 198 data->data = malloc(data->length * sizeof(data->data[0])); 199 if (data->data == NULL && data->length != 0) 200 return ENOMEM; 201 202 for (i = 0; i < data->length; i++) { 203 data->data[i] = (p[0] << 8) | p[1]; 204 p += 2; 205 } 206 if (size) *size = len; 207 208 return 0; 209 } 210 211 int 212 der_get_universal_string (const unsigned char *p, size_t len, 213 heim_universal_string *data, size_t *size) 214 { 215 size_t i; 216 217 if (len & 3) 218 return ASN1_BAD_FORMAT; 219 data->length = len / 4; 220 if (data->length > UINT_MAX/sizeof(data->data[0])) 221 return ERANGE; 222 data->data = malloc(data->length * sizeof(data->data[0])); 223 if (data->data == NULL && data->length != 0) 224 return ENOMEM; 225 226 for (i = 0; i < data->length; i++) { 227 data->data[i] = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; 228 p += 4; 229 } 230 if (size) *size = len; 231 return 0; 232 } 233 234 int 235 der_get_visible_string (const unsigned char *p, size_t len, 236 heim_visible_string *str, size_t *size) 237 { 238 return der_get_general_string(p, len, str, size); 239 } 240 241 int 242 der_get_octet_string (const unsigned char *p, size_t len, 243 heim_octet_string *data, size_t *size) 244 { 245 data->length = len; 246 data->data = malloc(len); 247 if (data->data == NULL && data->length != 0) 248 return ENOMEM; 249 memcpy (data->data, p, len); 250 if(size) *size = len; 251 return 0; 252 } 253 254 int 255 der_get_heim_integer (const unsigned char *p, size_t len, 256 heim_integer *data, size_t *size) 257 { 258 data->length = 0; 259 data->negative = 0; 260 data->data = NULL; 261 262 if (len == 0) { 263 if (size) 264 *size = 0; 265 return 0; 266 } 267 if (p[0] & 0x80) { 268 unsigned char *q; 269 int carry = 1; 270 data->negative = 1; 271 272 data->length = len; 273 274 if (p[0] == 0xff) { 275 p++; 276 data->length--; 277 } 278 data->data = malloc(data->length); 279 if (data->data == NULL) { 280 data->length = 0; 281 if (size) 282 *size = 0; 283 return ENOMEM; 284 } 285 q = &((unsigned char*)data->data)[data->length - 1]; 286 p += data->length - 1; 287 while (q >= (unsigned char*)data->data) { 288 *q = *p ^ 0xff; 289 if (carry) 290 carry = !++*q; 291 p--; 292 q--; 293 } 294 } else { 295 data->negative = 0; 296 data->length = len; 297 298 if (p[0] == 0) { 299 p++; 300 data->length--; 301 } 302 data->data = malloc(data->length); 303 if (data->data == NULL && data->length != 0) { 304 data->length = 0; 305 if (size) 306 *size = 0; 307 return ENOMEM; 308 } 309 memcpy(data->data, p, data->length); 310 } 311 if (size) 312 *size = len; 313 return 0; 314 } 315 316 static int 317 generalizedtime2time (const char *s, time_t *t) 318 { 319 struct tm tm; 320 321 memset(&tm, 0, sizeof(tm)); 322 if (sscanf (s, "%04d%02d%02d%02d%02d%02dZ", 323 &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, 324 &tm.tm_min, &tm.tm_sec) != 6) { 325 if (sscanf (s, "%02d%02d%02d%02d%02d%02dZ", 326 &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, 327 &tm.tm_min, &tm.tm_sec) != 6) 328 return ASN1_BAD_TIMEFORMAT; 329 if (tm.tm_year < 50) 330 tm.tm_year += 2000; 331 else 332 tm.tm_year += 1900; 333 } 334 tm.tm_year -= 1900; 335 tm.tm_mon -= 1; 336 *t = _der_timegm (&tm); 337 return 0; 338 } 339 340 static int 341 der_get_time (const unsigned char *p, size_t len, 342 time_t *data, size_t *size) 343 { 344 char *times; 345 int e; 346 347 if (len > len + 1 || len == 0) 348 return ASN1_BAD_LENGTH; 349 350 times = malloc(len + 1); 351 if (times == NULL) 352 return ENOMEM; 353 memcpy(times, p, len); 354 times[len] = '\0'; 355 e = generalizedtime2time(times, data); 356 free (times); 357 if(size) *size = len; 358 return e; 359 } 360 361 int 362 der_get_generalized_time (const unsigned char *p, size_t len, 363 time_t *data, size_t *size) 364 { 365 return der_get_time(p, len, data, size); 366 } 367 368 int 369 der_get_utctime (const unsigned char *p, size_t len, 370 time_t *data, size_t *size) 371 { 372 return der_get_time(p, len, data, size); 373 } 374 375 int 376 der_get_oid (const unsigned char *p, size_t len, 377 heim_oid *data, size_t *size) 378 { 379 size_t n; 380 size_t oldlen = len; 381 382 if (len < 1) 383 return ASN1_OVERRUN; 384 385 if (len > len + 1) 386 return ASN1_BAD_LENGTH; 387 388 if (len + 1 > UINT_MAX/sizeof(data->components[0])) 389 return ERANGE; 390 391 data->components = malloc((len + 1) * sizeof(data->components[0])); 392 if (data->components == NULL) 393 return ENOMEM; 394 data->components[0] = (*p) / 40; 395 data->components[1] = (*p) % 40; 396 --len; 397 ++p; 398 for (n = 2; len > 0; ++n) { 399 unsigned u = 0, u1; 400 401 do { 402 --len; 403 u1 = u * 128 + (*p++ % 128); 404 /* check that we don't overflow the element */ 405 if (u1 < u) { 406 der_free_oid(data); 407 return ASN1_OVERRUN; 408 } 409 u = u1; 410 } while (len > 0 && p[-1] & 0x80); 411 data->components[n] = u; 412 } 413 if (n > 2 && p[-1] & 0x80) { 414 der_free_oid (data); 415 return ASN1_OVERRUN; 416 } 417 data->length = n; 418 if (size) 419 *size = oldlen; 420 return 0; 421 } 422 423 int 424 der_get_tag (const unsigned char *p, size_t len, 425 Der_class *class, Der_type *type, 426 unsigned int *tag, size_t *size) 427 { 428 size_t ret = 0; 429 if (len < 1) 430 return ASN1_OVERRUN; 431 *class = (Der_class)(((*p) >> 6) & 0x03); 432 *type = (Der_type)(((*p) >> 5) & 0x01); 433 *tag = (*p) & 0x1f; 434 p++; len--; ret++; 435 if(*tag == 0x1f) { 436 unsigned int continuation; 437 unsigned int tag1; 438 *tag = 0; 439 do { 440 if(len < 1) 441 return ASN1_OVERRUN; 442 continuation = *p & 128; 443 tag1 = *tag * 128 + (*p % 128); 444 /* check that we don't overflow the tag */ 445 if (tag1 < *tag) 446 return ASN1_OVERFLOW; 447 *tag = tag1; 448 p++; len--; ret++; 449 } while(continuation); 450 } 451 if(size) *size = ret; 452 return 0; 453 } 454 455 int 456 der_match_tag (const unsigned char *p, size_t len, 457 Der_class class, Der_type type, 458 unsigned int tag, size_t *size) 459 { 460 size_t l; 461 Der_class thisclass; 462 Der_type thistype; 463 unsigned int thistag; 464 int e; 465 466 e = der_get_tag (p, len, &thisclass, &thistype, &thistag, &l); 467 if (e) return e; 468 if (class != thisclass || type != thistype) 469 return ASN1_BAD_ID; 470 if(tag > thistag) 471 return ASN1_MISPLACED_FIELD; 472 if(tag < thistag) 473 return ASN1_MISSING_FIELD; 474 if(size) *size = l; 475 return 0; 476 } 477 478 int 479 der_match_tag_and_length (const unsigned char *p, size_t len, 480 Der_class class, Der_type type, unsigned int tag, 481 size_t *length_ret, size_t *size) 482 { 483 size_t l, ret = 0; 484 int e; 485 486 e = der_match_tag (p, len, class, type, tag, &l); 487 if (e) return e; 488 p += l; 489 len -= l; 490 ret += l; 491 e = der_get_length (p, len, length_ret, &l); 492 if (e) return e; 493 p += l; 494 len -= l; 495 ret += l; 496 if(size) *size = ret; 497 return 0; 498 } 499 500 /* 501 * Old versions of DCE was based on a very early beta of the MIT code, 502 * which used MAVROS for ASN.1 encoding. MAVROS had the interesting 503 * feature that it encoded data in the forward direction, which has 504 * it's problems, since you have no idea how long the data will be 505 * until after you're done. MAVROS solved this by reserving one byte 506 * for length, and later, if the actual length was longer, it reverted 507 * to indefinite, BER style, lengths. The version of MAVROS used by 508 * the DCE people could apparently generate correct X.509 DER encodings, and 509 * did this by making space for the length after encoding, but 510 * unfortunately this feature wasn't used with Kerberos. 511 */ 512 513 int 514 _heim_fix_dce(size_t reallen, size_t *len) 515 { 516 if(reallen == ASN1_INDEFINITE) 517 return 1; 518 if(*len < reallen) 519 return -1; 520 *len = reallen; 521 return 0; 522 } 523 524 int 525 der_get_bit_string (const unsigned char *p, size_t len, 526 heim_bit_string *data, size_t *size) 527 { 528 if (len < 1) 529 return ASN1_OVERRUN; 530 if (p[0] > 7) 531 return ASN1_BAD_FORMAT; 532 if (len - 1 == 0 && p[0] != 0) 533 return ASN1_BAD_FORMAT; 534 /* check if any of the three upper bits are set 535 * any of them will cause a interger overrun */ 536 if ((len - 1) >> (sizeof(len) * 8 - 3)) 537 return ASN1_OVERRUN; 538 data->length = (len - 1) * 8; 539 data->data = malloc(len - 1); 540 if (data->data == NULL && (len - 1) != 0) 541 return ENOMEM; 542 memcpy (data->data, p + 1, len - 1); 543 data->length -= p[0]; 544 if(size) *size = len; 545 return 0; 546 } 547