static int create_wolfssl_instance(TLS_IO_INSTANCE* tls_io_instance) { int result; if (add_certificate_to_store(tls_io_instance) != 0) { wolfSSL_CTX_free(tls_io_instance->ssl_context); result = __LINE__; } else { tls_io_instance->ssl = wolfSSL_new(tls_io_instance->ssl_context); if (tls_io_instance->ssl == NULL) { wolfSSL_CTX_free(tls_io_instance->ssl_context); result = __LINE__; } else { tls_io_instance->socket_io_read_bytes = NULL; tls_io_instance->socket_io_read_byte_count = 0; tls_io_instance->on_send_complete = NULL; tls_io_instance->on_send_complete_callback_context = NULL; wolfSSL_set_using_nonblock(tls_io_instance->ssl, 1); wolfSSL_SetIOSend(tls_io_instance->ssl_context, on_io_send); wolfSSL_SetIORecv(tls_io_instance->ssl_context, on_io_recv); wolfSSL_SetHsDoneCb(tls_io_instance->ssl, on_handshake_done, tls_io_instance); wolfSSL_SetIOWriteCtx(tls_io_instance->ssl, tls_io_instance); wolfSSL_SetIOReadCtx(tls_io_instance->ssl, tls_io_instance); tls_io_instance->tlsio_state = TLSIO_STATE_NOT_OPEN; result = 0; } } return result; }
int MqttSocket_Connect(MqttClient *client, const char* host, word16 port, int timeout_ms, int use_tls, MqttTlsCb cb) { int rc; /* Validate arguments */ if (client == NULL || client->net == NULL || client->net->connect == NULL) { return MQTT_CODE_ERROR_BAD_ARG; } /* Validate port */ if (port == 0) { port = (use_tls) ? MQTT_SECURE_PORT : MQTT_DEFAULT_PORT; } /* Connect to host */ rc = client->net->connect(client->net->context, host, port, timeout_ms); if (rc != 0) { return rc; } client->flags |= MQTT_CLIENT_FLAG_IS_CONNECTED; #ifdef ENABLE_MQTT_TLS if (use_tls) { /* Setup the WolfSSL library */ wolfSSL_Init(); /* Issue callback to allow setup of the wolfSSL_CTX and cert verification settings */ rc = SSL_SUCCESS; if (cb) { rc = cb(client); } if (rc == SSL_SUCCESS) { /* Create and initialize the WOLFSSL_CTX structure */ if (client->tls.ctx == NULL) { /* Use defaults */ client->tls.ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method()); if (client->tls.ctx) { wolfSSL_CTX_set_verify(client->tls.ctx, SSL_VERIFY_NONE, 0); } } if (client->tls.ctx) { /* Seutp the async IO callbacks */ wolfSSL_SetIORecv(client->tls.ctx, MqttSocket_TlsSocketReceive); wolfSSL_SetIOSend(client->tls.ctx, MqttSocket_TlsSocketSend); client->tls.ssl = wolfSSL_new(client->tls.ctx); if (client->tls.ssl) { wolfSSL_SetIOReadCtx(client->tls.ssl, (void *)client); wolfSSL_SetIOWriteCtx(client->tls.ssl, (void *)client); rc = wolfSSL_connect(client->tls.ssl); if (rc == SSL_SUCCESS) { client->flags |= MQTT_CLIENT_FLAG_IS_TLS; rc = MQTT_CODE_SUCCESS; } } else { #ifndef WOLFMQTT_NO_STDIO printf("MqttSocket_TlsConnect: wolfSSL_new error!\n"); #endif rc = -1; } } else { #ifndef WOLFMQTT_NO_STDIO printf("MqttSocket_TlsConnect: wolfSSL_CTX_new error!\n"); #endif rc = -1; } } else { #ifndef WOLFMQTT_NO_STDIO printf("MqttSocket_TlsConnect: TLS callback error!\n"); #endif rc = -1; } /* Handle error case */ if (rc) { #ifndef WOLFMQTT_NO_STDIO const char* errstr = NULL; int errnum = 0; if (client->tls.ssl) { errnum = wolfSSL_get_error(client->tls.ssl, 0); errstr = wolfSSL_ERR_reason_error_string(errnum); } printf("MqttSocket_TlsConnect Error %d: Num %d, %s\n", rc, errnum, errstr); #endif /* Make sure we cleanup on error */ MqttSocket_Disconnect(client); rc = MQTT_CODE_ERROR_TLS_CONNECT; } } #else (void)cb; #endif /* ENABLE_MQTT_TLS */ #ifdef WOLFMQTT_DEBUG_SOCKET printf("MqttSocket_Connect: Rc=%d\n", rc); #endif /* Check for error */ if (rc < 0) { rc = MQTT_CODE_ERROR_NETWORK; } return rc; }
int main (int argc, char** argv) { /* standard variables used in a dtls client */ int ret = 0, err; int sockfd = -1; WOLFSSL* ssl = NULL; WOLFSSL_CTX* ctx = NULL; const char* ca_cert = "../certs/ca-cert.pem"; char buff[MSGLEN]; int buffLen; SharedDtls shared; /* Program argument checking */ if (argc != 2) { printf("usage: udpcli <IP address>\n"); return 1; } /* Code for handling signals */ struct sigaction act, oact; act.sa_handler = sig_handler; sigemptyset(&act.sa_mask); act.sa_flags = 0; sigaction(SIGINT, &act, &oact); wolfSSL_Debugging_ON(); /* Initialize wolfSSL before assigning ctx */ wolfSSL_Init(); if ( (ctx = wolfSSL_CTX_new(wolfDTLSv1_2_client_method())) == NULL) { fprintf(stderr, "wolfSSL_CTX_new error.\n"); goto exit; } /* Register callbacks */ wolfSSL_CTX_SetIORecv(ctx, my_IORecv); wolfSSL_CTX_SetIOSend(ctx, my_IOSend); /* Load CA certificates into ctx variable */ if (wolfSSL_CTX_load_verify_locations(ctx, ca_cert, 0) != SSL_SUCCESS) { fprintf(stderr, "Error loading %s, please check the file.\n", ca_cert); goto exit; } /* Assign ssl variable */ ssl = wolfSSL_new(ctx); if (ssl == NULL) { printf("unable to get ssl object"); goto exit; } memset(&shared, 0, sizeof(shared)); shared.ssl = ssl; /* servAddr setup */ shared.servSz = sizeof(shared.servAddr); shared.servAddr.sin_family = AF_INET; shared.servAddr.sin_port = htons(SERV_PORT); if (inet_pton(AF_INET, argv[1], &shared.servAddr.sin_addr) < 1) { printf("Error and/or invalid IP address"); goto exit; } if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { printf("cannot create a socket."); goto exit; } shared.sd = sockfd; wolfSSL_SetIOWriteCtx(ssl, &shared); wolfSSL_SetIOReadCtx(ssl, &shared); if (wolfSSL_connect(ssl) != SSL_SUCCESS) { err = wolfSSL_get_error(ssl, 0); printf("err = %d, %s\n", err, wolfSSL_ERR_reason_error_string(err)); printf("SSL_connect failed\n"); goto exit; } /**************************************************************************/ /* Code for sending datagram to server */ if (fgets(buff, sizeof(buff), stdin) != NULL) { /* Send buffer to the server */ buffLen = strlen(buff); if (( wolfSSL_write(ssl, buff, buffLen)) != buffLen) { err = wolfSSL_get_error(ssl, 0); if (err != SSL_ERROR_WANT_WRITE) { printf("err = %d, %s\n", err, wolfSSL_ERR_reason_error_string(err)); printf("SSL_write failed\n"); goto exit; } } /* Receive message from server */ ret = wolfSSL_read(ssl, buff, sizeof(buff)-1); if (ret < 0) { err = wolfSSL_get_error(ssl, 0); if (err != SSL_ERROR_WANT_READ) { printf("err = %d, %s\n", err, wolfSSL_ERR_reason_error_string(err)); printf("SSL_read failed\n"); goto exit; } } buffLen = ret; ret = 0; /* Add a terminating character to the generic server message */ buff[buffLen] = '\0'; fputs(buff, stdout); } /* End code for sending datagram to server */ /**************************************************************************/ exit: /* Housekeeping */ if (ssl) { wolfSSL_shutdown(ssl); wolfSSL_free(ssl); } if (sockfd != -1) { close(sockfd); } if (ctx) { wolfSSL_CTX_free(ctx); } wolfSSL_Cleanup(); return ret; }