#include <stdio.h>
#include "cryptlib.h"
-#include "buffer.h"
-#include "asn1_mac.h"
+#include <openssl/buffer.h>
+#include <openssl/asn1_mac.h>
-#define HEADER_SIZE 8
+static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb);
+
+#ifndef NO_OLD_ASN1
+#ifndef OPENSSL_NO_FP_API
-#ifndef NO_FP_API
-char *ASN1_d2i_fp(char *(*xnew)(), char *(*d2i)(), FILE *in,
- unsigned char **x)
+void *ASN1_d2i_fp(void *(*xnew)(void), d2i_of_void *d2i, FILE *in, void **x)
{
BIO *b;
- char *ret;
+ void *ret;
if ((b=BIO_new(BIO_s_file())) == NULL)
{
}
#endif
-char *ASN1_d2i_bio(char *(*xnew)(), char *(*d2i)(), BIO *in,
- unsigned char **x)
+void *ASN1_d2i_bio(void *(*xnew)(void), d2i_of_void *d2i, BIO *in, void **x)
+ {
+ BUF_MEM *b = NULL;
+ const unsigned char *p;
+ void *ret=NULL;
+ int len;
+
+ len = asn1_d2i_read_bio(in, &b);
+ if(len < 0) goto err;
+
+ p=(unsigned char *)b->data;
+ ret=d2i(x,&p,len);
+err:
+ if (b != NULL) BUF_MEM_free(b);
+ return(ret);
+ }
+
+#endif
+
+void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x)
+ {
+ BUF_MEM *b = NULL;
+ const unsigned char *p;
+ void *ret=NULL;
+ int len;
+
+ len = asn1_d2i_read_bio(in, &b);
+ if(len < 0) goto err;
+
+ p=(const unsigned char *)b->data;
+ ret=ASN1_item_d2i(x,&p,len, it);
+err:
+ if (b != NULL) BUF_MEM_free(b);
+ return(ret);
+ }
+
+#ifndef OPENSSL_NO_FP_API
+void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x)
+ {
+ BIO *b;
+ char *ret;
+
+ if ((b=BIO_new(BIO_s_file())) == NULL)
+ {
+ ASN1err(ASN1_F_ASN1_ITEM_D2I_FP,ERR_R_BUF_LIB);
+ return(NULL);
+ }
+ BIO_set_fp(b,in,BIO_NOCLOSE);
+ ret=ASN1_item_d2i_bio(it,b,x);
+ BIO_free(b);
+ return(ret);
+ }
+#endif
+
+#define HEADER_SIZE 8
+static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
{
BUF_MEM *b;
unsigned char *p;
int i;
- char *ret=NULL;
- ASN1_CTX c;
+ int ret=-1;
+ ASN1_const_CTX c;
int want=HEADER_SIZE;
int eos=0;
+#if defined(__GNUC__) && defined(__ia64)
+ /* pathetic compiler bug in all known versions as of Nov. 2002 */
+ long off=0;
+#else
int off=0;
+#endif
int len=0;
b=BUF_MEM_new();
if (b == NULL)
{
- ASN1err(ASN1_F_ASN1_D2I_BIO,ERR_R_MALLOC_FAILURE);
- return(NULL);
+ ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ERR_R_MALLOC_FAILURE);
+ return -1;
}
ERR_clear_error();
{
want-=(len-off);
- if (!BUF_MEM_grow(b,len+want))
+ if (!BUF_MEM_grow_clean(b,len+want))
{
- ASN1err(ASN1_F_ASN1_D2I_BIO,ERR_R_MALLOC_FAILURE);
+ ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ERR_R_MALLOC_FAILURE);
goto err;
}
i=BIO_read(in,&(b->data[len]),want);
if ((i < 0) && ((len-off) == 0))
{
- ASN1err(ASN1_F_ASN1_D2I_BIO,ASN1_R_NOT_ENOUGH_DATA);
+ ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_NOT_ENOUGH_DATA);
goto err;
}
if (i > 0)
if (e != ASN1_R_TOO_LONG)
goto err;
else
- ERR_get_error(); /* clear error */
+ ERR_clear_error(); /* clear error */
}
i=c.p-p;/* header length */
off+=i; /* end of data */
if (want > (len-off))
{
want-=(len-off);
- if (!BUF_MEM_grow(b,len+want))
+ if (!BUF_MEM_grow_clean(b,len+want))
{
- ASN1err(ASN1_F_ASN1_D2I_BIO,ERR_R_MALLOC_FAILURE);
+ ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ERR_R_MALLOC_FAILURE);
goto err;
}
- i=BIO_read(in,&(b->data[len]),want);
- if (i <= 0)
+ while (want > 0)
{
- ASN1err(ASN1_F_ASN1_D2I_BIO,ASN1_R_NOT_ENOUGH_DATA);
- goto err;
+ i=BIO_read(in,&(b->data[len]),want);
+ if (i <= 0)
+ {
+ ASN1err(ASN1_F_ASN1_D2I_READ_BIO,
+ ASN1_R_NOT_ENOUGH_DATA);
+ goto err;
+ }
+ len+=i;
+ want -= i;
}
- len+=i;
}
off+=(int)c.slen;
if (eos <= 0)
}
}
- p=(unsigned char *)b->data;
- ret=d2i(x,&p,off);
+ *pb = b;
+ return off;
err:
if (b != NULL) BUF_MEM_free(b);
return(ret);