Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: SalesforceInterface df-2014-heroku-thermostat-k64f SalesforceInterface
Fork of HTTPClient by
Revision 51:3bdf57f7fd60, committed 2015-08-20
- Comitter:
- ansond
- Date:
- Thu Aug 20 18:55:41 2015 +0000
- Parent:
- 50:a18a06b000f3
- Child:
- 52:cea1021a822d
- Commit message:
- initial port of HTTPS library to make use of the mbedTLS library...
Changed in this revision
--- a/CyaSSL.lib Tue Jun 09 16:26:02 2015 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -http://mbed.org/users/wolfSSL/code/CyaSSL/#64d4f7cb83d5
--- a/HTTPClient.cpp Tue Jun 09 16:26:02 2015 +0000
+++ b/HTTPClient.cpp Thu Aug 20 18:55:41 2015 +0000
@@ -46,15 +46,8 @@
#include <cstring>
-#include <../CyaSSL/cyassl/ctaocrypt/settings.h>
-#include <../CyaSSL/cyassl/ctaocrypt/types.h>
-#include <../CyaSSL/cyassl/internal.h>
-#include <../CyaSSL/cyassl/ssl.h>
-
#include "HTTPClient.h"
-
-
// ************ should be a better way to adjust for platform limitations
#if defined (TARGET_K64F)
@@ -68,6 +61,7 @@
#define MAX_HEADER_KEY_LENGTH 40
#define HEADER_SCANF_FORMAT "%40[^:]: %4096[^\r\n]" /* must align with BIG_MEMORY_CHUNK */
#define REDIRECT_SCANF_FORMAT "%40[^:]: %4096[^\r\n]" /* must align with BIG_MEMORY_CHUNK */
+ #define RECV_RETRY 3
#else
// default smaller buffers
#define CHUNK_SIZE 256
@@ -78,6 +72,7 @@
#define MAX_HEADER_KEY_LENGTH 40
#define HEADER_SCANF_FORMAT "%40[^:]: %40[^\r\n]" /* must align with MAX_HEADER_VALUE_LENGTH */
#define REDIRECT_SCANF_FORMAT "%40[^:]: %128[^\r\n]" /* must align with MAX_URL_PATH_LENGTH */
+ #define RECV_RETRY 3
#endif
// ************ should be a better way to adjust for platform limitations
@@ -105,40 +100,101 @@
}
out[i] = '\0' ;
}
-int SocketReceive(CYASSL* ssl, char *buf, int sz, void *ctx)
+
+static int SocketReceive(void* ssl, unsigned char *buf, size_t sz)
{
- int n ;
- int i ;
-#define RECV_RETRY 3
+ int n = 0;
+ int i = 0;
for(i=0; i<RECV_RETRY; i++) {
- n = m_sock_p->receive(buf, sz) ;
- if(n >= 0)return n ;
- Thread::wait(200) ;
+ n = m_sock_p->receive((char *)buf,(int)sz) ;
+ if (n >= 0) return n;
}
- ERR("SocketReceive:%d/%d\n", n, sz) ;
- return n ;
+ ERR("SocketReceive: receive failed. received: %d bytes. tried to receive: %d bytes\n", n, sz) ;
+ return n;
}
-int SocketSend(CYASSL* ssl, char *buf, int sz, void *ctx)
+
+static int SocketSend(void* ssl, const unsigned char *buf, size_t sz)
{
- int n ;
-
- Thread::wait(100) ;
- n = m_sock_p->send(buf, sz);
- if(n > 0) {
- Thread::wait(300) ;
- return n ;
- } else ERR("SocketSend:%d/%d\n", n, sz);
- return n ;
+ int n = 0;
+ n = m_sock_p->send((char *)buf,(int)sz);
+ if(n > 0) return n;
+ ERR("SocketSend: send failed. sent: %d bytes. tried to send: %d bytes\n", n, sz);
+ return n;
+}
+
+short ssl_socket_read(ssl_context *ssl, char *receiveBuffer, unsigned int receiveBufferSize, unsigned int timeoutMilliseconds) {
+ int n = ssl_read(ssl,(unsigned char *)receiveBuffer, (size_t)receiveBufferSize);
+ if (n <= 0) {
+ ERR("ssl_socket_read failed\r\n");
+ return -1;
+ }
+ DBG("ssl_socket_read: read %d bytes...",n);
+ return n;
+}
+
+short ssl_socket_write(ssl_context *ssl, const char *sendBuffer, unsigned int sendBufferSize) {
+ sendBufferSize = strlen(sendBuffer);
+ int n = ssl_write(ssl,(const unsigned char *)sendBuffer,(size_t)sendBufferSize);
+ if (n != sendBufferSize) {
+ ERR("ssl_socket_write failed written=%d\r\n",n);
+ return -1;
+ }
+ DBG("ssl_socket_write: sent %d bytes...",sendBufferSize);
+ return sendBufferSize;
}
-HTTPClient::HTTPClient() :
- m_basicAuthUser(NULL), m_basicAuthPassword(NULL), m_httpResponseCode(0), m_oauthToken(NULL)
+void HTTPClient::set_ssl_version() {
+ // set the SSL version to be used
+ ssl_set_max_version(&this->ssl,SSL_MAX_MAJOR_VERSION,SSL_MAX_MINOR_VERSION);
+ if (this->SSLver == 0) {
+ // use v3
+ ssl_set_min_version(&this->ssl,SSL_MIN_MAJOR_VERSION,SSL_MIN_MINOR_VERSION);
+ }
+ if (this->SSLver == 1) {
+ // use v1
+ ssl_set_min_version(&this->ssl,SSL_MIN_MAJOR_VERSION,SSL_MINOR_VERSION_1);
+ }
+ if (this->SSLver == 2) {
+ // use v1.1
+ ssl_set_min_version(&this->ssl,SSL_MIN_MAJOR_VERSION,SSL_MINOR_VERSION_2);
+ }
+ if (this->SSLver == 3) {
+ // use v1.2
+ ssl_set_min_version(&this->ssl,SSL_MIN_MAJOR_VERSION,SSL_MINOR_VERSION_3);
+ }
+}
+
+void HTTPClient::ssl_setup(const unsigned char *tag) {
+ entropy_init(&this->entropy);
+ ctr_drbg_init(&this->ctr_drbg,entropy_func,&this->entropy,tag,strlen((const char *)tag));
+ memset(&this->ssl,0,sizeof(ssl_context));
+ this->ssl_connected = false;
+}
+
+short HTTPClient::ssl_connect() {
+ short status = 0;
+ if (this->ssl_connected == false) {
+ this->ssl_setup("mbed_https_lib"); // debug tag could be taken from constructor parameter... fix me...
+ short status = ssl_init(&this->ssl);
+ if (status == 0) {
+ ssl_set_endpoint(&this->ssl,SSL_IS_CLIENT);
+ this->set_ssl_version();
+ ssl_set_rng(&this->ssl, ctr_drbg_random, &this->ctr_drbg);
+ ssl_set_authmode(&this->ssl,SSL_VERIFY_NONE); // FIX ME:
+ ssl_set_bio(&this->ssl,SocketReceive,(void *)NULL,SocketSend,(void *)NULL);
+ this->ssl_connected = true;
+ }
+ DBG("ssl_connect: status=%d\r\n",status);
+ }
+ else {
+ DBG("ssl_connect: already connected (OK) status=%d\r\n",status);
+ }
+ return status;
+}
+
+HTTPClient::HTTPClient() : m_basicAuthUser(NULL), m_basicAuthPassword(NULL), m_httpResponseCode(0), m_oauthToken(NULL)
{
- // To DEBUG the underlying SSL - uncomment this...
- //CyaSSL_Debugging_ON();
- ctx = 0 ;
- ssl = 0 ;
SSLver = 3 ;
m_basicAuthUser = NULL ;
m_basicAuthPassword = NULL;
@@ -250,7 +306,7 @@
#define CHECK_CONN_ERR(ret) \
do{ \
if(ret) { \
- cyassl_free() ;\
+ ssl_cleanup() ;\
m_sock.close(); \
ERR("Connection error (%d)", ret); \
return HTTP_CONN; \
@@ -259,28 +315,22 @@
#define PRTCL_ERR() \
do{ \
- cyassl_free() ;\
+ ssl_cleanup() ;\
m_sock.close(); \
ERR("Protocol error"); \
return HTTP_PRTCL; \
} while(0)
-void HTTPClient::cyassl_free(void)
+void HTTPClient::ssl_cleanup(void)
{
- if(ssl) {
- CyaSSL_free(ssl) ;
- ssl = NULL ;
- }
- if(ctx) {
- CyaSSL_CTX_free(ctx) ;
- ctx = NULL ;
- }
- CyaSSL_Cleanup() ;
+ ssl_free( &this->ssl );
+ ctr_drbg_free( &this->ctr_drbg );
+ entropy_free( &this->entropy );
+ this->ssl_connected = false;
}
HTTPResult HTTPClient::connect(const char* url, HTTP_METH method, IHTTPDataOut* pDataOut, IHTTPDataIn* pDataIn, int timeout) //Execute request
{
- CYASSL_METHOD * SSLmethod = NULL;
m_httpResponseCode = 0; //Invalidate code
m_timeout = timeout;
redirect = 0 ;
@@ -335,45 +385,15 @@
}
if(port == HTTPS_PORT) {
-
/* Start SSL connect */
- DBG("SSLver=%d", SSLver) ;
- if(ctx == NULL) {
- switch(SSLver) {
- case 0 : SSLmethod = CyaSSLv3_client_method() ; break ;
- case 1 : SSLmethod = CyaTLSv1_client_method() ; break ;
- case 2 : SSLmethod = CyaTLSv1_1_client_method() ; break ;
- case 3 : SSLmethod = CyaTLSv1_2_client_method() ; break ;
- }
- ctx = CyaSSL_CTX_new((CYASSL_METHOD *)SSLmethod);
- if (ctx == NULL) {
- ERR("unable to get ctx");
- return HTTP_CONN;
- }
- CyaSSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, 0);
- CyaSSL_SetIORecv(ctx, SocketReceive) ;
- CyaSSL_SetIOSend(ctx, SocketSend) ;
- }
- if (ssl == NULL) {
- ssl = CyaSSL_new(ctx);
- if (ssl == NULL) {
- ERR("unable to get SSL object");
- cyassl_free() ;
- return HTTP_CONN;
- }
- }
-
- DBG("ctx=%x, ssl=%x, ssl->ctx->CBIORecv, CBIOSend=%x, %x\n",ctx, ssl, SocketReceive, SocketSend ) ;
- int result = CyaSSL_connect(ssl);
- if (result != SSL_SUCCESS) {
- ERR("SSL_connect failed");
- int err = CyaSSL_get_error(ssl, result);
- char errorString[80];
- CyaSSL_ERR_error_string(err, errorString);
- ERR("SSL Error: %s (err=%d,status=%d)",errorString,err,result);
- cyassl_free() ;
+ DBG("SSLver=%d", SSLver);
+ short ssl_connect_status = this->ssl_connect();
+ if (ssl_connect_status != 0) {
+ ERR("SSL connection failure: %d\r\n",ssl_connect_status);
+ ssl_cleanup();
return HTTP_CONN;
}
+ DBG("SSL connection succeeded...\r\n");
} /* SSL connect complete */
//Send request
@@ -668,7 +688,7 @@
}
}
- cyassl_free() ;
+ ssl_cleanup() ;
m_sock.close();
DBG("Completed HTTP transaction");
if(redirect)return HTTP_REDIRECT ;
@@ -688,15 +708,15 @@
int ret;
if(port == HTTPS_PORT) {
- DBG("Enter CyaSSL_read") ;
+ DBG("Enter ssl_socket_read") ;
m_sock.set_blocking(false, m_timeout);
- readLen = CyaSSL_read(ssl, buf, maxLen);
+ readLen = ssl_socket_read(&this->ssl, buf, maxLen, m_timeout);
if (readLen > 0) {
buf[readLen] = 0;
- DBG("CyaSSL_read:%s\n", buf);
+ DBG("ssl_socket_read:%s\n", buf);
} else {
- ERR("CyaSSL_read, ret = %d", readLen) ;
+ ERR("ssl_socket_read, ret = %d", readLen) ;
return HTTP_ERROR ;
}
DBG("Read %d bytes", readLen);
@@ -789,12 +809,13 @@
}
if(port == HTTPS_PORT) {
- DBG("Enter CyaSSL_write") ;
- if (CyaSSL_write(ssl, buf, len) != len) {
- ERR("SSL_write failed");
+ DBG("Enter ssl_socket_write");
+ int write_len = ssl_socket_write(&this->ssl, buf, len);
+ if (write_len != len) {
+ ERR("ssl_socket_write failed: wrote: %d bytes, expected to write %d bytes\r\n",write_len,len);
return HTTP_ERROR ;
}
- DBG("Written %d bytes", writtenLen);
+ DBG("ssl_socket_write: sent %d bytes", writtenLen);
return HTTP_OK;
}
m_sock.set_blocking(false, m_timeout);
--- a/HTTPClient.h Tue Jun 09 16:26:02 2015 +0000
+++ b/HTTPClient.h Thu Aug 20 18:55:41 2015 +0000
@@ -32,6 +32,11 @@
#include "mbed.h"
#include "TCPSocketConnection.h"
+#include "polarssl/ssl.h"
+#include "polarssl/net.h"
+#include "polarssl/entropy.h"
+#include "polarssl/ctr_drbg.h"
+
///HTTP client results
enum HTTPResult {
HTTP_PROCESSING, ///<Processing
@@ -59,8 +64,6 @@
///Instantiate the HTTP client
HTTPClient();
~HTTPClient();
-
-
/**
Provides a OAUTH2 authentification feature
@@ -150,18 +153,22 @@
HTTPResult send(char* buf, size_t len = 0); //0 on success, err code on failure
HTTPResult flush(void); //0 on success, err code on failure
HTTPResult parseURL(const char* url, char* scheme, size_t maxSchemeLen, char* host, size_t maxHostLen, uint16_t* port, char* path, size_t maxPathLen); //Parse URL
- void cyassl_free(void) ;
HTTPResult bAuth(void) ;
HTTPResult tokenAuth(void) ;
HTTPResult readHeader(void) ;
+ // SSL internal methods...
+ void ssl_cleanup(void) ;
+ void ssl_setup(const unsigned char *tag);
+ short ssl_connect();
+ void set_ssl_version();
+
//Parameters
-
int m_timeout;
const char* m_basicAuthUser;
const char* m_basicAuthPassword;
+ int m_httpResponseCode;
const char* m_oauthToken;
- int m_httpResponseCode;
TCPSocketConnection m_sock;
@@ -170,11 +177,13 @@
int redirect_url_size ;
int redirect ;
- /* for CyaSSL */
- int SSLver ;
- uint16_t port;
- struct CYASSL_CTX* ctx ;
- struct CYASSL * ssl ;
+ // mbedTLS Support
+ int SSLver;
+ uint16_t port;
+ entropy_context entropy;
+ ctr_drbg_context ctr_drbg;
+ ssl_context ssl;
+ bool ssl_connected;
};
//Including data containers here for more convenience
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbedTLSLibrary.lib Thu Aug 20 18:55:41 2015 +0000 @@ -0,0 +1,1 @@ +http://developer.mbed.org/users/ansond/code/mbedTLSLibrary/#137634ff4186
