1            Using and Abusing SSL Securty
2                       OR
3      It must be secure, its so bloody hard to use
4
5 (With apologies to Eric A. Young and the OpenSSL developers)
6
7                   Patrick Powell
8            Thu Jul 18 10:20:58 PDT 2002
9
10Executive Summary
11  SSL Encryption and authentication is supported using the OpenSSL
12library.  The following changes have been made to LPRng:
13
14  lprng_certs  - a certificate creation/management tool
15  lpd.perms - 
16    AUTHFROM set to the 'subject' value of sender CERT
17    AUTHCA set to the 'issuer' value of sender CERT and
18      the hierarchy of 'issuer' values of CERT signers.
19    ${HOME}/.lpr/client.crt, ${HOME}/.lpr/client.pwd - 
20      user or client certificate locations 
21    /etc/lpd/ssl.ca, /etc/lpd/ssl.server - locations
22      of signer/root certificates and server certificates 
23
24Introduction
25  Why add SSL security to LPRng?
26   a) It's there.
27   b) Everybody and their dog is using it.
28   c) It is needed to support IPP
29
30So I got hold of the SSL and TLS book by Eric Rescorla (he may
31regret this shameless plug, but be it on his head), and started
32reading it.  After two weeks and a VERY large bottle of 'Super Strong
33No Doze Wakeup Pills'  I figured out what needed to be done:
34  a)  Set up some certs (i.e. - X509 Authentication Certificates).
35  b)  Get some code from some other places and the examples.
36  c)  Read the code, figure out what it was doing, and then
37      reverse engineer the SSL stuff.
38  d)  File off serial numbers, recode, etc., where necessary to
39      1) avoid the GNU license curse
40      2) make it LPRng specific
41
42My references were:
43
44Mod_ssl from the Apache project.
45       http://www.apache.org
46   Follow links to Mod_SSL OR get apache2 which has mod_ssl in it.
47   Stole the organization for certs, as well
48   as looking at how the Makefile created and installed the various
49   certificates.
50
51fetchmail
52    ftp://ftp.ccil.org/pub/esr/fetchmail
53    http://www.tuxedo.org/~esr/fetchmail
54  Ummm... this was happenstance,  I use fetchmail and it
55  has the SSL authentication in it.
56
57curl
58  http://download.sourceforge.net/curl/
59   Again, I use curl and it has SSL.
60
61The articles by Eric Rescola:
62  An Introduction to OpenSSL Programming
63   http://www.rtfm.com/openssl-examples/
64      wserver, wclient, sclient
65  And the book: SSL and TLS - Desiging and Building Secure Systems
66
67And, of course, the OpenSSL code, the examples in the code,
68  the utilities,  etc. etc. etc. About 260,000 lines of etc.
69  Sigh...
70
71WHAT I DID
72
73  a) Started with the Eric Rescola articles, and the
74        examples for wserver, wclient.
75  b) Added various things to handle getting authentication.
76     - printing the Subject and Issuer information
77     - adding directory information for Certificate locations
78  c) Created new certificates using what I thought would work...
79  d) Read 260,000 lines of OpenSSL code and heartily cursed
80     the OpenSSL developers, the OpenSSL coders, and just about
81     anybody who is associated with the project for NOT putting
82     in some trace statements OR better error message reporting.
83     But that is over new, and I have recalled the guys with the
84     baseball bats.
85  e) Documented this so that other people can figure out what I did.
86
87HERE IS WHAT YOU NEED TO KNOW
88
89The idea behind SSL is that you create some files (Certificates)
90that have various private/public key information in them.
91A checksum is calculated over the information,  and then the checksum
92is 'encrypted' using a private key of some 'signer'. This is attached
93to the certficate file... and the whole thing is encoded in the most
94obnoxious manner... ANS1 to be exact. This is then EXPANDED into a text
95format called PEM, and forms the 'certificate file'.
96
97   <aside> Ignore the SSL experts who are frothing over this
98   cavalier description of the details.
99   Details, smetails.  You listen to them, you be on the No Doze,
100   big time, pretty quick.  Boring stuff, the SSL details</aside>
101
102Now lets see what we do to validate that a certificate is correct
103or from the 'Subject' who is identified in the Certificate.  We get
104the X509 certificate for the 'signer' (or 'Issuer' in X509 jargon).
105Since the public key of the signer is including in the 'signer'
106certificate, we can use this to check that the information in the
107suspect certificate is valid by using it to decrypt the checksum
108information encoded with the private key.  If this matches, we have
109validated the certificate. (Well, not quite.  There are a couple
110more gotchas.)
111
112Now we must validate the 'signers' cerificate, which was
113in turn signed by another signer, and so we go up the food chain,
114I mean 'authentication chain', until we reach Nirvana:
115
116  a certificate which is signed by itself (i.e. - root certificate)
117
118or more exactly, a certificate where the 'subject' or the person
119identified by the CERT and the 'issuer' or the person who signed the
120CERT are the same.
121
122Now lets see how we use this for printing.
123
124Each user and/or print spooler is given a certificate with a corresponding
125set of private and secret keys.  When a client sends a request to the lpd
126server, he signs it using his private key; the lpd spooler gets the request,
127and then decodes/checks it using the public key in the users certificate.
128
129The SSL protocol provides a way to:
130
131  a) set up an encrypted connection (not our problem)
132  b) exchange certificate information
133      (Hmm... need to tell OpenSSL what certs to exchange)
134  c) validate the certificates (strictly speaking, this X509
135     stuff, but what the hey...) and hence, authenticate the
136     end users.
137       (Need to tell OpenSSL where the certs are).
138  d) set up and perform encrypted data exchange. (not our problem).
139
140So all we really need to do is set up the CERTIFICATES, tell the
141OpenSSL library where they are,  and it should do the work for us.
142(Ho ho ho... it sounds so simple...)
143
144There are two components to a certificate:
145  a) the certificate file (name.crt file) itself
146  b) the private key corresponding to the public key in
147     the certificate file (name.key file).
148
149Now clearly if the private key was obtained by somebody
150then they could impersonate a user. So there are two possibilities:
151 a) make the private key file readable only by the people that
152   need it (more on this later).
153 b) encrypt the private key and then when you need to use it
154   to sign something, provide a decryption password/key.
155
156So, we have 3 components:  the certificate (name.crt), the encrypted
157private key (name.key, but encrypted) and a password that we use
158to decrypt the private key.  But since we do not need to keep the
159private key hidden away, we can put the private key and certificate
160in the same file:
161
162  -----BEGIN RSA PRIVATE KEY-----
163  Proc-Type: 4,ENCRYPTED
164  DEK-Info: DES-EDE3-CBC,3EAD3ED0FA436761
165  
166  Vi5K0olpFfe2ltDpY/7gPM4iW74gYqtO1yEFm1DOhp7Kd8hB5Is6TVuVX78zkTaP
167  ...
168  j6Z5TX61x4YCHKleFa9nXFC5god/MCYzIHKKep0f4TKWCZcJLR5AyQ==
169  -----END RSA PRIVATE KEY-----
170  -----BEGIN CERTIFICATE-----
171  MIIDGzCCAoSgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBkzELMAkGA1UEBhMCVVMx
172  ...
173  3VapletoUPtYPvUAAgAg4w28pKWvlVW3tU/CsoHDEw==
174  -----END CERTIFICATE-----
175
176Which is the convention we adopted for LPRng.
177
178Now lets deal with the problem of certificates.  There are
179FOUR types of certificates that we need:
180
181                          CERTS/files
182  root                   (/etc/lpd/ssl.crt/ca.crt)
183   - signer1             (/etc/lpd/ssl.crt/signer1.crt - signed by ca)
184      - print spoolers   (/etc/lpd/ssl.server/h121.crt - signed by signer1 )
185      - users            (${HOME}/.lpd/user1.crt - signed by signer1 )
186   - signer2             (/etc/lpd/ssl.crt/signer2.crt - signed by ca)
187      - print spoolers   (/etc/lpd/ssl.server/h121.crt - signed by signer2)
188      - users            (${HOME}/.lpd/user2.crt - signed by signer2)
189
190The ROOT cert signs the signer certs, which in turn
191can sign print spooler certs and user certs.  If you feel
192lucky, you can also use the root cert to sign print spoolers
193or user certs.
194
195Now, what happens if and when somebody gets hold of the
196private key for the root cert or a signing cert?  If it is
197for the root cert, you are doomed.  Reissue all the CERTS.
198Start from square 0.
199
200If it is a signing cert,  then you can REVOKE it. How do you do this?
201You put it into a 'revocation' directory, and then tell OpenSSL
202to do its magic and update the CERT information so that it is revoked.
203(More on this later).
204
205Finally, how does the certificate information get transferred?
206
207This is a little complicated,  and there are a zillion ways to do
208this.  I have opted to implement and use a very simple method based
209on the Apached mod_perl SSL setup.
210
211a) A directory (/etc/lpd/ssl.crt/) containing
212   all of the signing certificates, including the root certificate
213   (ca.crt).  These will be used by both servers and clients.
214   Note: due to the OpenSSL implementation,  it is necessary
215   to create a set of symbolic links to these files.
216
217   Just to totally confuse things,  OpenSSL also supports putting
218   all of the certificates in a single file. The certificates should
219   be put in root to leaf order, i.e. - a breadth first walk
220   of the certificate tree.
221   
222    printcap/configure option:  ssl_ca_path=DIR 
223    configure:
224      --with-ssl_ca_path=DIR
225           default ${sysconfdir}/lpd/ssl.crt/
226      --with-ssl_ca_file=FILE
227           default - none
228   Note: See the SSL_CTX_load_verify_locations(
229      SSL_CTX *ctx, const char *CAfile, const char *CApath);
230   documentation for the details.
231
232b) A file (/etc/lpd/server.crt/server.crt) containing
233   the cert that is used by the server and is sent to the
234   client to identify the server.  It should also contain
235   the private key for the server.
236
237    printcap/configure option:  ssl_server_cert=FILE 
238    configure:
239      --with-ssl_server_cert=PATH
240        default ${sysconfdir}/lpd/server.crt/server.crt
241
242    Note: See SSL_CTX_use_certificate_chain_file(
243            SSL_CTX *ctx, const char *file);
244       SSL_use_PrivateKey_file(SSL *ssl, char *file,
245	    	int type);
246    documentation for details.  Note that this file can
247    contain multiple certs, but these must be sorted in top
248    (root CA) to bottom (server) order.
249     i.e. - 
250           private_key, server cert (additional certs
251           specified by ssl_ca_path or ssl_ca_file)
252     OR
253           root CA cert, signer1 cert, ..., server cert
254
255     Note: the private key can be in any position.
256
257c) A file (/etc/lpd/server.crt/server.pwd) containing the
258   password for the private key in the server cert file.
259   This file should to be 600, owned by the LPD server user.
260
261   Note: See the SSL_CTX_set_default_passwd_cb for details.
262   The password is read from the file.
263
264    printcap/configure option:  ssl_server_passwd=FILE 
265      --with-ssl_server_passwd=PATH
266        default ${sysconfdir}/lpd/server.crt/server.crt
267
268d) For user authentication to the server,  users will need to
269   specify a certificate and password.  This can be by using
270   values in default files or
271
272   ${HOME}/.lpr/ssl.crt/    - signing/root certificates
273     (if not present, then ${sysconfdir}/lpd/ssl.crt/ is used)
274     Environment variable: LPR_CA_PATH
275   ${HOME}/.lpr/client.crt  - client cert and key
276     Environment variable: LPR_SSL_CERT 
277   ${HOME}/.lpr/client.pwd  - file containing client password
278     Environment variable: LPR_SSL_PASSWORD
279
280
281SETTING UP CERTIFICATE AUTHORITY
282
283There are several types of certificate files:
284  - CA root (self signed)
285  - signing certs (signed by CA or by signing cert)
286  - user certs (used only by client programs)
287  - server certs (used by lpd server AND by lpd server when
288      forwarding to a remote queue)
289
290The certificates are arranged as follows:
291
2921. signing certs are in a directory (or a file)
293     default: /etc/lpd/ssl.ca
294
2952. certificates are created in a working directory
296     default: /etc/lpd/ssl.certs
297
2983. user certificates are kept in a subdirectory of the
299   user home directory, say:
300      ${HOME}/.lpr/client.crt   - cert
301      ${HOME}/.lpr/client.pwd   - password to use cert
302        private key for authentication
303
304The lprng_certs script provides a way to create ROOT certs,
305signer certs, server (lpd) certs, and user certs:
306
307usage: lprng_certs option
308  init              - make directory structure
309  newca             - make new root CA and defaults
310  defaults          - set new default values
311  encrypt keyfile   - set or change password on private key file
312  gen               - generate user, server, or signing cert
313  verify cert*      - verify certs
314     certs can be path or user-XX.csr values
315
316CREATE DIRECTORY STRUCTURE
317  Use:  lprng_certs init
318  - creates directories for lpd server
319      These are, by default:
320     /etc/lpd/ssl.ca/  - ca root and/or signer certs
321            default location for creation
322     /etc/lpd/ssl.server/  - server cert
323            (usually server.crt and server.pwd files)
324     /etc/lpd/ssl.certs/  - server and/or user certs
325            default location for creation
326
327   You use this to set up the directories for certificates
328   on a non-master system.
329
330CREATE CA ROOT CERT
331   Use: lprng newca
332
333    calls lprng_certs init
334    calls lprng_certs defaults to set up and/or modify
335      default values
336    creates the CA root certificate and key file in the
337      ssl.ca directory
338
339  You use this when you want to set up a totally  new
340  CA on a master system.
341
342Example:
343 
344  #> lprng_certs newca
345  
346  lprng_certs -- LPRng SSL Certificate Management
347  Copyright (c) 2002 Patrick Powell
348  Based on CCA by Ralf S. Engelschall
349  (Copyright (c) 1998-2001 Ralf S. Engelschall, All Rights Reserved.)
350  
351  WARNING: /etc/lpd/ssl.ca/ca.crt already exists! Do you want to overwrite it? [N/y] Y
352  
353  INITIALIZATION - SET DEFAULTS
354  ...  
355  ______________________________________________________________________
356  
357  STEP 1: Generating RSA private key for CA (1024 bit)
358  ______________________________________________________________________
359  
360  STEP 2: Generating X.509 certificate signing request for CA
361  ______________________________________________________________________
362  
363  STEP 3: Generating X.509 certificate for CA signed by itself
364  ______________________________________________________________________
365  
366  RESULT:
367  /etc/lpd/ssl.ca/ca.crt:
368  /C=US/ST=California/L=San Diego/O=Astart/OU=Certificate Authority/CN=Astart CA/Email=id@astart.com
369  error 18 at 0 depth lookup:self signed certificate
370  OK
371  ______________________________________________________________________
372  
373  STEP 4. Enrypting RSA private key with a pass phrase for security
374  The contents of the certificate key file (the generated private key)
375  should be echo kept secret, especially so if it is used to sign
376  Certificates or for User authentication.
377    SSL experts strongly recommend you to encrypt the key file with
378  a Triple-DES cipher and a Pass Phrase.  When using LPRng, you provide
379  the password via a file or file descriptor specified by an environent
380  variable, i.e. - SSL_PASSWORD_FILE or SSL_PASSWORD_FD, or in the
381  ${HOME}/.ssl_password file.
382    The LPD server uses the ssl_server_password_file option to specify
383  the location of a file containing the password.
384    See the LPRng Refernce Manual for details, or the printcap(5) man page.
385  
386  key file is /etc/lpd/ssl.ca/ca.key
387  Encrypt the private key now? [Y/n]: y
388  Fine, you're using an encrypted private key to sign CERTS.
389  ______________________________________________________________________
390  
391  STEP 5: Combine CERT and KEY file
392  Generate single CERT and KEY file? [Y/n] y
393  
394  Use the following commands to examine the CERT and KEY files:
395     openssl x509 -text -in /etc/lpd/ssl.ca/ca.crt
396     openssl rsa -text -in /etc/lpd/ssl.ca/ca.crt
397  
398CREATE A USER/SERVER CERT
399
400- creates a certificate with the appropriate entries for use
401  as a signing, server (lpd), or client (user) certificate.
402
403Example:
404 
405  #> lprng_certs newca
406  lprng_certs -- LPRng SSL Certificate Management
407  Copyright (c) 2002 Patrick Powell
408  Based on CCA by Ralf S. Engelschall
409  (Copyright (c) 1998-2001 Ralf S. Engelschall, All Rights Reserved.)
410  
411  CERTIFICATE GENERATION
412  What type of certificate? User/Server/Signing Authority/Help? [u/s/a/H] u
413  Create in '/etc/lpd/ssl.certs' [return for yes, or specify directory] y
414  CERT name 'user-01'? [return for yes, or specify name] papowell
415  CERT name 'papowell'? [return for yes, or specify name]
416  Creating papowell in /etc/lpd/ssl.certs
417  Sign with Certificate '/etc/lpd/ssl.ca/ca.crt' [return for yes, or specify cert file]
418  Private key in /etc/lpd/ssl.ca/ca.crt
419  
420  Generating user Certificate [papowell] 
421  ______________________________________________________________________
422  
423  STEP 1: Generating RSA private key for user (1024 bit)
424  ______________________________________________________________________
425  
426  STEP 2: Generating X.509 certificate signing request for user
427  User Certificate Validity in days  [default 365]
428  ______________________________________________________________________
429  
430  STEP 3: Generating X.509 certificate signed by own CA
431  ______________________________________________________________________
432  
433  RESULT:
434  /etc/lpd/ssl.certs/papowell.crt: OK
435  ______________________________________________________________________
436  
437  STEP 4. Enrypting RSA private key with a pass phrase for security
438  The contents of the certificate key file (the generated private key)
439  should be echo kept secret, especially so if it is used to sign
440  Certificates or for User authentication.
441    SSL experts strongly recommend you to encrypt the key file with
442  a Triple-DES cipher and a Pass Phrase.  When using LPRng, you provide
443  the password via a file or file descriptor specified by an environent
444  variable, i.e. - SSL_PASSWORD_FILE or SSL_PASSWORD_FD, or in the
445  ${HOME}/.ssl_password file.
446    The LPD server uses the ssl_server_password_file option to specify
447  the location of a file containing the password.
448    See the LPRng Refernce Manual for details, or the printcap(5) man page.
449  
450  key file is /etc/lpd/ssl.certs/papowell.key
451  Encrypt the private key now? [Y/n]: y
452  Fine, you're using an encrypted private key to sign CERTS.
453  ______________________________________________________________________
454  
455  STEP 5: Combine CERT and KEY file
456  Generate single CERT and KEY file? [Y/n] y
457  
458  Use the following commands to examine the CERT and KEY files:
459     openssl x509 -text -in /etc/lpd/ssl.certs/papowell.crt
460     openssl rsa -text -in /etc/lpd/ssl.certs/papowell.crt
461
462CREATE A SIGNING CERT
463
464  You will need to do this if you want to create a certificate that
465  you can use to sign other certificates - i.e. - delegate signing
466  authority.  This is done by creating a signing certificate.  The
467  private key file for this certificate should be treated in the same
468  was as for the root certificate - it should not be stored in the
469  same file as the certificate, or if it is,  the password for the
470  key should be very long and resistant to a dictionary attack.
471  I do not recommend storing the private key and certificate in the
472  same file.
473
474  lprng_certs -- LPRng SSL Certificate Management
475  Copyright (c) 2002 Patrick Powell
476  Based on CCA by Ralf S. Engelschall
477  (Copyright (c) 1998-2001 Ralf S. Engelschall, All Rights Reserved.)
478  
479  CERTIFICATE GENERATION
480  What type of certificate? User/Server/Signing Authority/Help? [u/s/a/H] a
481  Create in '/etc/lpd/ssl.ca' [return for yes, or specify directory]
482  CERT name 'signer-02'? [return for yes, or specify name]
483  Creating signer-02 in /etc/lpd/ssl.ca
484  Sign with Certificate '/etc/lpd/ssl.ca/ca.crt' [return for yes, or specify cert file]
485  Private key in /etc/lpd/ssl.ca/ca.crt
486  
487  Generating signer Certificate [signer-02] 
488  ______________________________________________________________________
489  
490  STEP 1: Generating RSA private key for signer (1024 bit)
491  ______________________________________________________________________
492  
493  STEP 2: Generating X.509 certificate signing request for signer
494  User Certificate Validity in days  [default 365]
495  ______________________________________________________________________
496  
497  STEP 3: Generating X.509 certificate signed by own CA
498  ______________________________________________________________________
499  
500  RESULT:
501  /etc/lpd/ssl.ca/signer-02.crt: OK
502  ______________________________________________________________________
503  
504  STEP 4. Enrypting RSA private key with a pass phrase for security
505  The contents of the certificate key file (the generated private key)
506  should be echo kept secret, especially so if it is used to sign
507  Certificates or for User authentication.
508    SSL experts strongly recommend you to encrypt the key file with
509  a Triple-DES cipher and a Pass Phrase.  When using LPRng, you provide
510  the password via a file or file descriptor specified by an environent
511  variable, i.e. - SSL_PASSWORD_FILE or SSL_PASSWORD_FD, or in the
512  ${HOME}/.ssl_password file.
513    The LPD server uses the ssl_server_password_file option to specify
514  the location of a file containing the password.
515    See the LPRng Refernce Manual for details, or the printcap(5) man page.
516  
517  key file is /etc/lpd/ssl.ca/signer-02.key
518  Encrypt the private key now? [Y/n]:
519  Fine, you're using an encrypted private key to sign CERTS.
520  ______________________________________________________________________
521  
522  STEP 5: Combine CERT and KEY file
523  Generate single CERT and KEY file? [Y/n] 
524  
525  Use the following commands to examine the CERT and KEY files:
526     openssl x509 -text -in /etc/lpd/ssl.ca/signer-02.crt
527     openssl rsa -text -in /etc/lpd/ssl.ca/signer-02.crt
528  
529  - creates a certificate with the appropriate entries for use
530    as a signing, server (lpd), or client (user) certificate.
531  
532CREATING CERT AND SIGNING IT WITH SIGNING CERT
533
534  This is done in the same manner as creating a CERT, but
535  you simply select the signing cert to be used.  When requested
536  for the password,  you should supply the password of the signing
537  cert, not the root cert.
538
539SETTING UP LPD SERVERS WITH SSL CERTS
540
541  First, you will need to create a root CA as described above,
542and then create a certificate and key for the server. I recommend
543you put the key and cert into the same file.
544
545CERTIFICATE REVOCATION AND PERMSSIONS CHECKING
546
547The current implementation does not support or provide support
548for the X509 Certificate Revocation List or files.  Instead,
549we use the lpd.perms facilities and reject user and/or signers
550based on the information in their 'subject' or 'issuer' information.
551The AUTHFROM and AUTHCA contain the subject and issuer information
552for the user certificate received by the LPD server.  Actually,
553the AUTHCA information contains the hierarchy of certificate signers,
554so you can reject a request based on the presence or abscence
555of a certificate signer.
556
557For example:
558h110: {230} % openssl x509 -issuer -subject -noout -in ${HOME}/.lpr/client.crt
559issuer= /C=US/ST=California/L=San Diego/O=Astart/\
560    OU=CertificateAuthority/CN=AstartCA/Email=ca@astart.com
561subject= /C=US/ST=California/L=San Diego/O=Astart/\
562    OU=Server/CN=papowell/Email=papowell@astart.com
563
564You can now use:
565
566# /etc/lpd.perms
567REJECT NOT AUTHTYPE=ssl
568REJECT NOT AUTHCA=*/CN=AstartCA/*
569REJECT AUTHFROM=*/CN=papowell/*
570
571You can also put this in a file, say /etc/lpd/signers.auth
572 */CN=AstartCA/*
573and, say /etc/lpd/reject.users
574 */CN=papowell/*
575
576Now you can use:
577REJECT NOT AUTHCA=</etc/lpd/signers.auth
578REJECT AUTHFROM=</etc/lpd/reject.users
579
580Now you might want to try to automate this process by putting the CERTS of
581bad users or bad signers into a directory and then extracting the subject
582keys::
583
584#> lprng_certs verify
585