diff --git a/libraries/ESP8266WiFi/src/WiFiClientSecure.cpp b/libraries/ESP8266WiFi/src/WiFiClientSecure.cpp
index da7248fab6..6e5e5d8e2c 100644
--- a/libraries/ESP8266WiFi/src/WiFiClientSecure.cpp
+++ b/libraries/ESP8266WiFi/src/WiFiClientSecure.cpp
@@ -91,7 +91,15 @@ class SSLContext
     void connect(ClientContext* ctx, const char* hostName, uint32_t timeout_ms)
     {
         s_io_ctx = ctx;
-        _ssl = ssl_client_new(_ssl_ctx, 0, nullptr, 0, hostName);
+        _ssl_ext = ssl_ext_new();
+        
+        int name_len = strlen(hostName);
+        
+        _ssl_ext->host_name = (char*) malloc((name_len + 1) * sizeof (char));
+        strncpy(_ssl_ext->host_name, hostName, name_len + 1);
+        _ssl_ext->host_name[name_len] = 0;
+        
+        _ssl = ssl_client_new(_ssl_ctx, 0, nullptr, 0, _ssl_ext);
         uint32_t t = millis();
 
         while (millis() - t < timeout_ms && ssl_handshake_status(_ssl) != SSL_OK) {
@@ -112,6 +120,11 @@ class SSLContext
     {
         return _ssl != nullptr && ssl_handshake_status(_ssl) == SSL_OK;
     }
+    
+    void discardCache() {
+        _available = 0;
+        _read_ptr = nullptr;
+    }
 
     int read(uint8_t* dst, size_t size)
     {
@@ -179,6 +192,14 @@ class SSLContext
         }
         return cb;
     }
+    
+    bool wantRead() {
+        return _available > 0 || (_ssl && ssl_want_read(_ssl) == 1);
+    }
+    
+    bool emptyCache() {
+        return _available == 0;
+    }
 
     bool loadObject(int type, Stream& stream, size_t size)
     {
@@ -245,6 +266,7 @@ class SSLContext
     static SSL_CTX* _ssl_ctx;
     static int _ssl_ctx_refcnt;
     SSL* _ssl = nullptr;
+    SSL_EXTENSIONS* _ssl_ext = nullptr;
     int _refcnt = 0;
     const uint8_t* _read_ptr = nullptr;
     size_t _available = 0;
@@ -332,7 +354,14 @@ size_t WiFiClientSecure::write(const uint8_t *buf, size_t size)
     if (!_ssl) {
         return 0;
     }
-
+    
+    // axTLS is half-duplex so if a read operation is already underway,
+    // finish the read before trying to write; otherwise the read
+    // cache will be overwritten and data will be lost
+    if (!_ssl->emptyCache()) {
+        return SSL_ERROR_READ_LOCK;
+    }
+    
     int rc = ssl_write(*_ssl, buf, size);
     if (rc >= 0) {
         return rc;
@@ -346,6 +375,20 @@ size_t WiFiClientSecure::write(const uint8_t *buf, size_t size)
     return 0;
 }
 
+int WiFiClientSecure::wantRead() {
+    if (_ssl) {
+        return _ssl->wantRead();
+    }
+    
+    return 0;
+}
+
+void WiFiClientSecure::discardCache() {
+    if (_ssl) {
+        _ssl->discardCache();
+    }
+}
+
 int WiFiClientSecure::read(uint8_t *buf, size_t size)
 {
     if (!_ssl) {
@@ -420,7 +463,7 @@ err     x       N           N
 uint8_t WiFiClientSecure::connected()
 {
     if (_ssl) {
-        if (_ssl->available()) {
+        if (_ssl->wantRead()) {
             return true;
         }
         if (_client && _client->state() == ESTABLISHED && _ssl->connected()) {
@@ -595,6 +638,20 @@ bool WiFiClientSecure::loadPrivateKey(Stream& stream, size_t size)
     return _ssl->loadObject(SSL_OBJ_RSA_KEY, stream, size);
 }
 
+extern "C" int __ax_port_pending(int fd) {
+    //Serial.println("ax_port_pending");
+    ClientContext* _client = SSLContext::getIOContext(fd);
+    if (!_client || _client->state() != ESTABLISHED && !_client->getSize()) {
+        errno = EIO;
+        return -1;
+    }
+    
+    //Serial.printf("pending: %d\r\n", _client->getSize());
+    return _client->getSize();
+}
+
+extern "C" void ax_port_pending() __attribute__ ((weak, alias("__ax_port_pending")));
+
 extern "C" int __ax_port_read(int fd, uint8_t* buffer, size_t count)
 {
     ClientContext* _client = SSLContext::getIOContext(fd);
diff --git a/libraries/ESP8266WiFi/src/WiFiClientSecure.h b/libraries/ESP8266WiFi/src/WiFiClientSecure.h
index 4b5b9c9343..1dce858872 100644
--- a/libraries/ESP8266WiFi/src/WiFiClientSecure.h
+++ b/libraries/ESP8266WiFi/src/WiFiClientSecure.h
@@ -25,6 +25,7 @@
 #include "WiFiClient.h"
 #include "include/ssl.h"
 
+#define SSL_ERROR_READ_LOCK -275
 
 class SSLContext;
 
@@ -49,6 +50,9 @@ class WiFiClientSecure : public WiFiClient {
   int peek() override;
   size_t peekBytes(uint8_t *buffer, size_t length) override;
   void stop() override;
+  
+  void discardCache();
+  int  wantRead();
 
   bool setCACert(const uint8_t* pk, size_t size);
   bool setCertificate(const uint8_t* pk, size_t size);
diff --git a/libraries/ESP8266WiFi/src/include/ssl.h b/libraries/ESP8266WiFi/src/include/ssl.h
index f23d86af3a..2761c588b8 100644
--- a/libraries/ESP8266WiFi/src/include/ssl.h
+++ b/libraries/ESP8266WiFi/src/include/ssl.h
@@ -1,11 +1,12 @@
 /*
- * Copyright (c) 2007, Cameron Rich
- *
+ * Copyright (c) 2007-2016, Cameron Rich
+ * Copyright (c) 2017, Diego Guerrero (ssl_want_write)
+ * 
  * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
+ * 
+ * Redistribution and use in source and binary forms, with or without 
  * modification, are permitted provided that the following conditions are met:
- *
+ * 
  * * Redistributions of source code must retain the above copyright notice,
  *   this list of conditions and the following disclaimer.
  * * Redistributions in binary form must reproduce the above copyright notice,
@@ -72,10 +73,15 @@ extern "C" {
 
 #define EXP_FUNC
 #define STDCALL
-// struct SSL_CTX_;
+
 typedef struct SSL_CTX_ SSL_CTX;
 typedef struct SSL_ SSL;
 
+typedef struct {
+    char *host_name; /* Needed for the SNI support */
+    uint16_t max_fragment_size; /* Needed for the Max Fragment Size Extension. Allowed values: 2^9, 2^10 .. 2^14 */
+} SSL_EXTENSIONS;
+
 /* The optional parameters that can be given to the client/server SSL engine */
 #define SSL_CLIENT_AUTHENTICATION               0x00010000
 #define SSL_SERVER_VERIFY_LATER                 0x00020000
@@ -93,13 +99,16 @@ typedef struct SSL_ SSL;
 #define SSL_ERROR_DEAD                          -2
 #define SSL_CLOSE_NOTIFY                        -3
 #define SSL_ERROR_CONN_LOST                     -256
+#define SSL_ERROR_RECORD_OVERFLOW               -257
 #define SSL_ERROR_SOCK_SETUP_FAILURE            -258
 #define SSL_ERROR_INVALID_HANDSHAKE             -260
 #define SSL_ERROR_INVALID_PROT_MSG              -261
 #define SSL_ERROR_INVALID_HMAC                  -262
 #define SSL_ERROR_INVALID_VERSION               -263
+#define SSL_ERROR_UNSUPPORTED_EXTENSION         -264
 #define SSL_ERROR_INVALID_SESSION               -265
 #define SSL_ERROR_NO_CIPHER                     -266
+#define SSL_ERROR_INVALID_CERT_HASH_ALG         -267
 #define SSL_ERROR_BAD_CERTIFICATE               -268
 #define SSL_ERROR_INVALID_KEY                   -269
 #define SSL_ERROR_FINISHED_INVALID              -271
@@ -117,19 +126,25 @@ typedef struct SSL_ SSL;
 #define SSL_ALERT_CLOSE_NOTIFY                  0
 #define SSL_ALERT_UNEXPECTED_MESSAGE            10
 #define SSL_ALERT_BAD_RECORD_MAC                20
+#define SSL_ALERT_RECORD_OVERFLOW               22
 #define SSL_ALERT_HANDSHAKE_FAILURE             40
 #define SSL_ALERT_BAD_CERTIFICATE               42
+#define SSL_ALERT_UNSUPPORTED_CERTIFICATE       43
+#define SSL_ALERT_CERTIFICATE_EXPIRED           45
+#define SSL_ALERT_CERTIFICATE_UNKNOWN           46
 #define SSL_ALERT_ILLEGAL_PARAMETER             47
+#define SSL_ALERT_UNKNOWN_CA                    48
 #define SSL_ALERT_DECODE_ERROR                  50
 #define SSL_ALERT_DECRYPT_ERROR                 51
 #define SSL_ALERT_INVALID_VERSION               70
 #define SSL_ALERT_NO_RENEGOTIATION              100
+#define SSL_ALERT_UNSUPPORTED_EXTENSION         110
 
 /* The ciphers that are supported */
 #define SSL_AES128_SHA                          0x2f
 #define SSL_AES256_SHA                          0x35
-#define SSL_RC4_128_SHA                         0x05
-#define SSL_RC4_128_MD5                         0x04
+#define SSL_AES128_SHA256                       0x3c
+#define SSL_AES256_SHA256                       0x3d
 
 /* build mode ids' */
 #define SSL_BUILD_SKELETON_MODE                 0x01
@@ -218,6 +233,22 @@ EXP_FUNC SSL_CTX * STDCALL ssl_ctx_new(uint32_t options, int num_sessions);
  */
 EXP_FUNC void STDCALL ssl_ctx_free(SSL_CTX *ssl_ctx);
 
+/**
+ * @brief Allocates new SSL extensions structure and returns pointer to it
+ *
+ * @return ssl_ext Pointer to SSL_EXTENSIONS structure
+ *
+ */
+EXP_FUNC SSL_EXTENSIONS * STDCALL ssl_ext_new();
+
+/**
+ * @brief Frees SSL extensions structure
+ *
+ * @param ssl_ext [in] Pointer to SSL_EXTENSION structure
+ *
+ */
+EXP_FUNC void STDCALL ssl_ext_free(SSL_EXTENSIONS *ssl_ext);
+
 /**
  * @brief (server only) Establish a new SSL connection to an SSL client.
  *
@@ -244,11 +275,11 @@ EXP_FUNC SSL * STDCALL ssl_server_new(SSL_CTX *ssl_ctx, int client_fd);
  * can be null if no session resumption is being used or required. This option
  * is not used in skeleton mode.
  * @param sess_id_size The size of the session id (max 32)
- * @param host_name If non-zero, host name to be sent to server for SNI support
- * @return An SSL object reference. Use ssl_handshake_status() to check
+ * @param ssl_ext pointer to a structure with the activated SSL extensions and their values
+ * @return An SSL object reference. Use ssl_handshake_status() to check 
  * if a handshake succeeded.
  */
-EXP_FUNC SSL * STDCALL ssl_client_new(SSL_CTX *ssl_ctx, int client_fd, const uint8_t *session_id, uint8_t sess_id_size, const char* host_name);
+EXP_FUNC SSL * STDCALL ssl_client_new(SSL_CTX *ssl_ctx, int client_fd, const uint8_t *session_id, uint8_t sess_id_size, SSL_EXTENSIONS* ssl_ext);
 
 /**
  * @brief Free any used resources on this connection.
@@ -259,6 +290,19 @@ EXP_FUNC SSL * STDCALL ssl_client_new(SSL_CTX *ssl_ctx, int client_fd, const uin
  */
 EXP_FUNC void STDCALL ssl_free(SSL *ssl);
 
+/**
+ * @brief Check the rx buffer for new information.
+ * If the socket has new information to be read, 1 will be returned.
+ * Cheap alternative to check availability without actually decrypting.
+ * @param ssl [in] An SSL object reference.
+ * @return Read status:
+ * - if == 1, then there are bytes to be read,
+ * - if == 0, then there are not,
+ * - if < 0,  there was an error.
+ * @see ssl.h for the error code list.
+ */
+EXP_FUNC int STDCALL ssl_want_read(SSL *ssl);
+
 /**
  * @brief Read the SSL data stream.
  * If the socket is non-blocking and data is blocked then SSO_OK will be
@@ -289,6 +333,15 @@ EXP_FUNC int STDCALL ssl_read(SSL *ssl, uint8_t **in_data);
  */
 EXP_FUNC int STDCALL ssl_write(SSL *ssl, const uint8_t *out_data, int out_len);
 
+/**
+ * @brief Calculate the size of the encrypted data from what you are about to send 
+ * @param ssl [in] An SSL obect reference.
+ * @param out_len [in] The number of bytes to be written.
+ * @return The number of bytes that will be sent, or if < 0 if an error.
+ * @see ssl.h for the error code list.
+ */
+EXP_FUNC int STDCALL ssl_calculate_write_length(SSL *ssl, int out_len);
+
 /**
  * @brief Find an ssl object based on a file descriptor.
  *
@@ -367,7 +420,7 @@ EXP_FUNC void STDCALL ssl_display_error(int error_code);
 
 /**
  * @brief Authenticate a received certificate.
- *
+ * 
  * This call is usually made by a client after a handshake is complete and the
  * context is in SSL_SERVER_VERIFY_LATER mode.
  * @param ssl [in] An SSL object reference.
@@ -385,8 +438,17 @@ EXP_FUNC int STDCALL ssl_verify_cert(const SSL *ssl);
 EXP_FUNC int STDCALL ssl_match_fingerprint(const SSL *ssl, const uint8_t* fp);
 
 /**
- * @brief Retrieve an X.509 distinguished name component.
+ * @brief Check if SHA256 hash of Subject Public Key Info matches the one given.
  *
+ * @param ssl [in] An SSL object reference.
+ * @param fp [in] SHA256 hash to match against
+ * @return SSL_OK if the certificate is verified.
+ */
+EXP_FUNC int STDCALL ssl_match_spki_sha256(const SSL *ssl, const uint8_t* hash);
+
+/**
+ * @brief Retrieve an X.509 distinguished name component.
+ * 
  * When a handshake is complete and a certificate has been exchanged, then the
  * details of the remote certificate can be retrieved.
  *
diff --git a/tools/sdk/lib/libaxtls.a b/tools/sdk/lib/libaxtls.a
index 8abb83ee7e..66c99c9eca 100644
Binary files a/tools/sdk/lib/libaxtls.a and b/tools/sdk/lib/libaxtls.a differ