/* Use this callback to setup TLS certificates and verify callbacks */ static int mqtt_aws_tls_cb(MqttClient* client) { int rc = SSL_FAILURE; client->tls.ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method()); if (client->tls.ctx) { wolfSSL_CTX_set_verify(client->tls.ctx, SSL_VERIFY_PEER, mqtt_aws_tls_verify_cb); /* Load CA certificate buffer */ rc = wolfSSL_CTX_load_verify_buffer(client->tls.ctx, (const byte*)root_ca, (long)XSTRLEN(root_ca), SSL_FILETYPE_PEM); /* Load Client Cert */ if (rc == SSL_SUCCESS) rc = wolfSSL_CTX_use_certificate_buffer(client->tls.ctx, (const byte*)device_cert, (long)XSTRLEN(device_cert), SSL_FILETYPE_PEM); /* Load Private Key */ if (rc == SSL_SUCCESS) rc = wolfSSL_CTX_use_PrivateKey_buffer(client->tls.ctx, (const byte*)device_priv_key, (long)XSTRLEN(device_priv_key), SSL_FILETYPE_PEM); } PRINTF("MQTT TLS Setup (%d)", rc); return rc; }
bool NET_PRES_EncProviderStreamClientInit0(NET_PRES_TransportObject * transObject) { const uint8_t * caCertsPtr; int32_t caCertsLen; if (!NET_PRES_CertStoreGetCACerts(&caCertsPtr, &caCertsLen, 0)) { return false; } if (_net_pres_wolfsslUsers == 0) { wolfSSL_Init(); _net_pres_wolfsslUsers++; } net_pres_wolfSSLInfoStreamClient0.transObject = transObject; net_pres_wolfSSLInfoStreamClient0.context = wolfSSL_CTX_new(wolfSSLv23_client_method()); if (net_pres_wolfSSLInfoStreamClient0.context == 0) { return false; } wolfSSL_SetIORecv(net_pres_wolfSSLInfoStreamClient0.context, (CallbackIORecv)&NET_PRES_EncGlue_StreamClientReceiveCb0); wolfSSL_SetIOSend(net_pres_wolfSSLInfoStreamClient0.context, (CallbackIOSend)&NET_PRES_EncGlue_StreamClientSendCb0); // Turn off verification, because SNTP is usually blocked by a firewall wolfSSL_CTX_set_verify(net_pres_wolfSSLInfoStreamClient0.context, SSL_VERIFY_NONE, 0); if (wolfSSL_CTX_load_verify_buffer(net_pres_wolfSSLInfoStreamClient0.context, caCertsPtr, caCertsLen, SSL_FILETYPE_ASN1) != SSL_SUCCESS) { // Couldn't load the certificates wolfSSL_CTX_free(net_pres_wolfSSLInfoStreamClient0.context); return false; } if(wolfSSL_CTX_use_PrivateKey_buffer(net_pres_wolfSSLInfoStreamClient0.context, (unsigned char *)appData.clientKey, strlen((char *)appData.clientKey), SSL_FILETYPE_PEM) != SSL_SUCCESS) { // Couldn't load the private key wolfSSL_CTX_free(net_pres_wolfSSLInfoStreamClient0.context); return false; } // Loading the client cert so that the server can authenticate us (client authentication)) if(wolfSSL_CTX_use_certificate_buffer(net_pres_wolfSSLInfoStreamClient0.context, (unsigned char *)appData.clientCert, strlen((char *)appData.clientCert), SSL_FILETYPE_PEM) != SSL_SUCCESS) { // Couldn't load the client certificate wolfSSL_CTX_free(net_pres_wolfSSLInfoStreamClient0.context); return false; } // Turn off verification, because SNTP is usually blocked by a firewall wolfSSL_CTX_set_verify(net_pres_wolfSSLInfoStreamClient0.context, SSL_VERIFY_NONE, 0); net_pres_wolfSSLInfoStreamClient0.isInited = true; return true; }
/* * this may now get called after the vhost creation, when certs become * available. */ int lws_tls_server_certs_load(struct lws_vhost *vhost, struct lws *wsi, const char *cert, const char *private_key, const char *mem_cert, size_t mem_cert_len, const char *mem_privkey, size_t mem_privkey_len) { #if !defined(OPENSSL_NO_EC) const char *ecdh_curve = "prime256v1"; #if !defined(LWS_WITH_BORINGSSL) && defined(LWS_HAVE_SSL_EXTRA_CHAIN_CERTS) STACK_OF(X509) *extra_certs = NULL; #endif EC_KEY *ecdh, *EC_key = NULL; EVP_PKEY *pkey; X509 *x = NULL; int ecdh_nid; int KeyType; #endif unsigned long error; lws_filepos_t flen; uint8_t *p; int ret; int n = lws_tls_generic_cert_checks(vhost, cert, private_key), m; (void)ret; if (!cert && !private_key) n = LWS_TLS_EXTANT_ALTERNATIVE; if (n == LWS_TLS_EXTANT_NO && (!mem_cert || !mem_privkey)) return 0; if (n == LWS_TLS_EXTANT_NO) n = LWS_TLS_EXTANT_ALTERNATIVE; if (n == LWS_TLS_EXTANT_ALTERNATIVE && (!mem_cert || !mem_privkey)) return 1; /* no alternative */ if (n == LWS_TLS_EXTANT_ALTERNATIVE) { #if OPENSSL_VERSION_NUMBER >= 0x10100000L /* * Although we have prepared update certs, we no longer have * the rights to read our own cert + key we saved. * * If we were passed copies in memory buffers, use those * in favour of the filepaths we normally want. */ cert = NULL; private_key = NULL; } /* * use the multi-cert interface for backwards compatibility in the * both simple files case */ if (n != LWS_TLS_EXTANT_ALTERNATIVE && cert) { /* set the local certificate from CertFile */ m = SSL_CTX_use_certificate_chain_file(vhost->tls.ssl_ctx, cert); if (m != 1) { error = ERR_get_error(); lwsl_err("problem getting cert '%s' %lu: %s\n", cert, error, ERR_error_string(error, (char *)vhost->context->pt[0].serv_buf)); return 1; } if (private_key) { /* set the private key from KeyFile */ if (SSL_CTX_use_PrivateKey_file(vhost->tls.ssl_ctx, private_key, SSL_FILETYPE_PEM) != 1) { error = ERR_get_error(); lwsl_err("ssl problem getting key '%s' %lu: %s\n", private_key, error, ERR_error_string(error, (char *)vhost->context->pt[0].serv_buf)); return 1; } } else { if (vhost->protocols[0].callback(wsi, LWS_CALLBACK_OPENSSL_CONTEXT_REQUIRES_PRIVATE_KEY, vhost->tls.ssl_ctx, NULL, 0)) { lwsl_err("ssl private key not set\n"); return 1; } } return 0; } /* otherwise allow for DER or PEM, file or memory image */ if (lws_tls_alloc_pem_to_der_file(vhost->context, cert, mem_cert, mem_cert_len, &p, &flen)) { lwsl_err("%s: couldn't read cert file\n", __func__); return 1; } #if !defined(USE_WOLFSSL) ret = SSL_CTX_use_certificate_ASN1(vhost->tls.ssl_ctx, (int)flen, p); #else ret = wolfSSL_CTX_use_certificate_buffer(vhost->tls.ssl_ctx, (uint8_t *)p, (int)flen, WOLFSSL_FILETYPE_ASN1); #endif lws_free_set_NULL(p); if (ret != 1) { lwsl_err("%s: Problem loading cert\n", __func__); return 1; } if (lws_tls_alloc_pem_to_der_file(vhost->context, private_key, mem_privkey, mem_privkey_len, &p, &flen)) { lwsl_notice("unable to convert memory privkey\n"); return 1; } #if !defined(USE_WOLFSSL) ret = SSL_CTX_use_PrivateKey_ASN1(EVP_PKEY_RSA, vhost->tls.ssl_ctx, p, (long)(long long)flen); if (ret != 1) { ret = SSL_CTX_use_PrivateKey_ASN1(EVP_PKEY_EC, vhost->tls.ssl_ctx, p, (long)(long long)flen); } #else ret = wolfSSL_CTX_use_PrivateKey_buffer(vhost->tls.ssl_ctx, p, flen, WOLFSSL_FILETYPE_ASN1); #endif lws_free_set_NULL(p); if (ret != 1) { lwsl_notice("unable to use memory privkey\n"); return 1; } #else /* * Although we have prepared update certs, we no longer have * the rights to read our own cert + key we saved. * * If we were passed copies in memory buffers, use those * instead. * * The passed memory-buffer cert image is in DER, and the * memory-buffer private key image is PEM. */ #ifndef USE_WOLFSSL if (SSL_CTX_use_certificate_ASN1(vhost->tls.ssl_ctx, (int)mem_cert_len, (uint8_t *)mem_cert) != 1) { #else if (wolfSSL_CTX_use_certificate_buffer(vhost->tls.ssl_ctx, (uint8_t *)mem_cert, (int)mem_cert_len, WOLFSSL_FILETYPE_ASN1) != 1) { #endif lwsl_err("Problem loading update cert\n"); return 1; } if (lws_tls_alloc_pem_to_der_file(vhost->context, NULL, mem_privkey, mem_privkey_len, &p, &flen)) { lwsl_notice("unable to convert memory privkey\n"); return 1; } #ifndef USE_WOLFSSL if (SSL_CTX_use_PrivateKey_ASN1(EVP_PKEY_RSA, vhost->tls.ssl_ctx, p, (long)(long long)flen) != 1) { #else if (wolfSSL_CTX_use_PrivateKey_buffer(vhost->tls.ssl_ctx, p, flen, WOLFSSL_FILETYPE_ASN1) != 1) { #endif lwsl_notice("unable to use memory privkey\n"); return 1; } goto check_key; } /* set the local certificate from CertFile */ m = SSL_CTX_use_certificate_chain_file(vhost->tls.ssl_ctx, cert); if (m != 1) { error = ERR_get_error(); lwsl_err("problem getting cert '%s' %lu: %s\n", cert, error, ERR_error_string(error, (char *)vhost->context->pt[0].serv_buf)); return 1; } if (n != LWS_TLS_EXTANT_ALTERNATIVE && private_key) { /* set the private key from KeyFile */ if (SSL_CTX_use_PrivateKey_file(vhost->tls.ssl_ctx, private_key, SSL_FILETYPE_PEM) != 1) { error = ERR_get_error(); lwsl_err("ssl problem getting key '%s' %lu: %s\n", private_key, error, ERR_error_string(error, (char *)vhost->context->pt[0].serv_buf)); return 1; } } else { if (vhost->protocols[0].callback(wsi, LWS_CALLBACK_OPENSSL_CONTEXT_REQUIRES_PRIVATE_KEY, vhost->tls.ssl_ctx, NULL, 0)) { lwsl_err("ssl private key not set\n"); return 1; } } check_key: #endif /* verify private key */ if (!SSL_CTX_check_private_key(vhost->tls.ssl_ctx)) { lwsl_err("Private SSL key doesn't match cert\n"); return 1; } #if !defined(OPENSSL_NO_EC) if (vhost->tls.ecdh_curve[0]) ecdh_curve = vhost->tls.ecdh_curve; ecdh_nid = OBJ_sn2nid(ecdh_curve); if (NID_undef == ecdh_nid) { lwsl_err("SSL: Unknown curve name '%s'", ecdh_curve); return 1; } ecdh = EC_KEY_new_by_curve_name(ecdh_nid); if (NULL == ecdh) { lwsl_err("SSL: Unable to create curve '%s'", ecdh_curve); return 1; } SSL_CTX_set_tmp_ecdh(vhost->tls.ssl_ctx, ecdh); EC_KEY_free(ecdh); SSL_CTX_set_options(vhost->tls.ssl_ctx, SSL_OP_SINGLE_ECDH_USE); lwsl_notice(" SSL ECDH curve '%s'\n", ecdh_curve); if (lws_check_opt(vhost->context->options, LWS_SERVER_OPTION_SSL_ECDH)) lwsl_notice(" Using ECDH certificate support\n"); /* Get X509 certificate from ssl context */ #if !defined(LWS_WITH_BORINGSSL) #if !defined(LWS_HAVE_SSL_EXTRA_CHAIN_CERTS) x = sk_X509_value(vhost->tls.ssl_ctx->extra_certs, 0); #else SSL_CTX_get_extra_chain_certs_only(vhost->tls.ssl_ctx, &extra_certs); if (extra_certs) x = sk_X509_value(extra_certs, 0); else lwsl_info("%s: no extra certs\n", __func__); #endif if (!x) { //lwsl_err("%s: x is NULL\n", __func__); goto post_ecdh; } #else return 0; #endif /* Get the public key from certificate */ pkey = X509_get_pubkey(x); if (!pkey) { lwsl_err("%s: pkey is NULL\n", __func__); return 1; } /* Get the key type */ KeyType = EVP_PKEY_type(EVP_PKEY_id(pkey)); if (EVP_PKEY_EC != KeyType) { lwsl_notice("Key type is not EC\n"); return 0; } /* Get the key */ EC_key = EVP_PKEY_get1_EC_KEY(pkey); /* Set ECDH parameter */ if (!EC_key) { lwsl_err("%s: ECDH key is NULL \n", __func__); return 1; } SSL_CTX_set_tmp_ecdh(vhost->tls.ssl_ctx, EC_key); EC_KEY_free(EC_key); #else lwsl_notice(" OpenSSL doesn't support ECDH\n"); #endif #if !defined(OPENSSL_NO_EC) && !defined(LWS_WITH_BORINGSSL) post_ecdh: #endif vhost->tls.skipped_certs = 0; return 0; } int lws_tls_server_vhost_backend_init(const struct lws_context_creation_info *info, struct lws_vhost *vhost, struct lws *wsi) { unsigned long error; SSL_METHOD *method = (SSL_METHOD *)SSLv23_server_method(); if (!method) { error = ERR_get_error(); lwsl_err("problem creating ssl method %lu: %s\n", error, ERR_error_string(error, (char *)vhost->context->pt[0].serv_buf)); return 1; } vhost->tls.ssl_ctx = SSL_CTX_new(method); /* create context */ if (!vhost->tls.ssl_ctx) { error = ERR_get_error(); lwsl_err("problem creating ssl context %lu: %s\n", error, ERR_error_string(error, (char *)vhost->context->pt[0].serv_buf)); return 1; } SSL_CTX_set_ex_data(vhost->tls.ssl_ctx, openssl_SSL_CTX_private_data_index, (char *)vhost->context); /* Disable SSLv2 and SSLv3 */ SSL_CTX_set_options(vhost->tls.ssl_ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); #ifdef SSL_OP_NO_COMPRESSION SSL_CTX_set_options(vhost->tls.ssl_ctx, SSL_OP_NO_COMPRESSION); #endif SSL_CTX_set_options(vhost->tls.ssl_ctx, SSL_OP_SINGLE_DH_USE); SSL_CTX_set_options(vhost->tls.ssl_ctx, SSL_OP_CIPHER_SERVER_PREFERENCE); if (info->ssl_cipher_list) SSL_CTX_set_cipher_list(vhost->tls.ssl_ctx, info->ssl_cipher_list); #if defined(LWS_HAVE_SSL_CTX_set_ciphersuites) if (info->tls1_3_plus_cipher_list) SSL_CTX_set_ciphersuites(vhost->tls.ssl_ctx, info->tls1_3_plus_cipher_list); #endif #if !defined(OPENSSL_NO_TLSEXT) SSL_CTX_set_tlsext_servername_callback(vhost->tls.ssl_ctx, lws_ssl_server_name_cb); SSL_CTX_set_tlsext_servername_arg(vhost->tls.ssl_ctx, vhost->context); #endif if (info->ssl_ca_filepath && !SSL_CTX_load_verify_locations(vhost->tls.ssl_ctx, info->ssl_ca_filepath, NULL)) { lwsl_err("%s: SSL_CTX_load_verify_locations unhappy\n", __func__); } if (info->ssl_options_set) SSL_CTX_set_options(vhost->tls.ssl_ctx, info->ssl_options_set); /* SSL_clear_options introduced in 0.9.8m */ #if (OPENSSL_VERSION_NUMBER >= 0x009080df) && !defined(USE_WOLFSSL) if (info->ssl_options_clear) SSL_CTX_clear_options(vhost->tls.ssl_ctx, info->ssl_options_clear); #endif lwsl_info(" SSL options 0x%lX\n", (unsigned long)SSL_CTX_get_options(vhost->tls.ssl_ctx)); if (!vhost->tls.use_ssl || (!info->ssl_cert_filepath && !info->server_ssl_cert_mem)) return 0; lws_ssl_bind_passphrase(vhost->tls.ssl_ctx, info); return lws_tls_server_certs_load(vhost, wsi, info->ssl_cert_filepath, info->ssl_private_key_filepath, info->server_ssl_cert_mem, info->server_ssl_cert_mem_len, info->server_ssl_private_key_mem, info->server_ssl_private_key_mem_len); }
/* Create a new wolfSSL server with a certificate for authentication. */ static int wolfssl_server_new(WOLFSSL_CTX** ctx, WOLFSSL** ssl) { int ret = 0; WOLFSSL_CTX* server_ctx = NULL; WOLFSSL* server_ssl = NULL; /* Create and initialize WOLFSSL_CTX */ if ((server_ctx = wolfSSL_CTX_new_ex(wolfTLSv1_2_server_method(), HEAP_HINT_SERVER)) == NULL) { printf("ERROR: failed to create WOLFSSL_CTX\n"); ret = -1; } if (ret == 0) { /* Load client certificates into WOLFSSL_CTX */ if (wolfSSL_CTX_use_certificate_buffer(server_ctx, SERVER_CERT, SERVER_CERT_LEN, WOLFSSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS) { printf("ERROR: failed to load server certificate\n"); ret = -1; } } if (ret == 0) { /* Load client certificates into WOLFSSL_CTX */ if (wolfSSL_CTX_use_PrivateKey_buffer(server_ctx, SERVER_KEY, SERVER_KEY_LEN, WOLFSSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS) { printf("ERROR: failed to load server key\n"); ret = -1; } } if (ret == 0) { /* Register callbacks */ wolfSSL_SetIORecv(server_ctx, recv_server); wolfSSL_SetIOSend(server_ctx, send_server); } if (ret == 0) { /* Create a WOLFSSL object */ if ((server_ssl = wolfSSL_new(server_ctx)) == NULL) { printf("ERROR: failed to create WOLFSSL object\n"); ret = -1; } } if (ret == 0) { /* make wolfSSL object nonblocking */ wolfSSL_set_using_nonblock(server_ssl, 1); } if (ret == 0) { *ctx = server_ctx; *ssl = server_ssl; } else { if (server_ssl != NULL) wolfSSL_free(server_ssl); if (server_ctx != NULL) wolfSSL_CTX_free(server_ctx); } return ret; }
bool NET_PRES_EncProviderStreamClientInit0(NET_PRES_TransportObject * transObject) { const uint8_t * caCertsPtr; const uint8_t * clientCertPtr; const uint8_t * clientKeyPtr; int32_t caCertsLen; int32_t clientCertLen; int32_t clientKeyLen; if (!NET_PRES_CertStoreGetCACerts(&caCertsPtr, &caCertsLen, 0)) { return false; } if (!NET_PRES_CertStoreGetClientCerts(&clientCertPtr, &clientCertLen, 0)) { return false; } if (!NET_PRES_CertStoreGetClientKey(&clientKeyPtr, &clientKeyLen, 0)) { return false; } if (_net_pres_wolfsslUsers == 0) { wolfSSL_Init(); _net_pres_wolfsslUsers++; } net_pres_wolfSSLInfoStreamClient0.transObject = transObject; net_pres_wolfSSLInfoStreamClient0.context = wolfSSL_CTX_new(wolfSSLv23_client_method()); if (net_pres_wolfSSLInfoStreamClient0.context == 0) { return false; } wolfSSL_SetIORecv(net_pres_wolfSSLInfoStreamClient0.context, (CallbackIORecv)&NET_PRES_EncGlue_StreamClientReceiveCb0); wolfSSL_SetIOSend(net_pres_wolfSSLInfoStreamClient0.context, (CallbackIOSend)&NET_PRES_EncGlue_StreamClientSendCb0); // Loading the rootCA cert so we can authenticate the server certificate given to us if (wolfSSL_CTX_load_verify_buffer(net_pres_wolfSSLInfoStreamClient0.context, caCertsPtr, caCertsLen, SSL_FILETYPE_ASN1) != SSL_SUCCESS) { // Couldn't load the certificates //SYS_CONSOLE_MESSAGE("Something went wrong loading the certificates\r\n"); wolfSSL_CTX_free(net_pres_wolfSSLInfoStreamClient0.context); return false; } // Loading the private key for client authentication use if(wolfSSL_CTX_use_PrivateKey_buffer(net_pres_wolfSSLInfoStreamClient0.context, clientKeyPtr, clientKeyLen, SSL_FILETYPE_ASN1) != SSL_SUCCESS) { // Couldn't load the private key //SYS_CONSOLE_MESSAGE("Something went wrong loading the private key\r\n"); wolfSSL_CTX_free(net_pres_wolfSSLInfoStreamClient0.context); return false; } // Loading the client cert so that the server can authenticate us (client authentication)) if(wolfSSL_CTX_use_certificate_buffer(net_pres_wolfSSLInfoStreamClient0.context, clientCertPtr, clientCertLen, SSL_FILETYPE_ASN1) != SSL_SUCCESS) { // Couldn't load the client certificate //SYS_CONSOLE_MESSAGE("Something went wrong loading the client certificate\r\n"); wolfSSL_CTX_free(net_pres_wolfSSLInfoStreamClient0.context); return false; } // Turn on verification, ensure SNTP is not blocked by firewall // SSL_VERIFY_PEER: This option is turned on by default so technically this // is not needed wolfSSL_CTX_set_verify(net_pres_wolfSSLInfoStreamClient0.context, SSL_VERIFY_NONE, 0); net_pres_wolfSSLInfoStreamClient0.isInited = true; return true; }
int main() { int sockfd; int connd; struct sockaddr_in servAddr; struct sockaddr_in clientAddr; socklen_t size = sizeof(clientAddr); char command[256]; char buffer[256]; int shutDown = 0; int ret, err, firstRead, gotFirstG, echoSz; unsigned char serverDer[2048]; int serverDerSz = sizeof(serverDer); /* PEM certificate buffers */ unsigned char server[2048]; unsigned char serveK[2048]; unsigned char cert[4096]; /* certificate chain to send */ int serverSz = sizeof(server); int serveKSz = sizeof(serveK); int certSz = sizeof(cert); /* declare wolfSSL objects */ WOLFSSL_CTX* ctx; WOLFSSL* ssl; wolfSSL_Debugging_ON(); /* Initialize wolfSSL */ wolfSSL_Init(); /* create new certificate with IP address as common name */ if (createSignedCert( (unsigned char*)server_cert_der_2048, sizeof_server_cert_der_2048, (unsigned char*)server_key_der_2048, sizeof_server_key_der_2048, serverDer, &serverDerSz, server, &serverSz, serveK, &serveKSz, "127.0.0.1", 0) != 0) { fprintf(stderr, "Failure creating new certificate\n"); return -1; } XMEMCPY(cert, server, serverSz); /* convert CA to PEM format */ ret = wc_DerToPem((unsigned char*)server_cert_der_2048, sizeof_server_cert_der_2048, cert + serverSz, certSz - serverSz, CERT_TYPE); if (ret <= 0) { fprintf(stderr, "error converting CA to PEM format.\n"); return -1; } certSz = ret + serverSz; { /* for debugging print out created certificate to files */ FILE* f = fopen("created_chain.pem", "wb"); if (f != NULL ) { fwrite(cert, 1, certSz, f); fclose(f); } f = fopen("created_cert.der", "wb"); if (f != NULL ) { fwrite(server, 1, serverSz, f); fclose(f); } f = fopen("created_key.der", "wb"); if (f != NULL ) { fwrite(serveK, 1, serveKSz, f); fclose(f); } } /* Create a socket that uses an internet IPv4 address, * Sets the socket to be stream based (TCP), * 0 means choose the default protocol. */ if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { fprintf(stderr, "ERROR: failed to create the socket\n"); return -1; } /* Create and initialize WOLFSSL_CTX */ if ((ctx = wolfSSL_CTX_new(wolfTLSv1_2_server_method())) == NULL) { fprintf(stderr, "ERROR: failed to create WOLFSSL_CTX\n"); return -1; } /* For this example load certificate chain into WOLFSSL_CTX */ if (wolfSSL_CTX_use_certificate_chain_buffer(ctx, cert, certSz) != SSL_SUCCESS) { fprintf(stderr, "ERROR: failed to load certificate chain.\n"); return -1; } /* Load server key into WOLFSSL_CTX */ if (wolfSSL_CTX_use_PrivateKey_buffer(ctx, serveK, serveKSz, SSL_FILETYPE_ASN1) != SSL_SUCCESS) { fprintf(stderr, "ERROR: failed to load server key.\n"); return -1; } /* Initialize the server address struct with zeros */ memset(&servAddr, 0, sizeof(servAddr)); /* Fill in the server address */ servAddr.sin_family = AF_INET; /* using IPv4 */ servAddr.sin_port = htons(DEFAULT_PORT); /* on DEFAULT_PORT */ servAddr.sin_addr.s_addr = INADDR_ANY; /* from anywhere */ /* Bind the server socket to our port */ if (bind(sockfd, (struct sockaddr*)&servAddr, sizeof(servAddr)) == -1) { fprintf(stderr, "ERROR: failed to bind\n"); return -1; } /* Listen for a new connection, allow 5 pending connections */ if (listen(sockfd, 5) == -1) { fprintf(stderr, "ERROR: failed to listen\n"); return -1; } /* Continue to accept clients until shutdown is issued */ while (!shutDown) { printf("Waiting for a connection...\n"); /* Accept client connections */ if ((connd = accept(sockfd, (struct sockaddr*)&clientAddr, &size)) == -1) { fprintf(stderr, "ERROR: failed to accept the connection\n\n"); return -1; } /* Create a WOLFSSL object */ if ((ssl = wolfSSL_new(ctx)) == NULL) { fprintf(stderr, "ERROR: failed to create WOLFSSL object\n"); return -1; } /* Attach wolfSSL to the socket */ wolfSSL_set_fd(ssl, connd); printf("Client connected successfully\n"); /* Very basic HTTP GET command -- intended to be used as an example. * read and write from wolfssl-root/examples/echoserver/echoserver.c */ while (1) { err = 0; /* reset error */ ret = wolfSSL_read(ssl, command, sizeof(command)-1); if (ret <= 0) { err = wolfSSL_get_error(ssl, 0); if (err != SSL_ERROR_WANT_READ && err != SSL_ERROR_ZERO_RETURN){ printf("SSL_read echo error %d, %s!\n", err, wolfSSL_ERR_error_string(err, buffer)); } break; } echoSz = ret; if (firstRead == 1) { firstRead = 0; /* browser may send 1 byte 'G' to start */ if (echoSz == 1 && command[0] == 'G') { gotFirstG = 1; continue; } } else if (gotFirstG == 1 && strncmp(command, "ET /", 4) == 0) { strncpy(command, "GET", 4); /* fall through to normal GET */ } if ( strncmp(command, "quit", 4) == 0) { printf("client sent quit command: shutting down!\n"); shutDown = 1; break; } if ( strncmp(command, "break", 5) == 0) { printf("client sent break command: closing session!\n"); break; } if ( strncmp(command, "GET", 3) == 0) { char type[] = "HTTP/1.0 200 ok\r\nContent-type:" " text/html\r\n\r\n"; char header[] = "<html><body BGCOLOR=\"#ffffff\">\n<pre>\n"; char body[] = "greetings from wolfSSL\n"; char footer[] = "</body></html>\r\n\r\n"; strncpy(command, type, sizeof(type)); echoSz = sizeof(type) - 1; strncpy(&command[echoSz], header, sizeof(header)); echoSz += (int)sizeof(header) - 1; strncpy(&command[echoSz], body, sizeof(body)); echoSz += (int)sizeof(body) - 1; strncpy(&command[echoSz], footer, sizeof(footer)); echoSz += (int)sizeof(footer); err = 0; /* reset error */ ret = wolfSSL_write(ssl, command, echoSz); if (ret <= 0) { err = wolfSSL_get_error(ssl, 0); } if (ret != echoSz) { printf("SSL_write get error = %d, %s\n", err, wolfSSL_ERR_error_string(err, buffer)); printf("SSL_write get failed\n"); } break; } command[echoSz] = 0; ret = wolfSSL_write(ssl, command, echoSz); if (ret <= 0) { printf("Error %d\n", wolfSSL_get_error(ssl, 0)); break; } if (ret != echoSz) { printf("SSL_write echo error = %d, %s\n", err, wolfSSL_ERR_error_string(err, buffer)); printf("SSL_write echo failed\n"); } } /* Cleanup after this connection */ wolfSSL_free(ssl); /* Free the wolfSSL object */ close(connd); /* Close the connection to the client */ } printf("Shutdown complete\n"); /* Cleanup and return */ wolfSSL_CTX_free(ctx); /* Free the wolfSSL context object */ wolfSSL_Cleanup(); /* Cleanup the wolfSSL environment */ close(sockfd); /* Close the socket listening for clients */ return 0; /* Return reporting a success */ }
/* * ======== tcpHandler ======== * Creates new Task to handle new TCP connections. */ Void tcpHandler(UArg arg0, UArg arg1) { int sockfd; int ret; struct sockaddr_in servAddr; Error_Block eb; bool flag = true; bool internal_flag = true; int nbytes; char *buffer; char msg[] = "Hello from TM4C1294XL Connected Launchpad"; WOLFSSL* ssl = (WOLFSSL *) arg0; fdOpenSession(TaskSelf()); wolfSSL_Init(); WOLFSSL_CTX* ctx = NULL; ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method()); if (ctx == 0) { System_printf("tcpHandler: wolfSSL_CTX_new error.\n"); exitApp(ctx); } if (wolfSSL_CTX_load_verify_buffer(ctx, ca_cert_der_2048, sizeof(ca_cert_der_2048) / sizeof(char), SSL_FILETYPE_ASN1) != SSL_SUCCESS) { System_printf("tcpHandler: Error loading ca_cert_der_2048" " please check the wolfssl/certs_test.h file.\n"); exitApp(ctx); } if (wolfSSL_CTX_use_certificate_buffer(ctx, client_cert_der_2048, sizeof(client_cert_der_2048) / sizeof(char), SSL_FILETYPE_ASN1) != SSL_SUCCESS) { System_printf("tcpHandler: Error loading client_cert_der_2048," " please check the wolfssl/certs_test.h file.\n"); exitApp(ctx); } if (wolfSSL_CTX_use_PrivateKey_buffer(ctx, client_key_der_2048, sizeof(client_key_der_2048) / sizeof(char), SSL_FILETYPE_ASN1) != SSL_SUCCESS) { System_printf("tcpHandler: Error loading client_key_der_2048," " please check the wolfssl/certs_test.h file.\n"); exitApp(ctx); } /* Init the Error_Block */ Error_init(&eb); do { sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) { System_printf("tcpHandler: socket failed\n"); Task_sleep(2000); continue; } memset((char *) &servAddr, 0, sizeof(servAddr)); servAddr.sin_family = AF_INET; servAddr.sin_port = htons(TCPPORT); inet_aton(IP_ADDR, &servAddr.sin_addr); ret = connect(sockfd, (struct sockaddr *) &servAddr, sizeof(servAddr)); if (ret < 0) { fdClose((SOCKET) sockfd); Task_sleep(2000); continue; } } while (ret != 0); if ((ssl = wolfSSL_new(ctx)) == NULL) { System_printf("tcpHandler: wolfSSL_new error.\n"); exitApp(ctx); } wolfSSL_set_fd(ssl, sockfd); ret = wolfSSL_connect(ssl); /* Delete "TOP_LINE" and "END_LINE" for debugging. */ /* TOP_LINE System_printf("looked for: %d.\n", SSL_SUCCESS); System_printf("return was: %d.\n", ret); int err; char err_buffer[80]; err = wolfSSL_get_error(ssl, 0); System_printf("wolfSSL error: %d\n", err); System_printf("wolfSSL error string: %s\n", wolfSSL_ERR_error_string(err, err_buffer)); END_LINE */ if (ret == SSL_SUCCESS) { sockfd = wolfSSL_get_fd(ssl); /* Get a buffer to receive incoming packets. Use the default heap. */ buffer = Memory_alloc(NULL, TCPPACKETSIZE, 0, &eb); if (buffer == NULL) { System_printf("tcpWorker: failed to alloc memory\n"); exitApp(ctx); } /* Say hello to the server */ while (flag) { if (wolfSSL_write(ssl, msg, strlen(msg)) != strlen(msg)) { ret = wolfSSL_get_error(ssl, 0); System_printf("Write error: %i.\n", ret); } while (internal_flag) { nbytes = wolfSSL_read(ssl, (char *) buffer, TCPPACKETSIZE); if (nbytes > 0) { internal_flag = false; } } /* success */ System_printf("Heard: \"%s\".\n", buffer); wolfSSL_free(ssl); fdClose((SOCKET) sockfd); flag = false; } /* Free the buffer back to the heap */ Memory_free(NULL, buffer, TCPPACKETSIZE); /* * Since deleteTerminatedTasks is set in the cfg file, * the Task will be deleted when the idle task runs. */ exitApp(ctx); } else { wolfSSL_free(ssl); fdClose((SOCKET) sockfd); System_printf("wolfSSL_connect failed.\n"); fdCloseSession(TaskSelf()); exitApp(ctx); } }