Assuming email@example.com
and email2@example.com
are the two other (non-RT) people, the first two lines make sense - its RT telling you it doesn’t have keys for them. The next three lines are from _Decrypt()
in RT::Crypt::SMIME
but further down the routine than you included above. What that is telling me is that after trying the first two (non-RT) email addresses it is trying another recipient, most probably one of your correspond/comment addresses, but openssl isn’t happy.
Now I’m guessing this is because openssl is complaining about a certificate, rather than a key. In _Decrypt()
we have a check just before this error is thrown that says,
if ( index($res{'stderr'}, 'no recipient matches key') >= 0 ) {
$RT::Logger->debug("Although we have a key for $address, it is not the one that encrypted this message");
next;
}
Now, I’m wondering if you can make an overlay for RT::Crypt::SMIME that traps the certificate as well as key errors? Maybe something like this in /opt/rt5/local/lib/RT/Crypt/SMIME_Local.pm
:
use strict;
no warnings qw(redefine);
package RT::Crypt::SMIME;
sub _Decrypt {
my $self = shift;
my %args = (Content => undef, @_ );
my %seen;
my @addresses =
grep !$seen{lc $_}++, map $_->address, map Email::Address->parse($_),
grep length && defined, @{$args{'Recipients'}};
my $opts = RT->Config->Get('SMIME');
my @providers = map { ( '-provider', $_ ) } @{ $opts->{'Providers'} };
my ($buf, $encrypted_to, %res);
foreach my $address ( @addresses ) {
my $file = $self->CheckKeyring( Key => $address, For => 'Encryption' );
unless ( $file ) {
my $keyring = $opts->{'Keyring'};
$RT::Logger->debug("No key found for $address in $keyring directory");
next;
}
local $ENV{SMIME_PASS} = $self->GetPassphrase( Address => $address, For => 'Encryption' );
local $SIG{CHLD} = 'DEFAULT';
my $cmd = [
$self->OpenSSLPath,
'smime',
@providers,
'-decrypt',
-recip => $file,
(defined $ENV{'SMIME_PASS'} && length $ENV{'SMIME_PASS'})
? (qw(-passin env:SMIME_PASS))
: (),
];
safe_run_child { run3( $cmd, $args{'Content'}, \$buf, \$res{'stderr'} ) };
unless ( $? ) {
$encrypted_to = $address;
$RT::Logger->debug("Message encrypted for $encrypted_to");
last;
}
if ( index($res{'stderr'}, 'no recipient matches key') >= 0 ) {
$RT::Logger->debug("Although we have a key for $address, it is not the one that encrypted this message");
next;
}
if ( index($res{'stderr'}, 'no recipient matches certificate') >= 0 ) {
$RT::Logger->debug("Although we have a certificate for $address, it is not the one that encrypted this message");
next;
}
$res{'exit_code'} = $?;
$res{'message'} = "openssl exited with error code ". ($? >> 8)
." and error: $res{stderr}";
$RT::Logger->error( $res{'message'} );
$res{'status'} = $self->FormatStatus({
Operation => 'Decrypt', Status => 'ERROR',
Message => 'Decryption failed',
EncryptedTo => $address,
});
return (undef, %res);
}
unless ( $encrypted_to ) {
$RT::Logger->error("Couldn't find SMIME key for addresses: ". join ', ', @addresses);
$res{'exit_code'} = 1;
$res{'status'} = $self->FormatStatus({
Operation => 'KeyCheck',
Status => 'MISSING',
Message => "Secret key is not available",
KeyType => 'secret',
});
return (undef, %res);
}
$res{'status'} = $self->FormatStatus({
Operation => 'Decrypt', Status => 'DONE',
Message => 'Decryption process succeeded',
EncryptedTo => $encrypted_to,
});
return (\$buf, %res);
}
1;