bool TLSConnection::connect(const char *host) { if (init_socket(SOCK_STREAM) < 0) return false; if (set_address(host, HTTPS_PORT) != 0) return false; if (lwip_connect(_sock_fd, (const struct sockaddr *) &_remoteHost, sizeof(_remoteHost)) < 0) { close(); return false; } if(ssl_ctx_new(&_ssl_ctx, 0, SSL_DEFAULT_CLNT_SESS) != &_ssl_ctx) return false; _ssl.ssl_ctx = &_ssl_ctx; if(ssl_client_new(&_ssl, _sock_fd, NULL, 0) == NULL) { close(); return false; } if(_ssl.hs_status != SSL_OK) { close(); return false; } _is_connected = true; return true; }
STATIC mp_obj_ssl_socket_t *socket_new(mp_obj_t sock, bool server_side) { mp_obj_ssl_socket_t *o = m_new_obj(mp_obj_ssl_socket_t); o->base.type = &ussl_socket_type; o->buf = NULL; o->bytes_left = 0; o->sock = sock; uint32_t options = SSL_SERVER_VERIFY_LATER; if ((o->ssl_ctx = ssl_ctx_new(options, SSL_DEFAULT_CLNT_SESS)) == NULL) { nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(EINVAL))); } if (server_side) { o->ssl_sock = ssl_server_new(o->ssl_ctx, (long)sock); } else { o->ssl_sock = ssl_client_new(o->ssl_ctx, (long)sock, NULL, 0); int res; /* check the return status */ if ((res = ssl_handshake_status(o->ssl_sock)) != SSL_OK) { printf("ssl_handshake_status: %d\n", res); ssl_display_error(res); nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(EIO))); } } return o; }
/*---------------------------------------------------------------------- | NPT_TlsSessionImpl::Handshake +---------------------------------------------------------------------*/ NPT_Result NPT_TlsSessionImpl::Handshake() { if (m_SSL == NULL) { // we have not performed the handshake yet m_SSL = ssl_client_new(m_SSL_CTX, &m_StreamAdapter.m_Base, NULL, 0); } int result = ssl_handshake_status(m_SSL); return NPT_Tls_MapResult(result); }
void connect(ClientContext* ctx, const char* hostName, uint32_t timeout_ms) { _ssl = ssl_client_new(_ssl_ctx, reinterpret_cast<int>(ctx), nullptr, 0, hostName); uint32_t t = millis(); while (millis() - t < timeout_ms && ssl_handshake_status(_ssl) != SSL_OK) { uint8_t* data; int rc = ssl_read(_ssl, &data); if (rc < SSL_OK) { break; } } }
ScmObj Scm_TLSConnect(ScmTLS* t, int fd) { #if defined(GAUCHE_USE_AXTLS) context_check(t, "connect"); if (t->conn) Scm_SysError("attempt to connect already-connected TLS %S", t); t->conn = ssl_client_new(t->ctx, fd, 0, 0); if (SSL_OK != ssl_handshake_status(t->conn)) { Scm_SysError("TLS handshake failed"); } #endif /*GAUCHE_USE_AXTLS*/ return SCM_OBJ(t); }
static SQRESULT sq_ssl_ctx_client_new(HSQUIRRELVM v){ SQ_FUNC_VARS(v); GET_ssl_ctx_INSTANCE(); SQ_GET_INTEGER(v, 2, client_fd); SQ_OPT_STRING(v, 3, session_id, NULL); SQ_OPT_INTEGER(v, 4, size, -1); SSL *ssl = ssl_client_new(self, client_fd, (const uint8_t *)session_id, size >= 0 ? size : session_id_size, NULL); SQRESULT rc = ssl_constructor(v, ssl, 1); if(rc == SQ_ERROR && ssl){ ssl_free(ssl); } return rc; }
void connect(ClientContext* ctx, const char* hostName, uint32_t timeout_ms) { SSL_EXTENSIONS* ext = ssl_ext_new(); ssl_ext_set_host_name(ext, hostName); ssl_ext_set_max_fragment_size(ext, 4096); s_io_ctx = ctx; if (_ssl) { ssl_free(_ssl); } _ssl = ssl_client_new(_ssl_ctx, 0, nullptr, 0, ext); uint32_t t = millis(); while (millis() - t < timeout_ms && ssl_handshake_status(_ssl) != SSL_OK) { uint8_t* data; int rc = ssl_read(_ssl, &data); if (rc < SSL_OK) { break; } } }
/* * This function is called after the TCP connect has completed. Setup the TLS * layer and do all necessary magic. */ CURLcode 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 *peer_CN; uint32_t dns_altname_index; const char *dns_altname; int8_t found_subject_alt_names = 0; int8_t found_subject_alt_name_matching_conn = 0; /* Assuming users will not compile in custom key/cert to axTLS */ uint32_t client_option = SSL_NO_DEFAULT_KEY|SSL_SERVER_VERIFY_LATER; 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 */ /* check to see if we've been told to use an explicit SSL/TLS version */ switch(data->set.ssl.version) { case CURL_SSLVERSION_DEFAULT: case CURL_SSLVERSION_TLSv1: break; default: 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); } /* curl_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; } } /* curl_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, (uint8_t)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, curl_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, curl_gtls.c does issuer verification. axTLS has no straightforward * equivalent, so omitting for now.*/ /* Here, curl_gtls.c does the following * 1) x509 hostname checking per RFC2818. axTLS doesn't support this, but * it seems useful. This is now implemented, by Oscar Koeroo * 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. */ /* There is no (DNS) Altnames count in the version 1.4.8 API. There is a risk of an inifite loop */ for(dns_altname_index = 0; ; dns_altname_index++) { dns_altname = ssl_get_cert_subject_alt_dnsname(ssl, dns_altname_index); if(dns_altname == NULL) { break; } found_subject_alt_names = 1; infof(data, "\tComparing subject alt name DNS with hostname: %s <-> %s\n", dns_altname, conn->host.name); if(Curl_cert_hostcheck(dns_altname, conn->host.name)) { found_subject_alt_name_matching_conn = 1; break; } } /* RFC2818 checks */ if(found_subject_alt_names && !found_subject_alt_name_matching_conn) { /* Break connection ! */ Curl_axtls_close(conn, sockindex); failf(data, "\tsubjectAltName(s) do not match %s\n", conn->host.dispname); return CURLE_PEER_FAILED_VERIFICATION; } else if(found_subject_alt_names == 0) { /* Per RFC2818, when no Subject Alt Names were available, examine the peer CN as a legacy fallback */ peer_CN = ssl_get_cert_dn(ssl, SSL_X509_CERT_COMMON_NAME); if(peer_CN == NULL) { /* Similar behaviour to the OpenSSL interface */ Curl_axtls_close(conn, sockindex); failf(data, "unable to obtain common name from peer certificate"); return CURLE_PEER_FAILED_VERIFICATION; } else { if(!Curl_cert_hostcheck((const char *)peer_CN, conn->host.name)) { if(data->set.ssl.verifyhost) { /* Break connection ! */ Curl_axtls_close(conn, sockindex); failf(data, "\tcommon name \"%s\" does not match \"%s\"\n", peer_CN, conn->host.dispname); return CURLE_PEER_FAILED_VERIFICATION; } else infof(data, "\tcommon name \"%s\" does not match \"%s\"\n", peer_CN, conn->host.dispname); } } } /* 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; }
/* * For both blocking and non-blocking connects, this function sets up the * ssl context and state. This function is called after the TCP connect * has completed. */ static CURLcode connect_prep(struct connectdata *conn, int sockindex) { struct SessionHandle *data = conn->data; SSL_CTX *ssl_ctx; SSL *ssl = NULL; 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; /* Assuming users will not compile in custom key/cert to axTLS. * Also, even for blocking connects, use axTLS non-blocking feature. */ uint32_t client_option = SSL_NO_DEFAULT_KEY | SSL_SERVER_VERIFY_LATER | SSL_CONNECT_IN_PARTS; 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 */ /* check to see if we've been told to use an explicit SSL/TLS version */ switch(data->set.ssl.version) { case CURL_SSLVERSION_DEFAULT: case CURL_SSLVERSION_TLSv1: break; default: 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; } conn->ssl[sockindex].ssl_ctx = ssl_ctx; conn->ssl[sockindex].ssl = NULL; /* 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) { 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]); 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]); 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, (uint8_t)ssl_idsize); } else ssl = ssl_client_new(ssl_ctx, conn->sock[sockindex], NULL, 0); conn->ssl[sockindex].ssl = ssl; return CURLE_OK; }
/****************************************************************************** * FunctionName : upgrade_task * Description : task to connect with target server and get firmware data * Parameters : pvParameters--save the server address\port\request frame for * : the upgrade server\call back functions to tell the userapp * : the result of this upgrade task * Returns : none *******************************************************************************/ void upgrade_ssl_task(void *pvParameters) { int recbytes; int sta_socket; int retry_count = 0; struct ip_info ipconfig; struct upgrade_server_info *server = pvParameters; flash_erased=FALSE; precv_buf = (char*)malloc(UPGRADE_DATA_SEG_LEN);//the max data length while (retry_count++ < UPGRADE_RETRY_TIMES) { if (giveup) break; wifi_get_ip_info(STATION_IF, &ipconfig); /* check the ip address or net connection state*/ while (ipconfig.ip.addr == 0) { vTaskDelay(1000 / portTICK_RATE_MS); wifi_get_ip_info(STATION_IF, &ipconfig); } sta_socket = socket(PF_INET,SOCK_STREAM,0); if (-1 == sta_socket) { close(sta_socket); vTaskDelay(1000 / portTICK_RATE_MS); os_printf("socket fail !\r\n"); continue; } /*for upgrade connection debug*/ //server->sockaddrin.sin_addr.s_addr= inet_addr("192.168.1.170"); if(0 != connect(sta_socket,(struct sockaddr *)(&server->sockaddrin),sizeof(struct sockaddr))) { close(sta_socket); vTaskDelay(1000 / portTICK_RATE_MS); os_printf("connect fail!\r\n"); continue; } uint32_t options = SSL_DISPLAY_CERTS | SSL_NO_DEFAULT_KEY; int i=0; int quiet = 0; int cert_index = 0, ca_cert_index = 0; int cert_size, ca_cert_size; char **ca_cert, **cert; SSL *ssl; SSL_CTX *ssl_ctx; uint8_t *read_buf = NULL; cert_size = ssl_get_config(SSL_MAX_CERT_CFG_OFFSET); ca_cert_size = ssl_get_config(SSL_MAX_CA_CERT_CFG_OFFSET); ca_cert = (char **)calloc(1, sizeof(char *)*ca_cert_size); cert = (char **)calloc(1, sizeof(char *)*cert_size); if ((ssl_ctx= ssl_ctx_new(options, SSL_DEFAULT_CLNT_SESS)) == NULL) { printf("Error: Client context is invalid\n"); close(sta_socket); continue; } ssl_obj_memory_load(ssl_ctx, SSL_OBJ_X509_CACERT, default_certificate, default_certificate_len, NULL); for (i = 0; i < cert_index; i++) { if (ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CERT, cert[i], NULL)){ printf("Certificate '%s' is undefined.\n", cert[i]); } } for (i = 0; i < ca_cert_index; i++) { if (ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CACERT, ca_cert[i], NULL)){ printf("Certificate '%s' is undefined.\n", ca_cert[i]); } } free(cert); free(ca_cert); ssl= ssl_client_new(ssl_ctx, sta_socket, NULL, 0); if (ssl == NULL){ ssl_ctx_free(ssl_ctx); close(sta_socket); continue; } if(ssl_handshake_status(ssl) != SSL_OK){ printf("client handshake fail.\n"); ssl_free(ssl); ssl_ctx_free(ssl_ctx); close(sta_socket); continue; } //handshake sucesses,show cert and free x509_ctx here if (!quiet) { const char *common_name = ssl_get_cert_dn(ssl,SSL_X509_CERT_COMMON_NAME); if (common_name) { printf("Common Name:\t\t\t%s\n", common_name); } display_session_id(ssl); display_cipher(ssl); quiet = true; x509_free(ssl->x509_ctx); ssl->x509_ctx=NULL; } system_upgrade_init(); system_upgrade_flag_set(UPGRADE_FLAG_START); if(ssl_write(ssl, server->url, strlen(server->url)+1) < 0) { ssl_free(ssl); ssl_ctx_free(ssl_ctx); close(sta_socket); vTaskDelay(1000 / portTICK_RATE_MS); os_printf("send fail\n"); continue; } os_printf("Request send success\n"); while((recbytes = ssl_read(ssl, &read_buf)) >= 0) { if(recbytes == 0){ vTaskDelay(500 / portTICK_RATE_MS); continue; } if(recbytes > UPGRADE_DATA_SEG_LEN) { ssl_free(ssl); ssl_ctx_free(ssl_ctx); close(sta_socket); vTaskDelay(2000 / portTICK_RATE_MS); printf("bigger than UPGRADE_DATA_SEG_LEN\n"); } if((recbytes)<=1460) memcpy(precv_buf,read_buf,recbytes); else os_printf("ERR2:arr_overflow,%u,%d\n",__LINE__,recbytes); if(FALSE==flash_erased){ ssl_free(ssl); ssl_ctx_free(ssl_ctx); close(sta_socket); os_printf("pre erase flash!\n"); upgrade_data_load(precv_buf,recbytes); break; } if(false == upgrade_data_load(read_buf,recbytes)) { os_printf("upgrade data error!\n"); ssl_free(ssl); ssl_ctx_free(ssl_ctx); close(sta_socket); flash_erased=FALSE; vTaskDelay(1000 / portTICK_RATE_MS); break; } /*this two length data should be equal, if totallength is bigger, *maybe data wrong or server send extra info, drop it anyway*/ if(totallength >= sumlength) { os_printf("upgrade data load finish.\n"); ssl_free(ssl); ssl_ctx_free(ssl_ctx); close(sta_socket); goto finish; } os_printf("upgrade_task %d word left\n",uxTaskGetStackHighWaterMark(NULL)); } if(recbytes < 0) { os_printf("ERROR:read data fail! recbytes %d\r\n",recbytes); ssl_free(ssl); ssl_ctx_free(ssl_ctx); close(sta_socket); flash_erased=FALSE; vTaskDelay(1000 / portTICK_RATE_MS); } os_printf("upgrade_task %d word left\n",uxTaskGetStackHighWaterMark(NULL)); totallength =0; sumlength = 0; } finish: if(upgrade_crc_check(system_get_fw_start_sec(),sumlength) != 0) { printf("upgrade crc check failed !\n"); server->upgrade_flag = false; system_upgrade_flag_set(UPGRADE_FLAG_IDLE); } os_timer_disarm(&upgrade_timer); totallength = 0; sumlength = 0; flash_erased=FALSE; free(precv_buf); if(retry_count == UPGRADE_RETRY_TIMES){ /*retry too many times, fail*/ server->upgrade_flag = false; system_upgrade_flag_set(UPGRADE_FLAG_IDLE); }else{ if (server->upgrade_flag == true) system_upgrade_flag_set(UPGRADE_FLAG_FINISH); } upgrade_deinit(); os_printf("\n Exit upgrade task.\n"); if (server->check_cb != NULL) { server->check_cb(server); } vTaskDelay(100 / portTICK_RATE_MS); vTaskDelete(NULL); }
void connect(ClientContext* ctx) { _ssl = ssl_client_new(_ssl_ctx, reinterpret_cast<int>(ctx), nullptr, 0); }
/** * Implement the SSL client logic. */ static void do_client(int argc, char *argv[]) { #ifdef CONFIG_SSL_ENABLE_CLIENT int res, i = 2; uint16_t port = 4433; uint32_t options = SSL_SERVER_VERIFY_LATER | SSL_DISPLAY_CERTS; int client_fd; char *private_key_file = NULL; struct sockaddr_in client_addr; struct hostent *hostent; int reconnect = 0; uint32_t sin_addr; SSL_CTX *ssl_ctx; SSL *ssl = NULL; int quiet = 0; int cert_index = 0, ca_cert_index = 0; int cert_size, ca_cert_size; char **ca_cert, **cert; uint8_t session_id[SSL_SESSION_ID_SIZE]; fd_set read_set; const char *password = NULL; FD_ZERO(&read_set); sin_addr = inet_addr("127.0.0.1"); cert_size = ssl_get_config(SSL_MAX_CERT_CFG_OFFSET); ca_cert_size = ssl_get_config(SSL_MAX_CA_CERT_CFG_OFFSET); ca_cert = (char **)calloc(1, sizeof(char *)*ca_cert_size); cert = (char **)calloc(1, sizeof(char *)*cert_size); while (i < argc) { if (strcmp(argv[i], "-connect") == 0) { char *host, *ptr; if (i >= argc - 1) { print_client_options(argv[i]); } host = argv[++i]; if ((ptr = strchr(host, ':')) == NULL) { print_client_options(argv[i]); } *ptr++ = 0; port = atoi(ptr); hostent = gethostbyname(host); if (hostent == NULL) { print_client_options(argv[i]); } sin_addr = *((uint32_t **)hostent->h_addr_list)[0]; } else if (strcmp(argv[i], "-cert") == 0) { if (i >= argc - 1 || cert_index >= cert_size) { print_client_options(argv[i]); } cert[cert_index++] = argv[++i]; } else if (strcmp(argv[i], "-key") == 0) { if (i >= argc - 1) { print_client_options(argv[i]); } private_key_file = argv[++i]; options |= SSL_NO_DEFAULT_KEY; } else if (strcmp(argv[i], "-CAfile") == 0) { if (i >= argc - 1 || ca_cert_index >= ca_cert_size) { print_client_options(argv[i]); } ca_cert[ca_cert_index++] = argv[++i]; } else if (strcmp(argv[i], "-verify") == 0) { options &= ~SSL_SERVER_VERIFY_LATER; } else if (strcmp(argv[i], "-reconnect") == 0) { reconnect = 4; } else if (strcmp(argv[i], "-quiet") == 0) { quiet = 1; options &= ~SSL_DISPLAY_CERTS; } else if (strcmp(argv[i], "-pass") == 0) { if (i >= argc - 1) { print_client_options(argv[i]); } password = argv[++i]; } #ifdef CONFIG_SSL_FULL_MODE else if (strcmp(argv[i], "-debug") == 0) { options |= SSL_DISPLAY_BYTES; } else if (strcmp(argv[i], "-state") == 0) { options |= SSL_DISPLAY_STATES; } else if (strcmp(argv[i], "-show-rsa") == 0) { options |= SSL_DISPLAY_RSA; } #endif else { /* don't know what this is */ print_client_options(argv[i]); } i++; } if ((ssl_ctx = ssl_ctx_new(options, SSL_DEFAULT_CLNT_SESS)) == NULL) { fprintf(stderr, "Error: Client context is invalid\n"); exit(1); } if (private_key_file) { int obj_type = SSL_OBJ_RSA_KEY; /* auto-detect the key type from the file extension */ if (strstr(private_key_file, ".p8")) { obj_type = SSL_OBJ_PKCS8; } else if (strstr(private_key_file, ".p12")) { obj_type = SSL_OBJ_PKCS12; } if (ssl_obj_load(ssl_ctx, obj_type, private_key_file, password)) { fprintf(stderr, "Error: Private key '%s' is undefined.\n", private_key_file); exit(1); } } for (i = 0; i < cert_index; i++) { if (ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CERT, cert[i], NULL)) { printf("Certificate '%s' is undefined.\n", cert[i]); exit(1); } } for (i = 0; i < ca_cert_index; i++) { if (ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CACERT, ca_cert[i], NULL)) { printf("Certificate '%s' is undefined.\n", ca_cert[i]); exit(1); } } free(cert); free(ca_cert); /************************************************************************* * This is where the interesting stuff happens. Up until now we've * just been setting up sockets etc. Now we do the SSL handshake. *************************************************************************/ client_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); memset(&client_addr, 0, sizeof(client_addr)); client_addr.sin_family = AF_INET; client_addr.sin_port = htons(port); client_addr.sin_addr.s_addr = sin_addr; if (connect(client_fd, (struct sockaddr *)&client_addr, sizeof(client_addr)) < 0) { perror("connect"); exit(1); } if (!quiet) { printf("CONNECTED\n"); TTY_FLUSH(); } /* Try session resumption? */ if (reconnect) { while (reconnect--) { ssl = ssl_client_new(ssl_ctx, client_fd, session_id, sizeof(session_id)); if ((res = ssl_handshake_status(ssl)) != SSL_OK) { if (!quiet) { ssl_display_error(res); } ssl_free(ssl); exit(1); } display_session_id(ssl); memcpy(session_id, ssl_get_session_id(ssl), SSL_SESSION_ID_SIZE); if (reconnect) { ssl_free(ssl); SOCKET_CLOSE(client_fd); client_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); connect(client_fd, (struct sockaddr *)&client_addr, sizeof(client_addr)); } } } else { ssl = ssl_client_new(ssl_ctx, client_fd, NULL, 0); } /* check the return status */ if ((res = ssl_handshake_status(ssl)) != SSL_OK) { if (!quiet) { ssl_display_error(res); } exit(1); } if (!quiet) { const char *common_name = ssl_get_cert_dn(ssl, SSL_X509_CERT_COMMON_NAME); if (common_name) { printf("Common Name:\t\t\t%s\n", common_name); } display_session_id(ssl); display_cipher(ssl); } for (;;) { uint8_t buf[1024]; /* allow parallel reading of server and standard input */ FD_SET(client_fd, &read_set); #ifndef WIN32 /* win32 doesn't like mixing up stdin and sockets */ FD_SET(STDIN_FILENO, &read_set); if ((res = select(client_fd + 1, &read_set, NULL, NULL, NULL)) > 0) { /* read standard input? */ if (FD_ISSET(STDIN_FILENO, &read_set)) #endif { if (fgets((char *)buf, sizeof(buf), stdin) == NULL) { /* bomb out of here */ ssl_free(ssl); break; } else { /* small hack to check renegotiation */ if (buf[0] == 'R' && (buf[1] == '\n' || buf[1] == '\r')) { res = ssl_renegotiate(ssl); } else { res = ssl_write(ssl, buf, strlen((char *)buf)); } } } #ifndef WIN32 else { /* a socket read */ uint8_t *read_buf; res = ssl_read(ssl, &read_buf); if (res > 0) { /* display our interesting output */ int written = 0; while (written < res) { written += write(STDOUT_FILENO, read_buf + written, res - written); } TTY_FLUSH(); } } } #endif if (res < 0) { if (!quiet) { ssl_display_error(res); } break; /* get outta here */ } } ssl_ctx_free(ssl_ctx); SOCKET_CLOSE(client_fd); #else print_client_options(argv[1]); #endif }