To build the OpenSSL project's ECH feature branch:
-```bash
- cd $HOME/code
- git clone https://github.com/openssl/openssl
- cd openssl
- git checkout feature/ech
- ./config --libdir=lib --prefix=$HOME/code/openssl-local-inst
- ...stuff...
- make -j8
- ...more stuff...
- make install_sw
- ...a little bit of stuff...
+```sh
+cd $HOME/code
+git clone https://github.com/openssl/openssl
+cd openssl
+git checkout feature/ech
+./config --libdir=lib --prefix=$HOME/code/openssl-local-inst
+...stuff...
+make -j8
+...more stuff...
+make install_sw
+...a little bit of stuff...
```
To build curl ECH-enabled, making use of the above:
-```bash
- cd $HOME/code
- git clone https://github.com/curl/curl
- cd curl
- autoreconf -fi
- LDFLAGS="-Wl,-rpath,$HOME/code/openssl-local-inst/lib/" ./configure --with-ssl=$HOME/code/openssl-local-inst --enable-ech
- ...lots of output...
- WARNING: ECH HTTPSRR enabled but marked EXPERIMENTAL...
- make
- ...lots more output...
+```sh
+cd $HOME/code
+git clone https://github.com/curl/curl
+cd curl
+autoreconf -fi
+LDFLAGS="-Wl,-rpath,$HOME/code/openssl-local-inst/lib/" ./configure --with-ssl=$HOME/code/openssl-local-inst --enable-ech
+...lots of output...
+WARNING: ECH HTTPSRR enabled but marked EXPERIMENTAL...
+make
+...lots more output...
```
If you do not get that WARNING at the end of the ``configure`` command, then
curl supports using DoH for A/AAAA lookups so it was relatively easy to add
retrieval of HTTPS RRs in that situation. To use ECH and DoH together:
-```bash
- cd $HOME/code/curl
- LD_LIBRARY_PATH=$HOME/code/openssl ./src/curl --ech true --doh-url https://one.one.one.one/dns-query https://defo.ie/ech-check.php
- ...
- SSL_ECH_STATUS: success <img src="greentick-small.png" alt="good" /> <br/>
- ...
+```sh
+cd $HOME/code/curl
+LD_LIBRARY_PATH=$HOME/code/openssl ./src/curl --ech true --doh-url https://one.one.one.one/dns-query https://defo.ie/ech-check.php
+...
+SSL_ECH_STATUS: success <img src="greentick-small.png" alt="good" /> <br/>
+...
```
The output snippet above is within the HTML for the webpage, when things work.
The above works for these test sites:
-```bash
- https://defo.ie/ech-check.php
- https://draft-13.esni.defo.ie:8413/stats
- https://draft-13.esni.defo.ie:8414/stats
- https://crypto.cloudflare.com/cdn-cgi/trace
- https://tls-ech.dev
+```sh
+https://defo.ie/ech-check.php
+https://draft-13.esni.defo.ie:8413/stats
+https://draft-13.esni.defo.ie:8414/stats
+https://crypto.cloudflare.com/cdn-cgi/trace
+https://tls-ech.dev
```
The list above has 4 different server technologies, implemented by 3 different
To supply the ECHConfigList on the command line, you might need a bit of
cut-and-paste, e.g.:
-```bash
- dig +short https defo.ie
- 1 . ipv4hint=213.108.108.101 ech=AED+DQA8PAAgACD8WhlS7VwEt5bf3lekhHvXrQBGDrZh03n/LsNtAodbUAAEAAEAAQANY292ZXIuZGVmby5pZQAA ipv6hint=2a00:c6c0:0:116:5::10
+```sh
+dig +short https defo.ie
+1 . ipv4hint=213.108.108.101 ech=AED+DQA8PAAgACD8WhlS7VwEt5bf3lekhHvXrQBGDrZh03n/LsNtAodbUAAEAAEAAQANY292ZXIuZGVmby5pZQAA ipv6hint=2a00:c6c0:0:116:5::10
```
Then paste the base64 encoded ECHConfigList onto the curl command line:
-```bash
- LD_LIBRARY_PATH=$HOME/code/openssl ./src/curl --ech ecl:AED+DQA8PAAgACD8WhlS7VwEt5bf3lekhHvXrQBGDrZh03n/LsNtAodbUAAEAAEAAQANY292ZXIuZGVmby5pZQAA https://defo.ie/ech-check.php
- ...
- SSL_ECH_STATUS: success <img src="greentick-small.png" alt="good" /> <br/>
- ...
+```sh
+LD_LIBRARY_PATH=$HOME/code/openssl ./src/curl --ech ecl:AED+DQA8PAAgACD8WhlS7VwEt5bf3lekhHvXrQBGDrZh03n/LsNtAodbUAAEAAEAAQANY292ZXIuZGVmby5pZQAA https://defo.ie/ech-check.php
+...
+SSL_ECH_STATUS: success <img src="greentick-small.png" alt="good" /> <br/>
+...
```
The output snippet above is within the HTML for the webpage.
If you paste in the wrong ECHConfigList (it changes hourly for ``defo.ie``) you
should get an error like this:
-```bash
- LD_LIBRARY_PATH=$HOME/code/openssl ./src/curl -vvv --ech ecl:AED+DQA8yAAgACDRMQo+qYNsNRNj+vfuQfFIkrrUFmM4vogucxKj/4nzYgAEAAEAAQANY292ZXIuZGVmby5pZQAA https://defo.ie/ech-check.php
- ...
- * OpenSSL/3.3.0: error:0A00054B:SSL routines::ech required
- ...
+```sh
+LD_LIBRARY_PATH=$HOME/code/openssl ./src/curl -vvv --ech ecl:AED+DQA8yAAgACDRMQo+qYNsNRNj+vfuQfFIkrrUFmM4vogucxKj/4nzYgAEAAEAAQANY292ZXIuZGVmby5pZQAA https://defo.ie/ech-check.php
+...
+* OpenSSL/3.3.0: error:0A00054B:SSL routines::ech required
+...
```
There is a reason to want this command line option - for use before publishing
good value, via the ``retry_configs`` mechanism. You can see that value in
the verbose output, e.g.:
-```bash
- LD_LIBRARY_PATH=$HOME/code/openssl ./src/curl -vvv --ech ecl:AED+DQA8yAAgACDRMQo+qYNsNRNj+vfuQfFIkrrUFmM4vogucxKj/4nzYgAEAAEAAQANY292ZXIuZGVmby5pZQAA https://defo.ie/ech-check.php
- ...
+```sh
+LD_LIBRARY_PATH=$HOME/code/openssl ./src/curl -vvv --ech ecl:AED+DQA8yAAgACDRMQo+qYNsNRNj+vfuQfFIkrrUFmM4vogucxKj/4nzYgAEAAEAAQANY292ZXIuZGVmby5pZQAA https://defo.ie/ech-check.php
+...
* ECH: retry_configs AQD+DQA8DAAgACBvYqJy+Hgk33wh/ZLBzKSPgwxeop7gvojQzfASq7zeZQAEAAEAAQANY292ZXIuZGVmby5pZQAA/g0APEMAIAAgXkT5r4cYs8z19q5rdittyIX8gfQ3ENW4wj1fVoiJZBoABAABAAEADWNvdmVyLmRlZm8uaWUAAP4NADw2ACAAINXSE9EdXzEQIJZA7vpwCIQsWqsFohZARXChgPsnfI1kAAQAAQABAA1jb3Zlci5kZWZvLmllAAD+DQA8cQAgACASeiD5F+UoSnVoHvA2l1EifUVMFtbVZ76xwDqmMPraHQAEAAEAAQANY292ZXIuZGVmby5pZQAA
* ECH: retry_configs for defo.ie from cover.defo.ie, 319
- ...
+...
```
At that point, you could copy the base64 encoded value above and try again.
curl has various ways to configure default settings, e.g. in ``$HOME/.curlrc``,
so one can set the DoH URL and enable ECH that way:
-```bash
- cat ~/.curlrc
- doh-url=https://one.one.one.one/dns-query
- silent
- ech=true
+```sh
+cat ~/.curlrc
+doh-url=https://one.one.one.one/dns-query
+silent
+ech=true
```
Note that when you use the system's curl command (rather than our ECH-enabled
If you want to always use our OpenSSL build you can set ``LD_LIBRARY_PATH``
in the environment:
-```bash
- export LD_LIBRARY_PATH=$HOME/code/openssl
+```sh
+export LD_LIBRARY_PATH=$HOME/code/openssl
```
When you do the above, there can be a mismatch between OpenSSL versions
for applications that check that. A ``git push`` for example fails so you
should unset ``LD_LIBRARY_PATH`` before doing that or use a different shell.
-```bash
- git push
- OpenSSL version mismatch. Built against 30000080, you have 30200000
- ...
+```sh
+git push
+OpenSSL version mismatch. Built against 30000080, you have 30200000
+...
```
With all that setup as above the command line gets simpler:
-```bash
- ./src/curl https://defo.ie/ech-check.php
- ...
- SSL_ECH_STATUS: success <img src="greentick-small.png" alt="good" /> <br/>
- ...
+```sh
+./src/curl https://defo.ie/ech-check.php
+...
+SSL_ECH_STATUS: success <img src="greentick-small.png" alt="good" /> <br/>
+...
```
The ``--ech true`` option is opportunistic, so tries to do ECH but does not fail if
To build with cmake, assuming our ECH-enabled OpenSSL is as before:
-```bash
- cd $HOME/code
- git clone https://github.com/curl/curl
- cd curl
- mkdir build
- cd build
- cmake -DOPENSSL_ROOT_DIR=$HOME/code/openssl -DUSE_ECH=1 ..
- ...
- make
- ...
- [100%] Built target curl
+```sh
+cd $HOME/code
+git clone https://github.com/curl/curl
+cd curl
+mkdir build
+cd build
+cmake -DOPENSSL_ROOT_DIR=$HOME/code/openssl -DUSE_ECH=1 ..
+...
+make
+...
+[100%] Built target curl
```
The binary produced by the cmake build does not need any ECH-specific
BoringSSL is also supported by curl and also supports ECH, so to build
with that, instead of our ECH-enabled OpenSSL:
-```bash
- cd $HOME/code
- git clone https://boringssl.googlesource.com/boringssl
- cd boringssl
- cmake -DCMAKE_INSTALL_PREFIX:PATH=$HOME/code/boringssl/inst -DBUILD_SHARED_LIBS=1
- make
- ...
- make install
+```sh
+cd $HOME/code
+git clone https://boringssl.googlesource.com/boringssl
+cd boringssl
+cmake -DCMAKE_INSTALL_PREFIX:PATH=$HOME/code/boringssl/inst -DBUILD_SHARED_LIBS=1
+make
+...
+make install
```
Then:
-```bash
- cd $HOME/code
- git clone https://github.com/curl/curl
- cd curl
- autoreconf -fi
- LDFLAGS="-Wl,-rpath,$HOME/code/boringssl/inst/lib" ./configure --with-ssl=$HOME/code/boringssl/inst --enable-ech
- ...lots of output...
- WARNING: ECH HTTPSRR enabled but marked EXPERIMENTAL. Use with caution.
- make
+```sh
+cd $HOME/code
+git clone https://github.com/curl/curl
+cd curl
+autoreconf -fi
+LDFLAGS="-Wl,-rpath,$HOME/code/boringssl/inst/lib" ./configure --with-ssl=$HOME/code/boringssl/inst --enable-ech
+...lots of output...
+WARNING: ECH HTTPSRR enabled but marked EXPERIMENTAL. Use with caution.
+make
```
The BoringSSL/AWS-LC APIs are fairly similar to those in our ECH-enabled
wolfSSL also supports ECH and can be used by curl, so here's how:
-```bash
- cd $HOME/code
- git clone https://github.com/wolfSSL/wolfssl
- cd wolfssl
- ./autogen.sh
- ./configure --prefix=$HOME/code/wolfssl/inst --enable-ech --enable-debug --enable-opensslextra
- make
- make install
+```sh
+cd $HOME/code
+git clone https://github.com/wolfSSL/wolfssl
+cd wolfssl
+./autogen.sh
+./configure --prefix=$HOME/code/wolfssl/inst --enable-ech --enable-debug --enable-opensslextra
+make
+make install
```
The install prefix (``inst``) in the above causes wolfSSL to be installed there
``--enable-opensslextra`` turns out (after much faffing about;-) to be
important or else we get build problems with curl below.
-```bash
- cd $HOME/code
- git clone https://github.com/curl/curl
- cd curl
- autoreconf -fi
- ./configure --with-wolfssl=$HOME/code/wolfssl/inst --enable-ech
- make
+```sh
+cd $HOME/code
+git clone https://github.com/curl/curl
+cd curl
+autoreconf -fi
+./configure --with-wolfssl=$HOME/code/wolfssl/inst --enable-ech
+make
```
There are some known issues with the ECH implementation in wolfSSL:
Just a note to self as remembering this is a nuisance:
-```bash
+```sh
LD_LIBRARY_PATH=$HOME/code/openssl:./lib/.libs gdb ./src/.libs/curl
```
in another repository. Once you have that set up, you can start a server
and then run curl against that:
-```bash
- cd $HOME/code/ech-dev-utils
- ./scripts/echsvr.sh -d
- ...
+```sh
+cd $HOME/code/ech-dev-utils
+./scripts/echsvr.sh -d
+...
```
The ``echsvr.sh`` script supports many ECH-related options. Use ``echsvr.sh -h``
In another window:
-```bash
- cd $HOME/code/curl/
- ./src/curl -vvv --insecure --connect-to foo.example.com:8443:localhost:8443 --ech ecl:AD7+DQA6uwAgACBix2B78sX+EQhEbxMspDOc8Z3xVS5aQpYP0Cxpc2AWPAAEAAEAAQALZXhhbXBsZS5jb20AAA==
+```sh
+cd $HOME/code/curl/
+./src/curl -vvv --insecure --connect-to foo.example.com:8443:localhost:8443 --ech ecl:AD7+DQA6uwAgACBix2B78sX+EQhEbxMspDOc8Z3xVS5aQpYP0Cxpc2AWPAAEAAEAAQALZXhhbXBsZS5jb20AAA==
```
### Automated use of ``retry_configs`` not supported so far...
You can use either autotools or cmake:
- ./configure \
- CC=/path/to/djgpp/bin/i586-pc-msdosdjgpp-gcc \
- AR=/path/to/djgpp/bin/i586-pc-msdosdjgpp-ar \
- RANLIB=/path/to/djgpp/bin/i586-pc-msdosdjgpp-ranlib \
- WATT_ROOT=/path/to/djgpp/net/watt \
- --host=i586-pc-msdosdjgpp \
- --with-openssl=/path/to/djgpp \
- --with-zlib=/path/to/djgpp \
- --without-libpsl \
- --disable-shared
-
- cmake . \
- -DCMAKE_SYSTEM_NAME=DOS \
- -DCMAKE_C_COMPILER_TARGET=i586-pc-msdosdjgpp \
- -DCMAKE_C_COMPILER=/path/to/djgpp/bin/i586-pc-msdosdjgpp-gcc \
- -DWATT_ROOT=/path/to/djgpp/net/watt \
- -DOPENSSL_INCLUDE_DIR=/path/to/djgpp/include \
- -DOPENSSL_SSL_LIBRARY=/path/to/djgpp/lib/libssl.a \
- -DOPENSSL_CRYPTO_LIBRARY=/path/to/djgpp/lib/libcrypto.a \
- -DZLIB_INCLUDE_DIR=/path/to/djgpp/include \
- -DZLIB_LIBRARY=/path/to/djgpp/lib/libz.a \
- -DCURL_USE_LIBPSL=OFF
+```sh
+./configure \
+ CC=/path/to/djgpp/bin/i586-pc-msdosdjgpp-gcc \
+ AR=/path/to/djgpp/bin/i586-pc-msdosdjgpp-ar \
+ RANLIB=/path/to/djgpp/bin/i586-pc-msdosdjgpp-ranlib \
+ WATT_ROOT=/path/to/djgpp/net/watt \
+ --host=i586-pc-msdosdjgpp \
+ --with-openssl=/path/to/djgpp \
+ --with-zlib=/path/to/djgpp \
+ --without-libpsl \
+ --disable-shared
+```
+
+```sh
+cmake . \
+ -DCMAKE_SYSTEM_NAME=DOS \
+ -DCMAKE_C_COMPILER_TARGET=i586-pc-msdosdjgpp \
+ -DCMAKE_C_COMPILER=/path/to/djgpp/bin/i586-pc-msdosdjgpp-gcc \
+ -DWATT_ROOT=/path/to/djgpp/net/watt \
+ -DOPENSSL_INCLUDE_DIR=/path/to/djgpp/include \
+ -DOPENSSL_SSL_LIBRARY=/path/to/djgpp/lib/libssl.a \
+ -DOPENSSL_CRYPTO_LIBRARY=/path/to/djgpp/lib/libcrypto.a \
+ -DZLIB_INCLUDE_DIR=/path/to/djgpp/include \
+ -DZLIB_LIBRARY=/path/to/djgpp/lib/libz.a \
+ -DCURL_USE_LIBPSL=OFF
+```
Notes:
You can use either autotools or cmake:
- ./configure \
- CC=/opt/amiga/bin/m68k-amigaos-gcc \
- AR=/opt/amiga/bin/m68k-amigaos-ar \
- RANLIB=/opt/amiga/bin/m68k-amigaos-ranlib \
- --host=m68k-amigaos \
- --with-amissl \
- CFLAGS='-O0 -msoft-float -mcrt=clib2' \
- CPPFLAGS=-I/path/to/AmiSSL/Developer/include \
- LDFLAGS=-L/path/to/AmiSSL/Developer/lib/AmigaOS3 \
- LIBS='-lnet -lm -latomic' \
- --without-libpsl \
- --disable-shared
-
- cmake . \
- -DAMIGA=1 \
- -DCMAKE_SYSTEM_NAME=Generic \
- -DCMAKE_C_COMPILER_TARGET=m68k-unknown-amigaos \
- -DCMAKE_C_COMPILER=/opt/amiga/bin/m68k-amigaos-gcc \
- -DCMAKE_C_FLAGS='-O0 -msoft-float -mcrt=clib2' \
- -DAMISSL_INCLUDE_DIR=/path/to/AmiSSL/Developer/include \
- -DAMISSL_STUBS_LIBRARY=/path/to/AmiSSL/Developer/lib/AmigaOS3/libamisslstubs.a \
- -DAMISSL_AUTO_LIBRARY=/path/to/AmiSSL/Developer/lib/AmigaOS3/libamisslauto.a \
- -DCURL_USE_LIBPSL=OFF
+```sh
+./configure \
+ CC=/opt/amiga/bin/m68k-amigaos-gcc \
+ AR=/opt/amiga/bin/m68k-amigaos-ar \
+ RANLIB=/opt/amiga/bin/m68k-amigaos-ranlib \
+ --host=m68k-amigaos \
+ --with-amissl \
+ CFLAGS='-O0 -msoft-float -mcrt=clib2' \
+ CPPFLAGS=-I/path/to/AmiSSL/Developer/include \
+ LDFLAGS=-L/path/to/AmiSSL/Developer/lib/AmigaOS3 \
+ LIBS='-lnet -lm -latomic' \
+ --without-libpsl \
+ --disable-shared
+```
+
+```sh
+cmake . \
+ -DAMIGA=1 \
+ -DCMAKE_SYSTEM_NAME=Generic \
+ -DCMAKE_C_COMPILER_TARGET=m68k-unknown-amigaos \
+ -DCMAKE_C_COMPILER=/opt/amiga/bin/m68k-amigaos-gcc \
+ -DCMAKE_C_FLAGS='-O0 -msoft-float -mcrt=clib2' \
+ -DAMISSL_INCLUDE_DIR=/path/to/AmiSSL/Developer/include \
+ -DAMISSL_STUBS_LIBRARY=/path/to/AmiSSL/Developer/lib/AmigaOS3/libamisslstubs.a \
+ -DAMISSL_AUTO_LIBRARY=/path/to/AmiSSL/Developer/lib/AmigaOS3/libamisslauto.a \
+ -DCURL_USE_LIBPSL=OFF
+```
## Disabling Specific Protocols in Windows builds
with CMake, where `ANDROID_NDK_HOME` points into your NDK:
- cmake . \
- -DANDROID_ABI=arm64-v8a \
- -DANDROID_PLATFORM=android-29 \
- -DCMAKE_TOOLCHAIN_FILE="$ANDROID_NDK_HOME/build/cmake/android.toolchain.cmake" \
- -DCURL_ENABLE_SSL=OFF \
- -DCURL_USE_LIBPSL=OFF
+```sh
+cmake . \
+ -DANDROID_ABI=arm64-v8a \
+ -DANDROID_PLATFORM=android-29 \
+ -DCMAKE_TOOLCHAIN_FILE="$ANDROID_NDK_HOME/build/cmake/android.toolchain.cmake" \
+ -DCURL_ENABLE_SSL=OFF \
+ -DCURL_USE_LIBPSL=OFF
+```
with `configure`, on macOS:
-```bash
+```sh
export ANDROID_NDK_HOME=~/Library/Android/sdk/ndk/25.1.8937393 # Point into your NDK.
-export HOST_TAG=darwin-x86_64 # Same tag for Apple Silicon. Other OS values here: https://developer.android.com/ndk/guides/other_build_systems#overview
+# Same tag for Apple Silicon. Other OS values here:
+# https://developer.android.com/ndk/guides/other_build_systems#overview
+export HOST_TAG=darwin-x86_64
export TOOLCHAIN=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/$HOST_TAG
export AR=$TOOLCHAIN/bin/llvm-ar
export AS=$TOOLCHAIN/bin/llvm-as
`include/openssl` to `$TOOLCHAIN/sysroot/usr/include`. Now you can build curl
for Android using OpenSSL like this:
-```bash
-LIBS="-lssl -lcrypto -lc++" # For OpenSSL/BoringSSL. In general, you need to the SSL/TLS layer's transitive dependencies if you are linking statically.
+```sh
+# For OpenSSL/BoringSSL. In general, you need to the SSL/TLS layer's transitive
+# dependencies if you are linking statically.
+LIBS='-lssl -lcrypto -lc++'
./configure --host aarch64-linux-android --with-pic --disable-shared --with-openssl="$TOOLCHAIN/sysroot/usr"
```
of cross-compiling for the IBM 405GP PowerPC processor using the toolchain on
Linux.
-```bash
-#! /bin/sh
-
+```sh
export PATH=$PATH:/opt/hardhat/devkit/ppc/405/bin
export CPPFLAGS="-I/opt/hardhat/devkit/ppc/405/target/usr/include"
export AR=ppc_405-ar
export CC=ppc_405-gcc
export NM=ppc_405-nm
-./configure --target=powerpc-hardhat-linux
- --host=powerpc-hardhat-linux
- --build=i586-pc-linux-gnu
- --prefix=/opt/hardhat/devkit/ppc/405/target/usr/local
- --exec-prefix=/usr/local
+./configure \
+ --target=powerpc-hardhat-linux
+ --host=powerpc-hardhat-linux
+ --build=i586-pc-linux-gnu
+ --prefix=/opt/hardhat/devkit/ppc/405/target/usr/local
+ --exec-prefix=/usr/local
```
The `--prefix` parameter specifies where curl gets installed. If `configure`