* Create per-connection SSL object, and load the client certificate, * private key, and trusted CA certs. * * Returns 0 if OK, -1 on failure (with a message in conn->errorMessage). */
| 787 | * Returns 0 if OK, -1 on failure (with a message in conn->errorMessage). |
| 788 | */ |
| 789 | static int |
| 790 | initialize_SSL(PGconn *conn) |
| 791 | { |
| 792 | SSL_CTX *SSL_context; |
| 793 | struct stat buf; |
| 794 | char homedir[MAXPGPATH]; |
| 795 | char fnbuf[MAXPGPATH]; |
| 796 | char sebuf[PG_STRERROR_R_BUFLEN]; |
| 797 | bool have_homedir; |
| 798 | bool have_cert; |
| 799 | bool have_rootcert; |
| 800 | EVP_PKEY *pkey = NULL; |
| 801 | |
| 802 | /* |
| 803 | * We'll need the home directory if any of the relevant parameters are |
| 804 | * defaulted. If pqGetHomeDirectory fails, act as though none of the |
| 805 | * files could be found. |
| 806 | */ |
| 807 | if (!(conn->sslcert && strlen(conn->sslcert) > 0) || |
| 808 | !(conn->sslkey && strlen(conn->sslkey) > 0) || |
| 809 | !(conn->sslrootcert && strlen(conn->sslrootcert) > 0) || |
| 810 | !((conn->sslcrl && strlen(conn->sslcrl) > 0) || |
| 811 | (conn->sslcrldir && strlen(conn->sslcrldir) > 0))) |
| 812 | have_homedir = pqGetHomeDirectory(homedir, sizeof(homedir)); |
| 813 | else /* won't need it */ |
| 814 | have_homedir = false; |
| 815 | |
| 816 | /* |
| 817 | * Create a new SSL_CTX object. |
| 818 | * |
| 819 | * We used to share a single SSL_CTX between all connections, but it was |
| 820 | * complicated if connections used different certificates. So now we |
| 821 | * create a separate context for each connection, and accept the overhead. |
| 822 | */ |
| 823 | SSL_context = SSL_CTX_new(SSLv23_method()); |
| 824 | if (!SSL_context) |
| 825 | { |
| 826 | char *err = SSLerrmessage(ERR_get_error()); |
| 827 | |
| 828 | appendPQExpBuffer(&conn->errorMessage, |
| 829 | libpq_gettext("could not create SSL context: %s\n"), |
| 830 | err); |
| 831 | SSLerrfree(err); |
| 832 | return -1; |
| 833 | } |
| 834 | |
| 835 | /* |
| 836 | * Delegate the client cert password prompt to the libpq wrapper callback |
| 837 | * if any is defined. |
| 838 | * |
| 839 | * If the application hasn't installed its own and the sslpassword |
| 840 | * parameter is non-null, we install ours now to make sure we supply |
| 841 | * PGconn->sslpassword to OpenSSL instead of letting it prompt on stdin. |
| 842 | * |
| 843 | * This will replace OpenSSL's default PEM_def_callback (which prompts on |
| 844 | * stdin), but we're only setting it for this SSL context so it's |
| 845 | * harmless. |
| 846 | */ |
no test coverage detected