I seems to me that I'am almost done with BigInt for SERIAL. But I need
some clarification, because I don't quite understand why it is done in a
such way. 
1st. CA certificate, even if created with -set_serial 01 is stored in
database under key which look like hexadecimal number. So cmd listCerts
list ca certificates referenced by serial number different from the real
one.
2nd. getOwner in AC.pm around line 1252 check serial length. and if it
less than 16 retrieves CERTIFICATE otherwise CA_CERTIFICATE. I don't
really know if these issues are related to each other, So I've changed
line 1252 in AC.pm from:
 "if (length ($self->{acl}->{object}) < 16) {"
to
 "if ( $self->{acl}->{object} =~ /^\d+$/ )"
Correct me If i'm wrong.

PS. Diff is not fully tested. Need some more time, particulary want to know
if genCRLfromFile works as expected.
PSS: Works for MySQL too. Use DECIMAL (49) for storing serial, so
ordering also works on serial.

  Best wishes

--
Alexei Chetroi

Smile... Tomorrow will be worse. (c) Murphy's Law
diff -ru openca-0.9.2.2.orig/src/common/lib/cmds/genCRLfromFile 
openca-0.9.2.2.lex/src/common/lib/cmds/genCRLfromFile
--- openca-0.9.2.2.orig/src/common/lib/cmds/genCRLfromFile      2005-03-10 
10:03:39.000000000 +0200
+++ openca-0.9.2.2.lex/src/common/lib/cmds/genCRLfromFile       2005-03-27 
14:47:13.000000000 +0300
@@ -9,6 +9,7 @@
 ## Cfg KeyWord: OpenCADir,TempDir
 
 use strict;
+use Math::BigInt lib => 'GMP';
 
 sub cmdGenCRLfromFile {
 
@@ -87,15 +88,25 @@
 print closeLogSection();
 
 print addLogSection(gettext ("Checking certificate serials ... "));
-my @h_csv = sort @csv;
+
+my @bigintcsv = ();
+my $h;
+foreach $h (@csv) {
+       push @bigintcsv, Math::BigInt->new ($h);
+}
+my @h_csv = sort { $a->bcmp ($b) } @bigintcsv;
 @csv = ();
-my $last = -1;
[EMAIL PROTECTED] = ();
+
+my $last = Math::BigInt->binf ();
 foreach my $h (@h_csv)
 {
-    next if ($h == $last);
+    next if ( !($h->bcmp ($last)) );
     push @csv, $h;
     $last = $h;
 }
[EMAIL PROTECTED] = ();
+
 print addLogLine (gettext ("OK"));
 print closeLogSection();
 
@@ -117,9 +128,10 @@
 print closeLogSection();
 
 print addLogSection(gettext ("Building special index.txt ... "));
-my @index;
-my $max = 0;
+my %index = ();
+my $max = Math::BigInt->bzero ();
 my @list;
+my $serial;
 foreach my $value (@csv_certs) {
     my %hash;
     $hash {DATE_1} = $ca_token->getOpenSSLDate ($value->getParsed 
()->{NOTBEFORE});
@@ -128,7 +140,8 @@
     } else {
         $hash {SERIAL} = "";
     }
-    $hash {SERIAL} .= sprintf ("%lX", $value->getSerial());
+    $serial = Math::BigInt->new ($value->getSerial ());
+    $hash {SERIAL} .= substr ($serial->as_hex (), 2);
     $hash {DN}     = $value->getParsed ()->{DN};
     my @result = $db->searchItems ( DATATYPE => "ARCHIVED_CRR",
                                     REVOKE_CERTIFICATE_DN => $hash {DN} );
@@ -140,13 +153,13 @@
             $hash {DATE_2} = $ca_token->getOpenSSLDate ($value->getParsed 
()->{SUBMIT_DATE});
         }
     }
-    $index [$value->getSerial()] = \%hash;
-    $max = $value->getSerial() if ($value->getSerial() > $max);
+    $index {$serial} = \%hash;
+    $max = $serial->copy () if ($serial->bcmp ($max) == 1);
 }
-my $i;
+my ( $key, $i);
 $tools->moveFiles (SRC => $sslindex, DEST => $dir."/".$$.".index.txt");
 open FD, ">$sslindex";
