1 /* 2 * Copyright (c) 1997-2005 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$"); 37 38 /* 39 * All encoding functions take a pointer `p' to first position in 40 * which to write, from the right, `len' which means the maximum 41 * number of characters we are able to write. The function returns 42 * the number of characters written in `size' (if non-NULL). 43 * The return value is 0 or an error. 44 */ 45 46 int 47 der_put_unsigned (unsigned char *p, size_t len, const unsigned *v, size_t *size) 48 { 49 unsigned char *base = p; 50 unsigned val = *v; 51 52 if (val) { 53 while (len > 0 && val) { 54 *p-- = val % 256; 55 val /= 256; 56 --len; 57 } 58 if (val != 0) 59 return ASN1_OVERFLOW; 60 else { 61 if(p[1] >= 128) { 62 if(len < 1) 63 return ASN1_OVERFLOW; 64 *p-- = 0; 65 } 66 *size = base - p; 67 return 0; 68 } 69 } else if (len < 1) 70 return ASN1_OVERFLOW; 71 else { 72 *p = 0; 73 *size = 1; 74 return 0; 75 } 76 } 77 78 int 79 der_put_unsigned64 (unsigned char *p, size_t len, const uint64_t *v, size_t *size) 80 { 81 unsigned char *base = p; 82 uint64_t val = *v; 83 84 if (val) { 85 while (len > 0 && val) { 86 *p-- = val % 256; 87 val /= 256; 88 --len; 89 } 90 if (val != 0) 91 return ASN1_OVERFLOW; 92 else { 93 if(p[1] >= 128) { 94 if(len < 1) 95 return ASN1_OVERFLOW; 96 *p-- = 0; 97 } 98 *size = base - p; 99 return 0; 100 } 101 } else if (len < 1) 102 return ASN1_OVERFLOW; 103 else { 104 *p = 0; 105 *size = 1; 106 return 0; 107 } 108 } 109 110 int 111 der_put_integer (unsigned char *p, size_t len, const int *v, size_t *size) 112 { 113 unsigned char *base = p; 114 int val = *v; 115 116 if(val >= 0) { 117 do { 118 if(len < 1) 119 return ASN1_OVERFLOW; 120 *p-- = val % 256; 121 len--; 122 val /= 256; 123 } while(val); 124 if(p[1] >= 128) { 125 if(len < 1) 126 return ASN1_OVERFLOW; 127 *p-- = 0; 128 len--; 129 } 130 } else { 131 val = ~val; 132 do { 133 if(len < 1) 134 return ASN1_OVERFLOW; 135 *p-- = ~(val % 256); 136 len--; 137 val /= 256; 138 } while(val); 139 if(p[1] < 128) { 140 if(len < 1) 141 return ASN1_OVERFLOW; 142 *p-- = 0xff; 143 len--; 144 } 145 } 146 *size = base - p; 147 return 0; 148 } 149 150 int 151 der_put_integer64 (unsigned char *p, size_t len, const int64_t *v, size_t *size) 152 { 153 unsigned char *base = p; 154 int64_t val = *v; 155 156 if(val >= 0) { 157 do { 158 if(len < 1) 159 return ASN1_OVERFLOW; 160 *p-- = val % 256; 161 len--; 162 val /= 256; 163 } while(val); 164 if(p[1] >= 128) { 165 if(len < 1) 166 return ASN1_OVERFLOW; 167 *p-- = 0; 168 len--; 169 } 170 } else { 171 val = ~val; 172 do { 173 if(len < 1) 174 return ASN1_OVERFLOW; 175 *p-- = ~(val % 256); 176 len--; 177 val /= 256; 178 } while(val); 179 if(p[1] < 128) { 180 if(len < 1) 181 return ASN1_OVERFLOW; 182 *p-- = 0xff; 183 len--; 184 } 185 } 186 *size = base - p; 187 return 0; 188 } 189 190 191 int 192 der_put_length (unsigned char *p, size_t len, size_t val, size_t *size) 193 { 194 if (len < 1) 195 return ASN1_OVERFLOW; 196 197 if (val < 128) { 198 *p = val; 199 *size = 1; 200 } else { 201 size_t l = 0; 202 203 while(val > 0) { 204 if(len < 2) 205 return ASN1_OVERFLOW; 206 *p-- = val % 256; 207 val /= 256; 208 len--; 209 l++; 210 } 211 *p = 0x80 | l; 212 if(size) 213 *size = l + 1; 214 } 215 return 0; 216 } 217 218 int 219 der_put_boolean(unsigned char *p, size_t len, const int *data, size_t *size) 220 { 221 if(len < 1) 222 return ASN1_OVERFLOW; 223 if(*data != 0) 224 *p = 0xff; 225 else 226 *p = 0; 227 *size = 1; 228 return 0; 229 } 230 231 int 232 der_put_general_string (unsigned char *p, size_t len, 233 const heim_general_string *str, size_t *size) 234 { 235 size_t slen = strlen(*str); 236 237 if (len < slen) 238 return ASN1_OVERFLOW; 239 p -= slen; 240 memcpy (p+1, *str, slen); 241 *size = slen; 242 return 0; 243 } 244 245 int 246 der_put_utf8string (unsigned char *p, size_t len, 247 const heim_utf8_string *str, size_t *size) 248 { 249 return der_put_general_string(p, len, str, size); 250 } 251 252 int 253 der_put_printable_string (unsigned char *p, size_t len, 254 const heim_printable_string *str, size_t *size) 255 { 256 return der_put_octet_string(p, len, str, size); 257 } 258 259 int 260 der_put_ia5_string (unsigned char *p, size_t len, 261 const heim_ia5_string *str, size_t *size) 262 { 263 return der_put_octet_string(p, len, str, size); 264 } 265 266 int 267 der_put_bmp_string (unsigned char *p, size_t len, 268 const heim_bmp_string *data, size_t *size) 269 { 270 size_t i; 271 if (len / 2 < data->length) 272 return ASN1_OVERFLOW; 273 p -= data->length * 2; 274 for (i = 0; i < data->length; i++) { 275 p[1] = (data->data[i] >> 8) & 0xff; 276 p[2] = data->data[i] & 0xff; 277 p += 2; 278 } 279 if (size) *size = data->length * 2; 280 return 0; 281 } 282 283 int 284 der_put_universal_string (unsigned char *p, size_t len, 285 const heim_universal_string *data, size_t *size) 286 { 287 size_t i; 288 if (len / 4 < data->length) 289 return ASN1_OVERFLOW; 290 p -= data->length * 4; 291 for (i = 0; i < data->length; i++) { 292 p[1] = (data->data[i] >> 24) & 0xff; 293 p[2] = (data->data[i] >> 16) & 0xff; 294 p[3] = (data->data[i] >> 8) & 0xff; 295 p[4] = data->data[i] & 0xff; 296 p += 4; 297 } 298 if (size) *size = data->length * 4; 299 return 0; 300 } 301 302 int 303 der_put_visible_string (unsigned char *p, size_t len, 304 const heim_visible_string *str, size_t *size) 305 { 306 return der_put_general_string(p, len, str, size); 307 } 308 309 int 310 der_put_octet_string (unsigned char *p, size_t len, 311 const heim_octet_string *data, size_t *size) 312 { 313 if (len < data->length) 314 return ASN1_OVERFLOW; 315 p -= data->length; 316 memcpy (p+1, data->data, data->length); 317 *size = data->length; 318 return 0; 319 } 320 321 int 322 der_put_heim_integer (unsigned char *p, size_t len, 323 const heim_integer *data, size_t *size) 324 { 325 unsigned char *buf = data->data; 326 int hibitset = 0; 327 328 if (data->length == 0) { 329 if (len < 1) 330 return ASN1_OVERFLOW; 331 *p-- = 0; 332 if (size) 333 *size = 1; 334 return 0; 335 } 336 if (len < data->length) 337 return ASN1_OVERFLOW; 338 339 len -= data->length; 340 341 if (data->negative) { 342 int i, carry; 343 for (i = data->length - 1, carry = 1; i >= 0; i--) { 344 *p = buf[i] ^ 0xff; 345 if (carry) 346 carry = !++*p; 347 p--; 348 } 349 if (p[1] < 128) { 350 if (len < 1) 351 return ASN1_OVERFLOW; 352 *p-- = 0xff; 353 len--; 354 hibitset = 1; 355 } 356 } else { 357 p -= data->length; 358 memcpy(p + 1, buf, data->length); 359 360 if (p[1] >= 128) { 361 if (len < 1) 362 return ASN1_OVERFLOW; 363 p[0] = 0; 364 len--; 365 hibitset = 1; 366 } 367 } 368 if (size) 369 *size = data->length + hibitset; 370 return 0; 371 } 372 373 int 374 der_put_generalized_time (unsigned char *p, size_t len, 375 const time_t *data, size_t *size) 376 { 377 heim_octet_string k; 378 size_t l; 379 int e; 380 381 e = _heim_time2generalizedtime (*data, &k, 1); 382 if (e) 383 return e; 384 e = der_put_octet_string(p, len, &k, &l); 385 free(k.data); 386 if(e) 387 return e; 388 if(size) 389 *size = l; 390 return 0; 391 } 392 393 int 394 der_put_utctime (unsigned char *p, size_t len, 395 const time_t *data, size_t *size) 396 { 397 heim_octet_string k; 398 size_t l; 399 int e; 400 401 e = _heim_time2generalizedtime (*data, &k, 0); 402 if (e) 403 return e; 404 e = der_put_octet_string(p, len, &k, &l); 405 free(k.data); 406 if(e) 407 return e; 408 if(size) 409 *size = l; 410 return 0; 411 } 412 413 int 414 der_put_oid (unsigned char *p, size_t len, 415 const heim_oid *data, size_t *size) 416 { 417 unsigned char *base = p; 418 int n; 419 420 for (n = data->length - 1; n >= 2; --n) { 421 unsigned u = data->components[n]; 422 423 if (len < 1) 424 return ASN1_OVERFLOW; 425 *p-- = u % 128; 426 u /= 128; 427 --len; 428 while (u > 0) { 429 if (len < 1) 430 return ASN1_OVERFLOW; 431 *p-- = 128 + u % 128; 432 u /= 128; 433 --len; 434 } 435 } 436 if (len < 1) 437 return ASN1_OVERFLOW; 438 *p-- = 40 * data->components[0] + data->components[1]; 439 *size = base - p; 440 return 0; 441 } 442 443 int 444 der_put_tag (unsigned char *p, size_t len, Der_class class, Der_type type, 445 unsigned int tag, size_t *size) 446 { 447 if (tag <= 30) { 448 if (len < 1) 449 return ASN1_OVERFLOW; 450 *p = MAKE_TAG(class, type, tag); 451 *size = 1; 452 } else { 453 size_t ret = 0; 454 unsigned int continuation = 0; 455 456 do { 457 if (len < 1) 458 return ASN1_OVERFLOW; 459 *p-- = tag % 128 | continuation; 460 len--; 461 ret++; 462 tag /= 128; 463 continuation = 0x80; 464 } while(tag > 0); 465 if (len < 1) 466 return ASN1_OVERFLOW; 467 *p-- = MAKE_TAG(class, type, 0x1f); 468 ret++; 469 *size = ret; 470 } 471 return 0; 472 } 473 474 int 475 der_put_length_and_tag (unsigned char *p, size_t len, size_t len_val, 476 Der_class class, Der_type type, 477 unsigned int tag, size_t *size) 478 { 479 size_t ret = 0; 480 size_t l; 481 int e; 482 483 e = der_put_length (p, len, len_val, &l); 484 if(e) 485 return e; 486 p -= l; 487 len -= l; 488 ret += l; 489 e = der_put_tag (p, len, class, type, tag, &l); 490 if(e) 491 return e; 492 493 ret += l; 494 *size = ret; 495 return 0; 496 } 497 498 int 499 _heim_time2generalizedtime (time_t t, heim_octet_string *s, int gtimep) 500 { 501 struct tm tm; 502 const size_t len = gtimep ? 15 : 13; 503 504 s->data = malloc(len + 1); 505 if (s->data == NULL) 506 return ENOMEM; 507 s->length = len; 508 if (_der_gmtime(t, &tm) == NULL) 509 return ASN1_BAD_TIMEFORMAT; 510 if (gtimep) 511 snprintf (s->data, len + 1, "%04d%02d%02d%02d%02d%02dZ", 512 tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, 513 tm.tm_hour, tm.tm_min, tm.tm_sec); 514 else 515 snprintf (s->data, len + 1, "%02d%02d%02d%02d%02d%02dZ", 516 tm.tm_year % 100, tm.tm_mon + 1, tm.tm_mday, 517 tm.tm_hour, tm.tm_min, tm.tm_sec); 518 519 return 0; 520 } 521 522 int 523 der_put_bit_string (unsigned char *p, size_t len, 524 const heim_bit_string *data, size_t *size) 525 { 526 size_t data_size = (data->length + 7) / 8; 527 if (len < data_size + 1) 528 return ASN1_OVERFLOW; 529 p -= data_size + 1; 530 531 memcpy (p+2, data->data, data_size); 532 if (data->length && (data->length % 8) != 0) 533 p[1] = 8 - (data->length % 8); 534 else 535 p[1] = 0; 536 *size = data_size + 1; 537 return 0; 538 } 539 540 int 541 _heim_der_set_sort(const void *a1, const void *a2) 542 { 543 const struct heim_octet_string *s1 = a1, *s2 = a2; 544 int ret; 545 546 ret = memcmp(s1->data, s2->data, 547 s1->length < s2->length ? s1->length : s2->length); 548 if(ret) 549 return ret; 550 return s1->length - s2->length; 551 } 552