]>
git.ipfire.org Git - thirdparty/openssl.git/blob - crypto/asn1/a_d2i_fp.c
2 * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the Apache License 2.0 (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
12 #include "internal/cryptlib.h"
13 #include "internal/numbers.h"
14 #include <openssl/buffer.h>
15 #include <openssl/asn1.h>
16 #include "internal/asn1.h"
17 #include "crypto/asn1.h"
20 # ifndef OPENSSL_NO_STDIO
22 void *ASN1_d2i_fp(void *(*xnew
) (void), d2i_of_void
*d2i
, FILE *in
, void **x
)
27 if ((b
= BIO_new(BIO_s_file())) == NULL
) {
28 ERR_raise(ERR_LIB_ASN1
, ERR_R_BUF_LIB
);
31 BIO_set_fp(b
, in
, BIO_NOCLOSE
);
32 ret
= ASN1_d2i_bio(xnew
, d2i
, b
, x
);
38 void *ASN1_d2i_bio(void *(*xnew
) (void), d2i_of_void
*d2i
, BIO
*in
, void **x
)
41 const unsigned char *p
;
45 len
= asn1_d2i_read_bio(in
, &b
);
49 p
= (unsigned char *)b
->data
;
50 ret
= d2i(x
, &p
, len
);
58 void *ASN1_item_d2i_bio(const ASN1_ITEM
*it
, BIO
*in
, void *x
)
61 const unsigned char *p
;
65 len
= asn1_d2i_read_bio(in
, &b
);
69 p
= (const unsigned char *)b
->data
;
70 ret
= ASN1_item_d2i(x
, &p
, len
, it
);
76 #ifndef OPENSSL_NO_STDIO
77 void *ASN1_item_d2i_fp(const ASN1_ITEM
*it
, FILE *in
, void *x
)
82 if ((b
= BIO_new(BIO_s_file())) == NULL
) {
83 ERR_raise(ERR_LIB_ASN1
, ERR_R_BUF_LIB
);
86 BIO_set_fp(b
, in
, BIO_NOCLOSE
);
87 ret
= ASN1_item_d2i_bio(it
, b
, x
);
94 #define ASN1_CHUNK_INITIAL_SIZE (16 * 1024)
95 int asn1_d2i_read_bio(BIO
*in
, BUF_MEM
**pb
)
100 size_t want
= HEADER_SIZE
;
106 const unsigned char *q
;
108 int inf
, tag
, xclass
;
112 ERR_raise(ERR_LIB_ASN1
, ERR_R_MALLOC_FAILURE
);
122 if (len
+ want
< len
|| !BUF_MEM_grow_clean(b
, len
+ want
)) {
123 ERR_raise(ERR_LIB_ASN1
, ERR_R_MALLOC_FAILURE
);
126 i
= BIO_read(in
, &(b
->data
[len
]), want
);
127 if (i
< 0 && diff
== 0) {
128 ERR_raise(ERR_LIB_ASN1
, ASN1_R_NOT_ENOUGH_DATA
);
133 ERR_raise(ERR_LIB_ASN1
, ASN1_R_TOO_LONG
);
139 /* else data already loaded */
141 p
= (unsigned char *)&(b
->data
[off
]);
146 inf
= ASN1_get_object(&q
, &slen
, &tag
, &xclass
, diff
);
150 e
= ERR_GET_REASON(ERR_peek_error());
151 if (e
!= ASN1_R_TOO_LONG
)
155 i
= q
- p
; /* header length */
156 off
+= i
; /* end of data */
159 /* no data body so go round again */
160 if (eos
== UINT32_MAX
) {
161 ERR_raise(ERR_LIB_ASN1
, ASN1_R_HEADER_TOO_LONG
);
166 } else if (eos
&& (slen
== 0) && (tag
== V_ASN1_EOC
)) {
167 /* eos value, so go back and read another header */
174 /* suck in slen bytes of data */
176 if (want
> (len
- off
)) {
177 size_t chunk_max
= ASN1_CHUNK_INITIAL_SIZE
;
180 if (want
> INT_MAX
/* BIO_read takes an int length */ ||
182 ERR_raise(ERR_LIB_ASN1
, ASN1_R_TOO_LONG
);
187 * Read content in chunks of increasing size
188 * so we can return an error for EOF without
189 * having to allocate the entire content length
192 size_t chunk
= want
> chunk_max
? chunk_max
: want
;
194 if (!BUF_MEM_grow_clean(b
, len
+ chunk
)) {
195 ERR_raise(ERR_LIB_ASN1
, ERR_R_MALLOC_FAILURE
);
200 i
= BIO_read(in
, &(b
->data
[len
]), chunk
);
202 ERR_raise(ERR_LIB_ASN1
, ASN1_R_NOT_ENOUGH_DATA
);
206 * This can't overflow because |len+want| didn't
212 if (chunk_max
< INT_MAX
/2)
216 if (off
+ slen
< off
) {
217 ERR_raise(ERR_LIB_ASN1
, ASN1_R_TOO_LONG
);
229 ERR_raise(ERR_LIB_ASN1
, ASN1_R_TOO_LONG
);