Error while reading X509 structure by d2i_X509_bio using memory bio

View: New views
3 Messages — Rating Filter:   Alert me  

Error while reading X509 structure by d2i_X509_bio using memory bio

by rajeshk_pec99-openssl :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I am trying to use d2i_X509_bio to read a DER encoded certificate from memory BIO, but I can't get it to work. It works fine if I construct a file BIO to read from a file. Am I doing something wrong, or is this a bug?

See the test application below that shows the problem. "der.cer" is DER encoded certificate.

>>>>>>>>>>>>>>>>>>>>>>>>>>>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/bio.h>
#include <openssl/evp.h>
#include <openssl/objects.h>

#define MAX_CERT_LEN 20000 /* arbitrary size limit */

int main(int argc, char *argv[]) {

  FILE *fp = 0;
  char derCert[MAX_CERT_LEN];
  long len;

  if (fp = fopen("../der.cer", "rb")) {
    len=fread(derCert, 1, MAX_CERT_LEN - 1, fp);
    derCert[len] = '\0';
   }
  //This is working
   do
   {
       X509 *x509Cert=NULL;
       BIO *cert;
       if ((cert=BIO_new(BIO_s_file())) == NULL)
        {
            printf("Error Initializing BIO pointer");
            break;
        }

       if (BIO_read_filename(cert,"../der.cer") <= 0)
       {
            printf("Error opening file\n");
            break;
       }

        if (d2i_X509_bio(cert,&x509Cert)!=NULL)
        {
                 printf("\nReading from file success!\n");
        }
   
    }while(0);
 
    //This is not working
    do
    {
       X509 *x509Cert=NULL;
       BIO *cert;
       BIO *bioCert;
      if(( bioCert = BIO_new_mem_buf(derCert, -1)) == NULL)
      {
            printf("Error init BIO pointer");
            break;

      }
        if (d2i_X509_bio(bioCert,&x509Cert)!=NULL)
        {
                 printf("\nReading success!\n");
        }
        else
        {
                 printf("\nError Reading Certificate:%ld\n",ERR_get_error());
        }

     
    }while(0);
}
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<


Reading from file success!

Error Reading Certificate:218542222

After reading problem
http://marc.info/?l=openssl-users&m=115689073330824&w=2

I also tried to put
BIO_set_mem_eof_return(bioCert, 0);
after "BIO_set_mem_eof_return" but it is still giving the same error.

I am new to openssl. Please do see where I am doing mistake?

--
Regards,
Rajesh
http://wpcStylePuzzles.blogspot.com
http://wscStylePuzzles.blogspot.com





Looking for local information? Find it on Yahoo! Local

Re: Error while reading X509 structure by d2i_X509_bio using memory bio

by Dr. Stephen Henson :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Thu, Jul 02, 2009, rajeshk_pec99-openssl@... wrote:

> I am trying to use d2i_X509_bio to read a DER encoded certificate from memory BIO, but I can't get it to work. It works fine if I construct a file BIO to read from a file. Am I doing something wrong, or is this a bug?
>
> See the test application below that shows the problem. "der.cer" is DER encoded certificate.
>
> >>>>>>>>>>>>>>>>>>>>>>>>>>>
> #include <stdio.h>
> #include <stdlib.h>
> #include <stdarg.h>
> #include <string.h>
> #include <openssl/crypto.h>
> #include <openssl/err.h>
> #include <openssl/bio.h>
> #include <openssl/evp.h>
> #include <openssl/objects.h>
>
> #define MAX_CERT_LEN 20000 /* arbitrary size limit */
>
> int main(int argc, char *argv[]) {
>
>   FILE *fp = 0;
>   char derCert[MAX_CERT_LEN];
>   long len;
>
>   if (fp = fopen("../der.cer", "rb")) {
>     len=fread(derCert, 1, MAX_CERT_LEN - 1, fp);
>     derCert[len] = '\0';
>    }
>   //This is working
>    do
>    {
>        X509 *x509Cert=NULL;
>        BIO *cert;
>        if ((cert=BIO_new(BIO_s_file())) == NULL)
>         {
>             printf("Error Initializing BIO pointer");
>             break;
>         }
>
>        if (BIO_read_filename(cert,"../der.cer") <= 0)
>        {
>             printf("Error opening file\n");
>             break;
>        }
>
>         if (d2i_X509_bio(cert,&x509Cert)!=NULL)
>         {
>                  printf("\nReading from file success!\n");
>         }
>    
>     }while(0);
>  
>     //This is not working
>     do
>     {
>        X509 *x509Cert=NULL;
>        BIO *cert;
>        BIO *bioCert;
>       if(( bioCert = BIO_new_mem_buf(derCert, -1)) == NULL)
>       {
>             printf("Error init BIO pointer");
>             break;
>
>       }
>         if (d2i_X509_bio(bioCert,&x509Cert)!=NULL)
>         {
>                  printf("\nReading success!\n");
>         }
>         else
>         {
>                  printf("\nError Reading Certificate:%ld\n",ERR_get_error());
>         }
>
>      
>     }while(0);
> }
> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
>
>
> Reading from file success!
>
> Error Reading Certificate:218542222
>
> After reading problem
> http://marc.info/?l=openssl-users&m=115689073330824&w=2
>
> I also tried to put
> BIO_set_mem_eof_return(bioCert, 0);
> after "BIO_set_mem_eof_return" but it is still giving the same error.
>
> I am new to openssl. Please do see where I am doing mistake?

DER format is binary data it is not null terminated, your call to
BIO_new_mem_buf() with -1 length will end up with a bogus length on the first
null in the certificate encoding.

You already worked out the lenght of the certifcate "len". Pass that as the
length instead.

Steve.
--
Dr Stephen N. Henson. OpenSSL project core developer.
Commercial tech support now available see: http://www.openssl.org
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    openssl-users@...
Automated List Manager                           majordomo@...

RE: Error while reading X509 structure by d2i_X509_bio using memory bio

by Dave Thompson-4 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

> From: owner-openssl-users@... On Behalf Of
rajeshk_pec99-openssl@...
> Sent: Thursday, 02 July, 2009 06:53
<snip>
>  FILE *fp = 0;
>  char derCert[MAX_CERT_LEN];
>  long len;
       
>  if (fp = fopen("../der.cer", "rb")) {
>    len=fread(derCert, 1, MAX_CERT_LEN - 1, fp);
>    derCert[len] = '\0';
>   }

DER data is not a C string; adding a null to 'terminate' it
will almost never help. To clarify/document this, I think
it is better style to use unsigned-char arrays (and pointers)
for it, although plain-char will work.

>  //This is working ...[ BIO_new file ]...

>    //This is not working
>      if(( bioCert = BIO_new_mem_buf(derCert, -1)) == NULL)
>      { ...[error]... }

DER data is not a C string; pass len from above instead of -1.

If you (convert to hex and) decode your error code, you get
error:0D06B08E:asn1 encoding routines:ASN1_D2I_READ_BIO:not enough data
which could have been a clue.

Incidentally, you don't need a mem-BIO to decode (or encode) exact
in-memory buffers; you can use the basic d2i and i2d routines.



______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    openssl-users@...
Automated List Manager                           majordomo@...