1b528cefcSMark Murray /* 2ae771770SStanislav Sedov * Copyright (c) 1997-2005 Kungliga Tekniska Högskolan 3b528cefcSMark Murray * (Royal Institute of Technology, Stockholm, Sweden). 4b528cefcSMark Murray * All rights reserved. 5b528cefcSMark Murray * 6b528cefcSMark Murray * Redistribution and use in source and binary forms, with or without 7b528cefcSMark Murray * modification, are permitted provided that the following conditions 8b528cefcSMark Murray * are met: 9b528cefcSMark Murray * 10b528cefcSMark Murray * 1. Redistributions of source code must retain the above copyright 11b528cefcSMark Murray * notice, this list of conditions and the following disclaimer. 12b528cefcSMark Murray * 13b528cefcSMark Murray * 2. Redistributions in binary form must reproduce the above copyright 14b528cefcSMark Murray * notice, this list of conditions and the following disclaimer in the 15b528cefcSMark Murray * documentation and/or other materials provided with the distribution. 16b528cefcSMark Murray * 17b528cefcSMark Murray * 3. Neither the name of the Institute nor the names of its contributors 18b528cefcSMark Murray * may be used to endorse or promote products derived from this software 19b528cefcSMark Murray * without specific prior written permission. 20b528cefcSMark Murray * 21b528cefcSMark Murray * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22b528cefcSMark Murray * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23b528cefcSMark Murray * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24b528cefcSMark Murray * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25b528cefcSMark Murray * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26b528cefcSMark Murray * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27b528cefcSMark Murray * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28b528cefcSMark Murray * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29b528cefcSMark Murray * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30b528cefcSMark Murray * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31b528cefcSMark Murray * SUCH DAMAGE. 32b528cefcSMark Murray */ 33b528cefcSMark Murray 34b528cefcSMark Murray #include "der_locl.h" 35b528cefcSMark Murray 36ae771770SStanislav Sedov RCSID("$Id$"); 37b528cefcSMark Murray 38b528cefcSMark Murray /* 39b528cefcSMark Murray * All encoding functions take a pointer `p' to first position in 40b528cefcSMark Murray * which to write, from the right, `len' which means the maximum 414137ff4cSJacques Vidrine * number of characters we are able to write. The function returns 424137ff4cSJacques Vidrine * the number of characters written in `size' (if non-NULL). 434137ff4cSJacques Vidrine * The return value is 0 or an error. 44b528cefcSMark Murray */ 45b528cefcSMark Murray 46c19800e8SDoug Rabson int 47c19800e8SDoug Rabson der_put_unsigned (unsigned char *p, size_t len, const unsigned *v, size_t *size) 48b528cefcSMark Murray { 49b528cefcSMark Murray unsigned char *base = p; 50c19800e8SDoug Rabson unsigned val = *v; 51b528cefcSMark Murray 52b528cefcSMark Murray if (val) { 53b528cefcSMark Murray while (len > 0 && val) { 54b528cefcSMark Murray *p-- = val % 256; 55b528cefcSMark Murray val /= 256; 56b528cefcSMark Murray --len; 57b528cefcSMark Murray } 58b528cefcSMark Murray if (val != 0) 59b528cefcSMark Murray return ASN1_OVERFLOW; 60b528cefcSMark Murray else { 61c19800e8SDoug Rabson if(p[1] >= 128) { 62c19800e8SDoug Rabson if(len < 1) 63c19800e8SDoug Rabson return ASN1_OVERFLOW; 64c19800e8SDoug Rabson *p-- = 0; 65c19800e8SDoug Rabson } 66b528cefcSMark Murray *size = base - p; 67b528cefcSMark Murray return 0; 68b528cefcSMark Murray } 69b528cefcSMark Murray } else if (len < 1) 70b528cefcSMark Murray return ASN1_OVERFLOW; 71b528cefcSMark Murray else { 72b528cefcSMark Murray *p = 0; 73b528cefcSMark Murray *size = 1; 74b528cefcSMark Murray return 0; 75b528cefcSMark Murray } 76b528cefcSMark Murray } 77b528cefcSMark Murray 78b528cefcSMark Murray int 79*1b748759SDimitry Andric der_put_unsigned64 (unsigned char *p, size_t len, const uint64_t *v, size_t *size) 80*1b748759SDimitry Andric { 81*1b748759SDimitry Andric unsigned char *base = p; 82*1b748759SDimitry Andric uint64_t val = *v; 83*1b748759SDimitry Andric 84*1b748759SDimitry Andric if (val) { 85*1b748759SDimitry Andric while (len > 0 && val) { 86*1b748759SDimitry Andric *p-- = val % 256; 87*1b748759SDimitry Andric val /= 256; 88*1b748759SDimitry Andric --len; 89*1b748759SDimitry Andric } 90*1b748759SDimitry Andric if (val != 0) 91*1b748759SDimitry Andric return ASN1_OVERFLOW; 92*1b748759SDimitry Andric else { 93*1b748759SDimitry Andric if(p[1] >= 128) { 94*1b748759SDimitry Andric if(len < 1) 95*1b748759SDimitry Andric return ASN1_OVERFLOW; 96*1b748759SDimitry Andric *p-- = 0; 97*1b748759SDimitry Andric } 98*1b748759SDimitry Andric *size = base - p; 99*1b748759SDimitry Andric return 0; 100*1b748759SDimitry Andric } 101*1b748759SDimitry Andric } else if (len < 1) 102*1b748759SDimitry Andric return ASN1_OVERFLOW; 103*1b748759SDimitry Andric else { 104*1b748759SDimitry Andric *p = 0; 105*1b748759SDimitry Andric *size = 1; 106*1b748759SDimitry Andric return 0; 107*1b748759SDimitry Andric } 108*1b748759SDimitry Andric } 109*1b748759SDimitry Andric 110*1b748759SDimitry Andric int 111c19800e8SDoug Rabson der_put_integer (unsigned char *p, size_t len, const int *v, size_t *size) 112b528cefcSMark Murray { 113b528cefcSMark Murray unsigned char *base = p; 114c19800e8SDoug Rabson int val = *v; 115b528cefcSMark Murray 116b528cefcSMark Murray if(val >= 0) { 117b528cefcSMark Murray do { 118b528cefcSMark Murray if(len < 1) 119b528cefcSMark Murray return ASN1_OVERFLOW; 120b528cefcSMark Murray *p-- = val % 256; 121b528cefcSMark Murray len--; 122b528cefcSMark Murray val /= 256; 123b528cefcSMark Murray } while(val); 124b528cefcSMark Murray if(p[1] >= 128) { 125b528cefcSMark Murray if(len < 1) 126b528cefcSMark Murray return ASN1_OVERFLOW; 127b528cefcSMark Murray *p-- = 0; 128b528cefcSMark Murray len--; 129b528cefcSMark Murray } 130b528cefcSMark Murray } else { 131b528cefcSMark Murray val = ~val; 132b528cefcSMark Murray do { 133b528cefcSMark Murray if(len < 1) 134b528cefcSMark Murray return ASN1_OVERFLOW; 135b528cefcSMark Murray *p-- = ~(val % 256); 136b528cefcSMark Murray len--; 137b528cefcSMark Murray val /= 256; 138b528cefcSMark Murray } while(val); 139b528cefcSMark Murray if(p[1] < 128) { 140b528cefcSMark Murray if(len < 1) 141b528cefcSMark Murray return ASN1_OVERFLOW; 142b528cefcSMark Murray *p-- = 0xff; 143b528cefcSMark Murray len--; 144b528cefcSMark Murray } 145b528cefcSMark Murray } 146b528cefcSMark Murray *size = base - p; 147b528cefcSMark Murray return 0; 148b528cefcSMark Murray } 149b528cefcSMark Murray 150*1b748759SDimitry Andric int 151*1b748759SDimitry Andric der_put_integer64 (unsigned char *p, size_t len, const int64_t *v, size_t *size) 152*1b748759SDimitry Andric { 153*1b748759SDimitry Andric unsigned char *base = p; 154*1b748759SDimitry Andric int64_t val = *v; 155*1b748759SDimitry Andric 156*1b748759SDimitry Andric if(val >= 0) { 157*1b748759SDimitry Andric do { 158*1b748759SDimitry Andric if(len < 1) 159*1b748759SDimitry Andric return ASN1_OVERFLOW; 160*1b748759SDimitry Andric *p-- = val % 256; 161*1b748759SDimitry Andric len--; 162*1b748759SDimitry Andric val /= 256; 163*1b748759SDimitry Andric } while(val); 164*1b748759SDimitry Andric if(p[1] >= 128) { 165*1b748759SDimitry Andric if(len < 1) 166*1b748759SDimitry Andric return ASN1_OVERFLOW; 167*1b748759SDimitry Andric *p-- = 0; 168*1b748759SDimitry Andric len--; 169*1b748759SDimitry Andric } 170*1b748759SDimitry Andric } else { 171*1b748759SDimitry Andric val = ~val; 172*1b748759SDimitry Andric do { 173*1b748759SDimitry Andric if(len < 1) 174*1b748759SDimitry Andric return ASN1_OVERFLOW; 175*1b748759SDimitry Andric *p-- = ~(val % 256); 176*1b748759SDimitry Andric len--; 177*1b748759SDimitry Andric val /= 256; 178*1b748759SDimitry Andric } while(val); 179*1b748759SDimitry Andric if(p[1] < 128) { 180*1b748759SDimitry Andric if(len < 1) 181*1b748759SDimitry Andric return ASN1_OVERFLOW; 182*1b748759SDimitry Andric *p-- = 0xff; 183*1b748759SDimitry Andric len--; 184*1b748759SDimitry Andric } 185*1b748759SDimitry Andric } 186*1b748759SDimitry Andric *size = base - p; 187*1b748759SDimitry Andric return 0; 188*1b748759SDimitry Andric } 189*1b748759SDimitry Andric 190b528cefcSMark Murray 191b528cefcSMark Murray int 192b528cefcSMark Murray der_put_length (unsigned char *p, size_t len, size_t val, size_t *size) 193b528cefcSMark Murray { 194b528cefcSMark Murray if (len < 1) 195b528cefcSMark Murray return ASN1_OVERFLOW; 196c19800e8SDoug Rabson 1974137ff4cSJacques Vidrine if (val < 128) { 198b528cefcSMark Murray *p = val; 199b528cefcSMark Murray *size = 1; 200b528cefcSMark Murray } else { 201c19800e8SDoug Rabson size_t l = 0; 202b528cefcSMark Murray 203c19800e8SDoug Rabson while(val > 0) { 204c19800e8SDoug Rabson if(len < 2) 205c19800e8SDoug Rabson return ASN1_OVERFLOW; 206c19800e8SDoug Rabson *p-- = val % 256; 207c19800e8SDoug Rabson val /= 256; 208c19800e8SDoug Rabson len--; 209c19800e8SDoug Rabson l++; 210c19800e8SDoug Rabson } 211b528cefcSMark Murray *p = 0x80 | l; 212c19800e8SDoug Rabson if(size) 213b528cefcSMark Murray *size = l + 1; 214c19800e8SDoug Rabson } 215b528cefcSMark Murray return 0; 216b528cefcSMark Murray } 217c19800e8SDoug Rabson 218c19800e8SDoug Rabson int 219c19800e8SDoug Rabson der_put_boolean(unsigned char *p, size_t len, const int *data, size_t *size) 220c19800e8SDoug Rabson { 221c19800e8SDoug Rabson if(len < 1) 222c19800e8SDoug Rabson return ASN1_OVERFLOW; 223c19800e8SDoug Rabson if(*data != 0) 224c19800e8SDoug Rabson *p = 0xff; 225c19800e8SDoug Rabson else 226c19800e8SDoug Rabson *p = 0; 227c19800e8SDoug Rabson *size = 1; 228c19800e8SDoug Rabson return 0; 229b528cefcSMark Murray } 230b528cefcSMark Murray 231b528cefcSMark Murray int 232b528cefcSMark Murray der_put_general_string (unsigned char *p, size_t len, 233c19800e8SDoug Rabson const heim_general_string *str, size_t *size) 234b528cefcSMark Murray { 235b528cefcSMark Murray size_t slen = strlen(*str); 236b528cefcSMark Murray 237b528cefcSMark Murray if (len < slen) 238b528cefcSMark Murray return ASN1_OVERFLOW; 239b528cefcSMark Murray p -= slen; 240b528cefcSMark Murray memcpy (p+1, *str, slen); 241b528cefcSMark Murray *size = slen; 242b528cefcSMark Murray return 0; 243b528cefcSMark Murray } 244b528cefcSMark Murray 245b528cefcSMark Murray int 246c19800e8SDoug Rabson der_put_utf8string (unsigned char *p, size_t len, 247c19800e8SDoug Rabson const heim_utf8_string *str, size_t *size) 248c19800e8SDoug Rabson { 249c19800e8SDoug Rabson return der_put_general_string(p, len, str, size); 250c19800e8SDoug Rabson } 251c19800e8SDoug Rabson 252c19800e8SDoug Rabson int 253c19800e8SDoug Rabson der_put_printable_string (unsigned char *p, size_t len, 254c19800e8SDoug Rabson const heim_printable_string *str, size_t *size) 255c19800e8SDoug Rabson { 256ae771770SStanislav Sedov return der_put_octet_string(p, len, str, size); 257c19800e8SDoug Rabson } 258c19800e8SDoug Rabson 259c19800e8SDoug Rabson int 260c19800e8SDoug Rabson der_put_ia5_string (unsigned char *p, size_t len, 261c19800e8SDoug Rabson const heim_ia5_string *str, size_t *size) 262c19800e8SDoug Rabson { 263ae771770SStanislav Sedov return der_put_octet_string(p, len, str, size); 264c19800e8SDoug Rabson } 265c19800e8SDoug Rabson 266c19800e8SDoug Rabson int 267c19800e8SDoug Rabson der_put_bmp_string (unsigned char *p, size_t len, 268c19800e8SDoug Rabson const heim_bmp_string *data, size_t *size) 269c19800e8SDoug Rabson { 270c19800e8SDoug Rabson size_t i; 271c19800e8SDoug Rabson if (len / 2 < data->length) 272c19800e8SDoug Rabson return ASN1_OVERFLOW; 273c19800e8SDoug Rabson p -= data->length * 2; 274c19800e8SDoug Rabson for (i = 0; i < data->length; i++) { 275c19800e8SDoug Rabson p[1] = (data->data[i] >> 8) & 0xff; 276c19800e8SDoug Rabson p[2] = data->data[i] & 0xff; 277c19800e8SDoug Rabson p += 2; 278c19800e8SDoug Rabson } 279c19800e8SDoug Rabson if (size) *size = data->length * 2; 280c19800e8SDoug Rabson return 0; 281c19800e8SDoug Rabson } 282c19800e8SDoug Rabson 283c19800e8SDoug Rabson int 284c19800e8SDoug Rabson der_put_universal_string (unsigned char *p, size_t len, 285c19800e8SDoug Rabson const heim_universal_string *data, size_t *size) 286c19800e8SDoug Rabson { 287c19800e8SDoug Rabson size_t i; 288c19800e8SDoug Rabson if (len / 4 < data->length) 289c19800e8SDoug Rabson return ASN1_OVERFLOW; 290c19800e8SDoug Rabson p -= data->length * 4; 291c19800e8SDoug Rabson for (i = 0; i < data->length; i++) { 292c19800e8SDoug Rabson p[1] = (data->data[i] >> 24) & 0xff; 293c19800e8SDoug Rabson p[2] = (data->data[i] >> 16) & 0xff; 294c19800e8SDoug Rabson p[3] = (data->data[i] >> 8) & 0xff; 295c19800e8SDoug Rabson p[4] = data->data[i] & 0xff; 296c19800e8SDoug Rabson p += 4; 297c19800e8SDoug Rabson } 298c19800e8SDoug Rabson if (size) *size = data->length * 4; 299c19800e8SDoug Rabson return 0; 300c19800e8SDoug Rabson } 301c19800e8SDoug Rabson 302c19800e8SDoug Rabson int 303c19800e8SDoug Rabson der_put_visible_string (unsigned char *p, size_t len, 304c19800e8SDoug Rabson const heim_visible_string *str, size_t *size) 305c19800e8SDoug Rabson { 306c19800e8SDoug Rabson return der_put_general_string(p, len, str, size); 307c19800e8SDoug Rabson } 308c19800e8SDoug Rabson 309c19800e8SDoug Rabson int 310b528cefcSMark Murray der_put_octet_string (unsigned char *p, size_t len, 311c19800e8SDoug Rabson const heim_octet_string *data, size_t *size) 312b528cefcSMark Murray { 313b528cefcSMark Murray if (len < data->length) 314b528cefcSMark Murray return ASN1_OVERFLOW; 315b528cefcSMark Murray p -= data->length; 316b528cefcSMark Murray memcpy (p+1, data->data, data->length); 317b528cefcSMark Murray *size = data->length; 318b528cefcSMark Murray return 0; 319b528cefcSMark Murray } 320b528cefcSMark Murray 321b528cefcSMark Murray int 322c19800e8SDoug Rabson der_put_heim_integer (unsigned char *p, size_t len, 323c19800e8SDoug Rabson const heim_integer *data, size_t *size) 324c19800e8SDoug Rabson { 325c19800e8SDoug Rabson unsigned char *buf = data->data; 326c19800e8SDoug Rabson int hibitset = 0; 327c19800e8SDoug Rabson 328c19800e8SDoug Rabson if (data->length == 0) { 329c19800e8SDoug Rabson if (len < 1) 330c19800e8SDoug Rabson return ASN1_OVERFLOW; 331c19800e8SDoug Rabson *p-- = 0; 332c19800e8SDoug Rabson if (size) 333c19800e8SDoug Rabson *size = 1; 334c19800e8SDoug Rabson return 0; 335c19800e8SDoug Rabson } 336c19800e8SDoug Rabson if (len < data->length) 337c19800e8SDoug Rabson return ASN1_OVERFLOW; 338c19800e8SDoug Rabson 339c19800e8SDoug Rabson len -= data->length; 340c19800e8SDoug Rabson 341c19800e8SDoug Rabson if (data->negative) { 342c19800e8SDoug Rabson int i, carry; 343c19800e8SDoug Rabson for (i = data->length - 1, carry = 1; i >= 0; i--) { 344c19800e8SDoug Rabson *p = buf[i] ^ 0xff; 345c19800e8SDoug Rabson if (carry) 346c19800e8SDoug Rabson carry = !++*p; 347c19800e8SDoug Rabson p--; 348c19800e8SDoug Rabson } 349c19800e8SDoug Rabson if (p[1] < 128) { 350c19800e8SDoug Rabson if (len < 1) 351c19800e8SDoug Rabson return ASN1_OVERFLOW; 352c19800e8SDoug Rabson *p-- = 0xff; 353c19800e8SDoug Rabson len--; 354c19800e8SDoug Rabson hibitset = 1; 355c19800e8SDoug Rabson } 356c19800e8SDoug Rabson } else { 357c19800e8SDoug Rabson p -= data->length; 358c19800e8SDoug Rabson memcpy(p + 1, buf, data->length); 359c19800e8SDoug Rabson 360c19800e8SDoug Rabson if (p[1] >= 128) { 361c19800e8SDoug Rabson if (len < 1) 362c19800e8SDoug Rabson return ASN1_OVERFLOW; 363c19800e8SDoug Rabson p[0] = 0; 364c19800e8SDoug Rabson len--; 365c19800e8SDoug Rabson hibitset = 1; 366c19800e8SDoug Rabson } 367c19800e8SDoug Rabson } 368c19800e8SDoug Rabson if (size) 369c19800e8SDoug Rabson *size = data->length + hibitset; 370c19800e8SDoug Rabson return 0; 371c19800e8SDoug Rabson } 372c19800e8SDoug Rabson 373c19800e8SDoug Rabson int 374c19800e8SDoug Rabson der_put_generalized_time (unsigned char *p, size_t len, 375c19800e8SDoug Rabson const time_t *data, size_t *size) 376c19800e8SDoug Rabson { 377c19800e8SDoug Rabson heim_octet_string k; 378c19800e8SDoug Rabson size_t l; 379c19800e8SDoug Rabson int e; 380c19800e8SDoug Rabson 381c19800e8SDoug Rabson e = _heim_time2generalizedtime (*data, &k, 1); 382c19800e8SDoug Rabson if (e) 383c19800e8SDoug Rabson return e; 384c19800e8SDoug Rabson e = der_put_octet_string(p, len, &k, &l); 385c19800e8SDoug Rabson free(k.data); 386c19800e8SDoug Rabson if(e) 387c19800e8SDoug Rabson return e; 388c19800e8SDoug Rabson if(size) 389c19800e8SDoug Rabson *size = l; 390c19800e8SDoug Rabson return 0; 391c19800e8SDoug Rabson } 392c19800e8SDoug Rabson 393c19800e8SDoug Rabson int 394c19800e8SDoug Rabson der_put_utctime (unsigned char *p, size_t len, 395c19800e8SDoug Rabson const time_t *data, size_t *size) 396c19800e8SDoug Rabson { 397c19800e8SDoug Rabson heim_octet_string k; 398c19800e8SDoug Rabson size_t l; 399c19800e8SDoug Rabson int e; 400c19800e8SDoug Rabson 401c19800e8SDoug Rabson e = _heim_time2generalizedtime (*data, &k, 0); 402c19800e8SDoug Rabson if (e) 403c19800e8SDoug Rabson return e; 404c19800e8SDoug Rabson e = der_put_octet_string(p, len, &k, &l); 405c19800e8SDoug Rabson free(k.data); 406c19800e8SDoug Rabson if(e) 407c19800e8SDoug Rabson return e; 408c19800e8SDoug Rabson if(size) 409c19800e8SDoug Rabson *size = l; 410c19800e8SDoug Rabson return 0; 411c19800e8SDoug Rabson } 412c19800e8SDoug Rabson 413c19800e8SDoug Rabson int 4144137ff4cSJacques Vidrine der_put_oid (unsigned char *p, size_t len, 415c19800e8SDoug Rabson const heim_oid *data, size_t *size) 4164137ff4cSJacques Vidrine { 4174137ff4cSJacques Vidrine unsigned char *base = p; 4184137ff4cSJacques Vidrine int n; 4194137ff4cSJacques Vidrine 4204137ff4cSJacques Vidrine for (n = data->length - 1; n >= 2; --n) { 4214137ff4cSJacques Vidrine unsigned u = data->components[n]; 4224137ff4cSJacques Vidrine 4234137ff4cSJacques Vidrine if (len < 1) 4244137ff4cSJacques Vidrine return ASN1_OVERFLOW; 4254137ff4cSJacques Vidrine *p-- = u % 128; 4264137ff4cSJacques Vidrine u /= 128; 4274137ff4cSJacques Vidrine --len; 4284137ff4cSJacques Vidrine while (u > 0) { 4294137ff4cSJacques Vidrine if (len < 1) 4304137ff4cSJacques Vidrine return ASN1_OVERFLOW; 4314137ff4cSJacques Vidrine *p-- = 128 + u % 128; 4324137ff4cSJacques Vidrine u /= 128; 4334137ff4cSJacques Vidrine --len; 4344137ff4cSJacques Vidrine } 4354137ff4cSJacques Vidrine } 4364137ff4cSJacques Vidrine if (len < 1) 4374137ff4cSJacques Vidrine return ASN1_OVERFLOW; 4384137ff4cSJacques Vidrine *p-- = 40 * data->components[0] + data->components[1]; 4394137ff4cSJacques Vidrine *size = base - p; 4404137ff4cSJacques Vidrine return 0; 4414137ff4cSJacques Vidrine } 4424137ff4cSJacques Vidrine 4434137ff4cSJacques Vidrine int 444b528cefcSMark Murray der_put_tag (unsigned char *p, size_t len, Der_class class, Der_type type, 445c19800e8SDoug Rabson unsigned int tag, size_t *size) 446b528cefcSMark Murray { 447c19800e8SDoug Rabson if (tag <= 30) { 448b528cefcSMark Murray if (len < 1) 449b528cefcSMark Murray return ASN1_OVERFLOW; 450c19800e8SDoug Rabson *p = MAKE_TAG(class, type, tag); 451b528cefcSMark Murray *size = 1; 452c19800e8SDoug Rabson } else { 453c19800e8SDoug Rabson size_t ret = 0; 454c19800e8SDoug Rabson unsigned int continuation = 0; 455c19800e8SDoug Rabson 456c19800e8SDoug Rabson do { 457c19800e8SDoug Rabson if (len < 1) 458c19800e8SDoug Rabson return ASN1_OVERFLOW; 459c19800e8SDoug Rabson *p-- = tag % 128 | continuation; 460c19800e8SDoug Rabson len--; 461c19800e8SDoug Rabson ret++; 462c19800e8SDoug Rabson tag /= 128; 463c19800e8SDoug Rabson continuation = 0x80; 464c19800e8SDoug Rabson } while(tag > 0); 465c19800e8SDoug Rabson if (len < 1) 466c19800e8SDoug Rabson return ASN1_OVERFLOW; 467c19800e8SDoug Rabson *p-- = MAKE_TAG(class, type, 0x1f); 468c19800e8SDoug Rabson ret++; 469c19800e8SDoug Rabson *size = ret; 470c19800e8SDoug Rabson } 471b528cefcSMark Murray return 0; 472b528cefcSMark Murray } 473b528cefcSMark Murray 474b528cefcSMark Murray int 475b528cefcSMark Murray der_put_length_and_tag (unsigned char *p, size_t len, size_t len_val, 476c19800e8SDoug Rabson Der_class class, Der_type type, 477c19800e8SDoug Rabson unsigned int tag, size_t *size) 478b528cefcSMark Murray { 479b528cefcSMark Murray size_t ret = 0; 480b528cefcSMark Murray size_t l; 481b528cefcSMark Murray int e; 482b528cefcSMark Murray 483b528cefcSMark Murray e = der_put_length (p, len, len_val, &l); 484b528cefcSMark Murray if(e) 485b528cefcSMark Murray return e; 486b528cefcSMark Murray p -= l; 487b528cefcSMark Murray len -= l; 488b528cefcSMark Murray ret += l; 489b528cefcSMark Murray e = der_put_tag (p, len, class, type, tag, &l); 490b528cefcSMark Murray if(e) 491b528cefcSMark Murray return e; 492ae771770SStanislav Sedov 493b528cefcSMark Murray ret += l; 494b528cefcSMark Murray *size = ret; 495b528cefcSMark Murray return 0; 496b528cefcSMark Murray } 497b528cefcSMark Murray 498b528cefcSMark Murray int 499c19800e8SDoug Rabson _heim_time2generalizedtime (time_t t, heim_octet_string *s, int gtimep) 500b528cefcSMark Murray { 501ae771770SStanislav Sedov struct tm tm; 502c19800e8SDoug Rabson const size_t len = gtimep ? 15 : 13; 503bbd80c28SJacques Vidrine 504bbd80c28SJacques Vidrine s->data = malloc(len + 1); 5055e9cd1aeSAssar Westerlund if (s->data == NULL) 5065e9cd1aeSAssar Westerlund return ENOMEM; 507bbd80c28SJacques Vidrine s->length = len; 508ae771770SStanislav Sedov if (_der_gmtime(t, &tm) == NULL) 509ae771770SStanislav Sedov return ASN1_BAD_TIMEFORMAT; 510c19800e8SDoug Rabson if (gtimep) 511bbd80c28SJacques Vidrine snprintf (s->data, len + 1, "%04d%02d%02d%02d%02d%02dZ", 512ae771770SStanislav Sedov tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, 513ae771770SStanislav Sedov tm.tm_hour, tm.tm_min, tm.tm_sec); 514c19800e8SDoug Rabson else 515c19800e8SDoug Rabson snprintf (s->data, len + 1, "%02d%02d%02d%02d%02d%02dZ", 516ae771770SStanislav Sedov tm.tm_year % 100, tm.tm_mon + 1, tm.tm_mday, 517ae771770SStanislav Sedov tm.tm_hour, tm.tm_min, tm.tm_sec); 518c19800e8SDoug Rabson 5195e9cd1aeSAssar Westerlund return 0; 520b528cefcSMark Murray } 521b528cefcSMark Murray 522b528cefcSMark Murray int 523c19800e8SDoug Rabson der_put_bit_string (unsigned char *p, size_t len, 524c19800e8SDoug Rabson const heim_bit_string *data, size_t *size) 525b528cefcSMark Murray { 526c19800e8SDoug Rabson size_t data_size = (data->length + 7) / 8; 527c19800e8SDoug Rabson if (len < data_size + 1) 528c19800e8SDoug Rabson return ASN1_OVERFLOW; 529c19800e8SDoug Rabson p -= data_size + 1; 530ae771770SStanislav Sedov 531c19800e8SDoug Rabson memcpy (p+2, data->data, data_size); 532c19800e8SDoug Rabson if (data->length && (data->length % 8) != 0) 533c19800e8SDoug Rabson p[1] = 8 - (data->length % 8); 534c19800e8SDoug Rabson else 535c19800e8SDoug Rabson p[1] = 0; 536c19800e8SDoug Rabson *size = data_size + 1; 537b528cefcSMark Murray return 0; 538b528cefcSMark Murray } 539c19800e8SDoug Rabson 540c19800e8SDoug Rabson int 541c19800e8SDoug Rabson _heim_der_set_sort(const void *a1, const void *a2) 542c19800e8SDoug Rabson { 543c19800e8SDoug Rabson const struct heim_octet_string *s1 = a1, *s2 = a2; 544c19800e8SDoug Rabson int ret; 545c19800e8SDoug Rabson 546c19800e8SDoug Rabson ret = memcmp(s1->data, s2->data, 547c19800e8SDoug Rabson s1->length < s2->length ? s1->length : s2->length); 548c19800e8SDoug Rabson if(ret) 549c19800e8SDoug Rabson return ret; 550c19800e8SDoug Rabson return s1->length - s2->length; 551c19800e8SDoug Rabson } 552