diff --git a/pam/auth_client.c b/pam/auth_client.c
index 8c7d559d7a40e431432174221cefe5bff5e65be9..56d8f6df65884e38db0216d22cdc4136fb4e0903 100644
--- a/pam/auth_client.c
+++ b/pam/auth_client.c
@@ -6,9 +6,14 @@
 #ifdef HAVE_MEMORY_H
 #include <memory.h>
 #endif
+#include <sys/stat.h>
 #include <curl/curl.h>
 #include "auth_client.h"
 
+#define CURL_CHECK(x) { \
+  int _err = (x); if (_err != CURLE_OK) { return auth_client_err_from_curl(_err); } \
+}
+
 static const char *kAuthApiPath = "/api/1/auth";
 
 struct auth_client {
@@ -17,10 +22,11 @@ struct auth_client {
   const char *server;
 };
 
-static void auth_client_set_proto(auth_client_t ac, const char *proto) {
+static int auth_client_set_proto(auth_client_t ac, const char *proto) {
   char url[strlen(ac->server) + 32];
   sprintf(url, "%s://%s%s", proto, ac->server, kAuthApiPath);
-  curl_easy_setopt(ac->c, CURLOPT_URL, url);
+  CURL_CHECK(curl_easy_setopt(ac->c, CURLOPT_URL, url));
+  return AC_OK;
 }
 
 auth_client_t auth_client_new(const char *service, const char *server) {
@@ -35,18 +41,34 @@ auth_client_t auth_client_new(const char *service, const char *server) {
   return ac;
 }
 
-void auth_client_set_certificate(auth_client_t ac,
-                                 const char *ca_file,
-                                 const char *crt_file,
-                                 const char *key_file) {
-  curl_easy_setopt(ac->c, CURLOPT_CAPATH, ca_file);
-  curl_easy_setopt(ac->c, CURLOPT_SSLCERTTYPE, "PEM");
-  curl_easy_setopt(ac->c, CURLOPT_SSLCERT, crt_file);
-  curl_easy_setopt(ac->c, CURLOPT_SSLKEYTYPE, "PEM");
-  curl_easy_setopt(ac->c, CURLOPT_SSLKEY, key_file);
-  curl_easy_setopt(ac->c, CURLOPT_SSL_VERIFYPEER, 1);
-  curl_easy_setopt(ac->c, CURLOPT_SSL_VERIFYHOST, 0);
-  auth_client_set_proto(ac, "https");
+static int file_exists(const char *path) {
+  struct stat stbuf;
+  if (stat(path, &stbuf) < 0) {
+    return 0;
+  }
+  return 1;
+}
+
+void auth_client_set_verbose(auth_client_t ac, int verbose) {
+  curl_easy_setopt(ac->c, CURLOPT_VERBOSE, verbose);
+}
+
+int auth_client_set_certificate(auth_client_t ac,
+                                const char *ca_file,
+                                const char *crt_file,
+                                const char *key_file) {
+  if (!file_exists(ca_file) || !file_exists(crt_file) || !file_exists(key_file)) {
+    return AC_ERR_FILE_NOT_FOUND;
+  }
+  CURL_CHECK(curl_easy_setopt(ac->c, CURLOPT_SSLCERTTYPE, "PEM"));
+  CURL_CHECK(curl_easy_setopt(ac->c, CURLOPT_SSLCERT, crt_file));
+  CURL_CHECK(curl_easy_setopt(ac->c, CURLOPT_SSLKEYTYPE, "PEM"));
+  CURL_CHECK(curl_easy_setopt(ac->c, CURLOPT_SSLKEY, key_file));
+  CURL_CHECK(curl_easy_setopt(ac->c, CURLOPT_CAINFO, ca_file));
+  CURL_CHECK(curl_easy_setopt(ac->c, CURLOPT_SSL_VERIFYPEER, 2));
+  CURL_CHECK(curl_easy_setopt(ac->c, CURLOPT_SSL_VERIFYHOST, 0));
+  CURL_CHECK(curl_easy_setopt(ac->c, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1));
+  return auth_client_set_proto(ac, "https");
 }
 
 void auth_client_free(auth_client_t ac) {
@@ -63,6 +85,10 @@ const char *auth_client_strerror(int err) {
     return "Authentication failure";
   case AC_ERR_OTP_REQUIRED:
     return "OTP required";
+  case AC_ERR_BAD_RESPONSE:
+    return "Bad server response";
+  case AC_ERR_FILE_NOT_FOUND:
+    return "Certificate or CA file not found";
   default:
     return "Unknown error";
   }
@@ -144,7 +170,7 @@ static void post_field_add(struct cbuf *form_data, const char *key, const char *
     cbuf_append(form_data, "&", 1);
   }
   cbuf_append(form_data, quoted_key, strlen(quoted_key));
-  cbuf_append(form_data, "&", 1);
+  cbuf_append(form_data, "=", 1);
   cbuf_append(form_data, quoted_value, strlen(quoted_value));
   free(quoted_key);
   free(quoted_value);
diff --git a/pam/auth_client.h b/pam/auth_client.h
index f9457518b1d2f58c988b87f01efc42e8169c9ecd..8228bb09bf5de453fe2a037e253a02e1ce88524b 100644
--- a/pam/auth_client.h
+++ b/pam/auth_client.h
@@ -10,6 +10,7 @@ typedef struct auth_client* auth_client_t;
 #define AC_ERR_AUTHENTICATION_FAILURE  -1
 #define AC_ERR_OTP_REQUIRED            -2
 #define AC_ERR_BAD_RESPONSE            -3
+#define AC_ERR_FILE_NOT_FOUND          -4
 #define AC_ERR_CURL_BASE             -100
 #define auth_client_err_to_curl(e)     (-(e)+(AC_ERR_CURL_BASE))
 #define auth_client_err_from_curl(e)   ((AC_ERR_CURL_BASE)-(e))
@@ -17,10 +18,11 @@ typedef struct auth_client* auth_client_t;
 auth_client_t auth_client_new(const char *service, const char *server);
 void auth_client_free(auth_client_t ac);
 const char *auth_client_strerror(int err);
-void auth_client_set_certificate(auth_client_t ac,
-                                 const char *ca_file,
-                                 const char *crt_file,
-                                 const char *key_file);
+void auth_client_set_verbose(auth_client_t ac, int verbose);
+int auth_client_set_certificate(auth_client_t ac,
+                                const char *ca_file,
+                                const char *crt_file,
+                                const char *key_file);
 int auth_client_authenticate(auth_client_t ac,
                              const char *username,
                              const char *password,
diff --git a/pam/auth_client_test.cc b/pam/auth_client_test.cc
index a560b120ad24dc48d0a0acafc2926c91c6c0ca93..1ca19dad3cc8ba84702e7721cc06f808a5e9dfab 100644
--- a/pam/auth_client_test.cc
+++ b/pam/auth_client_test.cc
@@ -8,8 +8,8 @@ extern "C" {
 
 static const char *server = NULL;
 
-static const char *ssl_ca = "../authserv/test/testca/public/ca.pem";
-static const char *ssl_cert = "../authserv/test/testca/public/certs/client.pem";
+static const char *ssl_ca = "../authserv/test/testca/ca.pem";
+static const char *ssl_cert = "../authserv/test/testca/certs/client.pem";
 static const char *ssl_key = "../authserv/test/testca/private/client.key";
 
 TEST(AuthClientCurlInterface, ErrorConversion) {
@@ -22,7 +22,21 @@ TEST(AuthClientCurlInterface, ErrorConversion) {
 TEST(AuthClient, NewAndFree) {
   auth_client_t ac;
   ac = auth_client_new("service", server);
-  EXPECT_TRUE(ac != NULL);
+  ASSERT_TRUE(ac != NULL);
+
+  auth_client_free(ac);
+}
+
+TEST(AuthClient, CertSetupFailsWithoutCA) {
+  auth_client_t ac = auth_client_new("service", server);
+  ASSERT_TRUE(ac != NULL);
+
+  EXPECT_NE(AC_OK,
+            auth_client_set_certificate(ac, "nonexisting.pem", ssl_cert, ssl_key));
+  EXPECT_NE(AC_OK,
+            auth_client_set_certificate(ac, ssl_ca, "nonexisting.pem", ssl_key));
+  EXPECT_NE(AC_OK,
+            auth_client_set_certificate(ac, ssl_ca, ssl_cert, "nonexisting.key"));
 
   auth_client_free(ac);
 }
@@ -31,13 +45,17 @@ TEST(AuthClient, AuthOK) {
   auth_client_t ac;
   int result;
 
-  printf("Connecting to %s...\n", server);
   ac = auth_client_new("service", server);
-  EXPECT_TRUE(ac != NULL);
+  ASSERT_TRUE(ac != NULL);
+
+  auth_client_set_verbose(ac, 1);
+
+  result = auth_client_set_certificate(ac, ssl_ca, ssl_cert, ssl_key);
+  EXPECT_EQ(AC_OK, result) << "set_certificate() error: " << auth_client_strerror(result);
 
-  auth_client_set_certificate(ac, ssl_ca, ssl_cert, ssl_key);
   result = auth_client_authenticate(ac, "user", "pass", NULL, "127.0.0.1");
-  EXPECT_EQ(AC_OK, result) << "Got error: " << auth_client_strerror(result);
+  EXPECT_EQ(AC_OK, result) << "authenticate() error: " << auth_client_strerror(result)
+                           << ", server=" << server;
 
   auth_client_free(ac);
 }
diff --git a/pam/pam_authclient.c b/pam/pam_authclient.c
index e8623a364bf6981ce62a5d37381cdcfded6b1714..506eb02ac949ad7b7c85f8a523417bdab3c89e39 100644
--- a/pam/pam_authclient.c
+++ b/pam/pam_authclient.c
@@ -140,14 +140,18 @@ PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh,
     password = resp->resp;
   }
 
+  retval = PAM_AUTH_ERR;
+
   // Create the auth client request.
   ac = auth_client_new(service, cfg.auth_server);
   if (cfg.ssl_crt && cfg.ssl_key && cfg.ca_file) {
-    auth_client_set_certificate(ac, cfg.ca_file, cfg.ssl_crt, cfg.ssl_key);
+    err = auth_client_set_certificate(ac, cfg.ca_file, cfg.ssl_crt, cfg.ssl_key);
+    if (err != AC_OK) {
+      D(("auth_client_set_certificate() error: %s", auth_client_strerror(err)));
+      goto error;
+    }
   }
 
-  retval = PAM_AUTH_ERR;
-
   // Allow two authentication attempts in case we receive an
   // OTP_REQUIRED response from the server.
   for (i = 0; i < 2; i++) {
@@ -183,6 +187,7 @@ PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh,
     break;
   }
 
+ error:
   auth_client_free(ac);
   return retval;
 }