#!/usr/bin/perl

# This is a elaborate wrapper around 2 simple OpenSSL commands. 
# It provides file encryption and decryption using just OpenSSL
# using the Blowfish in CBC mode encryption by default but also 
# optionally Three key triple DES EDE in CBC mode (-3)
#
# This came about after a discussion on IRC when someone needed
# a simple platform independant general file de/encrypter.  Usually
# one could use PGP/GPG but this would require you to have your keys
# etc.  This simply requires a password.
#
# By installing symlinks to ssldec and sslenc and calling those you
# can imply encryption and decryption.
#
# Contact R.I.Pienaar <rip@devco.net> with questions and comments.
#
# References:
#	http://www.monkey.org/openbsd/archive/misc/0102/msg00798.html
#	http://www.monkey.org/openbsd/archive/misc/0102/msg00804.html
#	enc(1) man page
#
# $Name: REL_1_0 $
# $Id: sslcrypt.pl,v 1.8 2003/08/03 15:46:06 rip Exp $

$openssl="/usr/bin/openssl";

use Getopt::Std;

getopts('afhevdi:o:O:3');

checkInput();

if ($action eq "enc") {
	system("$openssl enc $base64 -salt $encCipher -in $infile -out $outfile");
} else {
	system("$openssl enc $base64 -salt $encCipher -d -in $infile -out $outfile");
}

sub checkInput() {
	# Did they override the path to openssl?
	if ($opt_O) {
		$openssl = $opt_O;
	}

	# is it executable by us?
	unless (-x $openssl) {
		print ("$openssl is not executable, override the configured path with -O\n");
		exit;
	}

	if ($opt_h) {
		showHelp();
		exit;
	}

	if ($opt_v) {
		showVersion();
		exit;
	}

	# First we check if we are called with a name that would imply an action
	if ($0 =~ /ssldec/) {
		$opt_d = 1;
	}

	if ($0 =~ /sslenc/) {
		$opt_e = 1;
	}

	# No action specified, not in command line or by executable name
	unless ($opt_e or $opt_d) {
		print ("Neither encryption or decryption has been specified, -h will show options\n");
		exit;
	}

	if ($opt_e) { 
		$action = "enc"; 
	} elsif ($opt_d) { 
		$action = "dec"; 
	}

	unless ($opt_i and $opt_o) {
		print ("Both infile and outfile need to be specified, -h will show options\n");
		exit;
	}

	$outfile = $opt_o;
	$infile = $opt_i;
	
	# $outfile cannot = $infile
	if ($outfile eq $infile) {
		print ("infile and outfile is the same file.\n");
		exit;
	}

	# outfile should not exist unless -f is specified
	unless ($opt_f) {
		if (-f $outfile) {
			print ("The output file already exist, use -f to force overwrite\n");
			exit;
		}
	}

	# Three key triple DES EDE in CBC mode
	# or
	# Blowfish in CBC mode
	if ($opt_3) {
		$encCipher = "-des3";
	} else {
		$encCipher = "-bf";
	}

	if ($opt_a) {
		$base64 = "-a";
	}
}

sub showHelp() {
	print ("Usage: $0 [commands] -i infile -o outfile\n\n");
	print ("Commands:\n");
	print ("\t-d\t\tDecrypts the infile into outfile\n");
	print ("\t-e\t\tEncrypts the infile into outfile\n");
	print ("\t-3\t\tThree key triple DES EDE in CBC mode\n\n");
	print ("Input and Output modifiers:\n");
	print ("\t-i infile\tInput file\n");
	print ("\t-o outfile\tOutput file\n");
	print ("\t-a\t\tbase64 encrypt/decrypt.  Good for emailing\n");
	print ("\t-f\t\tForce overwrite of outfile\n\n");
	print ("General:\n");
	print ("\t-O openssl\tOverride path to OpenSSL\n");
	print ("\t-h\t\tShow this help.\n");
	print ("\t-v\t\tShow version information\n\n");
	print ("R.I.Pienaar <rip\@devco.net>\n\n");
}

sub showVersion() {
	print ("OpenSSL General Encrypter and Decrypter\n");
	print ("\n");
	print ("CVS ID:\n");
	print ('$Id: sslcrypt.pl,v 1.8 2003/08/03 15:46:06 rip Exp $' . "\n\n");
	print ("CVS Release Name:\n");
	print ('$Name: REL_1_0 $' . "\n\n");
	print ("R.I.Pienaar <rip\@devco.net>\n\n");
}
