>       From: owner-openssl-us...@openssl.org On Behalf Of bhaarat pachori
>       Sent: Saturday, 13 November, 2010 08:23

>       Actually I am trying to get the Serial number of the der encoded
certificate 
>       
>       AOL_Member_CA.der. For the better understanding I am attaching my
code 
        
Your code appears to process whatever file is specified as argv[1].
I'll assume that is AOL_Member_CA.der but it doesn't really matter.

> struct x509cert_info {
>       unsigned char   subject[256];
>       int             subject_len;
>       unsigned char   issuer[256];
>       int             issuer_len;
>       unsigned char   serialnum[128];
>       int             serialnum_len;
>};

It isn't really safe to assume that DNs (issuer and subject names) 
are <= 256 bytes (encoded); see below. There are perfectly valid 
naming schemes which produce longer names. Although if you only 
handle certs under some particular CA hierarchy, such as AOL, 
that might impose limits, I don't know.

I don't believe the standards actually limit serialnum either, 
but in practice I believe there is no reason anyone should ever 
use more than about 32 bytes, so 128 should be pretty safe.

>static int parse_certificate(struct x509cert_info *cert,
>               unsigned char *data, int len)
>{
>       X509 *x; 
>       unsigned char *p;
>       const unsigned char *pp;
>       int n;
>
>       pp = data;
>       x = d2i_X509(NULL, &pp, len);
>       if (!x) {
>               g_printerr ("OpenSSL error during X509 certificate
parsing");
>               return -1;
>       }

For an error return from libcrypto, you should look at OpenSSL's 
error queue. http://www.openssl.org/support/faq.html#PROG6 
If you need to do your I/O through glib, as you seem to be doing, 
you may need something more like:
  u_long err;
  while( (err = ERR_get_error()) != 0 ){
    ERR_error_string (err, buffer);
    /* output and/or log string in buffer */
  }

>       p = cert->subject;
>       n = i2d_X509_NAME(x->cert_info->subject, &p);
>       if (n < 0)
>       {
>               g_printerr("OpenSSL error while encoding subject name");
>               return -1;
>       }

Ditto in principle, but I don't think i2d(mem) can actually fail 
for valid data, which any d2i_X509 return should be.

>       printf("\nThe Certificate Subject name is %s\n",p);

The result of DER-encoding is not a C string, and it is 
both wrong and unsafe to printf with %s, or strcpy etc.
(Some DN components might not even be characters.)

>       if (n > (int)sizeof (cert->subject))
>       {
>               g_printerr("subject name too long");
>               return -1;
>       }

In general this is too late, i2d_ has already clobbered memory.
For your case, cert->subject is in a struct followed by field(s)
that don't matter at this point, and so is cert->issuer next.

<snip same for issuer>

(i and sn are file-static variables)

>       p = cert->serialnum;
>       n = i2d_ASN1_INTEGER(x->cert_info->serialNumber, &p);
>       if(i==0)
>       {
>               g_print("\nThe certificate serial number is copied in
serialnumber\n");               
>               if(g_strlcpy((gchar *)sn, (const gchar
*)x->cert_info->serialNumber, sizeof(sn)))
>               {
>                       i++;
>                       printf("\nSerial number copied successfully
%s\n",sn);
>               }
>       }

The serialNumber field in X509->X509_CINF is an ASN1_OBJECT; 
it doesn't contain actual data, only pointer, length, and flags.
Saving it at all without properly managing the memory it points 
to is unsafe and useless, and assuming those glib(?) routines 
do what their names look like, trying to copy it and later compare 
it as a C string won't work right, because it's not a C string.
(And the actual pointed-to value isn't a C string either.)

If you want the actual value you need to extract it, but since 
you've just (trivially) encoded it into cert->serialnum, and 
you normally can't do anything useful with a serial as a number,
why not just use the encoding?

<snip rest>

Finally it's not clear what your search is looking for. If you 
are looking under a given issuer ONLY, then serial should be 
unique (assuming no one can fake the issuer name, or you use 
AKID/SKID which are collision-resistant hashes). But in general 
across multiple issuers you cannot assume serials are unique.



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

Reply via email to