-foreach $i (@index) {
+while ( ($key, $i) = each (%index) ) {
        next if (not $i->{DN});
     $i->{DN} =~ s/, *([A-Za-z0-9\-]+)=/\/$1=/g;
     $i->{DN} = "/".$i->{DN};
diff -ru openca-0.9.2.2.orig/src/common/lib/cmds/listCerts 
openca-0.9.2.2.lex/src/common/lib/cmds/listCerts
--- openca-0.9.2.2.orig/src/common/lib/cmds/listCerts   2005-03-10 
10:03:40.000000000 +0200
+++ openca-0.9.2.2.lex/src/common/lib/cmds/listCerts    2005-03-27 
14:07:32.000000000 +0300
@@ -8,7 +8,7 @@
 ##  Parameters: dataType, viewFrom, rows
 
 use strict;
-
+use Math::BigInt lib => 'GMP';
 
 sub cmdListCerts {
 
@@ -75,10 +75,11 @@
 
        my ( $format, $key, $type, $ser_col, $check );
        my @vals;
-       my $hex;
+       my ( $hex, $ser );
 
        $key  = $cert->getSerial($dataType);
-       $hex  = " (0x".sprintf("%X",$key).")";
+       $ser = Math::BigInt->new ($key)->as_hex ();
+       $hex  = " (".$ser.")";
        $type = $dataType;
 
        $ser_col = "<a class=\"list\" href=\"$self?cmd=viewCert&dataType=$type" 
.
diff -ru openca-0.9.2.2.orig/src/common/lib/cmds/lists 
openca-0.9.2.2.lex/src/common/lib/cmds/lists
--- openca-0.9.2.2.orig/src/common/lib/cmds/lists       2005-03-10 
10:03:40.000000000 +0200
+++ openca-0.9.2.2.lex/src/common/lib/cmds/lists        2005-03-27 
14:07:32.000000000 +0300
@@ -8,6 +8,7 @@
 ##  Parameters: action (type of list)
 
 use strict;
+use Math::BigInt lib => 'GMP';
 
 sub cmdLists {
 
@@ -140,6 +141,7 @@
        my ( $format, $key, $ser_col, $op_col, $email, $email_col, $role_col );
        my ( $lnk, $parsed, $head );
        my ( $hex, $notBefore, $submit );
+       my $ser;
 
         my $pos = scalar @{$item_list->{BODY}};
         my $index = 0;
@@ -148,7 +150,8 @@
        $head   = $parsed->{HEADER};
 
         $key    = $dbItem->getSerial();
-       $hex    = " (0x".sprintf("%X",$key).")";
+       $ser    = Math::BigInt->new ($key)->as_hex ();
+       $hex    = " (".$ser.")";
        $submit = $parsed->{DN_HASH}->{CN}[0];
 
         $notBefore = ( $parsed->{NOTBEFORE} or $head->{NOTBEFORE}
diff -ru openca-0.9.2.2.orig/src/common/lib/cmds/viewCert 
openca-0.9.2.2.lex/src/common/lib/cmds/viewCert
--- openca-0.9.2.2.orig/src/common/lib/cmds/viewCert    2005-03-10 
10:03:40.000000000 +0200
+++ openca-0.9.2.2.lex/src/common/lib/cmds/viewCert     2005-03-27 
14:07:32.000000000 +0300
@@ -22,6 +22,7 @@
 ## DELETE_PUBLIC_PASSWD
 
 use strict;
+use Math::BigInt lib => 'GMP';
 
 sub cmdViewCert {
 
@@ -150,7 +151,8 @@
     $info_list->{BODY}->[$info_pos]->[0]   = gettext("Certificate Version");
     $info_list->{BODY}->[$info_pos++]->[1] = ($parsedCert->{VERSION} or 
gettext("n/a"));
     $info_list->{BODY}->[$info_pos]->[0]   = gettext("Serial Number");
-    $info_list->{BODY}->[$info_pos++]->[1] = $cert->getSerial()." 
(0x".sprintf("%X",$cert->getSerial()).")";
+    my $hexser = Math::BigInt->new ($cert->getSerial ())->as_hex ();
+    $info_list->{BODY}->[$info_pos++]->[1] = $cert->getSerial()." 
(".$hexser.")";
     $info_list->{BODY}->[$info_pos]->[0]   = gettext("Common Name");
     $info_list->{BODY}->[$info_pos++]->[1] = ($parsedCert->{DN_HASH}->{CN}[0] 
or gettext("n/a"));
     $info_list->{BODY}->[$info_pos]->[0]   = gettext("E-Mail");
diff -ru openca-0.9.2.2.orig/src/common/lib/functions/crypto-utils.lib 
openca-0.9.2.2.lex/src/common/lib/functions/crypto-utils.lib
--- openca-0.9.2.2.orig/src/common/lib/functions/crypto-utils.lib       
2005-03-10 10:03:40.000000000 +0200
+++ openca-0.9.2.2.lex/src/common/lib/functions/crypto-utils.lib        
2005-03-27 14:07:32.000000000 +0300
@@ -19,6 +19,7 @@
 
 use strict;
 use Locale::Messages (':libintl_h');
+use Math::BigInt lib => 'GMP';
 
 ##
 ## following you can find the defined errorcodes of this library
@@ -343,8 +344,9 @@
   ## $keys->{OCSP};
   ##   if defined and (Y|ON) then SUSPENDED will be interpreted like REVOKED
 
-  my @index = ();
-  my $max = 0;
+  my %index = ();
+  my $max = Math::BigInt->bzero ();
+  my $serial;
   my @list;
   ## all entries are hashes with the following format
   ## STATUS V,E,R
@@ -362,12 +364,13 @@
     $hash {STATUS} = "V";
     $hash {DATE_1} = $cryptoShell->getOpenSSLDate ($value->getParsed 
()->{NOTBEFORE});
     $hash {DATE_2} = "";
-    $hash {SERIAL} = sprintf ("%lX", $value->getSerial());
+    $serial = Math::BigInt->new ($value->getSerial());
+    $hash {SERIAL} = substr ($serial->as_hex(), 2);
     $hash {SERIAL} = "0".$hash {SERIAL} if (length ($hash {SERIAL}) % 2);
     $hash {DN}     = $value->getParsed ()->{OPENSSL_SUBJECT};
     print addPreLogLine (i18nGettext ("VALID_CA_CERTIFICATE: __CERT_SERIAL__", 
"__CERT_SERIAL__", $hash{SERIAL}));
-    $index [$value->getSerial()] = \%hash;
-    $max = $value->getSerial() if ($value->getSerial() > $max);
+    $index {$serial} = \%hash;
+    $max = $serial->copy() if ($serial->bcmp($max) == 1);
   }
 
   ## get all expired_ca_certificates
@@ -377,12 +380,13 @@
     $hash {STATUS} = "E";
     $hash {DATE_1} = $cryptoShell->getOpenSSLDate ($value->getParsed 
()->{NOTBEFORE});
     $hash {DATE_2} = "";
-    $hash {SERIAL} = sprintf ("%lX", $value->getSerial());
+    $serial = Math::BigInt->new ($value->getSerial());
+    $hash {SERIAL} = substr ($serial->as_hex(), 2);
     $hash {SERIAL} = "0".$hash {SERIAL} if (length ($hash {SERIAL}) % 2);
     $hash {DN}     = $value->getParsed ()->{OPENSSL_SUBJECT};
     print addPreLogLine (i18nGettext ("EXPIRED_CA_CERTIFICATE: 
__CERT_SERIAL__", "__CERT_SERIAL__", $hash{SERIAL}));
-    $index [$value->getSerial()] = \%hash;
-    $max = $value->getSerial() if ($value->getSerial() > $max);
+    $index {$serial} = \%hash;
+    $max = $serial->copy() if ($serial->bcmp($max) == 1);
   }
 
   ## get all valid_certificates
@@ -392,12 +396,13 @@
     $hash {STATUS} = "V";
     $hash {DATE_1} = $cryptoShell->getOpenSSLDate ($value->getParsed 
()->{NOTBEFORE});
     $hash {DATE_2} = "";
-    $hash {SERIAL} = sprintf ("%lX", $value->getSerial());
+    $serial = Math::BigInt->new ($value->getSerial());
+    $hash {SERIAL} = substr ($serial->as_hex(), 2);
     $hash {SERIAL} = "0".$hash {SERIAL} if (length ($hash {SERIAL}) % 2);
     $hash {DN}     = $value->getParsed ()->{OPENSSL_SUBJECT};
     print addPreLogLine (i18nGettext ("VALID_CERTIFICATE: __CERT_SERIAL__", 
"__CERT_SERIAL__", $hash{SERIAL}));
-    $index [$value->getSerial()] = \%hash;
-    $max = $value->getSerial() if ($value->getSerial() > $max);
+    $index {$serial} = \%hash;
+    $max = $serial->copy() if ($serial->bcmp($max) == 1);
   }
 
   ## get all expired_certificates
@@ -407,12 +412,13 @@
     $hash {STATUS} = "E";
     $hash {DATE_1} = $cryptoShell->getOpenSSLDate ($value->getParsed 
()->{NOTBEFORE});
     $hash {DATE_2} = "";
-    $hash {SERIAL} = sprintf ("%lX", $value->getSerial());
+    $serial = Math::BigInt->new ($value->getSerial());
+    $hash {SERIAL} = substr ($serial->as_hex(), 2);
     $hash {SERIAL} = "0".$hash {SERIAL} if (length ($hash {SERIAL}) % 2);
     $hash {DN}     = $value->getParsed ()->{OPENSSL_SUBJECT};
     print addPreLogLine (i18nGettext ("EXPIRED_CERTIFICATE: __CERT_SERIAL__", 
"__CERT_SERIAL__", $hash{SERIAL}));
-    $index [$value->getSerial()] = \%hash;
-    $max = $value->getSerial() if ($value->getSerial() > $max);
+    $index {$serial} = \%hash;
+    $max = $serial->copy() if ($serial->bcmp($max) == 1);
   }
 
   ## get all suspended_certificates
@@ -426,12 +432,13 @@
     }
     $hash {DATE_1} = $cryptoShell->getOpenSSLDate ($value->getParsed 
()->{NOTBEFORE});
     $hash {DATE_2} = "";
-    $hash {SERIAL} = sprintf ("%lX", $value->getSerial());
+    $serial = Math::BigInt->new ($value->getSerial());
+    $hash {SERIAL} = substr ($serial->as_hex(), 2);
     $hash {SERIAL} = "0".$hash {SERIAL} if (length ($hash {SERIAL}) % 2);
     $hash {DN}     = $value->getParsed ()->{OPENSSL_SUBJECT};
     print addPreLogLine (i18nGettext ("SUSPENDED_CERTIFICATE: 
__CERT_SERIAL__", "__CERT_SERIAL__", $hash{SERIAL}));
-    $index [$value->getSerial()] = \%hash;
-    $max = $value->getSerial() if ($value->getSerial() > $max);
+    $index {$serial} = \%hash;
+    $max = $serial->copy() if ($serial->bcmp($max) == 1);
   }
 
   ## get all revoked_certificates
@@ -440,7 +447,8 @@
     my %hash;
     $hash {STATUS} = "R";
     $hash {DATE_1} = $cryptoShell->getOpenSSLDate ($value->getParsed 
()->{NOTBEFORE});
-    $hash {SERIAL} = sprintf ("%lX", $value->getSerial());
+    $serial = Math::BigInt->new ($value->getSerial());
+    $hash {SERIAL} = substr ($serial->as_hex(), 2);
     $hash {SERIAL} = "0".$hash {SERIAL} if (length ($hash {SERIAL}) % 2);
     $hash {DN}     = $value->getParsed ()->{OPENSSL_SUBJECT};
     my @result = $db->searchItems ( DATATYPE => "ARCHIVED_CRR",
@@ -454,8 +462,8 @@
       }
     }
     print addPreLogLine (i18nGettext ("REVOKED_CERTIFICATE: __CERT_SERIAL__", 
"__CERT_SERIAL__", $hash{SERIAL}));
-    $index [$value->getSerial()] = \%hash;
-    $max = $value->getSerial() if ($value->getSerial() > $max);
+    $index {$serial} = \%hash;
+    $max = $serial->copy() if ($serial->bcmp($max) == 1);
   }
 
   print closeLogSection ();
@@ -473,8 +481,8 @@
                            "__FILE__", $keys->{DB});
        return undef;
   }
