ssl-auth - secure sockets for the peasants
netpipes 4.2
ssl-auth --fd n ( --server | --client ) [ --cert file ] [ --key file ] [ --verbose ] [ --verify n ] [ --CApath path/ ] [ --CAfile file ] [ --cipher cipher-list ] [ --criteria criteria-expr ] [ --subproc [ --infd n ] [ --outfd n ] ] [ -[#n][v][s[in][on]] ]
ssl-auth provides SSL capability for simple programs and shell scripts. With ssl-auth you can secure and authenticate your netpipes scripts, provide secure proxies for mundane internet services such as IMAP, and communicate with such servers.
You must specify a file descriptor (using --fd) over which to conduct the SSL conversation. This must be a socket (readable and writable), not just a pipe. Also, you must define the polarity of the conversation with --server or --client.
Servers must specify a --key and a --cert. Failure to do so generally results in a ``no shared ciphers'' error on the server and a ``handshake failure'' on the client.
--verbose currently just prints a copyright notice.
--verify n specifies a verify depth. Errors deeper than n will be ignored. Issuer errors (UNABLE_TO_GET_ISSUER_CERT, and UNABLE_TO_GET_ISSUER_CERT_LOCALLY) are treated as a depth one greater than that reported by the SSL library because, while they are reported as a problem with the signed certificate, in a common case it is better to treat them as a problem with the signer (issuer) certificate. The typical value for n is 1. (behavior with the presence of --criteria in the absence of --verify is currently ill-defined and uninvestigated).
--CApath allows you to specify the location of your Certificate Authority directory. This directory contains the (usually self–signed) certificates from certificate authorities and the hash links. Here's a BASH function to create a hash link for a certificate in the current directory:
function make-ssl-cert-link { hash=`x509 -noout -hash < $1` ln -s $1 $hash.0 }
--cipher lets you specify a cipher list to be passed to SSL_CTX_set_cipher_list(). It is a colon-separated list of names. Each name has an optional prefix of -, +, or !. - and ! remove the cipher from the list supported by the library. + adds the cipher to the front, and no prefix adds it to the front unless it is already listed.
--criteria is the most powerful feature of ssl-auth. You can use it to specify a set of criteria to apply to the certificate chain presented by the SSL peer. The grammar of the criteria-expression is documented in the CRITERIA LANGUAGE section below.
--subproc allows you to specify a process that will supply the payload for the SSL conversation. Without --subproc ssl-auth merely encrypts stdin to the socket and decrypts from the socket to stdout. When --subproc is specified ssl-auth spawns a child, attaches pipes to the specified --infd and/or --outfd (if both descriptor numbers are the same, it attaches a socket instead of a pipe), and routes those data streams through the SSL socket.
ssl-auth also accepts one–character compact flags. These flags may be compacted together in one argument, or spread throughout several. You may use any mixture of long and compact flags, as long as you don't mix them in the same argument. The compact flags that expect arguments expect them to immediately follow their activating character.
-# corresponds to --fd. -v corresponds to --verbose. -s corresponds to --subproc. -i corresponds to --infd. -o corresponds to --outfd.
The grammar parsed by the --criteria flag will be unsurprising to the average computer–literate person. At the lowest precedence level is the or list whose members are separated by -o or --or. The next highest precedence level is the and list whose members are separated by -a or --and. The next level of precedence is the prefix unary operators which include --not (can be shortened to !, but be sure to escape it if your shell treats it specially; most do) and --depth n (which can be shortened to -d n). The highest precedence are the primitives (listed below). Precedence may be overridden using parenthesis, but remember to escape them with a \ because ()s are usually treated specially by the shell.
The following lists the correspondence between the X509 field names and the primitives that are designed to compare them.
X509 | criteria primitive |
---|---|
CN | --common-name |
C | --country-name |
ST | --state-name, --province-name |
L | --locality-name |
O | --organization-name |
OU | --organizational-unit-name, --department-name |
--public-key-match-cert compares the public key (exponent and modulus) from the SSL peer with the public key in the PEM-encoded certificate in fname. This can be used to verify the identity of the remote end in the absence of a certificate authority.
--cert-md5-digest compares the MD5 fingerprint of the SSL peer's certificate with the 32-digit hex string argument. It incorporates much more than the public key such as the name, issuer, algorithm, and signature. You can compute the md5 fingerprint by running the following command upon the server's certificate.
server$ ssleay x509 -md5 -fingerprint -in certificate.pem -out /dev/null MD5 Fingerprint=F6:0A:A2:D1:A3:12:5A:41:49:C7:56:0B:4E:67:1D:3CIn this case you would use a criteria of --cert-md5-digest F60AA2D1A3125A4149C7560B4E671D3C.
--write-pem-cert writes the certificate of the SSL peer to fname in PEM format.
Here is an example ssl-imapd spawnable from inetd:
#!/bin/sh exec > /dev/null exec 2>&1 exec /usr/local/bin/ssl-auth --fd 0 --server \ --cert /usr/local/ssl/certs/imapd.cert \ --key /usr/local/ssl/private/imapd.key \ --CApath /usr/local/ssl/certs/ \ -si0o1 /usr/local/sbin/imapd
To use it, put this in your /etc/inetd.conf
993 stream tcp nowait root /usr/local/sbin/ssl-imapd
If you want to turn a non-ssl IMAP client into an ssl-capable IMAP client, try putting this in your local machine's inetd.conf:
imap stream tcp nowait root /usr/local/sbin/ssl-proxy imap.remote.com
/usr/local/sbin/ssl-proxy looks like this:
#!/bin/sh exec > /dev/null exec 2>&1 exec hose "$1" 993 --fd 3 \ ssl-auth --fd 3 --client \ --CApath /usr/local/ssl/certs/ --verify 1 >&0
Now point your IMAP client at your local machine. The connection should be tunnelled through SSL to the remote machine. Tell me if it works...
If you can type HTTP requests yourself, you can probe an SSL HTTPd with the following command:
$ hose web.purplefrog.com 443 --fd 3 ssl-auth --fd 3 --clientThen type your GET or POST request
To get a copy of the remote server's certificate for local inspection you can do this:
$ hose web.purplefrog.com 443 --fd 3 ssl-auth --fd 3 --client \ --CApath /usr/local/ssl/certs/ \ --verify 1 --criteria --write-pem-cert tmp.cert \ -si0o1 /bin/true
This program is raw. Even I don't know how to operate it fully.
Thanks to Dr. Stephen Henson <shenson@drh-consultancy.demon.co.uk> for numerous hints and answers.
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.