1 /* 2 * Copyright (c) 1997, 1998, 1999 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.27 1999/12/02 17:05:01 joda 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_general_string (const unsigned char *p, size_t len, 229 general_string *str, size_t *size) 230 { 231 size_t ret = 0; 232 size_t l; 233 int e; 234 size_t slen; 235 236 e = der_match_tag (p, len, UNIV, PRIM, UT_GeneralString, &l); 237 if (e) return e; 238 p += l; 239 len -= l; 240 ret += l; 241 242 e = der_get_length (p, len, &slen, &l); 243 if (e) return e; 244 p += l; 245 len -= l; 246 ret += l; 247 if (len < slen) 248 return ASN1_OVERRUN; 249 250 e = der_get_general_string (p, slen, str, &l); 251 if (e) return e; 252 p += l; 253 len -= l; 254 ret += l; 255 if(size) *size = ret; 256 return 0; 257 } 258 259 int 260 decode_octet_string (const unsigned char *p, size_t len, 261 octet_string *k, size_t *size) 262 { 263 size_t ret = 0; 264 size_t l; 265 int e; 266 size_t slen; 267 268 e = der_match_tag (p, len, UNIV, PRIM, UT_OctetString, &l); 269 if (e) return e; 270 p += l; 271 len -= l; 272 ret += l; 273 274 e = der_get_length (p, len, &slen, &l); 275 if (e) return e; 276 p += l; 277 len -= l; 278 ret += l; 279 if (len < slen) 280 return ASN1_OVERRUN; 281 282 e = der_get_octet_string (p, slen, k, &l); 283 if (e) return e; 284 p += l; 285 len -= l; 286 ret += l; 287 if(size) *size = ret; 288 return 0; 289 } 290 291 static void 292 generalizedtime2time (const char *s, time_t *t) 293 { 294 struct tm tm; 295 296 memset(&tm, 0, sizeof(tm)); 297 sscanf (s, "%04d%02d%02d%02d%02d%02dZ", 298 &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, 299 &tm.tm_min, &tm.tm_sec); 300 tm.tm_year -= 1900; 301 tm.tm_mon -= 1; 302 *t = timegm (&tm); 303 } 304 305 int 306 decode_generalized_time (const unsigned char *p, size_t len, 307 time_t *t, size_t *size) 308 { 309 octet_string k; 310 char *times; 311 size_t ret = 0; 312 size_t l; 313 int e; 314 size_t slen; 315 316 e = der_match_tag (p, len, UNIV, PRIM, UT_GeneralizedTime, &l); 317 if (e) return e; 318 p += l; 319 len -= l; 320 ret += l; 321 322 e = der_get_length (p, len, &slen, &l); 323 if (e) return e; 324 p += l; 325 len -= l; 326 ret += l; 327 if (len < slen) 328 return ASN1_OVERRUN; 329 e = der_get_octet_string (p, slen, &k, &l); 330 if (e) return e; 331 p += l; 332 len -= l; 333 ret += l; 334 times = realloc(k.data, k.length + 1); 335 if (times == NULL){ 336 free(k.data); 337 return ENOMEM; 338 } 339 times[k.length] = 0; 340 generalizedtime2time (times, t); 341 free (times); 342 if(size) *size = ret; 343 return 0; 344 } 345 346 347 int 348 fix_dce(size_t reallen, size_t *len) 349 { 350 if(reallen == ASN1_INDEFINITE) 351 return 1; 352 if(*len < reallen) 353 return -1; 354 *len = reallen; 355 return 0; 356 } 357