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