The issue of the passphrase is a little more subtle. Since on some Unix implementations anybody can see the contents of the environment of a process, it might not be a good idea to send secret things that way.
What I do is to build a pipe from a program that creates and prints (to standard output) the passphrase, to the OpenSSL program, which is told to expect to read the passphrase on the pipe. Here's an example:
# ##### PKEYTRAN #####
# Translate passphrase for private key # Prepare a private key for delivery by unencrypting with the # private key storage passphrase and optionally re-encrypting with # the passphrase given by the caller.
sub pkeytran { my ($vault,$vkey,$openssl,$key,$outpass) = @_; # Arguments my ($pid, $error, $newkey); # Proc ID, err & result strs
{ $^F = 99; # FORCE CLOSE-ON-WRITE OFF!!! pipe KDR,KDW; # Kid Decode Read/Write if ($outpass) { pipe KCR,KCW; # Kid Code Read/Write print KCW $outpass; # New passphrase to PE pipe close KCW; # Make EOF } }
# Copy old passphrase from the vault into the KD pipe.
if ( !perlfork(sub{ # Run in forked process close KDR; # Close parent's pipe end open STDOUT,'>&KDW'; # Bind std out to the KD pipe exec $vault,$vkey; # Send passphrase to KDW die "Could not EXEC vault (pkeytran): $!"; # NOT REACHED }) ) { htmlfail "Could not FORK (pkeytran): $!"; } close KDW; # Close kid's pipe end
# Run OpenSSL rsa to change the passphrase
pipe KIR,KIW; # Kid std Input Read/Write pipe KOR,KOW; # Kid std Output Read/Write pipe KER,KEW; # Kid std Error Read/Write if ( !($pid=perlfork(sub{ # Run in forked process close KIW; # Close pipe end parent will use close KOR; # Close pipe end parent will use close KER; # Close pipe end parent will use open STDIN, '<&KIR'; # Bind pipe to standard in open STDOUT,'>&KOW'; # Bind pipe to standard out open STDERR,'>&KEW'; # Bind pipe to standard err exec $openssl.' rsa -passin file:/dev/fd/'.fileno(KDR). ($outpass?' -des3 -passout file:/dev/fd/'.fileno(KCR):''); die "Could not EXEC OpenSSL (trankey): $!"; # NOT REACHED })) ) { htmlfail "Could not FORK (pkeytran): $!"; } close KDR; # Close pipe from vault if ($outpass) { close KCR; # Close pipe from here } close KIR; # Close pipe end used by kid close KOW; # Close pipe end used by kid close KEW; # Close pipe end used by kid print KIW $key; # Old key is input for OpenSSL close KIW; # Make EOF on the KI pipe read KER,$error,4096; # Read any errors from kid read KOR,$newkey,4096; # Read any output from kid waitpid($pid,0); # Wait for kid to terminate if ($?) { # If error in kid htmlfail "OpenSSL rsa failed (pkeytran): $?\n".$error; } close KOR; # Close pipe from kid close KER; # Close pipe from kid
return $newkey; # Return rekeyed private key } # pkeytran
******** NOTE **********
This code uses "/dev/fd" which may or may not be implemented in your version of Unix! If you don't want to use this way of doing it, you COULD write the passphrases to two files in /tmp and give the filenames as arguments in the 'exec $openssl" call, but note that if more than one process may be doing this at any given time, you want to edit the process number into the filename, that NOBODY you don't want to read the passphrase can read those /tmp files, and that they get deleted really quick after they are used.
In some other cases it may be possible to condition OpenSSL to read the pass phrase from standard input, which makes the pipe stuff a little easier, however, I was not able to make "openssl rsa" do this.
There is a section in the FAQ/Readme about passing pass phrases. I condidered it WELL worth reading.
When should I have broken down and just started writing C code that calls the library directly, or a Perl module to call the library directly, instead of trying to shoe-horn the existing main programs???
Webmaster wrote:
Hello,
I also have a little question, with this methode I can also send the passphase of the seckey of the CA??????
The basic idea is great! Simply great and very useful. But how to make and secure the passphrase?
thanks Stephan
-----Ursprungliche Nachricht----- Von: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] Auftrag von Charles B Cranston Gesendet: Freitag, 3. September 2004 21:00 An: [EMAIL PROTECTED] Betreff: Re: How to create a certificate silently
If you're using Unix or another system that supports the Environment variables, you can write a fixed openssl conf file that references appropriate variables in appropriate places. If you don't have Environment you can still write a custom openssl conf file for each instance of signing.
Lule Chen wrote:
Hi, I use the openssl to create a self signed certificate, but it needs interactively input country name, province name, ... Common name. I am wondering if there is a way to do it silently, i.e. let it read those response from a configure file? Because I want to run the openssl command
in
a script and don't want user to input any thing. I badly need your help!
Thanks,
Louis
-- Charles B (Ben) Cranston mailto: [EMAIL PROTECTED] http://www.wam.umd.edu/~zben
______________________________________________________________________ OpenSSL Project http://www.openssl.org User Support Mailing List [EMAIL PROTECTED] Automated List Manager [EMAIL PROTECTED]
______________________________________________________________________ OpenSSL Project http://www.openssl.org User Support Mailing List [EMAIL PROTECTED] Automated List Manager [EMAIL PROTECTED]
-- Charles B (Ben) Cranston mailto: [EMAIL PROTECTED] http://www.wam.umd.edu/~zben
______________________________________________________________________ OpenSSL Project http://www.openssl.org User Support Mailing List [EMAIL PROTECTED] Automated List Manager [EMAIL PROTECTED]