Change buffer sizes to support GR-PEACH
Dependents: GR-PEACH_Azure_Speech
Fork of HTTPClient-SSL by
Diff: HTTPClient.cpp
- Revision:
- 38:a4ccad70be9d
- Parent:
- 37:293e8eae4230
- Child:
- 39:d7c5541a9124
--- 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; }