1e1051a39Sopenharmony_ci/*
2e1051a39Sopenharmony_ci * Copyright 1998-2020 The OpenSSL Project Authors. All Rights Reserved.
3e1051a39Sopenharmony_ci *
4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License").  You may not use
5e1051a39Sopenharmony_ci * this file except in compliance with the License.  You can obtain a copy
6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at
7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html
8e1051a39Sopenharmony_ci */
9e1051a39Sopenharmony_ci
10e1051a39Sopenharmony_ci/*-
11e1051a39Sopenharmony_ci * A minimal program to do SSL to a passed host and port.
12e1051a39Sopenharmony_ci * It is actually using non-blocking IO but in a very simple manner
13e1051a39Sopenharmony_ci * sconnect host:port - it does a 'GET / HTTP/1.0'
14e1051a39Sopenharmony_ci *
15e1051a39Sopenharmony_ci * cc -I../../include sconnect.c -L../.. -lssl -lcrypto
16e1051a39Sopenharmony_ci */
17e1051a39Sopenharmony_ci#include <stdio.h>
18e1051a39Sopenharmony_ci#include <stdlib.h>
19e1051a39Sopenharmony_ci#include <unistd.h>
20e1051a39Sopenharmony_ci#include <string.h>
21e1051a39Sopenharmony_ci#include <errno.h>
22e1051a39Sopenharmony_ci#include <openssl/err.h>
23e1051a39Sopenharmony_ci#include <openssl/ssl.h>
24e1051a39Sopenharmony_ci
25e1051a39Sopenharmony_ci#define HOSTPORT "localhost:4433"
26e1051a39Sopenharmony_ci#define CAFILE "root.pem"
27e1051a39Sopenharmony_ci
28e1051a39Sopenharmony_ciint main(int argc, char *argv[])
29e1051a39Sopenharmony_ci{
30e1051a39Sopenharmony_ci    const char *hostport = HOSTPORT;
31e1051a39Sopenharmony_ci    const char *CAfile = CAFILE;
32e1051a39Sopenharmony_ci    const char *hostname;
33e1051a39Sopenharmony_ci    char *cp;
34e1051a39Sopenharmony_ci    BIO *out = NULL;
35e1051a39Sopenharmony_ci    char buf[1024 * 10], *p;
36e1051a39Sopenharmony_ci    SSL_CTX *ssl_ctx = NULL;
37e1051a39Sopenharmony_ci    SSL *ssl;
38e1051a39Sopenharmony_ci    BIO *ssl_bio;
39e1051a39Sopenharmony_ci    int i, len, off, ret = EXIT_FAILURE;
40e1051a39Sopenharmony_ci
41e1051a39Sopenharmony_ci    if (argc > 1)
42e1051a39Sopenharmony_ci        hostport = argv[1];
43e1051a39Sopenharmony_ci    if (argc > 2)
44e1051a39Sopenharmony_ci        CAfile = argv[2];
45e1051a39Sopenharmony_ci
46e1051a39Sopenharmony_ci#ifdef WATT32
47e1051a39Sopenharmony_ci    dbug_init();
48e1051a39Sopenharmony_ci    sock_init();
49e1051a39Sopenharmony_ci#endif
50e1051a39Sopenharmony_ci
51e1051a39Sopenharmony_ci    ssl_ctx = SSL_CTX_new(TLS_client_method());
52e1051a39Sopenharmony_ci
53e1051a39Sopenharmony_ci    /* Enable trust chain verification */
54e1051a39Sopenharmony_ci    SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, NULL);
55e1051a39Sopenharmony_ci    SSL_CTX_load_verify_locations(ssl_ctx, CAfile, NULL);
56e1051a39Sopenharmony_ci
57e1051a39Sopenharmony_ci    /* Lets make a SSL structure */
58e1051a39Sopenharmony_ci    ssl = SSL_new(ssl_ctx);
59e1051a39Sopenharmony_ci    SSL_set_connect_state(ssl);
60e1051a39Sopenharmony_ci
61e1051a39Sopenharmony_ci
62e1051a39Sopenharmony_ci    /* Use it inside an SSL BIO */
63e1051a39Sopenharmony_ci    ssl_bio = BIO_new(BIO_f_ssl());
64e1051a39Sopenharmony_ci    BIO_set_ssl(ssl_bio, ssl, BIO_CLOSE);
65e1051a39Sopenharmony_ci
66e1051a39Sopenharmony_ci    /* Lets use a connect BIO under the SSL BIO */
67e1051a39Sopenharmony_ci    out = BIO_new(BIO_s_connect());
68e1051a39Sopenharmony_ci    BIO_set_conn_hostname(out, hostport);
69e1051a39Sopenharmony_ci
70e1051a39Sopenharmony_ci    /* The BIO has parsed the host:port and even IPv6 literals in [] */
71e1051a39Sopenharmony_ci    hostname = BIO_get_conn_hostname(out);
72e1051a39Sopenharmony_ci    if (!hostname || SSL_set1_host(ssl, hostname) <= 0)
73e1051a39Sopenharmony_ci        goto err;
74e1051a39Sopenharmony_ci
75e1051a39Sopenharmony_ci    BIO_set_nbio(out, 1);
76e1051a39Sopenharmony_ci    out = BIO_push(ssl_bio, out);
77e1051a39Sopenharmony_ci
78e1051a39Sopenharmony_ci    p = "GET / HTTP/1.0\r\n\r\n";
79e1051a39Sopenharmony_ci    len = strlen(p);
80e1051a39Sopenharmony_ci
81e1051a39Sopenharmony_ci    off = 0;
82e1051a39Sopenharmony_ci    for (;;) {
83e1051a39Sopenharmony_ci        i = BIO_write(out, &(p[off]), len);
84e1051a39Sopenharmony_ci        if (i <= 0) {
85e1051a39Sopenharmony_ci            if (BIO_should_retry(out)) {
86e1051a39Sopenharmony_ci                fprintf(stderr, "write DELAY\n");
87e1051a39Sopenharmony_ci                sleep(1);
88e1051a39Sopenharmony_ci                continue;
89e1051a39Sopenharmony_ci            } else {
90e1051a39Sopenharmony_ci                goto err;
91e1051a39Sopenharmony_ci            }
92e1051a39Sopenharmony_ci        }
93e1051a39Sopenharmony_ci        off += i;
94e1051a39Sopenharmony_ci        len -= i;
95e1051a39Sopenharmony_ci        if (len <= 0)
96e1051a39Sopenharmony_ci            break;
97e1051a39Sopenharmony_ci    }
98e1051a39Sopenharmony_ci
99e1051a39Sopenharmony_ci    for (;;) {
100e1051a39Sopenharmony_ci        i = BIO_read(out, buf, sizeof(buf));
101e1051a39Sopenharmony_ci        if (i == 0)
102e1051a39Sopenharmony_ci            break;
103e1051a39Sopenharmony_ci        if (i < 0) {
104e1051a39Sopenharmony_ci            if (BIO_should_retry(out)) {
105e1051a39Sopenharmony_ci                fprintf(stderr, "read DELAY\n");
106e1051a39Sopenharmony_ci                sleep(1);
107e1051a39Sopenharmony_ci                continue;
108e1051a39Sopenharmony_ci            }
109e1051a39Sopenharmony_ci            goto err;
110e1051a39Sopenharmony_ci        }
111e1051a39Sopenharmony_ci        fwrite(buf, 1, i, stdout);
112e1051a39Sopenharmony_ci    }
113e1051a39Sopenharmony_ci
114e1051a39Sopenharmony_ci    ret = EXIT_SUCCESS;
115e1051a39Sopenharmony_ci    goto done;
116e1051a39Sopenharmony_ci
117e1051a39Sopenharmony_ci err:
118e1051a39Sopenharmony_ci    if (ERR_peek_error() == 0) { /* system call error */
119e1051a39Sopenharmony_ci        fprintf(stderr, "errno=%d ", errno);
120e1051a39Sopenharmony_ci        perror("error");
121e1051a39Sopenharmony_ci    } else {
122e1051a39Sopenharmony_ci        ERR_print_errors_fp(stderr);
123e1051a39Sopenharmony_ci    }
124e1051a39Sopenharmony_ci done:
125e1051a39Sopenharmony_ci    BIO_free_all(out);
126e1051a39Sopenharmony_ci    SSL_CTX_free(ssl_ctx);
127e1051a39Sopenharmony_ci    return ret;
128e1051a39Sopenharmony_ci}
129