Certificate questions Peter Antman To do something really useful with SSL (and thereby SSLtcl) one have to be able to handle certificate. This can sometimes be a little hard to learn, so here are a few word about what to do to create certificates. Autentication in SSL is partly done through a chain of signed certificates, where there somewhere in the end is a signer that you have good reason to trust. For Netscape-servers and clients, and even for apache-ssl, there are certain organizations that acts as Certificate Authorities. To have a website that people really know are your you can create a certificate and get an authority that everybody trust to guaranty that this certificate it really yours. In the lingua franca of SSL (and SSLtcl) we can hereby speak of two different kind of certificate. One is a CA certificate. That is, it is a certificate that you uses to verify other certificates against. The other is your own certificate, that is signed by someone else, in SSLtcl called cert. You will also have a private key that accompanies the certificate (where your public key is). I don't know if any CA will sign certificates for use in SSLtcl based applications. But you can set up your own CA and creates your own certificates. In the demo directory there is includes a demoCA directory. In it I have placed a demo CA certificate and a signed certificate. The private keys are removed prom there password so that they can be used by anybody. But when you start using SSLtcl you probably wants to create your own certificates. The easiest way to do that is to use the script CA.sh in the demo directory. This is a slightly modified version of the CA.sh that comes with SSLeay. Create a directory where you want to store your certificates and copy CA.sh there or start ut with its full path. The following command will set a demoCA up for you and create a CA certificate, that is a self signed certificate. CH.sh -newca You will be asked some questions, just answer them the best you can. If you are running a website you should however pay attention to the question about your common name. Several clients demand that this is not your personal name but the domainname of the server. You are now a CA authority. Time to sign some certificates. You begin by creating a certificate request: CA.sh -newreq and answers the questions again. Now you send it to your CA which is you and you sign it: CA.sh -sign By now you have a CAfile, a cert and a key. The key to use is the key that was generated when you did your request, not your CA. As you saw you had to fill in a password or passphrase each time you generated a certificate. This is to protect the private key. Anybody thats gets hold of your plain private key can pretend his you. So it should be protected. But sometimes it is quite boring to have to type the passfrase every time you do something with a key. Luckily the passfrase can be removed with the following command: ssleay rsa -in key.pwprotected -out key.plain You will find ssleay in the bin directory under ssl. I couple of questions might remain. How to I do to get a (Netscape) client to accept my new CA? Here is a small cgi-bin script that handle just that. You call it without argument from a webpage and the client will have it send to it, and reject or save it. The only thing you have to do is to convert your CA from pem to der encoded this way: x509 -inform pem -outform der < newca.pem > newca.der #!/bin/sh # ca-cert.sh # # (c) Peter Antman, 1997. # # cgi-bin-script to send a server ca file to netscape. # The script is called witout any argument, and the der-encoded certificate # is specified in the variable ''certfile'' certfile=/home/www/certs/newca.der if [ -e $certfile ]; then echo ''Content-Type: application/x-x509-ca-cert''; echo cat $certfile else cat << END Content-Type: text/html Certificate not found! <BODY> <B>Sorry, I can't find the certificate I had planned to send back. Please tr y again some other time. END fi exit 0 How do I sign a client certificate for Netscape? This is also a good question for a server maintainer. Client authentication through certificates and SSL can be a good way of server data only to people you really know who they are. For Netscape there is a special FORM tag in html that can be used to get Netscape to generate a certificate request and send it (and also get it back with a special mime format). Here is a perl cgi-bin script that does just that. It is selfexplaining. Just one thing should be said. It actually does three separate things that actual could be done separately. It gets the request, it signs the request, and it sends it back. #!/usr/bin/perl -T # client # #(c) Peter Antman, 1997. # # This script handles at client-sertificate request from a form # containinggen the keygen name pair. # $ENV{PATH} = '/bin:/usr/bin:/usr/local/ssl/bin'; $tempfil = ''/tmp/client-req''; $utfil = ''/tmp/client-cert.der''; $online = ''/tmp/online-cert''; # the ca program $passwd = oph84ov; # Password for your private key # Command for the ca-program to make a client certificate $ca = ''/usr/local/ssl/bin/ca -config /usr/local/ssl/lib/min.cnf -key oph84ov -spkac /tmp/client-req -out /tmp/client-cert.der''; #$arg = ''-config /usr/local/ssl/lib/min.cnf -key oph84ov -spkac /tmp/client-req -out /tmp/client-cert.der''; #@args = (''-config /usr/local/ssl/lib/min.cnf'', ''-key oph84ov'', ''spkac /tmp/client-req'', ''-out /tmp/client-cert.der''); #Tar in postdata if ($ENV{''REQUEST_METHOD''} eq ''POST'') { # Get the input read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); # Split the name-value pairs @pairs = split(/&/, $buffer); # Load the FORM variables foreach $pair (@pairs) { ($name, $value) = split(/=/, $pair); $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack(''C'', hex($1))/eg; $FORM{$name} = $value; } # Print the request to a temporary file. Should we untaint the form-variables # with a REGEXP? open (h, ''>$tempfil''); print h ''C = $FORM{land}\n''; print h ''SP = $FORM{stad}\n''; print h ''O = $FORM{org}\n''; print h ''CN = $FORM{namn}\n''; print h ''Email = $FORM{epost}\n''; # This is kinky, the newlines have to be escaped with an ''\'' $FORM{key} =~ s/\n/\\\n/g; print h ''SPKAC = $FORM{key}''; close h; # make the client certificate; untained with PATH set. In reality all the # elements in the form, including SPKAC ougt to be considered tainted. But # if there is not a bug in ca they are not harmfull, because they are not # passed trough the shell system $ca; # make an x509 online version to use for individual client certification with # apache-sll if (-e ''$online''){ open (f, ''>>$online''); } else{ open (f, ''>$online''); } print f ''/C=$FORM{land}/SP=$FORM{stad}/O=$FORM{org}/CN=$FORM{namn}/Email=$FORM{epost}:xxj31ZMTZzkVA\n''; close f; # Send the client certificate to the browser print ''Content-type: application/x-x509-user-cert\n\n''; open (h, ''$utfil''); while (<h>){ print } } If you plan to get serious in your certification business you should have a look in ssleay.cof. This is the default format file for certificate generation and it contains sections that you will have to change directly in this file. You should create your own format file and learn how to feed it to SSLeay when you handle certificates.