1 /* 2 * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the OpenSSL license (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10 #include <stdio.h> 11 #include <limits.h> 12 #include "internal/cryptlib.h" 13 #include "internal/numbers.h" 14 #include <openssl/buffer.h> 15 #include <openssl/asn1.h> 16 #include "crypto/asn1.h" 17 18 #ifndef NO_OLD_ASN1 19 # ifndef OPENSSL_NO_STDIO 20 21 void *ASN1_d2i_fp(void *(*xnew) (void), d2i_of_void *d2i, FILE *in, void **x) 22 { 23 BIO *b; 24 void *ret; 25 26 if ((b = BIO_new(BIO_s_file())) == NULL) { 27 ASN1err(ASN1_F_ASN1_D2I_FP, ERR_R_BUF_LIB); 28 return NULL; 29 } 30 BIO_set_fp(b, in, BIO_NOCLOSE); 31 ret = ASN1_d2i_bio(xnew, d2i, b, x); 32 BIO_free(b); 33 return ret; 34 } 35 # endif 36 37 void *ASN1_d2i_bio(void *(*xnew) (void), d2i_of_void *d2i, BIO *in, void **x) 38 { 39 BUF_MEM *b = NULL; 40 const unsigned char *p; 41 void *ret = NULL; 42 int len; 43 44 len = asn1_d2i_read_bio(in, &b); 45 if (len < 0) 46 goto err; 47 48 p = (unsigned char *)b->data; 49 ret = d2i(x, &p, len); 50 err: 51 BUF_MEM_free(b); 52 return ret; 53 } 54 55 #endif 56 57 void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x) 58 { 59 BUF_MEM *b = NULL; 60 const unsigned char *p; 61 void *ret = NULL; 62 int len; 63 64 len = asn1_d2i_read_bio(in, &b); 65 if (len < 0) 66 goto err; 67 68 p = (const unsigned char *)b->data; 69 ret = ASN1_item_d2i(x, &p, len, it); 70 err: 71 BUF_MEM_free(b); 72 return ret; 73 } 74 75 #ifndef OPENSSL_NO_STDIO 76 void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x) 77 { 78 BIO *b; 79 char *ret; 80 81 if ((b = BIO_new(BIO_s_file())) == NULL) { 82 ASN1err(ASN1_F_ASN1_ITEM_D2I_FP, ERR_R_BUF_LIB); 83 return NULL; 84 } 85 BIO_set_fp(b, in, BIO_NOCLOSE); 86 ret = ASN1_item_d2i_bio(it, b, x); 87 BIO_free(b); 88 return ret; 89 } 90 #endif 91 92 #define HEADER_SIZE 8 93 #define ASN1_CHUNK_INITIAL_SIZE (16 * 1024) 94 int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb) 95 { 96 BUF_MEM *b; 97 unsigned char *p; 98 int i; 99 size_t want = HEADER_SIZE; 100 uint32_t eos = 0; 101 size_t off = 0; 102 size_t len = 0; 103 104 const unsigned char *q; 105 long slen; 106 int inf, tag, xclass; 107 108 b = BUF_MEM_new(); 109 if (b == NULL) { 110 ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ERR_R_MALLOC_FAILURE); 111 return -1; 112 } 113 114 ERR_clear_error(); 115 for (;;) { 116 if (want >= (len - off)) { 117 want -= (len - off); 118 119 if (len + want < len || !BUF_MEM_grow_clean(b, len + want)) { 120 ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ERR_R_MALLOC_FAILURE); 121 goto err; 122 } 123 i = BIO_read(in, &(b->data[len]), want); 124 if ((i < 0) && ((len - off) == 0)) { 125 ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_NOT_ENOUGH_DATA); 126 goto err; 127 } 128 if (i > 0) { 129 if (len + i < len) { 130 ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_TOO_LONG); 131 goto err; 132 } 133 len += i; 134 } 135 } 136 /* else data already loaded */ 137 138 p = (unsigned char *)&(b->data[off]); 139 q = p; 140 inf = ASN1_get_object(&q, &slen, &tag, &xclass, len - off); 141 if (inf & 0x80) { 142 unsigned long e; 143 144 e = ERR_GET_REASON(ERR_peek_error()); 145 if (e != ASN1_R_TOO_LONG) 146 goto err; 147 else 148 ERR_clear_error(); /* clear error */ 149 } 150 i = q - p; /* header length */ 151 off += i; /* end of data */ 152 153 if (inf & 1) { 154 /* no data body so go round again */ 155 if (eos == UINT32_MAX) { 156 ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_HEADER_TOO_LONG); 157 goto err; 158 } 159 eos++; 160 want = HEADER_SIZE; 161 } else if (eos && (slen == 0) && (tag == V_ASN1_EOC)) { 162 /* eos value, so go back and read another header */ 163 eos--; 164 if (eos == 0) 165 break; 166 else 167 want = HEADER_SIZE; 168 } else { 169 /* suck in slen bytes of data */ 170 want = slen; 171 if (want > (len - off)) { 172 size_t chunk_max = ASN1_CHUNK_INITIAL_SIZE; 173 174 want -= (len - off); 175 if (want > INT_MAX /* BIO_read takes an int length */ || 176 len + want < len) { 177 ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_TOO_LONG); 178 goto err; 179 } 180 while (want > 0) { 181 /* 182 * Read content in chunks of increasing size 183 * so we can return an error for EOF without 184 * having to allocate the entire content length 185 * in one go. 186 */ 187 size_t chunk = want > chunk_max ? chunk_max : want; 188 189 if (!BUF_MEM_grow_clean(b, len + chunk)) { 190 ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ERR_R_MALLOC_FAILURE); 191 goto err; 192 } 193 want -= chunk; 194 while (chunk > 0) { 195 i = BIO_read(in, &(b->data[len]), chunk); 196 if (i <= 0) { 197 ASN1err(ASN1_F_ASN1_D2I_READ_BIO, 198 ASN1_R_NOT_ENOUGH_DATA); 199 goto err; 200 } 201 /* 202 * This can't overflow because |len+want| didn't 203 * overflow. 204 */ 205 len += i; 206 chunk -= i; 207 } 208 if (chunk_max < INT_MAX/2) 209 chunk_max *= 2; 210 } 211 } 212 if (off + slen < off) { 213 ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_TOO_LONG); 214 goto err; 215 } 216 off += slen; 217 if (eos == 0) { 218 break; 219 } else 220 want = HEADER_SIZE; 221 } 222 } 223 224 if (off > INT_MAX) { 225 ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_TOO_LONG); 226 goto err; 227 } 228 229 *pb = b; 230 return off; 231 err: 232 BUF_MEM_free(b); 233 return -1; 234 } 235