1 /* $NetBSD: der_length.c,v 1.2 2017/01/28 21:31:45 christos Exp $ */ 2 3 /* 4 * Copyright (c) 1997-2005 Kungliga Tekniska Högskolan 5 * (Royal Institute of Technology, Stockholm, Sweden). 6 * All rights reserved. 7 * 8 * Portions Copyright (c) 2009 Apple Inc. All rights reserved. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 21 * 3. Neither the name of the Institute nor the names of its contributors 22 * may be used to endorse or promote products derived from this software 23 * without specific prior written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35 * SUCH DAMAGE. 36 */ 37 38 #include "der_locl.h" 39 40 __RCSID("$NetBSD: der_length.c,v 1.2 2017/01/28 21:31:45 christos Exp $"); 41 42 size_t 43 _heim_len_unsigned (unsigned val) 44 { 45 size_t ret = 0; 46 int last_val_gt_128; 47 48 do { 49 ++ret; 50 last_val_gt_128 = (val >= 128); 51 val /= 256; 52 } while (val); 53 54 if(last_val_gt_128) 55 ret++; 56 57 return ret; 58 } 59 60 size_t 61 _heim_len_unsigned64 (uint64_t val) 62 { 63 size_t ret = 0; 64 int last_val_gt_128; 65 66 do { 67 ++ret; 68 last_val_gt_128 = (val >= 128); 69 val /= 256; 70 } while (val); 71 72 if(last_val_gt_128) 73 ret++; 74 75 return ret; 76 } 77 78 size_t 79 _heim_len_int (int val) 80 { 81 unsigned char q; 82 size_t ret = 0; 83 84 if (val >= 0) { 85 do { 86 q = val % 256; 87 ret++; 88 val /= 256; 89 } while(val); 90 if(q >= 128) 91 ret++; 92 } else { 93 val = ~val; 94 do { 95 q = ~(val % 256); 96 ret++; 97 val /= 256; 98 } while(val); 99 if(q < 128) 100 ret++; 101 } 102 return ret; 103 } 104 105 size_t 106 _heim_len_int64 (int64_t val) 107 { 108 unsigned char q; 109 size_t ret = 0; 110 111 if (val >= 0) { 112 do { 113 q = val % 256; 114 ret++; 115 val /= 256; 116 } while(val); 117 if(q >= 128) 118 ret++; 119 } else { 120 val = ~val; 121 do { 122 q = ~(val % 256); 123 ret++; 124 val /= 256; 125 } while(val); 126 if(q < 128) 127 ret++; 128 } 129 return ret; 130 } 131 132 static size_t 133 len_oid (const heim_oid *oid) 134 { 135 size_t ret = 1; 136 size_t n; 137 138 for (n = 2; n < oid->length; ++n) { 139 unsigned u = oid->components[n]; 140 141 do { 142 ++ret; 143 u /= 128; 144 } while(u > 0); 145 } 146 return ret; 147 } 148 149 size_t 150 der_length_len (size_t len) 151 { 152 if (len < 128) 153 return 1; 154 else { 155 int ret = 0; 156 do { 157 ++ret; 158 len /= 256; 159 } while (len); 160 return ret + 1; 161 } 162 } 163 164 size_t 165 der_length_tag(unsigned int tag) 166 { 167 size_t len = 0; 168 169 if(tag <= 30) 170 return 1; 171 while(tag) { 172 tag /= 128; 173 len++; 174 } 175 return len + 1; 176 } 177 178 size_t 179 der_length_integer (const int *data) 180 { 181 return _heim_len_int (*data); 182 } 183 184 size_t 185 der_length_integer64 (const int64_t *data) 186 { 187 return _heim_len_int64 (*data); 188 } 189 190 size_t 191 der_length_unsigned (const unsigned *data) 192 { 193 return _heim_len_unsigned(*data); 194 } 195 196 size_t 197 der_length_unsigned64 (const uint64_t *data) 198 { 199 return _heim_len_unsigned64(*data); 200 } 201 202 size_t 203 der_length_enumerated (const unsigned *data) 204 { 205 return _heim_len_int (*data); 206 } 207 208 size_t 209 der_length_general_string (const heim_general_string *data) 210 { 211 return strlen(*data); 212 } 213 214 size_t 215 der_length_utf8string (const heim_utf8_string *data) 216 { 217 return strlen(*data); 218 } 219 220 size_t 221 der_length_printable_string (const heim_printable_string *data) 222 { 223 return data->length; 224 } 225 226 size_t 227 der_length_ia5_string (const heim_ia5_string *data) 228 { 229 return data->length; 230 } 231 232 size_t 233 der_length_bmp_string (const heim_bmp_string *data) 234 { 235 return data->length * 2; 236 } 237 238 size_t 239 der_length_universal_string (const heim_universal_string *data) 240 { 241 return data->length * 4; 242 } 243 244 size_t 245 der_length_visible_string (const heim_visible_string *data) 246 { 247 return strlen(*data); 248 } 249 250 size_t 251 der_length_octet_string (const heim_octet_string *k) 252 { 253 return k->length; 254 } 255 256 size_t 257 der_length_heim_integer (const heim_integer *k) 258 { 259 if (k->length == 0) 260 return 1; 261 if (k->negative) 262 return k->length + (((~(((unsigned char *)k->data)[0])) & 0x80) ? 0 : 1); 263 else 264 return k->length + ((((unsigned char *)k->data)[0] & 0x80) ? 1 : 0); 265 } 266 267 size_t 268 der_length_oid (const heim_oid *k) 269 { 270 return len_oid (k); 271 } 272 273 size_t 274 der_length_generalized_time (const time_t *t) 275 { 276 heim_octet_string k; 277 size_t ret; 278 279 _heim_time2generalizedtime (*t, &k, 1); 280 ret = k.length; 281 free(k.data); 282 return ret; 283 } 284 285 size_t 286 der_length_utctime (const time_t *t) 287 { 288 heim_octet_string k; 289 size_t ret; 290 291 _heim_time2generalizedtime (*t, &k, 0); 292 ret = k.length; 293 free(k.data); 294 return ret; 295 } 296 297 size_t 298 der_length_boolean (const int *k) 299 { 300 return 1; 301 } 302 303 size_t 304 der_length_bit_string (const heim_bit_string *k) 305 { 306 return (k->length + 7) / 8 + 1; 307 } 308