I'm still working on the changes to smime.c, but thought I'd send these two patches out for now.
The first patch adds the purpose field to the index. It also adds trust and purpose to the private keys index file. To keep the private keys index format the same, it adds a placeholder for issuer but only puts a "?" in the field. The second patch adds a "smime_keys refresh" command. This will recheck trust (e.g. for expired certs), and will add missing purpose and trust to both index files if needed. Since mutt doesn't use it yet, testing at this point is limited to visually inspecting both index files. I'd appreciate any testing or feedback, but please back up your index files first! Thanks, -Kevin
# HG changeset patch # User Kevin McCarthy <[email protected]> # Date 1433003676 25200 # Sat May 30 09:34:36 2015 -0700 # Node ID b73179c18fa93dc5210b4baa9a487976e9e9999c # Parent 0255b37be491bf11347c91d2197a4d9031423010 smime_keys: Add purpose flag to index. A subsequent patch will change smime.c to use the purpose to filter certs and keys that can't be used for signing or encryption. Issuer, trust, and purpose flags were also added to the keys index file, to keep parsing simpler in smime_keys as well as smime.c. The trust and purpose are derived from the cert. Issuer is set to '?' as this should never be needed for keys. diff --git a/smime_keys.pl b/smime_keys.pl --- a/smime_keys.pl +++ b/smime_keys.pl @@ -43,26 +43,29 @@ sub openssl_format ($); sub openssl_x509_query ($@); sub openssl_hash ($); sub openssl_fingerprint ($); sub openssl_emails ($); sub openssl_p12_to_pem ($$); sub openssl_verify ($$); sub openssl_crl_text($); -sub openssl_cert_flag ($$$); +sub openssl_trust_flag ($$;$); sub openssl_parse_pem ($$); sub openssl_dump_cert ($); +sub openssl_purpose_flag ($); # key/certificate management methods sub cm_list_certs (); -sub cm_add_entry ($$$$$); -sub cm_add_certificate ($$$$;$); -sub cm_add_key ($$$$); +sub cm_add_entry ($$$$$$;$); +sub cm_add_cert ($); +sub cm_add_indexed_cert ($$$); +sub cm_add_key ($$$$$$); sub cm_modify_entry ($$$;$); +sub cm_find_entry ($$); # op handlers sub handle_init_paths (); sub handle_change_label ($); sub handle_add_cert ($); sub handle_add_pem ($); sub handle_add_p12 ($); sub handle_add_chain ($$$); @@ -96,49 +99,49 @@ $root_certs_switch = -CAfile; } ###### # OPS ###### -if(@ARGV == 1 and $ARGV[0] eq "init") { +if (@ARGV == 1 and $ARGV[0] eq "init") { handle_init_paths(); } -elsif(@ARGV == 1 and $ARGV[0] eq "list") { +elsif (@ARGV == 1 and $ARGV[0] eq "list") { cm_list_certs(); } -elsif(@ARGV == 2 and $ARGV[0] eq "label") { +elsif (@ARGV == 2 and $ARGV[0] eq "label") { handle_change_label($ARGV[1]); } -elsif(@ARGV == 2 and $ARGV[0] eq "add_cert") { +elsif (@ARGV == 2 and $ARGV[0] eq "add_cert") { verify_files_exist($ARGV[1]); handle_add_cert($ARGV[1]); } -elsif(@ARGV == 2 and $ARGV[0] eq "add_pem") { +elsif (@ARGV == 2 and $ARGV[0] eq "add_pem") { verify_files_exist($ARGV[1]); handle_add_pem($ARGV[1]); } -elsif( @ARGV == 2 and $ARGV[0] eq "add_p12") { +elsif ( @ARGV == 2 and $ARGV[0] eq "add_p12") { verify_files_exist($ARGV[1]); handle_add_p12($ARGV[1]); } -elsif(@ARGV == 4 and $ARGV[0] eq "add_chain") { +elsif (@ARGV == 4 and $ARGV[0] eq "add_chain") { verify_files_exist($ARGV[1], $ARGV[2], $ARGV[3]); handle_add_chain($ARGV[1], $ARGV[2], $ARGV[3]); } -elsif((@ARGV == 2 or @ARGV == 3) and $ARGV[0] eq "verify") { +elsif ((@ARGV == 2 or @ARGV == 3) and $ARGV[0] eq "verify") { verify_files_exist($ARGV[2]) if (@ARGV == 3); handle_verify_cert($ARGV[1], $ARGV[2]); } -elsif(@ARGV == 2 and $ARGV[0] eq "remove") { +elsif (@ARGV == 2 and $ARGV[0] eq "remove") { handle_remove_pair($ARGV[1]); } -elsif(@ARGV == 2 and $ARGV[0] eq "add_root") { +elsif (@ARGV == 2 and $ARGV[0] eq "add_root") { verify_files_exist($ARGV[1]); handle_add_root_cert($ARGV[1]); } else { usage(); exit(1); } @@ -427,24 +430,26 @@ my @args = ("crl", "-text", "-noout", "-in", $crl); my @output = openssl_exec(@args); $? and die "openssl crl -text '$crl' returned $?"; return @output; } -sub openssl_cert_flag ($$$) { +sub openssl_trust_flag ($$;$) { my ($cert, $issuerid, $crl) = @_; + print "==> about to verify certificate of $cert\n"; + my $result = 't'; my $issuer_path; my $cert_path = "$certificates_path/$cert"; - if($issuerid eq '?') { + if ($issuerid eq '?') { $issuer_path = "$certificates_path/$cert"; } else { $issuer_path = "$certificates_path/$issuerid"; } my $output = openssl_verify($issuer_path, $cert_path); if ($?) { print "openssl verify returned exit code " . ($? >> 8) . " with output:\n"; @@ -528,18 +533,18 @@ my $bag_count = 0; my $cert_tmp_fh; my $cert_tmp_filename; $cert_data = new_cert_structure(); ($cert_tmp_fh, $cert_data->{datafile}) = create_tempfile(); open(PEM_FILE, "<$filename") or die("Can't open $filename: $!"); - while(<PEM_FILE>) { - if(/^Bag Attributes/) { + while (<PEM_FILE>) { + if (/^Bag Attributes/) { $bag_count++; $state == 0 or die("PEM-parse error at: $."); $state = 1; } # Allow attributes without the "Bag Attributes" header if ($state != 2) { if (/localKeyID:\s*(.*)/) { @@ -551,32 +556,32 @@ } if (/issuer=\s*(.*)/) { $cert_data->{issuer} = $1; } } - if(/^-----/) { - if(/BEGIN/) { + if (/^-----/) { + if (/BEGIN/) { print $cert_tmp_fh $_; $state = 2; - if(/PRIVATE/) { + if (/PRIVATE/) { $cert_data->{type} = "K"; next; } - if(/CERTIFICATE/) { + if (/CERTIFICATE/) { $cert_data->{type} = "C"; next; } die("What's this: $_"); } - if(/END/) { + if (/END/) { $state = 0; print $cert_tmp_fh $_; close($cert_tmp_fh); $cert_count++; push (@certs, $cert_data); $cert_data = new_cert_structure(); @@ -602,36 +607,60 @@ my $format = openssl_format($filename); my @args = ("x509", "-in", $filename, "-inform", $format); my $output = join("", openssl_exec(@args)); $? and die "openssl x509 certicate dump returned $?"; return $output; } +sub openssl_purpose_flag ($) { + my ($filename) = @_; + + my $purpose = ""; + + my @output = openssl_x509_query($filename, "-purpose"); + $? and die "openssl -purpose '$filename' returned $?"; + + foreach my $line (@output) { + if ($line =~ /^S\/MIME signing\s*:\s*Yes/) { + $purpose .= "s"; + } + elsif ($line =~ /^S\/MIME encryption\s*:\s*Yes/) { + $purpose .= "e"; + } + } + + if (! $purpose) { + $purpose = "-"; + } + + return $purpose; +} + ################################# # certificate management methods ################################# sub cm_list_certs () { my %keyflags = ( 'i', '(Invalid)', 'r', '(Revoked)', 'e', '(Expired)', 'u', '(Unverified)', 'v', '(Valid)', 't', '(Trusted)'); open(INDEX, "<$certificates_path/.index") or die "Couldn't open $certificates_path/.index: $!"; print "\n"; - while(<INDEX>) { + while (<INDEX>) { my $tmp; my @tmp; my $tab = " "; my @fields = split; - if($fields[2] eq '-') { + if ($fields[2] eq '-') { print "$fields[1]: Issued for: $fields[0] $keyflags{$fields[4]}\n"; } else { print "$fields[1]: Issued for: $fields[0] \"$fields[2]\" $keyflags{$fields[4]}\n"; } my $certfile = "$certificates_path/$fields[1]"; my $cert; { @@ -643,26 +672,26 @@ } my ($subject_in, $issuer_in, $date1_in, $date2_in) = openssl_x509_query($certfile, "-subject", "-issuer", "-dates"); $? and print "ERROR: openssl -subject -issuer -dates '$certfile' returned $?\n\n" and next; my @subject = split(/\//, $subject_in); - while(@subject) { + while (@subject) { $tmp = shift @subject; ($tmp =~ /^CN\=/) and last; undef $tmp; } defined $tmp and @tmp = split (/\=/, $tmp) and print $tab."Subject: $tmp[1]\n"; my @issuer = split(/\//, $issuer_in); - while(@issuer) { + while (@issuer) { $tmp = shift @issuer; ($tmp =~ /^CN\=/) and last; undef $tmp; } defined $tmp and @tmp = split (/\=/, $tmp) and print $tab."Issued by: $tmp[1]"; if ( defined $date1_in and defined $date2_in ) { @@ -676,165 +705,205 @@ -e "$private_keys_path/$fields[1]" and print "$tab - Matching private key installed -\n"; my @purpose = openssl_x509_query($certfile, "-purpose"); $? and die "openssl -purpose '$certfile' returned $?"; chomp(@purpose); print "$tab$purpose[0] (displays S/MIME options only)\n"; - while(@purpose) { + while (@purpose) { $tmp = shift @purpose; ($tmp =~ /^S\/MIME/ and $tmp =~ /Yes/) or next; my @tmptmp = split (/:/, $tmp); print "$tab $tmptmp[0]\n"; } print "\n"; } close(INDEX); } -sub cm_add_entry ($$$$$) { - my ($mailbox, $hashvalue, $use_cert, $label, $issuer_hash) = @_; +sub cm_add_entry ($$$$$$;$) { + my ($mailbox, $hashvalue, $use_cert, $label, $trust, $purpose, $issuer_hash) = @_; - my @fields; + if (! defined($issuer_hash) ) { + $issuer_hash = "?"; + } if ($use_cert) { open(INDEX, "+<$certificates_path/.index") or die "Couldn't open $certificates_path/.index: $!"; } else { open(INDEX, "+<$private_keys_path/.index") or die "Couldn't open $private_keys_path/.index: $!"; } - while(<INDEX>) { - @fields = split; - return if ($fields[0] eq $mailbox && $fields[1] eq $hashvalue); + while (<INDEX>) { + my @fields = split; + if (($fields[0] eq $mailbox) && ($fields[1] eq $hashvalue)) { + close(INDEX); + return; + } } - if ($use_cert) { - print INDEX "$mailbox $hashvalue $label $issuer_hash u\n"; - } - else { - print INDEX "$mailbox $hashvalue $label \n"; - } + print INDEX "$mailbox $hashvalue $label $issuer_hash $trust $purpose\n"; close(INDEX); } -sub cm_add_certificate ($$$$;$) { - my ($filename, $hashvalue, $add_to_index, $label, $issuer_hash) = @_; +# Returns the hashvalue.index of the stored cert +sub cm_add_cert ($) { + my ($filename) = @_; my $iter = 0; - my @mailboxes; - + my $hashvalue = openssl_hash($filename); my $fp1 = openssl_fingerprint($filename); - while (-e "$certificates_path/$$hashvalue.$iter") { - my $fp2 = openssl_fingerprint("$certificates_path/$$hashvalue.$iter"); + while (-e "$certificates_path/$hashvalue.$iter") { + my $fp2 = openssl_fingerprint("$certificates_path/$hashvalue.$iter"); last if $fp1 eq $fp2; $iter++; } - $$hashvalue .= ".$iter"; + $hashvalue .= ".$iter"; - if (-e "$certificates_path/$$hashvalue") { - print "\nCertificate: $certificates_path/$$hashvalue already installed.\n"; + if (-e "$certificates_path/$hashvalue") { + print "\nCertificate: $certificates_path/$hashvalue already installed.\n"; } else { - mycopy $filename, "$certificates_path/$$hashvalue"; - - if ($add_to_index) { - @mailboxes = openssl_emails($filename); - foreach my $mailbox (@mailboxes) { - cm_add_entry($mailbox, $$hashvalue, 1, $label, $issuer_hash); - print "\ncertificate $$hashvalue ($label) for $mailbox added.\n"; - } - cm_modify_entry('V', $$hashvalue, 1); - } - else { - print "added certificate: $certificates_path/$$hashvalue.\n"; - } + mycopy $filename, "$certificates_path/$hashvalue"; } - return @mailboxes; + return $hashvalue; } -sub cm_add_key ($$$$) { - my ($file, $hashvalue, $mailbox, $label) = @_; +# Returns a reference containing the hashvalue, mailboxes, trust flag, and purpose +# flag of the stored cert. +sub cm_add_indexed_cert ($$$) { + my ($filename, $label, $issuer_hash) = @_; + + my $cert_data = {}; + + $cert_data->{hashvalue} = cm_add_cert($filename); + $cert_data->{mailboxes} = [ openssl_emails($filename) ]; + $cert_data->{trust} = openssl_trust_flag($cert_data->{hashvalue}, $issuer_hash); + $cert_data->{purpose} = openssl_purpose_flag($filename); + + foreach my $mailbox (@{$cert_data->{mailboxes}}) { + cm_add_entry($mailbox, $cert_data->{hashvalue}, 1, $label, + $cert_data->{trust}, $cert_data->{purpose}, $issuer_hash); + print "\ncertificate ", $cert_data->{hashvalue}, " ($label) for $mailbox added.\n"; + } + + return $cert_data; +} + +sub cm_add_key ($$$$$$) { + my ($file, $hashvalue, $mailbox, $label, $trust, $purpose) = @_; unless (-e "$private_keys_path/$hashvalue") { mycopy $file, "$private_keys_path/$hashvalue"; } - cm_add_entry($mailbox, $hashvalue, 0, $label, ""); + cm_add_entry($mailbox, $hashvalue, 0, $label, $trust, $purpose); print "added private key: " . "$private_keys_path/$hashvalue for $mailbox\n"; } sub cm_modify_entry ($$$;$) { my ($op, $hashvalue, $use_cert, $opt_param) = @_; - my $crl; my $label; + my $trust; + my $purpose; my $path; my @fields; $op eq 'L' and ($label = $opt_param); - $op eq 'V' and ($crl = $opt_param); - + $op eq 'T' and ($trust = $opt_param); + $op eq 'P' and ($purpose = $opt_param); if ($use_cert) { - $path = $certificates_path; + $path = $certificates_path; } else { - $path = $private_keys_path; + $path = $private_keys_path; } open(INDEX, "<$path/.index") or die "Couldn't open $path/.index: $!"; my ($newindex_fh, $newindex) = create_tempfile(); - while(<INDEX>) { + while (<INDEX>) { + chomp; + + # fields: mailbox hash label issuer_hash trust purpose @fields = split; - if($fields[1] eq $hashvalue or $hashvalue eq 'all') { + + if ($fields[1] eq $hashvalue or $hashvalue eq 'all') { $op eq 'R' and next; - print $newindex_fh "$fields[0] $fields[1]"; - - if($op eq 'L') { - if($use_cert) { - print $newindex_fh " $label $fields[3] $fields[4]"; - } - else { - print $newindex_fh " $label"; - } + if ($op eq 'L') { + $fields[2] = $label; } - if ($op eq 'V') { - print "\n==> about to verify certificate of $fields[0]\n"; - my $flag = openssl_cert_flag($fields[1], $fields[3], $crl); - print $newindex_fh " $fields[2] $fields[3] $flag"; + if ($op eq 'T') { + $fields[3] = "?" if ($#fields < 3); + $fields[4] = $trust; } - print $newindex_fh "\n"; - next; + if ($op eq 'P') { + $fields[3] = "?" if ($#fields < 3); + $fields[4] = "u" if ($#fields < 4); + $fields[5] = $purpose; + } + + print $newindex_fh join(" ", @fields), "\n"; } - print $newindex_fh $_; + else { + print $newindex_fh $_, "\n"; + } } close(INDEX); close($newindex_fh); move $newindex, "$path/.index" or die "Couldn't move $newindex to $path/.index: $!\n"; +} - print "\n"; +# This returns the first matching entry. +sub cm_find_entry ($$) { + my ($hashvalue, $use_cert) = @_; + + my ($path, $index_fh); + + if ($use_cert) { + $path = $certificates_path; + } + else { + $path = $private_keys_path; + } + + open($index_fh, "<$path/.index") or + die "Couldn't open $path/.index: $!"; + + while (<$index_fh>) { + chomp; + my @fields = split; + if ($fields[1] eq $hashvalue) { + close($index_fh); + return @fields; + } + } + + close($index_fh); + return; } ############## # Op handlers ############## sub handle_init_paths () { @@ -897,22 +966,20 @@ my $issuer_datafile = $issuer->{datafile}; open(my $issuer_fh, "< $issuer_datafile") or die "can't open $issuer_datafile: $?"; print $issuer_chain_fh $_ while (<$issuer_fh>); close($issuer_fh); } close($issuer_chain_fh); - $issuer_chain_hash = openssl_hash($issuer_chain_file); - cm_add_certificate($issuer_chain_file, \$issuer_chain_hash, 0, $label); + $issuer_chain_hash = cm_add_cert($issuer_chain_file); } - my $leaf_hash = openssl_hash($leaf->{datafile}); - cm_add_certificate($leaf->{datafile}, \$leaf_hash, 1, $label, $issuer_chain_hash); + cm_add_indexed_cert($leaf->{datafile}, $label, $issuer_chain_hash); } } sub handle_add_pem ($) { my ($filename) = @_; my @pem_contents; my $iter; @@ -920,47 +987,47 @@ my $certificate; my $root_cert; my $issuer_cert_file; @pem_contents = openssl_parse_pem($filename, 1); # look for key $iter = 0; - while($iter <= $#pem_contents) { + while ($iter <= $#pem_contents) { if ($pem_contents[$iter]->{type} eq "K") { $key = $pem_contents[$iter]; splice(@pem_contents, $iter, 1); last; } $iter++; } defined($key) or die("Couldn't find private key!"); $key->{localKeyID} or die("Attribute 'localKeyID' wasn't set."); # private key and certificate use the same 'localKeyID' $iter = 0; - while($iter <= $#pem_contents) { + while ($iter <= $#pem_contents) { if (($pem_contents[$iter]->{type} eq "C") && ($pem_contents[$iter]->{localKeyID} eq $key->{localKeyID})) { $certificate = $pem_contents[$iter]; splice(@pem_contents, $iter, 1); last; } $iter++; } defined($certificate) or die("Couldn't find matching certificate!"); if ($#pem_contents < 0) { die("No root and no intermediate certificates. Can't continue."); } # Look for a self signed root certificate $iter = 0; - while($iter <= $#pem_contents) { + while ($iter <= $#pem_contents) { if ($pem_contents[$iter]->{subject} eq $pem_contents[$iter]->{issuer}) { $root_cert = $pem_contents[$iter]; splice(@pem_contents, $iter, 1); last; } $iter++; } if (defined($root_cert)) { @@ -970,17 +1037,17 @@ } # what's left are intermediate certificates. if ($#pem_contents >= 0) { my ($tmp_issuer_cert_fh, $tmp_issuer_cert) = create_tempfile(); $issuer_cert_file = $tmp_issuer_cert; $iter = 0; - while($iter <= $#pem_contents) { + while ($iter <= $#pem_contents) { my $cert_datafile = $pem_contents[$iter]->{datafile}; open (CERT, "< $cert_datafile") or die "can't open $cert_datafile: $?"; print $tmp_issuer_cert_fh $_ while (<CERT>); close CERT; $iter++; } close $tmp_issuer_cert_fh; @@ -1003,35 +1070,41 @@ -e $pem_file and -s $pem_file or die("Conversion of $filename failed."); handle_add_pem($pem_file); } sub handle_add_chain ($$$) { my ($key_file, $cert_file, $issuer_file) = @_; - my $cert_hash = openssl_hash($cert_file); - my $issuer_hash = openssl_hash($issuer_file); - my $label = query_label(); - cm_add_certificate($issuer_file, \$issuer_hash, 0, $label); - my @mailbox = cm_add_certificate($cert_file, \$cert_hash, 1, $label, $issuer_hash); + my $issuer_hash = cm_add_cert($issuer_file); + my $cert_data = cm_add_indexed_cert($cert_file, $label, $issuer_hash); - foreach my $mailbox (@mailbox) { - cm_add_key($key_file, $cert_hash, $mailbox, $label); + foreach my $mailbox (@{$cert_data->{mailboxes}}) { + cm_add_key($key_file, $cert_data->{hashvalue}, $mailbox, $label, + $cert_data->{trust}, $cert_data->{purpose}); } } sub handle_verify_cert ($$) { my ($keyid, $crl) = @_; -e "$certificates_path/$keyid" or $keyid eq 'all' or die "No such certificate: $keyid"; - cm_modify_entry('V', $keyid, 1, $crl); + + my @fields = cm_find_entry($keyid, 1); + if (scalar(@fields)) { + my $issuer_hash = $fields[3]; + my $trust = openssl_trust_flag($keyid, $issuer_hash, $crl); + + cm_modify_entry('T', $keyid, 0, $trust); + cm_modify_entry('T', $keyid, 1, $trust); + } } sub handle_remove_pair ($) { my ($keyid) = @_; if (-e "$certificates_path/$keyid") { unlink "$certificates_path/$keyid"; cm_modify_entry('R', $keyid, 1);
# HG changeset patch # User Kevin McCarthy <[email protected]> # Date 1433003701 25200 # Sat May 30 09:35:01 2015 -0700 # Node ID 2134ecae80dad21b4a14765d18366ae709712f78 # Parent d898ebf4a4049ee386ddd16ebce2766104b80426 smime_keys: Add refresh command. Refresh verifies the trust of each certificate and adds the purpose flag if it is missing. It pushes those values to the private keys' index file too. diff --git a/smime_keys.pl b/smime_keys.pl --- a/smime_keys.pl +++ b/smime_keys.pl @@ -56,16 +56,17 @@ # key/certificate management methods sub cm_list_certs (); sub cm_add_entry ($$$$$$;$); sub cm_add_cert ($); sub cm_add_indexed_cert ($$$); sub cm_add_key ($$$$$$); sub cm_modify_entry ($$$;$); sub cm_find_entry ($$); +sub cm_refresh_index (); # op handlers sub handle_init_paths (); sub handle_change_label ($); sub handle_add_cert ($); sub handle_add_pem ($); sub handle_add_p12 ($); sub handle_add_chain ($$$); @@ -102,16 +103,19 @@ ###### # OPS ###### if (@ARGV == 1 and $ARGV[0] eq "init") { handle_init_paths(); } +elsif (@ARGV == 1 and $ARGV[0] eq "refresh") { + cm_refresh_index(); +} elsif (@ARGV == 1 and $ARGV[0] eq "list") { cm_list_certs(); } elsif (@ARGV == 2 and $ARGV[0] eq "label") { handle_change_label($ARGV[1]); } elsif (@ARGV == 2 and $ARGV[0] eq "add_cert") { verify_files_exist($ARGV[1]); @@ -158,16 +162,19 @@ sub usage () { print <<EOF; Usage: smime_keys <operation> [file(s) | keyID [file(s)]] with operation being one of: init : no files needed, inits directory structure. + refresh : refreshes certificate and key index files. + Updates trust flag (expiration). + Adds purpose flag if missing. list : lists the certificates stored in database. label : keyID required. changes/removes/adds label. remove : keyID required. verify : 1=keyID and optionally 2=CRL Verifies the certificate chain, and optionally wether this certificate is included in supplied CRL (PEM format). Note: to verify all certificates at the same time, @@ -896,16 +903,68 @@ return @fields; } } close($index_fh); return; } +# Refreshes trust flags, and adds purpose if missing +# (e.g. from an older index format) +sub cm_refresh_index () { + my $index_fh; + + my ($last_hash, $last_trust, $last_purpose) = ("", "", ""); + + open($index_fh, "<$certificates_path/.index") or + die "Couldn't open $certificates_path/.index: $!"; + my ($newindex_fh, $newindex) = create_tempfile(); + + while (<$index_fh>) { + chomp; + + # fields: mailbox hash label issuer_hash trust purpose + my @fields = split; + + if ($fields[1] eq $last_hash) { + $fields[4] = $last_trust; + $fields[5] = $last_purpose; + } + else { + # Don't overwrite a revoked flag, because we don't have the CRL + if ($fields[4] ne "r") { + $fields[4] = openssl_trust_flag($fields[1], $fields[3]); + } + + if ($#fields < 5) { + $fields[5] = openssl_purpose_flag("$certificates_path/$fields[1]"); + } + + # To update an old private keys index format, always push the trust + # and purpose out. + if (-e "$private_keys_path/$fields[1]") { + cm_modify_entry ("T", $fields[1], 0, $fields[4]); + cm_modify_entry ("P", $fields[1], 0, $fields[5]); + } + + $last_hash = $fields[1]; + $last_trust = $fields[4]; + $last_purpose = $fields[5]; + } + + print $newindex_fh join(" ", @fields), "\n"; + } + close($index_fh); + close($newindex_fh); + + move $newindex, "$certificates_path/.index" + or die "Couldn't move $newindex to $certificates_path/.index: $!\n"; +} + ############## # Op handlers ############## sub handle_init_paths () { mkdir_recursive($certificates_path); mkdir_recursive($private_keys_path);
signature.asc
Description: PGP signature
