Mail-Make

 view release on metacpan or  search on metacpan

lib/Mail/Make/SMIME.pm  view on Meta::CPAN

{
    my $self   = shift( @_ );
    my $opts   = $self->_get_args_as_hash( @_ );
    my $entity = $opts->{entity} ||
        return( $self->error( 'sign(): entity option is required.' ) );

    $self->_ensure_envelope_headers( $entity ) || return( $self->pass_error );

    my $smime = $self->_make_crypt_smime || return( $self->pass_error );

    $self->_load_private_key( $smime, $opts ) || return( $self->pass_error );

    $self->_load_ca_cert( $smime, $opts );    # optional; ignore error

    my $raw = $self->_serialise_for_smime( $entity ) || return( $self->pass_error );

    my $signed;
    local $@;
    eval{ $signed = $smime->sign( $raw ) };
    return( $self->error( "sign(): Crypt::SMIME::sign() failed: $@" ) ) if( $@ );
    unless( defined( $signed ) && CORE::length( $signed ) )

lib/Mail/Make/SMIME.pm  view on Meta::CPAN

    my $entity = $opts->{entity} ||
        return( $self->error( 'sign_encrypt(): entity option is required.' ) );

    $opts->{RecipientCert} ||
        return( $self->error( 'sign_encrypt(): RecipientCert option is required.' ) );

    $self->_ensure_envelope_headers( $entity ) || return( $self->pass_error );

    my $smime = $self->_make_crypt_smime || return( $self->pass_error );

    $self->_load_private_key( $smime, $opts ) || return( $self->pass_error );

    $self->_load_ca_cert( $smime, $opts );    # optional

    # Load recipient certificate(s)
    my @certs = ref( $opts->{RecipientCert} ) eq 'ARRAY'
        ? @{$opts->{RecipientCert}}
        : ( $opts->{RecipientCert} );

    my @pem_certs;
    for my $cert ( @certs )

lib/Mail/Make/SMIME.pm  view on Meta::CPAN


    my $pem = $self->_read_pem( $source ) || return( $self->pass_error );

    local $@;
    eval{ $smime->setPublicKey( [$pem] ) };
    return( $self->error( "_load_ca_cert(): failed to load CA certificate: $@" ) ) if( $@ );

    return(1);
}

# _load_private_key( $smime_obj, \%opts )
# Loads the private key and signing certificate into a Crypt::SMIME instance.
# Source priority: option Cert/Key > constructor cert/key.
# Handles key_password as string or CODE ref.
sub _load_private_key
{
    my( $self, $smime, $opts_ref ) = @_;

    my $cert_source = $opts_ref->{Cert} // $self->{cert};
    my $key_source  = $opts_ref->{Key}  // $self->{key};

    unless( defined( $cert_source ) && CORE::length( $cert_source ) )
    {
        return( $self->error( '_load_private_key(): no certificate provided. Set Cert option or cert() accessor.' ) );
    }

    unless( defined( $key_source ) && CORE::length( $key_source ) )
    {
        return( $self->error( '_load_private_key(): no private key provided. Set Key option or key() accessor.' ) );
    }

    my $cert_pem = $self->_read_pem( $cert_source ) || return( $self->pass_error );

    my $key_pem = $self->_read_pem( $key_source )   || return( $self->pass_error );

    # Resolve key password
    my $password_src = $opts_ref->{KeyPassword} // $self->{key_password};
    my $password;
    if( defined( $password_src ) )
    {
        if( ref( $password_src ) eq 'CODE' )
        {
            local $@;
            $password = eval{ $password_src->() };
            return( $self->error( "_load_private_key(): KeyPassword CODE ref died: $@" ) ) if( $@ );
        }
        else
        {
            $password = $password_src;
        }
    }

    local $@;
    if( defined( $password ) )
    {
        eval{ $smime->setPrivateKey( $key_pem, $cert_pem, $password ) };
    }
    else
    {
        eval{ $smime->setPrivateKey( $key_pem, $cert_pem ) };
    }
    return( $self->error( "_load_private_key(): failed to load private key/certificate: $@" ) ) if( $@ );

    return(1);
}

# _make_crypt_smime() → Crypt::SMIME instance
# Loads Crypt::SMIME and returns a new instance, with a clear error if the module is not
# installed.
sub _make_crypt_smime
{
    my $self = shift( @_ );



( run in 3.345 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )