OpenCA-OpenSSL

 view release on metacpan or  search on metacpan

OpenSSL/SMIME.pm  view on Meta::CPAN

		push(@command, "-nodetach");	
	}

	push(@command, "-passin", "env:pwd") if($params{KEY_PASSWORD});
	push(@command, "-certfile", $cafile) if($cafile);
	push(@command, "-signer", $certfile,
		       "-inkey", $keyfile,
		       "-in", $self->{file},
		       "-out", $outfile);

	my($ec, $res) = $self->_exec(@command);

	foreach my $oo ( @command ) {
		$self->_debug("SMIME COMMAND: $oo");
	}

	delete($ENV{'pwd'}) if (defined($params{KEY_PASSWORD}));

	unless(defined($ec) && $ec == 0) {
		# Restore
		unless($params{NO_COPY_HEADERS}) {
			if($oldhead) {
				$self->{headers_cache} = $oldhead;
			} else {
				$self->{headers_cache} = undef;
			}
		}
		unless($params{NO_STRIP_HEADERS}) {
			$self->{entity} = $oldentity;
			$self->{file} = $oldfile;
		}
		return($self->_setError(8010006,
                           $self->{gettext} ("OpenCA::OpenSSL::SMIME->sign: unknown problem signing: __ERRVAL__",
                                             "__ERRVAL__", $res)));
	}

	$self->{file} = $outfile;	# Save result
	$self->{entity} = undef;
	$self->{needs_extract} = -1;	# When signing we want the original
					# headers
	return 1;
}

sub verify {
	my($self, %params) = @_;
	my($certfile, $signerfile, @command, $outfile, $oldhead);

	$self->_setError(0, "");
	$self->_set_status(0, "");

	# Clear last signer
	$self->{last_signer} = undef;
	$self->{last_signer_x509} = undef;

	# Check parameters
	unless(! $params{CERTIFICATE} || ref($params{CERTIFICATE})) {
		return($self->_setError(8011001,
                           $self->{gettext} ("OpenCA::OpenSSL::SMIME->verify: Invalid argument for CERTIFICATE")));
	}

	unless($params{CERTIFICATE} || $params{USES_EMBEDDED_CERT}) {
		return($self->_setError(8011002,
                           $self->{gettext} ("OpenCA::OpenSSL::SMIME->verify: No certificate specified and not using embedded certificate")));
	}

	# Set up files
	if($params{CERTIFICATE}) {
		$certfile = $self->_save_tmp($params{CERTIFICATE}->getPEM())
			or return(undef);
	}
	$outfile = $self->_save_tmp("") or return(undef);
	$signerfile = $self->_save_tmp("") or return(undef);

	# Sync data
	$self->_sync_data() or return(undef);

	# Create a copy of the headers cache
	if($self->{headers_cache}) {
		$oldhead = $self->{headers_cache}->dup()
			or return($self->_setError(8011003,
                                      $self->{gettext} ("OpenCA::OpenSSL::SMIME->verify: Can't duplicate headers cache for backup")));
	}

	# Save headers if necessary.
	unless($params{NO_COPY_HEADERS}) {
		$self->_save_headers() or return(undef);
	}

	push(@command, "smime", "-verify");
	push(@command, "-engine", $self->get_param ("ENGINE", %params),
                       "-keyform", $self->get_param ("KEYFORM", %params))
		if($self->get_param ("ENGINE", %params));
	push(@command, "-nointern") unless($params{USES_EMBEDDED_CERT});
	push(@command, "-CAfile", $self->{ca_certs_file}) if($self->{ca_certs_file});
	push(@command, "-certfile", $certfile) if($certfile);
	push(@command, "-in", $self->{file},
		       "-out", $outfile,
		       "-signer", $signerfile);

	my($ec, $res) = $self->_exec(@command);
	unless(defined($ec) && $ec == 0) {
		# Restore headers
		unless($params{NO_COPY_HEADERS}) {
			if($oldhead) {
				$self->{headers_cache} = $oldhead;
			} else {
				$self->{headers_cache} = undef;
			}
		}
# Possible errors reported by openssl:
# :No such file or directory:
# 			fatal: file missing!
# :no content type:	fatal: not even a mime stream
# :invalid mime type:	not a smime content-type
# :wrong content type:	pkcs7 found but it is not a signed
# 			envelope
# :certificate verify error:
# 	Verify error:self signed certificate in certificate chain
# 			ca cert found, but not trusted
# 	Verify error:unable to get local issuer certificate
# 			missing chain of trust
# 	Verify error:certificate has expired
# 			exactly that
# :digest failure:
# :signature failure:	modified message
		if($res =~ /:invalid mime type:|:wrong content type:/si) {
			$self->_set_status(1100, 'message not signed');
		} elsif($res =~ /:certificate verify error:/si) {
			if($res =~ /Verify error:unable to get local issuer certificate/) {
				$self->_set_status(1110, 'invalid certificate chain');
			} elsif($res =~ /Verify error:unable to get local issuer certificate/) {
				$self->_set_status(1111, 'no chain of trust supplied');
			} elsif($res =~ /Verify error:certificate has expired/) {
				$self->_set_status(1112, 'certificate has expired');
			} elsif($res =~ /Verify error:certificate is not yet valid/) {
				$self->_set_status(1113, 'certificate is not yet valid');
			} else {
				$self->_set_status(1119, 'unknown certificate problem: '. ($res =~ /Verify error:(.*)/)[0]);
			}
		} elsif($res =~ /:digest failure:|:signature failure:/) {
			$self->_set_status(1105, 'corrupted message');
		} elsif($res =~ /:no content type:/) {
			return($self->_setError(8011004,
                                   $self->{gettext} ("OpenCA::OpenSSL::SMIME->verify: found invalid mime stream")));
		} elsif($res =~ /:No such file or directory:/) {
			return($self->_setError(8011005,
                                   $self->{gettext} ("OpenCA::OpenSSL::SMIME->verify: missing file")));
		} else {
			return($self->_setError(8011006,
                                   $self->{gettext} ("OpenCA::OpenSSL::SMIME->verify: unknown error: __ERRVAL__",
                                                     "__ERRVAL__", $res)));
		}
		return undef;



( run in 0.466 second using v1.01-cache-2.11-cpan-71847e10f99 )