reverted HTTPCLient debug back to defaulted off
Fork of HTTPClient-SSL by
Revision 38:a4ccad70be9d, committed 2015-01-14
- Comitter:
- Vanger
- Date:
- Wed Jan 14 22:39:59 2015 +0000
- Parent:
- 37:293e8eae4230
- Child:
- 39:d7c5541a9124
- Commit message:
- Added functions to add Root Certificates for SSL verification of Peers, added a function to set the peer verify settings for the CyaSSL library, tweaked some debug and memory operations in the client.
Changed in this revision
--- a/CyaSSL.lib Tue Jan 06 16:46:44 2015 +0000 +++ b/CyaSSL.lib Wed Jan 14 22:39:59 2015 +0000 @@ -1,1 +1,1 @@ -http://developer.mbed.org/teams/Multi-Hackers/code/CyaSSL/#eb845606fd41 +http://developer.mbed.org/users/Vanger/code/CyaSSL/#e505054279ed
--- a/HTTPClient.cpp Tue Jan 06 16:46:44 2015 +0000 +++ b/HTTPClient.cpp Wed Jan 14 22:39:59 2015 +0000 @@ -113,13 +113,18 @@ HTTPClient::HTTPClient() : m_basicAuthUser(NULL), m_basicAuthPassword(NULL), m_httpResponseCode(0) { + set_time(1421106306); + + CyaSSL_Init(); //Initialize CyaSSL + m_sock = &_m_sock; - /* CyaSSL_Debugging_ON() ; */ + /* CyaSSL_Debugging_ON() ; */ //Turn on if the CyaSSL library isn't working for debug printf's + peerMethod = VERIFY_FAIL_IF_NO_PEER_CERT; ctx = 0 ; ssl = 0 ; SSLver = 3 ; - m_basicAuthUser = NULL ; + certificates = NULL; redirect_url = NULL ; redirect = 0 ; header = NULL ; @@ -127,7 +132,12 @@ HTTPClient::~HTTPClient() { - + free((void *)m_basicAuthPassword); + m_basicAuthPassword = NULL; + free((void *)m_basicAuthUser); + m_basicAuthUser = NULL; + free((void *)certificates); + certificates = NULL; } HTTPResult HTTPClient::basicAuth(const char* user, const char* password) //Basic Authentification @@ -140,13 +150,17 @@ if (user != NULL) { m_basicAuthUser = (char *)malloc(strlen(user)+1); strcpy((char *)m_basicAuthUser, user); + } else { + m_basicAuthUser = NULL; } if (m_basicAuthPassword) free((void *)m_basicAuthPassword); if (password != NULL) { m_basicAuthPassword = (char *)malloc(strlen(password)+1); strcpy((char *)m_basicAuthPassword, password); - } + } else { + m_basicAuthPassword = NULL; + } return HTTP_OK ; } @@ -202,6 +216,37 @@ return HTTP_OK ; } +HTTPResult HTTPClient::addRootCACertificate(const char* cert) +{ + if(cert == NULL) { + if(certificates != NULL) { + free((void *)certificates); + } + } else { + //Append certificate, else allocate new certificate + if(certificates != NULL) { + certificates = (char *)realloc((void *)certificates, strlen(cert) + 1 + strlen(certificates)); //+1 is for '\0' char + if(certificates == NULL) { + return HTTP_ERROR; + } else { + strcat((char *)certificates, cert); + } + } else { + certificates = (char *)malloc(strlen(cert) + 1); + if(certificates == NULL) { + return HTTP_ERROR; + } else { + strcpy((char *)certificates, cert); + } + } + } + return HTTP_OK; +} + +void HTTPClient::setPeerVerification(SSLMethod method) { + peerMethod = method; +} + #define CHECK_CONN_ERR(ret) \ do{ \ @@ -299,14 +344,38 @@ 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 ; + 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); + + if(certificates == NULL && peerMethod != VERIFY_NONE) { + ERR("No certificates passed for peer verification"); + return HTTP_PROCESSING; + } + + { //Localize pMethod array for less overall memory time-use + std::string pMethod; + if(peerMethod == VERIFY_NONE) { + pMethod = "not verify peer"; + } else if (peerMethod == VERIFY_PEER) { + pMethod = "verify peer if certificates available"; + } else if (peerMethod == VERIFY_FAIL_IF_NO_PEER_CERT) { + pMethod = "verify peer and fail if no peer certificates available"; + } + DBG("SSL connection set to %s", pMethod.c_str()); + } + + CyaSSL_CTX_set_verify(ctx, peerMethod, 0); //SSL_VERIFY_FAIL_IF_NO_PEER_CERT, VERIFY_NONE, SSL_VERIFY_PEER + + //Load the CA certificate(s) (If using multiple, concatenate them in the buffer being passed) + if (SSL_SUCCESS != CyaSSL_CTX_load_verify_buffer(ctx, (const unsigned char*)certificates, strlen(certificates), SSL_FILETYPE_PEM)) { + ERR("unable to load root certificates"); + return HTTP_CONN; + } CyaSSL_SetIORecv(ctx, SocketReceive) ; CyaSSL_SetIOSend(ctx, SocketSend) ; } @@ -321,8 +390,18 @@ DBG("ctx=%x, ssl=%x, ssl->ctx->CBIORecv, CBIOSend=%x, %x\r\n", ctx, ssl, SocketReceive, SocketSend ) ; - if (CyaSSL_connect(ssl) != SSL_SUCCESS) { + int ret = CyaSSL_connect(ssl); + if (ret != SSL_SUCCESS) { ERR("SSL_connect failed"); + int err = CyaSSL_get_error(ssl, ret); + char data[32]; + char data_new[32]; + strcpy(data_new, CyaSSL_ERR_error_string(err, data)); + if(!strcmp(data,data_new)) { + printf("Error code [%d] is [%s]\r\n", err, data); + } else { + printf("Failed to get error code [%d], Reason: [%s]\r\n", err, data_new); + } cyassl_free() ; return HTTP_CONN; } @@ -793,6 +872,15 @@ *port=0; } char* pathPtr = strchr(hostPtr, '/'); + if(pathPtr == NULL) { + pathPtr = strchr(hostPtr, '#'); + if(pathPtr != NULL) { + pathPtr++; + } else { + pathPtr = (char *)(url + strlen(url)); + } + } + if( hostLen == 0 ) { hostLen = pathPtr - hostPtr; }
--- a/HTTPClient.h Tue Jan 06 16:46:44 2015 +0000 +++ b/HTTPClient.h Wed Jan 14 22:39:59 2015 +0000 @@ -32,6 +32,13 @@ #include "mbed.h" #include "TCPSocketConnection.h" +///SSL peer verification setting +enum SSLMethod { + VERIFY_NONE = 0, ///Don't check peer certificate + VERIFY_PEER = 1, ///Check peer certificate and skip if none available (insecure) + VERIFY_FAIL_IF_NO_PEER_CERT = 2, ///Check peer certificate and fail if unavailable +}; + ///HTTP client results enum HTTPResult { HTTP_OK = 0, ///<Success @@ -123,9 +130,35 @@ */ int getHTTPResponseCode(); - void setHeader(const char *header) ; /* set http headers */ - HTTPResult setSSLversion(int minorV) ; /* set SSL/TLS version. 0: SSL3, 1: TLS1.0, 2: TLS1.1, 3: TLS1.2 */ - void setLocationBuf(char *url, int size) ; /* set URL buffer for redirection */ + /** Set headers to be included in the following HTTP requests. Pass a NULL pointer to reset the headers stored. + * Make sure the headers are formatted with a "\r\n" after each header. + * @param header pointer to array containing the headers to be added*/ + void setHeader(const char *header) ; + + /** Set SSL/TLS version. + * @param minorV integer witha a value between 0 and 3 + * 0: SSL3, 1: TLS1.0, 2: TLS1.1, 3: TLS1.2 + * @returns HTTPResult based on success*/ + HTTPResult setSSLversion(int minorV) ; + + /* set URL buffer for redirection */ + void setLocationBuf(char *url, int size) ; + + /** Stores a root CA certificate for host authentication of a website. + * Each new line should end with "\r\n" including the last line of each certificate. + * Pass a pointer to the char array containing the certificate stored as a c-string. + * Pass a NULL pointer to reset all certificates stored. + * (Can pass in multiple certificates with one function call if the array contains concatenated certificates) */ + HTTPResult addRootCACertificate(const char* cert) ; + + /** Sets the verification for peer authenticity when connecting with SSL + * @param method specifies the method to use for peer verification + * @VERIFY_NONE Sets the client to not verify the peer's certificates + * @VERIFY_PEER Sets the client to verify the peer's certificates but skips if certificates unavailable + * @VERIFY_FAIL_IF_NO_PEER_CERT Sets the client to verify the peer's certificates and throw an error if the + * certificates are unavailable. + * */ + void setPeerVerification(SSLMethod method); private: enum HTTP_METH { @@ -149,7 +182,7 @@ TCPSocketConnection _m_sock; int m_timeout; - + const char* m_basicAuthUser; const char* m_basicAuthPassword; int m_httpResponseCode; @@ -160,6 +193,8 @@ int redirect ; /* for CyaSSL */ + const char* certificates; //CA certificates + SSLMethod peerMethod; int SSLver ; uint16_t port; struct CYASSL_CTX* ctx ;