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