diff --git a/lib/axtls.c b/lib/axtls.c
index 9a253bc1e0fae357446b74db2b4929c0c49a7249..ff4ff2b15afa470dc7b808c5738187159ff994dc 100644
--- a/lib/axtls.c
+++ b/lib/axtls.c
@@ -50,17 +50,93 @@
 /* The last #include file should be: */
 #include "memdebug.h"
 
+/* SSL_read is opied from axTLS compat layer */
+static int SSL_read(SSL *ssl, void *buf, int num)
+{
+  uint8_t *read_buf;
+  int ret;
+  
+  while((ret = ssl_read(ssl, &read_buf)) == SSL_OK);
+
+  if(ret > SSL_OK){
+    memcpy(buf, read_buf, ret > num ? num : ret);
+  }
+
+  return ret;
+}
+
 /* Global axTLS init, called from Curl_ssl_init() */
 int Curl_axtls_init(void)
 {
+/* axTLS has no global init.  Everything is done through SSL and SSL_CTX
+ * structs stored in connectdata structure.  Perhaps can move to axtls.h.
+ */
   return 1;
 }
 
 int Curl_axtls_cleanup(void)
 {
+  /* axTLS has no global cleanup.  Perhaps can move this to axtls.h. */
   return 1;
 }
 
+static CURLcode map_error_to_curl(int axtls_err)
+{
+  switch (axtls_err)
+  {
+  case SSL_ERROR_NOT_SUPPORTED:
+  case SSL_ERROR_INVALID_VERSION:
+  case -70:                       /* protocol version alert from server */
+    return CURLE_UNSUPPORTED_PROTOCOL;
+    break;
+  case SSL_ERROR_NO_CIPHER:
+    return CURLE_SSL_CIPHER;
+    break;
+  case SSL_ERROR_BAD_CERTIFICATE: /* this may be bad server cert too */
+  case SSL_ERROR_NO_CERT_DEFINED:
+  case -42:                       /* bad certificate alert from server */
+  case -43:                       /* unsupported cert alert from server */
+  case -44:                       /* cert revoked alert from server */
+  case -45:                       /* cert expired alert from server */
+  case -46:                       /* cert unknown alert from server */
+    return CURLE_SSL_CERTPROBLEM;
+    break;
+  case SSL_X509_ERROR(X509_NOT_OK):
+  case SSL_X509_ERROR(X509_VFY_ERROR_NO_TRUSTED_CERT):
+  case SSL_X509_ERROR(X509_VFY_ERROR_BAD_SIGNATURE):
+  case SSL_X509_ERROR(X509_VFY_ERROR_NOT_YET_VALID):
+  case SSL_X509_ERROR(X509_VFY_ERROR_EXPIRED):
+  case SSL_X509_ERROR(X509_VFY_ERROR_SELF_SIGNED):
+  case SSL_X509_ERROR(X509_VFY_ERROR_INVALID_CHAIN):
+  case SSL_X509_ERROR(X509_VFY_ERROR_UNSUPPORTED_DIGEST):
+  case SSL_X509_ERROR(X509_INVALID_PRIV_KEY):
+    return CURLE_PEER_FAILED_VERIFICATION;
+    break;
+  case -48:                       /* unknown ca alert from server */
+    return CURLE_SSL_CACERT;
+    break;
+  case -49:                       /* access denied alert from server */
+    return CURLE_REMOTE_ACCESS_DENIED;
+    break;
+  case SSL_ERROR_CONN_LOST:
+  case SSL_ERROR_SOCK_SETUP_FAILURE:
+  case SSL_ERROR_INVALID_HANDSHAKE:
+  case SSL_ERROR_INVALID_PROT_MSG:
+  case SSL_ERROR_INVALID_HMAC:
+  case SSL_ERROR_INVALID_SESSION:
+  case SSL_ERROR_INVALID_KEY:     /* it's too bad this doesn't map better */
+  case SSL_ERROR_FINISHED_INVALID:
+  case SSL_ERROR_NO_CLIENT_RENOG:
+  default:
+    return CURLE_SSL_CONNECT_ERROR;
+    break;
+  }
+  return CURLE_SSL_CONNECT_ERROR; /* catch-all for non-easily-mapped errors */
+}
+
+static Curl_recv axtls_recv;
+static Curl_send axtls_send;
+
 /*
  * This function is called after the TCP connect has completed. Setup the TLS
  * layer and do all necessary magic.
@@ -70,25 +146,232 @@ Curl_axtls_connect(struct connectdata *conn,
                   int sockindex)
 
 {
+  struct SessionHandle *data = conn->data;
+  SSL_CTX *ssl_ctx;
+  SSL *ssl;
+  int cert_types[] = {SSL_OBJ_X509_CERT, SSL_OBJ_PKCS12, 0};
+  int key_types[] = {SSL_OBJ_RSA_KEY, SSL_OBJ_PKCS8, SSL_OBJ_PKCS12, 0};
+  int i, ssl_fcn_return;
+  const uint8_t *ssl_sessionid;
+  size_t ssl_idsize;
+  const char *x509;
+
+  /* Assuming users will not compile in custom key/cert to axTLS */
+  uint32_t client_option = SSL_NO_DEFAULT_KEY;
+
+  if(conn->ssl[sockindex].state == ssl_connection_complete)
+    /* to make us tolerant against being called more than once for the
+       same connection */
+    return CURLE_OK;
+
+  /* axTLS only supports TLSv1 */
+  if(data->set.ssl.version != CURL_SSLVERSION_TLSv1) {
+    failf(data, "axTLS only supports TLSv1");
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+#ifdef  AXTLSDEBUG
+  client_option |= SSL_DISPLAY_STATES | SSL_DISPLAY_RSA | SSL_DISPLAY_CERTS;
+#endif /* AXTLSDEBUG */
+
+  /* Allocate an SSL_CTX struct */
+  ssl_ctx = ssl_ctx_new(client_option, SSL_DEFAULT_CLNT_SESS);
+  if(ssl_ctx == NULL) {
+    failf(data, "unable to create client SSL context");
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+  /* Load the trusted CA cert bundle file */
+  if(data->set.ssl.CAfile) {
+    if(ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CACERT, data->set.ssl.CAfile, NULL) \
+       != SSL_OK){
+      infof(data, "error reading ca cert file %s \n",
+	    data->set.ssl.CAfile);
+      if(data->set.ssl.verifypeer){
+	Curl_axtls_close(conn, sockindex);	   
+	return CURLE_SSL_CACERT_BADFILE;
+      }
+    }
+    else
+      infof(data, "found certificates in %s\n", data->set.ssl.CAfile);
+  }
+
+  /* gtls.c tasks we're skipping for now:
+   * 1) certificate revocation list checking
+   * 2) dns name assignment to host
+   * 3) set protocol priority.  axTLS is TLSv1 only, so can probably ignore
+   * 4) set certificate priority.  axTLS ignores type and sends certs in 
+   *  order added.  can probably ignore this.
+   */
+
+  /* Load client certificate */
+  if(data->set.str[STRING_CERT]){
+    i=0;
+    /* Instead of trying to analyze cert type here, let axTLS try them all. */
+    while(cert_types[i] != 0){
+      ssl_fcn_return = ssl_obj_load(ssl_ctx, cert_types[i],		\
+				    data->set.str[STRING_CERT], NULL);
+      if(ssl_fcn_return == SSL_OK){
+	infof(data, "successfully read cert file %s \n",	\
+	      data->set.str[STRING_CERT]);
+	break;
+      }
+      i++;
+    }
+    /* Tried all cert types, none worked. */
+    if(cert_types[i] == 0){
+      failf(data, "%s is not x509 or pkcs12 format",	\
+	    data->set.str[STRING_CERT]);
+      Curl_axtls_close(conn, sockindex);	   
+      return CURLE_SSL_CERTPROBLEM;
+    }
+  }
+
+  /* Load client key.
+     If a pkcs12 file successfully loaded a cert, then there's nothing to do
+     because the key has already been loaded. */
+  if(data->set.str[STRING_KEY] && cert_types[i] != SSL_OBJ_PKCS12){
+    i=0;
+    /* Instead of trying to analyze key type here, let axTLS try them all. */
+    while(key_types[i] != 0){
+      ssl_fcn_return = ssl_obj_load(ssl_ctx, key_types[i], \
+				     data->set.str[STRING_KEY], NULL);
+      if(ssl_fcn_return == SSL_OK){
+	infof(data, "successfully read key file %s \n", \
+	      data->set.str[STRING_KEY]);
+	break;
+      }
+      i++;
+    }
+    /* Tried all key types, none worked. */
+    if(key_types[i] == 0){
+      failf(data, "Failure: %s is not a supported key file",	\
+	    data->set.str[STRING_KEY]);
+      Curl_axtls_close(conn, sockindex);	   
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+  }
+
+  /* gtls.c does more here that is being left out for now
+   * 1) set session credentials.  can probably ignore since axtls puts this
+   *    info in the ssl_ctx struct
+   * 2) setting up callbacks.  these seem gnutls specific
+   */
+
+  /* In axTLS, handshaking happens inside ssl_client_new. */
+  if(!Curl_ssl_getsessionid(conn, (void **) &ssl_sessionid, &ssl_idsize)){
+    /* we got a session id, use it! */
+    infof (data, "SSL re-using session ID\n");
+    ssl = ssl_client_new(ssl_ctx, conn->sock[sockindex], \
+			 ssl_sessionid, ssl_idsize);
+  }
+  else
+    ssl = ssl_client_new(ssl_ctx, conn->sock[sockindex], NULL, 0);
+
+  /* Check to make sure handshake was ok. */
+  ssl_fcn_return = ssl_handshake_status(ssl);
+  if(ssl_fcn_return != SSL_OK){
+    Curl_axtls_close(conn, sockindex);	   
+    ssl_display_error(ssl_fcn_return); /* goes to stdout. */
+    return map_error_to_curl(ssl_fcn_return);
+  }
+  infof (data, "handshake completed successfully\n");
+
+  /* Here, gtls.c gets the peer certificates and fails out depending on 
+   * settings in "data."  axTLS api doesn't have get cert chain fcn, so omit?
+   */
+
+  /* Verify server's certificate */
+  if(data->set.ssl.verifypeer){
+    if(ssl_verify_cert(ssl) != SSL_OK){
+      Curl_axtls_close(conn, sockindex);	   
+      failf(data, "server cert verify failed");
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+  }
+  else
+    infof(data, "\t server certificate verification SKIPPED\n");
+
+  /* Here, gtls.c does issuer verfication. axTLS has no straightforward
+   * equivalent, so omitting for now.*/
+
+  /* See if common name was set in server certificate */
+  x509 = ssl_get_cert_dn(ssl, SSL_X509_CERT_COMMON_NAME);
+  if(x509 == NULL) 
+    infof(data, "error fetching CN from cert\n");
+
+  /* Here, gtls.c does the following
+   * 1) x509 hostname checking per RFC2818.  axTLS doesn't support this, but 
+   *    it seems useful.  Omitting for now.
+   * 2) checks cert validity based on time.  axTLS does this in ssl_verify_cert
+   * 3) displays a bunch of cert information.  axTLS doesn't support most of
+   *    this, but a couple fields are available.
+   */
+
+  /* General housekeeping */
+  conn->ssl[sockindex].state = ssl_connection_complete;
+  conn->ssl[sockindex].ssl = ssl;
+  conn->ssl[sockindex].ssl_ctx = ssl_ctx;
+  conn->recv[sockindex] = axtls_recv;
+  conn->send[sockindex] = axtls_send;
+
+  /* Put our freshly minted SSL session in cache */
+  ssl_idsize = ssl_get_session_id_size(ssl);
+  ssl_sessionid = ssl_get_session_id(ssl);
+  if(Curl_ssl_addsessionid(conn, (void *) ssl_sessionid, ssl_idsize) \
+     != CURLE_OK)
+    infof (data, "failed to add session to cache\n");
+
   return CURLE_OK;
 }
 
 
 /* return number of sent (non-SSL) bytes */
-ssize_t Curl_axtls_send(struct connectdata *conn,
-                       int sockindex,
-                       const void *mem,
-                       size_t len)
+static ssize_t axtls_send(struct connectdata *conn,
+			  int sockindex,
+			  const void *mem,
+			  size_t len,   
+			  CURLcode *err)
 {
-  return 0;
+  /* ssl_write() returns 'int' while write() and send() returns
+     'size_t' */
+  char error_buffer[120]; /* Comply with OpenSSL, which documents that this 
+			     must be at least 120 bytes long. */
+  int rc = ssl_write(conn->ssl[sockindex].ssl, mem, (int)len);
+
+  if(rc < 0 ) {
+    *err = map_error_to_curl(rc);
+    rc = -1; /* generic error code for send failure */
+  }
+
+  *err = CURLE_OK;
+  return rc;
 }
 
 void Curl_axtls_close_all(struct SessionHandle *data)
 {
+  (void)data;
 }
 
 void Curl_axtls_close(struct connectdata *conn, int sockindex)
 {
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+
+  if(connssl->ssl) {
+    /* line from ssluse.c: (void)SSL_shutdown(connssl->ssl);
+       axTLS compat layer does nothing for SSL_shutdown */
+
+    /* The following line is from ssluse.c.  There seems to be no axTLS
+       equivalent.  ssl_free and ssl_ctx_free close things.
+       SSL_set_connect_state(connssl->handle); */
+
+    ssl_free (connssl->ssl);
+    connssl->ssl = NULL;
+  }
+  if(connssl->ssl_ctx) {
+    ssl_ctx_free (connssl->ssl_ctx);
+    connssl->ssl_ctx = NULL;
+  }
 }
 
 /*
@@ -97,7 +380,54 @@ void Curl_axtls_close(struct connectdata *conn, int sockindex)
  */
 int Curl_axtls_shutdown(struct connectdata *conn, int sockindex)
 {
-  return 0;
+  /* Outline taken from ssluse.c since functions are in axTLS compat layer.
+     axTLS's error set is much smaller, so a lot of error-handling was removed.
+   */
+  int retval = 0;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct SessionHandle *data = conn->data;
+  char buf[120]; /* We will use this for the OpenSSL error buffer, so it has
+                    to be at least 120 bytes long. */
+  ssize_t nread;
+
+  /* This has only been tested on the proftpd server, and the mod_tls code
+     sends a close notify alert without waiting for a close notify alert in
+     response. Thus we wait for a close notify alert from the server, but
+     we do not send one. Let's hope other servers do the same... */
+
+  /* axTLS compat layer does nothing for SSL_shutdown, so we do nothing too
+  if(data->set.ftp_ccc == CURLFTPSSL_CCC_ACTIVE)
+      (void)SSL_shutdown(connssl->ssl);
+  */
+
+  if(connssl->ssl) {
+    int what = Curl_socket_ready(conn->sock[sockindex],
+				 CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT);
+    if(what > 0) {
+      /* Something to read, let's do it and hope that it is the close
+	 notify alert from the server */
+      nread = (ssize_t)SSL_read(conn->ssl[sockindex].ssl, buf,
+				sizeof(buf));
+
+      if (nread < SSL_OK){
+	failf(data, "close notify alert not received during shutdown");
+	retval = -1;
+      }
+    }
+    else if(0 == what) {
+      /* timeout */
+      failf(data, "SSL shutdown timeout");
+    }
+    else {
+      /* anything that gets here is fatally bad */
+      failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
+      retval = -1;
+    }
+
+    ssl_free (connssl->ssl);
+    connssl->ssl = NULL;
+  }
+  return retval;
 }
 
 /*
@@ -105,13 +435,24 @@ int Curl_axtls_shutdown(struct connectdata *conn, int sockindex)
  * Otherwise we return the amount of data read. Other errors should return -1
  * and set 'wouldblock' to FALSE.
  */
-ssize_t Curl_axtls_recv(struct connectdata *conn, /* connection data */
-                       int num,                  /* socketindex */
-                       char *buf,                /* store read data here */
-                       size_t buffersize,        /* max amount to read */
-                       bool *wouldblock)
+static ssize_t axtls_recv(struct connectdata *conn, /* connection data */
+			  int num,                  /* socketindex */
+			  char *buf,                /* store read data here */
+			  size_t buffersize,        /* max amount to read */
+			  CURLcode *err)
 {
-  return 0;
+  ssize_t ret = (ssize_t)SSL_read(conn->ssl[num].ssl, buf,
+                                    (int)buffersize);
+
+  /* axTLS isn't terribly generous about error reporting */
+  if(ret < 0) {
+    failf(conn->data, "axTLS recv error (%d)", (int)ret);
+    *err = map_error_to_curl(ret);
+    return -1;
+  }
+
+  *err = CURLE_OK;
+  return ret;
 }
 
 /*
@@ -124,16 +465,23 @@ ssize_t Curl_axtls_recv(struct connectdata *conn, /* connection data */
  */
 int Curl_axtls_check_cxn(struct connectdata *conn)
 {
-   return 0;
+  /* ssluse.c line: rc = SSL_peek(conn->ssl[FIRSTSOCKET].ssl, (void*)&buf, 1);
+     axTLS compat layer always returns the last argument, so connection is 
+     always alive? */
+
+   return 1; /* connection still in place */
 }
 
 void Curl_axtls_session_free(void *ptr)
 {
+  /* free the ID */
+  /* both ssluse.c and gtls.c do something here, but axTLS's OpenSSL
+     compatibility layer does nothing, so we do nothing too. */
 }
 
 size_t Curl_axtls_version(char *buffer, size_t size)
 {
-  return snprintf(buffer, size, "axTLS/1.2.7");
+  return snprintf(buffer, size, "axTLS/%s", ssl_version());
 }
 
 #endif /* USE_AXTLS */
diff --git a/lib/axtls.h b/lib/axtls.h
index ba62eecbf9fd966e8cd74ee5df9c285d9966714a..f1e94b65c32f8cecc002a831ef7bc8504219c9e6 100644
--- a/lib/axtls.h
+++ b/lib/axtls.h
@@ -38,14 +38,6 @@ void Curl_axtls_close_all(struct SessionHandle *data);
  /* close a SSL connection */
 void Curl_axtls_close(struct connectdata *conn, int sockindex);
 
-/* return number of sent (non-SSL) bytes */
-ssize_t Curl_axtls_send(struct connectdata *conn, int sockindex,
-                       const void *mem, size_t len);
-ssize_t Curl_axtls_recv(struct connectdata *conn, /* connection data */
-                       int num,                  /* socketindex */
-                       char *buf,                /* store read data here */
-                       size_t buffersize,        /* max amount to read */
-                       bool *wouldblock);
 void Curl_axtls_session_free(void *ptr);
 size_t Curl_axtls_version(char *buffer, size_t size);
 int Curl_axtls_shutdown(struct connectdata *conn, int sockindex);
@@ -62,8 +54,6 @@ int Curl_axtls_check_cxn(struct connectdata *conn);
 #define curlssl_set_engine(x,y) (x=x, y=y, CURLE_FAILED_INIT)
 #define curlssl_set_engine_default(x) (x=x, CURLE_FAILED_INIT)
 #define curlssl_engines_list(x) (x=x, (struct curl_slist *)NULL)
-#define curlssl_send Curl_axtls_send
-#define curlssl_recv Curl_axtls_recv
 #define curlssl_version Curl_axtls_version
 #define curlssl_check_cxn(x) Curl_axtls_check_cxn(x)
 #define curlssl_data_pending(x,y) (x=x, y=y, 0)
diff --git a/tests/runtests.pl b/tests/runtests.pl
index 2eb65fd9ec0533406d5b61ebe9194321b70ce610..743fb1f62a768c97b1e10c5335e9e024a7882ffd 100755
--- a/tests/runtests.pl
+++ b/tests/runtests.pl
@@ -207,6 +207,7 @@ my $has_gnutls;  # built with GnuTLS
 my $has_nss;     # built with NSS
 my $has_yassl;   # built with yassl
 my $has_polarssl;# built with polarssl
+my $has_axtls;   # built with axTLS
 
 my $has_shared;  # built shared
 
@@ -696,6 +697,7 @@ sub verifyhttp {
     $flags .= "--silent ";
     $flags .= "--verbose ";
     $flags .= "--globoff ";
+    $flags .= "-1 "         if($has_axtls == 1);
     $flags .= "--insecure " if($proto eq 'https');
     $flags .= "\"$proto://$ip:$port/${bonus}verifiedserver\"";
 
@@ -1950,6 +1952,10 @@ sub checksystem {
                $has_openssl=1;
                $ssllib="polarssl";
            } 
+	   elsif ($libcurl =~ /axtls/i) {
+	       $has_axtls=1;
+	       $ssllib="axTLS";
+	   }
         }
         elsif($_ =~ /^Protocols: (.*)/i) {
             # these are the protocols compiled in to this libcurl
@@ -2297,6 +2303,11 @@ sub singletest {
                 next;
             }
         }
+	elsif($f eq "axTLS") {
+	    if($has_axtls) {
+		next;
+	    }
+	}
         elsif($f eq "netrc_debug") {
             if($debug_build) {
                 next;
@@ -2548,6 +2559,7 @@ sub singletest {
     if($curl_debug) {
         unlink($memdump);
     }
+    $cmd = "-1 ".$cmd if(exists $feature{"SSL"} && $has_axtls == 1);
 
     # create a (possibly-empty) file before starting the test
     my @inputfile=getpart("client", "file");