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 2 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
182 changes: 182 additions & 0 deletions tls/client-tls-http.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
/* client-tls-http.c
*
* Copyright (C) 2006-2022 wolfSSL Inc.
kojo1 marked this conversation as resolved.
Show resolved Hide resolved
*
* 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>
kojo1 marked this conversation as resolved.
Show resolved Hide resolved
#include <arpa/inet.h>
#include <netinet/in.h>
#include <unistd.h>

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

#define DEFAULT_PORT 443


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));
kojo1 marked this conversation as resolved.
Show resolved Hide resolved

/* 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){
kojo1 marked this conversation as resolved.
Show resolved Hide resolved
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");
printf("%d\n",ret);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure we need this printf for ret. On failure, wolfSSL_connect will just return SSL_FAILURE. If you want to print the specific error, please call wolfSSL_get_error(ssl, ret), then print out the return of that function.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deleted unnecessary debug printf at 446f0a7.

goto cleanup;
}

/* Get a message for the server from stdin */
printf("Message for server: ");
kojo1 marked this conversation as resolved.
Show resolved Hide resolved
memset(buff, 0, sizeof(buff));
if (fgets(buff, sizeof(buff), stdin) == NULL) {
fprintf(stderr, "ERROR: failed to get message for server\n");
ret = -1;
goto cleanup;
}
len = strnlen(buff, sizeof(buff));

/* Send the message to the server */
if ((ret = wolfSSL_write(ssl, buff, len)) != len) {
fprintf(stderr, "ERROR: failed to write entire message\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 */
}