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]