-  my $i;
-  foreach $i (@index) {
+  my ( $key, $i );
+  while ( ($key, $i) = each (%index) ) {
     next if (not $i);
     $i->{DN} =~ s/, *(?=[A-Za-z0-9\-]+=)/\//g;
     $i->{DN} = "/".$i->{DN};
@@ -501,12 +509,12 @@
                            "__FILE__", $keys->{DB});
        return undef;
     }
-    $max++;
-    $max = sprintf ("%lX", $max);
-    $max = "0".$max if (length ($max) % 2);
-    print FD $max;
+    $max->binc();
+    my $smax = substr ($max->as_hex(), 2);
+    $smax = "0".$smax if (length ($smax) % 2);
+    print FD $smax;
     close(FD);
-    print addLogLine (gettext($max));
+    print addLogLine (gettext($smax));
     print closeLogSection ();
   }
 
@@ -694,7 +702,8 @@
     #// perhaps the cert's serial must be stored in the dn
     my $use_cert_serial = getRequired ('SET_CERTIFICATE_SERIAL_IN_DN');
     if ($use_cert_serial =~ /^(Y|YES|ON)$/i) {
-        $cert_subject = getRequired 
('CERTIFICATE_SERIAL_NAME')."=".hex($ser).",";
+        my $strser = Math::BigInt->new ("0x".$ser);
+        $cert_subject = getRequired 
('CERTIFICATE_SERIAL_NAME')."=".$strser.",";
     }
 
     if ($csr->getParsed()->{HEADER}->{SUBJECT}) {
diff -ru openca-0.9.2.2.orig/src/common/lib/functions/export-import.lib 
openca-0.9.2.2.lex/src/common/lib/functions/export-import.lib
--- openca-0.9.2.2.orig/src/common/lib/functions/export-import.lib      
2005-03-10 10:03:40.000000000 +0200
+++ openca-0.9.2.2.lex/src/common/lib/functions/export-import.lib       
2005-03-27 14:07:32.000000000 +0300
@@ -6,6 +6,7 @@
 
 use strict;
 use DB_File;
+use Math::BigInt lib => 'GMP';
 
 ##
 ## Usage:
@@ -1343,14 +1344,16 @@
   print addLogSection (gettext("Make CA-Certificate available on the server 
..."));
   my @cacerts = $db->searchItems ( DATATYPE => "VALID_CA_CERTIFICATE" );
   my $key;
-  my $serial = -1;
+  my $max = Math::BigInt->bone ('-');
   my $cert_data = "";
   my $cert_der  = "";
   my $cert_txt  = "";
+  my $serial;
   foreach my $cert (@cacerts) {
-    if ( $cert->getSerial () > $serial ) {
-      $serial    = $cert->getSerial ();
-      $key       = $cert->getSerial ("CA_CERTIFICATE");
+    $serial = Math::BigInt->new ($cert->getSerial ());
+    if ( ($serial->bcmp ($max)) == 1 ) {
+      $max       = $serial->copy ();
+      $key       = Math::BigInt->new ($cert->getSerial ("CA_CERTIFICATE"));
       $cert_data = $cert->getPEM ();
       $cert_der  = $cert->getDER ();
       $cert_txt  = $cert->getTXT ();
diff -ru openca-0.9.2.2.orig/src/modules/openca-ac/AC.pm 
openca-0.9.2.2.lex/src/modules/openca-ac/AC.pm
--- openca-0.9.2.2.orig/src/modules/openca-ac/AC.pm     2005-03-10 
10:04:38.000000000 +0200
+++ openca-0.9.2.2.lex/src/modules/openca-ac/AC.pm      2005-03-27 
14:10:20.000000000 +0300
@@ -1248,13 +1248,13 @@
     
             ## load the certificate
             my @certs;
-            my $certtype = "CERTIFICATE";
-            if (length ($self->{acl}->{object}) < 16) {
-                @certs = $self->{db}->searchItems (KEY => 
$self->{acl}->{object}, DATATYPE => "CERTIFICATE");
+            my $certtype;
+            if ( $self->{acl}->{object} =~ /^\d+$/ ) {
+               $certtype = "CERTIFICATE";
             } else {
                 $certtype = "CA_CERTIFICATE";
-                @certs = $self->{db}->searchItems (KEY => 
$self->{acl}->{object}, DATATYPE => "CA_CERTIFICATE");
             }
+            @certs = $self->{db}->searchItems (KEY => $self->{acl}->{object}, 
DATATYPE => $certtype );
             my $cert;
             $cert = $certs[0] if (@certs);
             if (not $cert) {
diff -ru openca-0.9.2.2.orig/src/modules/openca-dbi/DBI.pm 
openca-0.9.2.2.lex/src/modules/openca-dbi/DBI.pm
--- openca-0.9.2.2.orig/src/modules/openca-dbi/DBI.pm   2005-03-10 
10:04:41.000000000 +0200
+++ openca-0.9.2.2.lex/src/modules/openca-dbi/DBI.pm    2005-03-28 
12:49:10.000000000 +0300
@@ -137,12 +137,12 @@
                                   FORMAT                => ["format",        
"TEXT"],
                                   DATA                  => ["data",          
"LONGTEXT"],
 
-                                  SERIAL                => ["serial",        
"BIGINT"],
+                                  SERIAL                => ["serial",        
"NUMERIC"],
                                   KEY                   => ["mykey",         
"TEXT_KEY"],
 
-                                  CERTIFICATE_SERIAL    => ["cert_key",      
"BIGINT"],
+                                  CERTIFICATE_SERIAL    => ["cert_key",      
"NUMERIC"],
                                   # same like certificate_serial but for CRR
-                                  REVOKE_CERTIFICATE_SERIAL    => ["cert_key", 
     "BIGINT"],
+                                  REVOKE_CERTIFICATE_SERIAL    => ["cert_key", 
     "NUMERIC"],
                                   CA_CERTIFICATE_SERIAL => ["ca_cert_key",   
"TEXT_KEY"],
                                   REQUEST_SERIAL        => ["req_key",       
"BIGINT"],
                                   CSR_SERIAL            => ["req_key",       
"BIGINT"],
@@ -514,6 +514,7 @@
                                     LONGTEXT   => "text",
                                     TEXT_KEY   => "text",
                                     BIGINT     => "int8",
+                                    NUMERIC    => "NUMERIC (49)",
                                     PRIMARYKEY => "PRIMARY KEY NOT NULL",
                                    },
                            DBI_OPTION => {
@@ -529,6 +530,7 @@
                                        LONGTEXT   => "TEXT",
                                        TEXT_KEY   => "VARCHAR (255)",
                                        BIGINT     => "BIGINT",
+                                       NUMERIC    => "DECIMAL (49)",
                                        PRIMARYKEY => "NOT NULL PRIMARY KEY",
                                       },
                               DBI_OPTION => {RaiseError => 0,
@@ -543,6 +545,7 @@
                                      ## 255 is the limit for a index key in db2
                                      TEXT_KEY   => "varchar (255)",
                                      BIGINT     => "decimal (31, 0)",
+                                     NUMERIC    => "decimal (49, 0)",
                                      PRIMARYKEY => "PRIMARY KEY NOT NULL",
                                     },
                             DBI_OPTION => {
@@ -558,6 +561,7 @@
                                      ## 2000 is the limit for varchar in 
Oracle7
                                      TEXT_KEY   => "varchar2 (1999)",
                                      BIGINT     => "number (38)",
+                                     NUMERIC    => "number (49)",
                                      PRIMARYKEY => "PRIMARY KEY NOT NULL",
                                     },
                             DBI_OPTION => {
diff -ru openca-0.9.2.2.orig/src/modules/openca-openssl/OpenSSL.xs 
openca-0.9.2.2.lex/src/modules/openca-openssl/OpenSSL.xs
--- openca-0.9.2.2.orig/src/modules/openca-openssl/OpenSSL.xs   2005-03-10 
10:04:41.000000000 +0200
+++ openca-0.9.2.2.lex/src/modules/openca-openssl/OpenSSL.xs    2005-03-27 
14:07:32.000000000 +0300
@@ -70,15 +70,11 @@
 
 # We do not really support serials that don't fit in one int
 
-int
+char *
 serial(cert)
        OpenCA_OpenSSL_X509 cert
-    PREINIT:
-       char * stringval;
     CODE:
-       stringval = i2s_ASN1_INTEGER(NULL,X509_get_serialNumber(cert));
-       RETVAL = atoi(stringval);
-       free(stringval);
+       RETVAL = i2s_ASN1_INTEGER(NULL,X509_get_serialNumber(cert));
     OUTPUT:
        RETVAL
 

Reply via email to