A Perl of a job
--#--
The following Perl script is based on one by Marc Brette, who
posted it to the ssl-users list in 1998.
#!/usr/bin/perl
use DB_File;
tie %hash, "DB_File", "mycerts.db", O_RDONLY, 0540, $DB_HASH
or die "No can do: $!\n";
A note: If your script fails at this point, you're likely running
the wrong version of Perl's DB_File against the .db file. Either
you have Berkeley DB 1.85 and you've converted the .db file to a
higher version, or you've got the higher version of Berkeley, but
didn't convert the file.
$i = 0;
while (($key, $val) = each %hash) {
@record = unpack("cc", $val);
if (@record[1] == 1) {
@record = unpack("x9n", $key);
open(CERTS, ">$i.der");
print CERTS unpack("x13 a@record[0]", $val);
close CERTS;
}
$i++;
}
untie %hash;
As an explanation of this code, cert7.db is filled with many more records
than there are CA certs. The second byte (network order) of each
record will indicate what it is. A 01 indicates a CA cert. (I unpacked
two chars -- "cc" -- because the code ran on an Intel -- LittleEndian --
machine. To make this work on Solaris, use "nn" for network order.) Steve
Henson's Web site at www.drh-consultancy.demon.co.uk
has more information on the file's format.
Once we know it's a record we're looking for, we skip 9 bytes into the key,
where the length of the encoded cert is stored. Using that, we then skip
13 bytes into the record value, where the cert begins, and unpack the
number of bytes we found in the key.