Hello

I have written a simple program. It uses a simple ASN1 structure ZPRAVA,
which containts INTEGER and IA5STRING. 

typedef struct {                  // ASN1 structure for message
  ASN1_INTEGER *cislo;            // integer number
  ASN1_IA5STRING *str;            // text
} ZPRAVA;


ASN1_SEQUENCE(ZPRAVA) = {                  
  ASN1_SIMPLE(ZPRAVA, cislo, ASN1_INTEGER),
  ASN1_SIMPLE(ZPRAVA, str, ASN1_IA5STRING)
} ASN1_SEQUENCE_END(ZPRAVA)




I have written a function for reading structure from BIO and decoding
from DER format.

// macro for BIO reading ZPRAVA
#define  d2i_ZPRAVA_bio(b, zprava)  \
           (ZPRAVA*) ASN1_d2i_bio((char *(*)()) ZPRAVA_new, \
           (char *(*)()) d2i_ZPRAVA, (b), (unsigned char **)(zprava))


ZPRAVA *read_ZPRAVA_bio(BIO *io, ZPRAVA **z)
{
  // there are two posibilities, how to read
  return d2i_ZPRAVA_bio(io, z);
//  return ASN1_item_d2i_bio(ASN1_ITEM_rptr(ZPRAVA), io, z);
}




I have made a function, which converts an ASN1 structure to DER format
and writes to a file. If parameter size is >= 0, only first size bytes
are written. 

void write_der_file(ZPRAVA *z, char *fn, int size)
{
  int len;
  unsigned char *dd;
  FILE *f;

  dd = NULL;                          // converting to DER format according
  len = i2d_ZPRAVA(z, &dd);           // the examples from man pages
  if (len < 0)
    exit(1);

  if ((size >= 0) && (size < len))    // if size is >= 0
    dd[size] = '\0';                  // dd is shortered to size
    
  f = fopen(fn, "w");
  fputs((char *) dd, f);              // writting to a file
  fclose(f);
}




In main() I create structure anf fill it by data. I write complete structure
to a file "test1.der" in DER format.

  z = ZPRAVA_new();                   // creating a structure and filling
  ASN1_INTEGER_set(z->cislo, 123);
  ASN1_STRING_set(z->str, "aaaaaaaaaaaaaaaaaaaa", 20);

  write_der_file(z, "test1.der", -1);     // writting structure to a file




I open file via BIO, read structure using my read_ZPRAVA_bio() and print
contents. Everything is OK.

  io = BIO_new_file("test1.der", "r");    // opening BIO
  z1 = ZPRAVA_new();
  read_ZPRAVA_bio(io, &z1);               // reading from BIO

  // printing to stdout
  fprintf(stdout, "ASN1\nCislo:  %ld\nText:   %s\n\n", 
    ASN1_INTEGER_get(z1->cislo), (char *) ASN1_STRING_data(z1->str));
  BIO_free(io);




I write incomplete structure to a "test2.der". I open "test2.der" and
read ASN1 structure from BIO like in prevous step and print.

  write_der_file(z, "test2.der", 10);     // writting incomplete structure

  ERR_clear_error();                      // clearing an error queue

  io = BIO_new_file("test2.der", "r");    // opening BIO
  z2 = ZPRAVA_new();
  read_ZPRAVA_bio(io, &z2);               // reading from BIO

  ERR_print_errors_fp(stdout);            // writing errors to stderr

  // printing to stdout
  fprintf(stdout, "ASN1\nCislo:  %ld\nText:   %s\n\n", 
    ASN1_INTEGER_get(z2->cislo), (char *) ASN1_STRING_data(z2->str));
  BIO_free(io);    

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Everything is OK again. The contens of ZPRAVA is shorter, but any
mistake or debug message isn't printed. OpenSSL doesn't recognize,
that DER encoded ASN1 structure is incomplete. 
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

I would like to know if it is bug or isn't. Does exist any way,
how to find out, that DER encoded ASN1 structure is incomplete?




There is an output in my shell.

jhofmann@monkey:~/ssl5$ ./zprava
ASN1
Cislo:  123
Text:   aaaaaaaaaaaaaaaaaaaa

