add example of how to use HPKE with all options (#356)

* add example of how to use HPKE with all options

* add example of how to use ech with a public server run by cloudflare

* move ech example to tls directory, update hpke instructions

* update client-ech based on pr comments

* update ech test to handle read error

* update hpke_test to match changed function signature

* add root CA cert for ech-client example, fix

various problems based on pr comments

* clear out variable for example

* remove unused variable
gojimmypi-patch-1
John Bland 2023-07-10 17:25:20 -04:00 committed by GitHub
parent 452ac9e109
commit f155379142
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 514 additions and 3 deletions

3
.gitignore vendored
View File

@ -105,11 +105,11 @@ android/wolfssljni-ndk-sample/proguard-project.txt
/tls/server-tls-uart
/tls/server-tls-verifycallback
/tls/server-tls-writedup
/tls/client-ech
/tls/client-ech-local
/tls/server-ech-local
crypto/3des/3des-file-encrypt
crypto/aes/aes-file-encrypt
crypto/aes/aescfb-file-encrypt
@ -238,6 +238,7 @@ pk/ed448/ed448_pub
pk/ed448/ed448_keys
pk/ed448/*.der
pk/curve25519/curve25519_test
pk/hpke/hpke_test
embedded/tls-client-server
embedded/tls-server-size

View File

@ -0,0 +1,75 @@
-----BEGIN CERTIFICATE-----
MIIFTDCCBPKgAwIBAgIQA5JQzuqRJy3ljWStInKQTjAKBggqhkjOPQQDAjBKMQsw
CQYDVQQGEwJVUzEZMBcGA1UEChMQQ2xvdWRmbGFyZSwgSW5jLjEgMB4GA1UEAxMX
Q2xvdWRmbGFyZSBJbmMgRUNDIENBLTMwHhcNMjMwMzA0MDAwMDAwWhcNMjQwMzAz
MjM1OTU5WjB1MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQG
A1UEBxMNU2FuIEZyYW5jaXNjbzEZMBcGA1UEChMQQ2xvdWRmbGFyZSwgSW5jLjEe
MBwGA1UEAxMVc25pLmNsb3VkZmxhcmVzc2wuY29tMFkwEwYHKoZIzj0CAQYIKoZI
zj0DAQcDQgAE1RXa9mRvotUaWVPtrpuTGJGAawyYYNRRkK2czd3xEadvstkDYygE
vE+xcpZFPPZQDkBlAAfvv8j2PNJ6f1nRN6OCA40wggOJMB8GA1UdIwQYMBaAFKXO
N+rrsHUOlGeItEX62SQQh5YfMB0GA1UdDgQWBBRekDZj95YFBGStBKQhAaqPvUhb
AzBQBgNVHREESTBHghVzbmkuY2xvdWRmbGFyZXNzbC5jb22CFWNyeXB0by5jbG91
ZGZsYXJlLmNvbYIXKi5jcnlwdG8uY2xvdWRmbGFyZS5jb20wDgYDVR0PAQH/BAQD
AgeAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjB7BgNVHR8EdDByMDeg
NaAzhjFodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vQ2xvdWRmbGFyZUluY0VDQ0NB
LTMuY3JsMDegNaAzhjFodHRwOi8vY3JsNC5kaWdpY2VydC5jb20vQ2xvdWRmbGFy
ZUluY0VDQ0NBLTMuY3JsMD4GA1UdIAQ3MDUwMwYGZ4EMAQICMCkwJwYIKwYBBQUH
AgEWG2h0dHA6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzB2BggrBgEFBQcBAQRqMGgw
JAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBABggrBgEFBQcw
AoY0aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0Nsb3VkZmxhcmVJbmNFQ0ND
QS0zLmNydDAMBgNVHRMBAf8EAjAAMIIBgQYKKwYBBAHWeQIEAgSCAXEEggFtAWsA
dwDuzdBk1dsazsVct520zROiModGfLzs3sNRSFlGcR+1mwAAAYaqF9guAAAEAwBI
MEYCIQCiv+PHjCl3yCBIN1geIV6nM8JVsdMDz+bi3fC0c5iSAAIhAN1bPyq66wKn
kXI9P85jRI++sCieQ8zS4KBN/yL19DsfAHcAc9meiRtMlnigIH1HneayxhzQUV5x
GSqMa4AQesF3crUAAAGGqhfYmwAABAMASDBGAiEA/rhcMmQfwxP2VpbyYpFPu5Sx
n/0Jc+/PMDSRqpst6QYCIQCuaV7aGhmR/PbE0SyQ5Y81IUPew23t5cWgQZIDLddU
GgB3AEiw42vapkc0D+VqAvqdMOscUgHLVt0sgdm7v6s52IRzAAABhqoX2GoAAAQD
AEgwRgIhAI58QAtsPkKun97n+4/gpHNqUQrC9GIyxzTTeu1quBvSAiEA1t0uZKdn
6KO27mCPHjtR8DUkhE27U2vhUICyuJGgVokwCgYIKoZIzj0EAwIDSAAwRQIhAPdp
FGP8NBnFfOe0w0vRmNwRxujz2eXnMk2LrPKqUavGAiANK5eY+3XClhMvDTTJkhzh
PEAwQeEKtlCRDESaSxItJw==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDzTCCArWgAwIBAgIQCjeHZF5ftIwiTv0b7RQMPDANBgkqhkiG9w0BAQsFADBa
MQswCQYDVQQGEwJJRTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJl
clRydXN0MSIwIAYDVQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTIw
MDEyNzEyNDgwOFoXDTI0MTIzMTIzNTk1OVowSjELMAkGA1UEBhMCVVMxGTAXBgNV
BAoTEENsb3VkZmxhcmUsIEluYy4xIDAeBgNVBAMTF0Nsb3VkZmxhcmUgSW5jIEVD
QyBDQS0zMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEua1NZpkUC0bsH4HRKlAe
nQMVLzQSfS2WuIg4m4Vfj7+7Te9hRsTJc9QkT+DuHM5ss1FxL2ruTAUJd9NyYqSb
16OCAWgwggFkMB0GA1UdDgQWBBSlzjfq67B1DpRniLRF+tkkEIeWHzAfBgNVHSME
GDAWgBTlnVkwgkdYzKz6CFQ2hns6tQRN8DAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0l
BBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMBIGA1UdEwEB/wQIMAYBAf8CAQAwNAYI
KwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5j
b20wOgYDVR0fBDMwMTAvoC2gK4YpaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL09t
bmlyb290MjAyNS5jcmwwbQYDVR0gBGYwZDA3BglghkgBhv1sAQEwKjAoBggrBgEF
BQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzALBglghkgBhv1sAQIw
CAYGZ4EMAQIBMAgGBmeBDAECAjAIBgZngQwBAgMwDQYJKoZIhvcNAQELBQADggEB
AAUkHd0bsCrrmNaF4zlNXmtXnYJX/OvoMaJXkGUFvhZEOFp3ArnPEELG4ZKk40Un
+ABHLGioVplTVI+tnkDB0A+21w0LOEhsUCxJkAZbZB2LzEgwLt4I4ptJIsCSDBFe
lpKU1fwg3FZs5ZKTv3ocwDfjhUkV+ivhdDkYD7fa86JXWGBPzI6UAPxGezQxPk1H
goE6y/SJXQ7vTQ1unBuCJN0yJV0ReFEQPaA1IwQvZW+cwdFD19Ae8zFnWSfda9J1
CZMRJCQUzym+5iPDuI9yP+kHyCREU3qzuWFloUwOxkgAyXVjBYdwRVKD05WdRerw
6DEdfgkfCv4+3ao8XnTSrLE=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ
RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD
VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX
DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y
ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy
VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr
mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr
IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK
mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu
XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy
dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye
jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1
BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3
DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92
9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx
jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0
Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz
ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS
R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp
-----END CERTIFICATE-----

12
pk/hpke/Makefile 100644
View File

@ -0,0 +1,12 @@
CC=gcc
LIB_PATH=/usr/local
CFLAGS= -I$(LIB_PATH)/include -Wall
LIBS= -L$(LIB_PATH)/lib -lwolfssl
hpke_test: hpke_test.o
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
.PHONY: clean
clean:
rm -f *.o hpke_test

View File

@ -0,0 +1,9 @@
# HPKE Example with all supported options
To build wolfSSL for this example run `./configure --enable-hpke --enable-aesgcm --enable-curve25519 --enable-ecc && make && sudo make install`
```sh
make
./hpke_test
HPKE test success
```

163
pk/hpke/hpke_test.c 100644
View File

@ -0,0 +1,163 @@
/* hpke_test.c
*
* Copyright (C) 2022 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
*/
#include <wolfssl/options.h>
#include <wolfssl/wolfcrypt/settings.h>
#include <wolfssl/wolfcrypt/hpke.h>
#include <wolfssl/wolfcrypt/random.h>
#include <wolfssl/wolfcrypt/error-crypt.h>
#if defined(HAVE_HPKE) && (defined(HAVE_ECC) || defined(HAVE_CURVE25519)) && \
defined(HAVE_AESGCM)
int test_hpke(Hpke* hpke)
{
int ret = 0;
int rngRet = 0;
WC_RNG rng[1];
const char* start_text = "this is a test";
const char* info_text = "info";
const char* aad_text = "aad";
byte ciphertext[MAX_HPKE_LABEL_SZ];
byte plaintext[MAX_HPKE_LABEL_SZ];
void* receiverKey = NULL;
void* ephemeralKey = NULL;
byte pubKey[HPKE_Npk_MAX]; /* public key */
word16 pubKeySz = (word16)sizeof(pubKey);
rngRet = ret = wc_InitRng(rng);
if (ret != 0)
return ret;
/* generate the keys */
if (ret == 0)
ret = wc_HpkeGenerateKeyPair(hpke, &ephemeralKey, rng);
if (ret == 0)
ret = wc_HpkeGenerateKeyPair(hpke, &receiverKey, rng);
/* seal */
if (ret == 0)
ret = wc_HpkeSealBase(hpke, ephemeralKey, receiverKey,
(byte*)info_text, (word32)XSTRLEN(info_text),
(byte*)aad_text, (word32)XSTRLEN(aad_text),
(byte*)start_text, (word32)XSTRLEN(start_text),
ciphertext);
/* export ephemeral key */
if (ret == 0)
ret = wc_HpkeSerializePublicKey(hpke, ephemeralKey, pubKey, &pubKeySz);
/* open with exported ephemeral key */
if (ret == 0)
ret = wc_HpkeOpenBase(hpke, receiverKey, pubKey, pubKeySz,
(byte*)info_text, (word32)XSTRLEN(info_text),
(byte*)aad_text, (word32)XSTRLEN(aad_text),
ciphertext, (word32)XSTRLEN(start_text),
plaintext);
if (ret == 0)
ret = XMEMCMP(plaintext, start_text, XSTRLEN(start_text));
if (ephemeralKey != NULL)
wc_HpkeFreeKey(hpke, hpke->kem, ephemeralKey, NULL);
if (receiverKey != NULL)
wc_HpkeFreeKey(hpke, hpke->kem, receiverKey, NULL);
if (rngRet == 0)
wc_FreeRng(rng);
return ret;
}
int main(void)
{
int ret = 0;
Hpke hpke[1];
#if defined(HAVE_ECC)
/* p256 */
ret = wc_HpkeInit(hpke, DHKEM_P256_HKDF_SHA256, HKDF_SHA256,
HPKE_AES_128_GCM, NULL);
if (ret != 0)
goto fail;
ret = test_hpke(hpke);
if (ret != 0)
goto fail;
/* p384 */
ret = wc_HpkeInit(hpke, DHKEM_P384_HKDF_SHA384, HKDF_SHA384,
HPKE_AES_128_GCM, NULL);
if (ret != 0)
goto fail;
ret = test_hpke(hpke);
if (ret != 0)
goto fail;
/* p521 */
ret = wc_HpkeInit(hpke, DHKEM_P521_HKDF_SHA512, HKDF_SHA512,
HPKE_AES_128_GCM, NULL);
if (ret != 0)
goto fail;
ret = test_hpke(hpke);
if (ret != 0)
goto fail;
#endif
#if defined(HAVE_CURVE25519)
/* test with curve25519 and aes256 */
ret = wc_HpkeInit(hpke, DHKEM_X25519_HKDF_SHA256, HKDF_SHA256,
HPKE_AES_256_GCM, NULL);
if (ret != 0)
goto fail;
ret = test_hpke(hpke);
if (ret != 0)
goto fail;
#endif
printf("HPKE test success\n");
return ret;
fail:
printf("HPKE test error %d: %s\n", ret, wc_GetErrorString(ret));
/* x448 and chacha20 are unimplemented */
return 1;
}
#else
int main(void)
{
printf("Please build wolfssl with ./configure --enable-hpke --enable-aesgcm --enable-curve25519 --enable-ecc\n");
return 0;
}
#endif

View File

@ -108,16 +108,18 @@ into.
2. [Client](#client-tls)
3. [Running](#run-tls)
4. [Using callbacks](#callback)
5. [Using callbacks](#callback)
1. [Running](#run-callback)
4. [Using ECC](#ecc)
6. [Using ECC](#ecc)
1. [Server](#server-ecc)
2. [Client](#client-ecc)
3. [Running](#run-ecc)
6. [Encrypted Client Hello](#ech)
## <a name="run">Running these examples</a>
@ -1335,6 +1337,47 @@ To generate your own cert text, see the [DER to C script](https://github.com/wol
<br />
## <a name="ech">Encrypted Client Hello</a>
Encrypted Client Hello (ECH) encrypts sensitive fields in the client hello step of the TLS handshake. The client-ech example connects to a cloudflare server that is setup to test different TLS options including ECH. To build wolfSSL for this ech example run `./configure --enable-ech && make && sudo make install`.
This test is successful if the cloudflare http response shows that `sni=encrypted`.
```sh
make
./client-ech
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Cache-Control: no-cache
Cf-Ray: 77c3e3e937c6b08e-ATL
Content-Type: text/plain
Expires: Thu, 01 Jan 1970 00:00:01 GMT
Server: cloudflare
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
Date: Mon, 19 Dec 2022 23:24:11 GMT
Transfer-Encoding: chunked
106
fl=507f46
h=crypto.cloudflare.com
ip=173.93.184.37
ts=1671492251.082
visit_scheme=https
uag=Mozilla/5.0 (X11; Linux x86_64; rv:105.0) Gecko/20100101 Firefox/105.0
colo=ATL
sliver=none
http=http/1.1
loc=US
tls=TLSv1.3
sni=encrypted
warp=off
gateway=off
kex=P-256
0
```
## Support
Please contact wolfSSL at support@wolfssl.com with any questions, bug fixes,

208
tls/client-ech.c 100644
View File

@ -0,0 +1,208 @@
/* client-ech.c
*
* Copyright (C) 2006-2022 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
*/
#include <wolfssl/options.h>
#include <wolfssl/wolfcrypt/settings.h>
#include <wolfssl/ssl.h>
#include <wolfssl/test.h>
#include <errno.h>
#define SERV_PORT 443
#define CERT_FILE "../certs/ech-client-cert.pem"
#define RDBUFF_LEN 512
#define ECHBUFF_LEN 256
#ifdef HAVE_ECH
int main(void)
{
int ret = 0;
byte rd_buf[RDBUFF_LEN];
int sockfd = -1;
WOLFSSL_CTX* ctx = NULL;
WOLFSSL* ssl = NULL;
WOLFSSL_METHOD* method;
struct sockaddr_in servAddr;
const char message[] =
"GET /cdn-cgi/trace/ HTTP/1.1\r\n"
"Host: crypto.cloudflare.com\r\n"
"User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:105.0) Gecko/20100101 Firefox/105.0\r\n"
"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8\r\n"
"Accept-Language: en-US,en;q=0.5\r\n"
"Referer: https://www.google.com/\r\n"
"DNT: 1\r\n"
"Connection: keep-alive\r\n"
"Upgrade-Insecure-Requests: 1\r\n"
"Sec-Fetch-Dest: document\r\n"
"Sec-Fetch-Mode: navigate\r\n"
"Sec-Fetch-Site: cross-site\r\n"
"Pragma: no-cache\r\n"
"Cache-Control: no-cache\r\n"
"\r\n";
const char ip_string[] = "162.159.137.85";
const char SNI[] = "crypto.cloudflare.com";
uint8_t ech_configs[ECHBUFF_LEN];
uint32_t ech_configs_len = ECHBUFF_LEN;
/* this first tls connection is only used to get the retry configs */
/* these configs can also be retrieved from DNS */
/* create and set up socket */
sockfd = socket(AF_INET, SOCK_STREAM, 0);
memset(&servAddr, 0, sizeof(servAddr));
servAddr.sin_family = AF_INET;
servAddr.sin_port = htons(SERV_PORT);
/* set the ip string to the cloudflare server */
servAddr.sin_addr.s_addr = inet_addr( ip_string );
/* connect to socket */
connect(sockfd, (struct sockaddr *) &servAddr, sizeof(servAddr));
/* initialize wolfssl library */
wolfSSL_Init();
method = wolfTLSv1_3_client_method(); /* use TLS v1.3 */
/* make new ssl context */
if ((ctx = wolfSSL_CTX_new(method)) == NULL) {
ret = 1;
goto cleanup;
}
/* set the server name we want to connect to */
ret = wolfSSL_CTX_UseSNI( ctx, WOLFSSL_SNI_HOST_NAME,
SNI, strlen(SNI) );
if (ret != WOLFSSL_SUCCESS) {
printf("wolfSSL_CTX_UseSNI error %d", ret);
goto ctx_clean;
}
/* make new wolfSSL struct */
if ((ssl = wolfSSL_new(ctx)) == NULL) {
printf("wolfSSL_new error");
ret = 1;
goto ctx_clean;
}
/* Add cert to ctx */
if ((ret = wolfSSL_CTX_load_verify_locations(ctx, CERT_FILE, 0)) !=
WOLFSSL_SUCCESS) {
printf("wolfSSL_CTX_load_verify_locations error %d", ret);
goto ssl_clean;
}
/* Connect wolfssl to the socket, server, then send message */
wolfSSL_set_fd(ssl, sockfd);
/* this connect will send a grease ech and get the retry configs back */
ret = wolfSSL_connect(ssl);
if (ret != WOLFSSL_SUCCESS) {
printf("%d %d\n", ret, wolfSSL_get_error(ssl, ret));
goto ssl_clean;
}
/* retrieve the retry configs sent by the server */
ret = wolfSSL_GetEchConfigs(ssl, ech_configs, &ech_configs_len);
if (ret != WOLFSSL_SUCCESS) {
printf("wolfSSL_GetEchConfigs error %d\n", ret);
goto ssl_clean;
}
/* frees all data before client termination */
wolfSSL_free(ssl);
close(sockfd);
ssl = NULL;
sockfd = -1;
/* now we create a new connection that will send the real ech */
/* create and set up socket */
sockfd = socket(AF_INET, SOCK_STREAM, 0);
memset(&servAddr, 0, sizeof(servAddr));
servAddr.sin_family = AF_INET;
servAddr.sin_port = htons(SERV_PORT);
/* set the ip string to the cloudflare server */
servAddr.sin_addr.s_addr = inet_addr( ip_string );
/* connect to socket */
connect(sockfd, (struct sockaddr *) &servAddr, sizeof(servAddr));
/* make new wolfSSL struct */
if ( (ssl = wolfSSL_new(ctx)) == NULL) {
printf("wolfSSL_new error");
ret = 1;
goto ctx_clean;
}
/* set the ech configs taken from dns */
ret = wolfSSL_SetEchConfigs(ssl, ech_configs, ech_configs_len);
if ( ret != WOLFSSL_SUCCESS ) {
printf("wolfSSL_SetEchConfigs error %d", ret);
goto ssl_clean;
}
/* Connect wolfssl to the socket, server, then send message */
wolfSSL_set_fd(ssl, sockfd);
/* this connect will send the real ech */
ret = wolfSSL_connect(ssl);
if (ret != WOLFSSL_SUCCESS) {
printf( "%d %d\n", ret, wolfSSL_get_error( ssl, ret ) );
goto ssl_clean;
}
wolfSSL_write(ssl, message, strlen(message));
do
{
ret = wolfSSL_read(ssl, rd_buf, RDBUFF_LEN);
if (ret <= 0)
break;
printf("%.*s", ret, rd_buf);
/* read until the chunk size is 0 */
} while (rd_buf[0] != '0');
ret = 0;
ssl_clean:
wolfSSL_free(ssl);
ssl = NULL;
close(sockfd);
sockfd = -1;
ctx_clean:
wolfSSL_CTX_free(ctx);
cleanup:
wolfSSL_Cleanup();
return ret;
}
#else
int main(void)
{
printf("Please build wolfssl with ./configure --enable-ech\n");
return 1;
}
#endif