1+ /* client-tls-http.c
2+ *
3+ * Copyright (C) 2006-2022 wolfSSL Inc.
4+ *
5+ * This file is part of wolfSSL. (formerly known as CyaSSL)
6+ *
7+ * wolfSSL is free software; you can redistribute it and/or modify
8+ * it under the terms of the GNU General Public License as published by
9+ * the Free Software Foundation; either version 2 of the License, or
10+ * (at your option) any later version.
11+ *
12+ * wolfSSL is distributed in the hope that it will be useful,
13+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+ * GNU General Public License for more details.
16+ *
17+ * You should have received a copy of the GNU General Public License
18+ * along with this program; if not, write to the Free Software
19+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
20+ */
21+
22+ /* the usual suspects */
23+ #include <stdlib.h>
24+ #include <stdio.h>
25+ #include <string.h>
26+ #include <stdint.h>
27+ #include <sys/types.h>
28+
29+ /* socket includes */
30+ #include <sys/socket.h>
31+ #include <netdb.h>
32+ #include <arpa/inet.h>
33+ #include <netinet/in.h>
34+ #include <unistd.h>
35+
36+ /* wolfSSL */
37+ #include <wolfssl/options.h>
38+ #include <wolfssl/ssl.h>
39+
40+ #define DEFAULT_PORT 443
41+
42+
43+ int main (int argc , char * * argv )
44+ {
45+ int sockfd ;
46+ struct sockaddr_in servAddr ;
47+ struct in_addr addr ;
48+ struct addrinfo hints ,* res ;
49+ char buff [256 ];
50+ size_t len ;
51+ int ret ;
52+
53+ /* declare wolfSSL objects */
54+ WOLFSSL_CTX * ctx ;
55+ WOLFSSL * ssl ;
56+
57+ /* Check for proper calling convention */
58+ if (argc != 3 ) {
59+ printf ("usage: %s <SERVER_NAME> <CERT_FILE>\n" , argv [0 ]);
60+ return 0 ;
61+ }
62+
63+ /* Initialize the addrinfo struct with zero */
64+ memset (& hints ,0 ,sizeof (hints ));
65+
66+ /* Fill in the addrinfo struct */
67+ hints .ai_family = AF_INET ; /* using IPv4 */
68+ hints .ai_socktype = SOCK_STREAM ; /* means TCP socket */
69+ char * service = "https" ; /* using https */
70+
71+ /* Get a Domain IP address */
72+ if (getaddrinfo (argv [1 ],service ,& hints ,& res ) != 0 ){
73+ fprintf (stderr , "ERROR: failed to get the server ip\n" );
74+ ret = -1 ;
75+ goto end ;
76+ }
77+
78+ /* Assign server IP to in_addr struct */
79+ addr .s_addr = ((struct sockaddr_in * )(res -> ai_addr ))-> sin_addr .s_addr ;
80+
81+ /* Free a list pointed by res */
82+ freeaddrinfo (res );
83+
84+ /* Create a socket that uses an internet IPv4 address,
85+ * Sets the socket to be stream based (TCP),
86+ * 0 means choose the default protocol. */
87+ if ((sockfd = socket (AF_INET , SOCK_STREAM , 0 )) == -1 ) {
88+ fprintf (stderr , "ERROR: failed to create the socket\n" );
89+ ret = -1 ;
90+ goto end ;
91+ }
92+
93+ /* Initialize the server address struct with zeros */
94+ memset (& servAddr , 0 , sizeof (servAddr ));
95+
96+ /* Fill in the server address */
97+ servAddr .sin_family = AF_INET ; /* using IPv4 */
98+ servAddr .sin_port = htons (DEFAULT_PORT ); /* on DEFAULT_PORT */
99+
100+ /* Get the server IPv4 address using adderinfo struct
101+ * convert bytes to const char* via inet_ntoa() */
102+ if (inet_pton (AF_INET , inet_ntoa (addr ), & servAddr .sin_addr ) != 1 ) {
103+ fprintf (stderr , "ERROR: invalid address\n" );
104+ ret = -1 ;
105+ goto end ;
106+ }
107+
108+ /* Connect to the server */
109+ if ((ret = connect (sockfd , (struct sockaddr * ) & servAddr , sizeof (servAddr )))
110+ == -1 ) {
111+ fprintf (stderr , "ERROR: failed to connect\n" );
112+ goto end ;
113+ }
114+
115+
116+
117+ /*---------------------------------*/
118+ /* Start of wolfSSL initialization and configuration */
119+ /*---------------------------------*/
120+ /* Initialize wolfSSL */
121+ if ((ret = wolfSSL_Init ()) != WOLFSSL_SUCCESS ) {
122+ fprintf (stderr , "ERROR: Failed to initialize the library\n" );
123+ goto socket_cleanup ;
124+ }
125+
126+ /* Create and initialize WOLFSSL_CTX */
127+ if ((ctx = wolfSSL_CTX_new (wolfTLSv1_2_client_method ())) == NULL ) {
128+ fprintf (stderr , "ERROR: failed to create WOLFSSL_CTX\n" );
129+ ret = -1 ;
130+ goto socket_cleanup ;
131+ }
132+
133+ /* Load client certificates into WOLFSSL_CTX */
134+ if ((ret = wolfSSL_CTX_load_verify_locations (ctx , argv [2 ], NULL ))
135+ != SSL_SUCCESS ) {
136+ fprintf (stderr , "ERROR: failed to load %s, please check the file.\n" ,
137+ argv [2 ]);
138+ goto ctx_cleanup ;
139+ }
140+
141+ /* Create a WOLFSSL object */
142+ if ((ssl = wolfSSL_new (ctx )) == NULL ) {
143+ fprintf (stderr , "ERROR: failed to create WOLFSSL object\n" );
144+ ret = -1 ;
145+ goto ctx_cleanup ;
146+ }
147+
148+ /* Attach wolfSSL to the socket */
149+ if ((ret = wolfSSL_set_fd (ssl , sockfd )) != WOLFSSL_SUCCESS ) {
150+ fprintf (stderr , "ERROR: Failed to set the file descriptor\n" );
151+ goto cleanup ;
152+ }
153+
154+ /* Connect to wolfSSL on the server side */
155+ if ((ret = wolfSSL_connect (ssl )) != SSL_SUCCESS ) {
156+ fprintf (stderr , "ERROR: failed to connect to wolfSSL\n" );
157+ printf ("%d\n" ,ret );
158+ goto cleanup ;
159+ }
160+
161+ /* Get a message for the server from stdin */
162+ printf ("Message for server: " );
163+ memset (buff , 0 , sizeof (buff ));
164+ if (fgets (buff , sizeof (buff ), stdin ) == NULL ) {
165+ fprintf (stderr , "ERROR: failed to get message for server\n" );
166+ ret = -1 ;
167+ goto cleanup ;
168+ }
169+ len = strnlen (buff , sizeof (buff ));
170+
171+ /* Send the message to the server */
172+ if ((ret = wolfSSL_write (ssl , buff , len )) != len ) {
173+ fprintf (stderr , "ERROR: failed to write entire message\n" );
174+ fprintf (stderr , "%d bytes of %d bytes were sent" , ret , (int ) len );
175+ goto cleanup ;
176+ }
177+
178+ /* Read the server data into our buff array */
179+ memset (buff , 0 , sizeof (buff ));
180+ if ((ret = wolfSSL_read (ssl , buff , sizeof (buff )- 1 )) == -1 ) {
181+ fprintf (stderr , "ERROR: failed to read\n" );
182+ goto cleanup ;
183+ }
184+
185+ /* Print to stdout any data the server sends */
186+ printf ("Server: %s\n" , buff );
187+
188+ /* Bidirectional shutdown */
189+ while (wolfSSL_shutdown (ssl ) == SSL_SHUTDOWN_NOT_DONE ) {
190+ printf ("Shutdown not complete\n" );
191+ }
192+
193+ printf ("Shutdown complete\n" );
194+
195+ ret = 0 ;
196+
197+ /* Cleanup and return */
198+ cleanup :
199+ wolfSSL_free (ssl ); /* Free the wolfSSL object */
200+ ctx_cleanup :
201+ wolfSSL_CTX_free (ctx ); /* Free the wolfSSL context object */
202+ wolfSSL_Cleanup (); /* Cleanup the wolfSSL environment */
203+ socket_cleanup :
204+ close (sockfd ); /* Close the connection to the server */
205+ end :
206+ return ret ; /* Return reporting a success */
207+ }
0 commit comments