Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added client-tls-http.c example #353

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
176 changes: 176 additions & 0 deletions tls/client-tls-http.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
/* client-tls-http.c
*
* Copyright (C) 2006-2025 wolfSSL Inc.
*
* This file is part of wolfSSL. (formerly known as CyaSSL)
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/

/* the usual suspects */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>

/* socket includes */
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <unistd.h>

/* wolfSSL */
#include <wolfssl/options.h>
#include <wolfssl/ssl.h>

#define DEFAULT_PORT 443

static const char kHttpGetMsg[] = "GET /index.html HTTP/1.0\r\n\r\n";

int main(int argc, char** argv)
{
int sockfd;
struct addrinfo hints, *res;
char buff[256];
size_t len;
int ret;

/* declare wolfSSL objects */
WOLFSSL_CTX* ctx;
WOLFSSL* ssl;

/* Check for proper calling convention */
if (argc != 3) {
printf("usage: %s <SERVER_NAME> <CERT_FILE>\n", argv[0]);
return 0;
}

/* Initialize the addrinfo struct with zero */
memset(&hints, 0, sizeof(hints));

/* Fill in the addrinfo struct */
hints.ai_family = AF_INET; /* using IPv4 */
hints.ai_socktype = SOCK_STREAM; /* means TCP socket */
char *service = "https"; /* using https */

/* Get a Domain IP address */
if(getaddrinfo(argv[1], service, &hints, &res) != 0){
fprintf(stderr, "ERROR: failed to get the server ip\n");
ret = -1;
goto end;
}

/* 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");
ret = -1;
goto end;
}
/* Free a list pointed by res */
freeaddrinfo(res);

/* Connect to the server */
if ((ret = connect(sockfd, res->ai_addr, res->ai_addrlen)) == -1) {
fprintf(stderr, "ERROR: failed to connect\n");
goto end;
}

/*---------------------------------*/
/* Start of wolfSSL initialization and configuration */
/*---------------------------------*/
/* Initialize wolfSSL */
if ((ret = wolfSSL_Init()) != WOLFSSL_SUCCESS) {
fprintf(stderr, "ERROR: Failed to initialize the library\n");
goto socket_cleanup;
}

/* Create and initialize WOLFSSL_CTX */
if ((ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method())) == NULL) {
fprintf(stderr, "ERROR: failed to create WOLFSSL_CTX\n");
ret = -1;
goto socket_cleanup;
}

/* Load client certificates into WOLFSSL_CTX */
if ((ret = wolfSSL_CTX_load_verify_locations(ctx, argv[2], NULL))
!= SSL_SUCCESS) {
fprintf(stderr, "ERROR: failed to load %s, please check the file.\n",
argv[2]);
goto ctx_cleanup;
}

/* Create a WOLFSSL object */
if ((ssl = wolfSSL_new(ctx)) == NULL) {
fprintf(stderr, "ERROR: failed to create WOLFSSL object\n");
ret = -1;
goto ctx_cleanup;
}

/* Attach wolfSSL to the socket */
if ((ret = wolfSSL_set_fd(ssl, sockfd)) != WOLFSSL_SUCCESS) {
fprintf(stderr, "ERROR: Failed to set the file descriptor\n");
goto cleanup;
}

/* Connect to wolfSSL on the server side */
if ((ret = wolfSSL_connect(ssl)) != SSL_SUCCESS) {
fprintf(stderr, "ERROR: failed to connect to wolfSSL\n");
goto cleanup;
}

/* kHttpGetMsg length */
len = strnlen(kHttpGetMsg, sizeof(kHttpGetMsg));

/* Send HTTP GET request to the server */
printf("Sending HTTP GET request ...\n");
if ((ret = wolfSSL_write(ssl, kHttpGetMsg, len)) != len) {
fprintf(stderr, "ERROR: failed to send HTTP GET request.\n");
fprintf(stderr, "%d bytes of %d bytes were sent", ret, (int) len);
goto cleanup;
}

/* Read the server data into our buff array */
memset(buff, 0, sizeof(buff));
if ((ret = wolfSSL_read(ssl, buff, sizeof(buff) - 1)) == -1) {
fprintf(stderr, "ERROR: failed to read\n");
goto cleanup;
}

/* Print to stdout any data the server sends */
printf("Server: %s\n", buff);

/* Bidirectional shutdown */
while (wolfSSL_shutdown(ssl) == SSL_SHUTDOWN_NOT_DONE) {
printf("Shutdown not complete\n");
}

printf("Shutdown complete\n");

ret = 0;

/* Cleanup and return */
cleanup:
wolfSSL_free(ssl); /* Free the wolfSSL object */
ctx_cleanup:
wolfSSL_CTX_free(ctx); /* Free the wolfSSL context object */
wolfSSL_Cleanup(); /* Cleanup the wolfSSL environment */
socket_cleanup:
close(sockfd); /* Close the connection to the server */
end:
return ret; /* Return reporting a success */
}