Resolve signed vs. unsigned.
[openssl.git] / crypto / asn1 / a_d2i_fp.c
index d952836a91036d41c5e75e43c84a3e9b365315b8..e409c273f266560b72a2f649ef74a84d9400e818 100644 (file)
 
 #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(xnew,d2i,in,x)
-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)
                {
@@ -85,27 +83,83 @@ unsigned char **x;
         }
 #endif
 
-char *ASN1_d2i_bio(xnew,d2i,in,x)
-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_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);
+               return -1;
                }
 
        ERR_clear_error();
@@ -115,7 +169,7 @@ unsigned char **x;
                        {
                        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);
                                goto err;
@@ -143,7 +197,7 @@ unsigned char **x;
                        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 */
@@ -170,18 +224,23 @@ unsigned char **x;
                        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);
                                        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_BIO,
+                                                   ASN1_R_NOT_ENOUGH_DATA);
+                                               goto err;
+                                               }
+                                       len+=i;
+                                       want -= i;
                                        }
-                               len+=i;
                                }
                        off+=(int)c.slen;
                        if (eos <= 0)
@@ -193,8 +252,8 @@ unsigned char **x;
                        }
                }
 
-       p=(unsigned char *)b->data;
-       ret=d2i(x,&p,off);
+       *pb = b;
+       return off;
 err:
        if (b != NULL) BUF_MEM_free(b);
        return(ret);