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 variablegojimmypi-patch-1
parent
452ac9e109
commit
f155379142
|
@ -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
|
||||
|
|
|
@ -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-----
|
|
@ -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
|
|
@ -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
|
||||
```
|
|
@ -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
|
|
@ -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,
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue