#!/usr/bin/perl -w

## dkim-sign : v0.1

## http://devsec.org/software/misc/dkim-sign

## about:
##  add a dkim signature to an rfc822 message on stdin
##
## usage:
##  dkim-sign example.com mySelector < rfc822_message.txt
##
## setup:
##  mkdir -m700 -p ~/.dkim/example.com/mySelector/
##  cd ~/.dkim/example.com/mySelector/
##  openssl genrsa -out private.key 1024
##  openssl rsa -in private.key -out public.key -pubout -outform PEM
##
## bugs (sorta; since the message shouldn't already have a dkim signature):
##  will not recognise and replace any pre-existing dkim sig in headers
##
## - Thor Kooda
##   2008-10-28


use Mail::DKIM::Signer;

exit(2) if $#ARGV ne 1;

my $domain = $ARGV[0];
my $selector = $ARGV[1];

# create a signer object
my $dkim = Mail::DKIM::Signer->new(
                Algorithm => "rsa-sha1",
                Method => "relaxed",
                Headers => "date:from:to:subject",
                Domain => $domain,
                Selector => $selector,
                KeyFile => "$ENV{HOME}/.dkim/$domain/$selector/private.key",
           );

my @buf = ();

# or read an email and pass it into the signer, one line at a time
while (<STDIN>)
{
	# remove local line terminators
	chomp;
	s/\015$//;
	
	# save line in array
	push ( @buf, "$_\n" );
	
	# use SMTP line terminators
	$dkim->PRINT("$_\015\012");
}
$dkim->CLOSE;

# print email with dkim signature
my $dkim_printed = 0;
foreach $line ( @buf ) {
	if ( ( $dkim_printed == 0 ) && ( $line =~ m/^(Date|From|To|Subject)/i ) ) {
		print $dkim->signature->as_string . "\n";
		$dkim_printed = 1;
	}
	print $line;
}

