• Bruce Momjian's avatar
    Attached are a revised set of SSL patches. Many of these patches · a9bd1761
    Bruce Momjian authored
    are motivated by security concerns, it's not just bug fixes.  The key
    differences (from stock 7.2.1) are:
    
    *) almost all code that directly uses the OpenSSL library is in two
       new files,
    
         src/interfaces/libpq/fe-ssl.c
         src/backend/postmaster/be-ssl.c
    
       in the long run, it would be nice to merge these two files.
    
    *) the legacy code to read and write network data have been
       encapsulated into read_SSL() and write_SSL().  These functions
       should probably be renamed - they handle both SSL and non-SSL
       cases.
    
       the remaining code should eliminate the problems identified
       earlier, albeit not very cleanly.
    
    *) both front- and back-ends will send a SSL shutdown via the
       new close_SSL() function.  This is necessary for sessions to
       work properly.
    
       (Sessions are not yet fully supported, but by cleanly closing
       the SSL connection instead of just sending a TCP FIN packet
       other SSL tools will be much happier.)
    
    *) The client certificate and key are now expected in a subdirectory
       of the user's home directory.  Specifically,
    
    	- the directory .postgresql must be owned by the user, and
    	  allow no access by 'group' or 'other.'
    
    	- the file .postgresql/postgresql.crt must be a regular file
    	  owned by the user.
    
    	- the file .postgresql/postgresql.key must be a regular file
    	  owned by the user, and allow no access by 'group' or 'other'.
    
       At the current time encrypted private keys are not supported.
       There should also be a way to support multiple client certs/keys.
    
    *) the front-end performs minimal validation of the back-end cert.
       Self-signed certs are permitted, but the common name *must*
       match the hostname used by the front-end.  (The cert itself
       should always use a fully qualified domain name (FDQN) in its
       common name field.)
    
       This means that
    
    	  psql -h eris db
    
       will fail, but
    
    	  psql -h eris.example.com db
    
       will succeed.  At the current time this must be an exact match;
       future patches may support any FQDN that resolves to the address
       returned by getpeername(2).
    
       Another common "problem" is expiring certs.  For now, it may be
       a good idea to use a very-long-lived self-signed cert.
    
       As a compile-time option, the front-end can specify a file
       containing valid root certificates, but it is not yet required.
    
    *) the back-end performs minimal validation of the client cert.
       It allows self-signed certs.  It checks for expiration.  It
       supports a compile-time option specifying a file containing
       valid root certificates.
    
    *) both front- and back-ends default to TLSv1, not SSLv3/SSLv2.
    
    *) both front- and back-ends support DSA keys.  DSA keys are
       moderately more expensive on startup, but many people consider
       them preferable than RSA keys.  (E.g., SSH2 prefers DSA keys.)
    
    *) if /dev/urandom exists, both client and server will read 16k
       of randomization data from it.
    
    *) the server can read empheral DH parameters from the files
    
         $DataDir/dh512.pem
         $DataDir/dh1024.pem
         $DataDir/dh2048.pem
         $DataDir/dh4096.pem
    
       if none are provided, the server will default to hardcoded
       parameter files provided by the OpenSSL project.
    
    Remaining tasks:
    
    *) the select() clauses need to be revisited - the SSL abstraction
       layer may need to absorb more of the current code to avoid rare
       deadlock conditions.  This also touches on a true solution to
       the pg_eof() problem.
    
    *) the SIGPIPE signal handler may need to be revisited.
    
    *) support encrypted private keys.
    
    *) sessions are not yet fully supported.  (SSL sessions can span
       multiple "connections," and allow the client and server to avoid
       costly renegotiations.)
    
    *) makecert - a script that creates back-end certs.
    
    *) pgkeygen - a tool that creates front-end certs.
    
    *) the whole protocol issue, SASL, etc.
    
     *) certs are fully validated - valid root certs must be available.
        This is a hassle, but it means that you *can* trust the identity
        of the server.
    
     *) the client library can handle hardcoded root certificates, to
        avoid the need to copy these files.
    
     *) host name of server cert must resolve to IP address, or be a
        recognized alias.  This is more liberal than the previous
        iteration.
    
     *) the number of bytes transferred is tracked, and the session
        key is periodically renegotiated.
    
     *) basic cert generation scripts (mkcert.sh, pgkeygen.sh).  The
        configuration files have reasonable defaults for each type
        of use.
    
    Bear Giles
    a9bd1761
fe-ssl.c 18.9 KB