package textbender::a::b::JarSigner; # Copyright 2005, Michael Allan. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Textbender Software"), to deal in the Textbender Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicence, and/or sell copies of the Textbender Software, and to permit persons to whom the Textbender Software is furnished to do so, subject to the following conditions: The preceding copyright notice and this permission notice shall be included in all copies or substantial portions of the Textbender Software. THE TEXTBENDER SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE TEXTBENDER SOFTWARE OR THE USE OR OTHER DEALINGS IN THE TEXTBENDER SOFTWARE. use strict; use warnings; =pod =head1 DESCRIPTION Cryptographic code signing with the Sun Java jarsigner tool. =head1 EXPORTS =over 4 =cut BEGIN { use Exporter (); our @ISA; @ISA = qw( Exporter ); our @EXPORT_OK; @EXPORT_OK = qw( alias keypass sign storepass ); } our @EXPORT_OK; { use textbender::a::b::Config qw( do_fail config_basepath_from_package ); my $config_path = config_basepath_from_package(__PACKAGE__) . '.pl'; do $config_path or do_fail $config_path; } sub _prompt_for_passphrases(); # # Prompts the user for keystore and key passphrases, # and records them in environment variables. # =pod =item B Returns the passphrase used to protect the private key. The user is prompted if necessary, and the result is cached in an environment variable (for the duration of this process run). =cut sub keypass() { $ENV{TEXTBENDER_KEYPASS} or _prompt_for_passphrases(); return $ENV{TEXTBENDER_KEYPASS}; } =pod =item B ( $I [$I] ) Sets the passphrases for storepass() and keypass(), so the user need not be prompted. If I is not specified, it defaults to I. =cut sub set_passphrases( $;$ ) { my $storepass = shift; $storepass or die; my $keypass = shift; $keypass or $keypass = $storepass; $ENV{TEXTBENDER_STOREPASS} = $storepass; $ENV{TEXTBENDER_KEYPASS} = $keypass; } =pod =item B( $I ) Signs the I. Note, an incorrect keypass() will generate this misleading error message: "jarsigner: key associated with I not a private key". =cut sub sign( $ ) { use textbender::a::b::Console qw( print_score $verbosity ); use textbender::a::b::Java qw( JDK_dir ); my $jar_file = shift; my $command = JDK_dir() . '/bin/jarsigner' . " -keypass '" . keypass() . "'" # in fact, this is only required if it differs from storepass . " -storepass '" . storepass() . "'" . " $jar_file " . alias(); if( $verbosity ) { print "\n$command\n"; print_score( undef, '^' ); } system( $command ) and die; } =pod =item B Returns the passphrase to access the keystore. The user is prompted if necessary, and the result is cached in an environment variable (for the duration of this process run). =cut sub storepass() { $ENV{TEXTBENDER_STOREPASS} or _prompt_for_passphrases(); return $ENV{TEXTBENDER_STOREPASS}; } =pod =back =cut ##### I m p l e m e n t a t i o n ######################################################## sub _prompt_for_passphrases() { print( "Passphrase for keystore: " ); my $storepass = ; chop $storepass; $storepass or die; $ENV{TEXTBENDER_STOREPASS} = $storepass; print( "Passphrase for key (or press enter if same): " ); my $keypass = ; chop $keypass; $keypass or $keypass = $storepass; $ENV{TEXTBENDER_KEYPASS} = $keypass; }