ASN1
Cislo:  123
Text:   aaa

jhofmann@monkey:~/ssl5$ 




There is source code of my program zprava.c.

#include <stdio.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/bio.h>
#include <openssl/asn1t.h>
#include <openssl/asn1.h>


typedef struct {                  // ASN1 structure for message
  ASN1_INTEGER *cislo;            // integer number
  ASN1_IA5STRING *str;            // text
} ZPRAVA;


ASN1_SEQUENCE(ZPRAVA) = {                  
  ASN1_SIMPLE(ZPRAVA, cislo, ASN1_INTEGER),
  ASN1_SIMPLE(ZPRAVA, str, ASN1_IA5STRING)
} ASN1_SEQUENCE_END(ZPRAVA)


IMPLEMENT_ASN1_FUNCTIONS(ZPRAVA)         
                                         
                                         
// macro for BIO reading ZPRAVA
#define  d2i_ZPRAVA_bio(b, zprava)  (ZPRAVA*) ASN1_d2i_bio((char *(*)()) ZPRAVA_new,\
           (char *(*)()) d2i_ZPRAVA, (b), (unsigned char **)(zprava))


ZPRAVA *read_ZPRAVA_bio(BIO *io, ZPRAVA **z)
{
  // there are two posibilities, how to read
  return d2i_ZPRAVA_bio(io, z);
//  return ASN1_item_d2i_bio(ASN1_ITEM_rptr(ZPRAVA), io, z);
}


void write_der_file(ZPRAVA *z, char *fn, int size)
{
  int len;
  unsigned char *dd;
  FILE *f;

  dd = NULL;                          // converting to DER format according
  len = i2d_ZPRAVA(z, &dd);           // the examples from man pages
  if (len < 0)
    exit(1);

  if ((size >= 0) && (size < len))    // if size is positive
    dd[size] = '\0';                  // dd is shortered to size
    
  f = fopen(fn, "w");
  fputs((char *) dd, f);              // writting to a file
  fclose(f);
}


int main(int argc, char *agv[])
{
  ZPRAVA *z, *z1, *z2;                // ASN1 structures
  BIO *io;                            // BIO object

  SSL_library_init();                 
  SSL_load_error_strings();

  z = ZPRAVA_new();                   // creating a structure and filling
  ASN1_INTEGER_set(z->cislo, 123);
  ASN1_STRING_set(z->str, "aaaaaaaaaaaaaaaaaaaa", 20);

  write_der_file(z, "test1.der", -1);     // writting structure to a file


  io = BIO_new_file("test1.der", "r");    // opening BIO
  z1 = ZPRAVA_new();
  read_ZPRAVA_bio(io, &z1);               // reading from BIO

  // printing to stdout
  fprintf(stdout, "ASN1\nCislo:  %ld\nText:   %s\n\n", 
    ASN1_INTEGER_get(z1->cislo), (char *) ASN1_STRING_data(z1->str));
  BIO_free(io);    
  

  write_der_file(z, "test2.der", 10);     // writting incomplete structure

  ERR_clear_error();                      // clearing an error queue

  io = BIO_new_file("test2.der", "r");    // opening BIO
  z2 = ZPRAVA_new();
  read_ZPRAVA_bio(io, &z2);               // reading from BIO

  ERR_print_errors_fp(stdout);            // writing errors to stderr


  // printing to stdout
  fprintf(stdout, "ASN1\nCislo:  %ld\nText:   %s\n\n", 
    ASN1_INTEGER_get(z2->cislo), (char *) ASN1_STRING_data(z2->str));
  BIO_free(io);    

  return 0;
}




Notes:

1. I have used  openssl-0.9.7-beta4.

2. I have compiled program by  gcc -Wall -pedantic -g   -c -o zprava.o zprava.c
                               gcc   zprava.o  -lssl -lcrypto -o zprava

3. I have tried both ways in read_ZPRAVA_bio().



Thanks

Jan Hofmann

I
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [EMAIL PROTECTED]
Automated List Manager                           [EMAIL PROTECTED]

Reply via email to