diff --git a/.github/workflows/local_openssl.yml b/.github/workflows/local_openssl.yml new file mode 100644 index 0000000..1fdd9fa --- /dev/null +++ b/.github/workflows/local_openssl.yml @@ -0,0 +1,37 @@ +name: validate-local-openssl + +defaults: + run: + working-directory: validation/local_ping_pong_openssl + +on: + pull_request: + paths-ignore: + - README.md + push: + branches: master + paths-ignore: + - README.md + +permissions: + contents: read + +env: + CARGO_INCREMENTAL: 0 + RUSTFLAGS: "-Dwarnings" + +jobs: + test: + strategy: + matrix: + toolchain: + - stable + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: RustCrypto/actions/cargo-cache@master + - uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ matrix.toolchain }} + - name: Test against OpenSSL locally + run: cargo test diff --git a/validation/README.md b/validation/README.md index 4670c20..913e210 100644 --- a/validation/README.md +++ b/validation/README.md @@ -6,6 +6,7 @@ between rustls and rustcrypto-rustcrypto provider under different targets. | Crate | Description | | :--- | :--- | | consumer-no_std | Basic consumer library aiming no_std environment | +| local_ping_pong_openssl | Local tests against OpenSSL reference | These live in the workspace due to different dependency requirements between tests where development-deps may pollute the integration under test. diff --git a/validation/local_ping_pong_openssl/.gitignore b/validation/local_ping_pong_openssl/.gitignore new file mode 100644 index 0000000..9f787f5 --- /dev/null +++ b/validation/local_ping_pong_openssl/.gitignore @@ -0,0 +1,6 @@ +target +certs/*.crt +certs/*.key +certs/*.pfx +certs/*.srl +certs/*.csr diff --git a/validation/local_ping_pong_openssl/Cargo.lock b/validation/local_ping_pong_openssl/Cargo.lock new file mode 100644 index 0000000..d6eebf0 --- /dev/null +++ b/validation/local_ping_pong_openssl/Cargo.lock @@ -0,0 +1,1046 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aead" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" +dependencies = [ + "crypto-common", + "generic-array", +] + +[[package]] +name = "aes" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "aes-gcm" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" +dependencies = [ + "aead", + "aes", + "cipher", + "ctr", + "ghash", + "subtle", +] + +[[package]] +name = "autocfg" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" + +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "bitflags" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "cc" +version = "1.0.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d32a725bc159af97c3e629873bb9f88fb8cf8a4867175f76dc987815ea07c83b" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chacha20" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "chacha20poly1305" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" +dependencies = [ + "aead", + "chacha20", + "cipher", + "poly1305", + "zeroize", +] + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", + "zeroize", +] + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[package]] +name = "cpufeatures" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +dependencies = [ + "libc", +] + +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array", + "rand_core", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "ctr" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" +dependencies = [ + "cipher", +] + +[[package]] +name = "curve25519-dalek" +version = "4.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a677b8922c94e01bdbb12126b0bc852f00447528dee1782229af9c720c3f348" +dependencies = [ + "cfg-if", + "cpufeatures", + "curve25519-dalek-derive", + "digest", + "fiat-crypto", + "platforms", + "rustc_version", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "der" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" +dependencies = [ + "const-oid", + "pem-rfc7468", + "zeroize", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "const-oid", + "crypto-common", + "subtle", +] + +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der", + "digest", + "elliptic-curve", + "rfc6979", + "signature", + "spki", +] + +[[package]] +name = "ed25519" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" +dependencies = [ + "pkcs8", + "signature", +] + +[[package]] +name = "ed25519-dalek" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871" +dependencies = [ + "curve25519-dalek", + "ed25519", + "serde", + "sha2", + "subtle", + "zeroize", +] + +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct", + "crypto-bigint", + "digest", + "ff", + "generic-array", + "group", + "hkdf", + "pem-rfc7468", + "pkcs8", + "rand_core", + "sec1", + "subtle", + "zeroize", +] + +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +dependencies = [ + "rand_core", + "subtle", +] + +[[package]] +name = "fiat-crypto" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38793c55593b33412e3ae40c2c9781ffaa6f438f6f8c10f24e71846fbd7ae01e" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", + "zeroize", +] + +[[package]] +name = "getrandom" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "ghash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1" +dependencies = [ + "opaque-debug", + "polyval", +] + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core", + "subtle", +] + +[[package]] +name = "hkdf" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +dependencies = [ + "hmac", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "generic-array", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +dependencies = [ + "spin 0.5.2", +] + +[[package]] +name = "libc" +version = "0.2.153" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" + +[[package]] +name = "libm" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + +[[package]] +name = "local_ping_pong_openssl" +version = "0.0.0" +dependencies = [ + "openssl", + "pem-rfc7468", + "rustls", + "rustls-rustcrypto", +] + +[[package]] +name = "num-bigint-dig" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151" +dependencies = [ + "byteorder", + "lazy_static", + "libm", + "num-integer", + "num-iter", + "num-traits", + "rand", + "smallvec", + "zeroize", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d869c01cc0c455284163fd0092f1f93835385ccab5a98a0dcc497b2f8bf055a9" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + +[[package]] +name = "openssl" +version = "0.10.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" +dependencies = [ + "bitflags", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "openssl-sys" +version = "0.9.102" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c597637d56fbc83893a35eb0dd04b2b8e7a50c91e64e9493e398b5df4fb45fa2" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "p256" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" +dependencies = [ + "ecdsa", + "elliptic-curve", + "primeorder", + "sha2", +] + +[[package]] +name = "p384" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70786f51bcc69f6a4c0360e063a4cac5419ef7c5cd5b3c99ad70f3be5ba79209" +dependencies = [ + "ecdsa", + "elliptic-curve", + "primeorder", + "sha2", +] + +[[package]] +name = "paste" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" + +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + +[[package]] +name = "pkcs1" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" +dependencies = [ + "der", + "pkcs8", + "spki", +] + +[[package]] +name = "pkcs5" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e847e2c91a18bfa887dd028ec33f2fe6f25db77db3619024764914affe8b69a6" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "pkcs5", + "spki", +] + +[[package]] +name = "pkg-config" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" + +[[package]] +name = "platforms" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db23d408679286588f4d4644f965003d056e3dd5abcaaa938116871d7ce2fee7" + +[[package]] +name = "poly1305" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" +dependencies = [ + "cpufeatures", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "polyval" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" +dependencies = [ + "cfg-if", + "cpufeatures", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "primeorder" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" +dependencies = [ + "elliptic-curve", +] + +[[package]] +name = "proc-macro2" +version = "1.0.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + +[[package]] +name = "ring" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +dependencies = [ + "cc", + "cfg-if", + "getrandom", + "libc", + "spin 0.9.8", + "untrusted", + "windows-sys", +] + +[[package]] +name = "rsa" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0e5124fcb30e76a7e79bfee683a2746db83784b86289f6251b54b7950a0dfc" +dependencies = [ + "const-oid", + "digest", + "num-bigint-dig", + "num-integer", + "num-traits", + "pkcs1", + "pkcs8", + "rand_core", + "sha2", + "signature", + "spki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + +[[package]] +name = "rustls" +version = "0.23.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afabcee0551bd1aa3e18e5adbf2c0544722014b899adb31bd186ec638d3da97e" +dependencies = [ + "once_cell", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-pki-types" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "beb461507cee2c2ff151784c52762cf4d9ff6a61f3e80968600ed24fa837fa54" + +[[package]] +name = "rustls-rustcrypto" +version = "0.1.0" +dependencies = [ + "aead", + "aes-gcm", + "chacha20poly1305", + "crypto-common", + "der", + "digest", + "ecdsa", + "ed25519-dalek", + "hmac", + "p256", + "p384", + "paste", + "pkcs8", + "rand_core", + "rsa", + "rustls", + "rustls-pki-types", + "rustls-webpki", + "sec1", + "sha2", + "signature", + "x25519-dalek", +] + +[[package]] +name = "rustls-webpki" +version = "0.102.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3bce581c0dd41bce533ce695a1437fa16a7ab5ac3ccfa99fe1a620a7885eabf" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der", + "generic-array", + "pkcs8", + "subtle", + "zeroize", +] + +[[package]] +name = "semver" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" + +[[package]] +name = "serde" +version = "1.0.199" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c9f6e76df036c77cd94996771fb40db98187f096dd0b9af39c6c6e452ba966a" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.199" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11bd257a6541e141e42ca6d24ae26f7714887b47e89aa739099104c7e4d3b7fc" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest", + "rand_core", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "subtle" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" + +[[package]] +name = "syn" +version = "2.0.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "909518bc7b1c9b779f1bbf07f2929d35af9f0f37e47c6e9ef7f9dddc1e1821f3" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "universal-hash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +dependencies = [ + "crypto-common", + "subtle", +] + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" + +[[package]] +name = "x25519-dalek" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7e468321c81fb07fa7f4c636c3972b9100f0346e5b6a9f2bd0603a52f7ed277" +dependencies = [ + "curve25519-dalek", + "rand_core", + "zeroize", +] + +[[package]] +name = "zeroize" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/validation/local_ping_pong_openssl/Cargo.toml b/validation/local_ping_pong_openssl/Cargo.toml new file mode 100644 index 0000000..9b224ac --- /dev/null +++ b/validation/local_ping_pong_openssl/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "local_ping_pong_openssl" +version = "0.0.0" +edition = "2021" +license = "MIT OR Apache-2.0" + +[dependencies] +rustls = { version = "0.23.0", default-features = false, features = ["std"] } +rustls-rustcrypto = { path = "../../" } +openssl = { version = "0.10", default-features = false } +pem-rfc7468 = { version = "0.7", default-features = false, features = ["alloc"] } diff --git a/validation/local_ping_pong_openssl/README.md b/validation/local_ping_pong_openssl/README.md new file mode 100644 index 0000000..149470e --- /dev/null +++ b/validation/local_ping_pong_openssl/README.md @@ -0,0 +1,5 @@ +# Validate OpenSSL compatibility + +Test compatibility between rustls-rustcrypto and OpenSSL + +Includes testing against OpenSSL generated certificates and keys diff --git a/validation/local_ping_pong_openssl/build.rs b/validation/local_ping_pong_openssl/build.rs new file mode 100644 index 0000000..6065074 --- /dev/null +++ b/validation/local_ping_pong_openssl/build.rs @@ -0,0 +1,47 @@ +use std::fs::metadata; +use std::path::Path; +use std::process::Command; +use std::time::SystemTime; + +fn main() { + check_gen_certs(); +} + +fn manifest_dir() -> String { + match std::env::var("CARGO_MANIFEST_DIR").as_deref() { + Ok(target_dir) => target_dir.into(), + _ => panic!("CARGO_MANIFEST_DIR required for build."), + } +} + +fn check_gen_certs() { + let out_dir_str = manifest_dir(); + let out_dir = Path::new(&out_dir_str).join("certs"); + + let ca_crt_path = out_dir.join("ca.rsa4096.crt"); + + let mut generate = true; + + if ca_crt_path.exists() { + let now = SystemTime::now(); + let meta = metadata(ca_crt_path).expect("fs metadata"); + let created = meta + .created() + .expect("fs no support to determine ctime from file?"); + let difference = now + .duration_since(created) + .expect("System clock gone backwards"); + + if difference.as_secs() < 364 * 24 * 3600 { + generate = false; + } + } + + if generate { + Command::new("make") + .arg("rsa4096") + .current_dir(out_dir) + .spawn() + .expect("make rsa4096"); + } +} diff --git a/validation/local_ping_pong_openssl/certs/Makefile b/validation/local_ping_pong_openssl/certs/Makefile new file mode 100644 index 0000000..39564b3 --- /dev/null +++ b/validation/local_ping_pong_openssl/certs/Makefile @@ -0,0 +1,62 @@ +ed25519: ed25519-key ed25519-csr sign-ed25519-csr pk12-ed25519 + +rsa4096: rsa4096-key ca-rsa4096-key ca-rsa4096-crt rsa4096-csr ca-sign-rsa4096-csr sign-rsa4096-csr pk12-rsa4096 + +clean: + rm rustcryp.to.key rustcryp.to.csr rustcryp.to.crt + +## Server Cert Keys + +ed25519-key: + openssl genpkey -algorithm ED25519 > rustcryp.to.ed25519.key + +rsa4096-key: + openssl genrsa -out rustcryp.to.rsa4096.key 4096 + +## CA + +ca-rsa4096-key: + openssl genrsa -out ca.rsa4096.key 4096 + +ca-rsa4096-crt: ca-rsa4096-key + openssl req -x509 -new -nodes -key ca.rsa4096.key -out ca.rsa4096.crt \ + -subj /C=XX/ST=YY/L=Antarctica/O=RustCrypto/OU=Contributors/CN=ca.rustcryp.to + +## CSR + +ed25519-csr: + openssl req -new -out rustcryp.to.ed25519.csr -key rustcryp.to.ed25519.key -config openssl.cnf + +rsa4096-csr: rsa4096-key + openssl req -new -out rustcryp.to.rsa4096.csr -key rustcryp.to.rsa4096.key -config cert.cnf + + +## Sign PKCS10 CA certified + +ca-sign-rsa4096-csr: + openssl x509 -req \ + -in rustcryp.to.rsa4096.csr \ + -out rustcryp.to.rsa4096.ca_signed.crt \ + -CA ca.rsa4096.crt \ + -CAkey ca.rsa4096.key \ + -CAcreateserial \ + -days 365 \ + -extensions v3_end \ + -extfile openssl.cnf + +## Sign PKCS10 self-certified + +sign-ed25591-csr: + openssl x509 -req -days 365 -in rustcryp.to.ed25519.csr -signkey rustcryp.to.ed25519.key -out rustcryp.to.ed25519.crt + +sign-rsa4096-csr: + openssl x509 -req -days 365 -in rustcryp.to.rsa4096.csr -signkey rustcryp.to.rsa4096.key -out rustcryp.to.rsa4096.crt + +## Export PKCS12 + +pk12-ed25519: + openssl pkcs12 -export -out rustcryp.to.ed25519.pfx -inkey rustcryp.to.ed25519.key -in rustcryp.to.ed25519.crt -passout pass:test + +pk12-rsa4096: + openssl pkcs12 -export -out rustcryp.to.rsa4096.pfx -inkey rustcryp.to.rsa4096.key -in rustcryp.to.rsa4096.crt -passout pass:test + diff --git a/validation/local_ping_pong_openssl/certs/cert.cnf b/validation/local_ping_pong_openssl/certs/cert.cnf new file mode 100644 index 0000000..6f97235 --- /dev/null +++ b/validation/local_ping_pong_openssl/certs/cert.cnf @@ -0,0 +1,21 @@ +[req] +default_bits = 4096 +prompt = no +default_md = sha256 +req_extensions = req_ext +distinguished_name = dn + +[ dn ] +C=XX +ST=YY +L=Antarctica +O=Contributors +OU=Testers +emailAddress=hello@rustcryp.to +CN = test.rustcryp.to + +[ req_ext ] +subjectAltName = @alt_names + +[ alt_names ] +DNS.1 = localhost diff --git a/validation/local_ping_pong_openssl/certs/openssl.cnf b/validation/local_ping_pong_openssl/certs/openssl.cnf new file mode 100644 index 0000000..eb94919 --- /dev/null +++ b/validation/local_ping_pong_openssl/certs/openssl.cnf @@ -0,0 +1,23 @@ +[ v3_end ] +basicConstraints = critical,CA:false +keyUsage = nonRepudiation, digitalSignature +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid:always,issuer:always +subjectAltName = @alt_names + +[ v3_client ] +basicConstraints = critical,CA:false +keyUsage = nonRepudiation, digitalSignature +extendedKeyUsage = critical, clientAuth +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid:always,issuer:always + +[ v3_inter ] +subjectKeyIdentifier = hash +extendedKeyUsage = critical, serverAuth, clientAuth +basicConstraints = CA:true +keyUsage = cRLSign, keyCertSign, digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment, keyAgreement, keyCertSign, cRLSign + +[ alt_names ] +DNS.1 = www.rustcryp.to +DNS.3 = localhost diff --git a/validation/local_ping_pong_openssl/src/lib.rs b/validation/local_ping_pong_openssl/src/lib.rs new file mode 100644 index 0000000..e4b659d --- /dev/null +++ b/validation/local_ping_pong_openssl/src/lib.rs @@ -0,0 +1,190 @@ +pub mod net_util; +mod openssl_util; +pub use openssl_util::CipherSuites as OpenSslCipherSuites; +pub use openssl_util::GroupsList as OpenSslGroupsList; +pub use openssl_util::Server as OpenSslServer; + +mod rustls_util; +pub use rustls_util::Client as RustCryptoTlsClient; + +#[cfg(test)] +mod test { + use super::*; + + use std::path::Path; + use std::thread; + use std::time::Duration; + + const CA_CERT: &'static str = "ca.rsa4096.crt"; + const CERT: &'static str = "rustcryp.to.rsa4096.ca_signed.crt"; + const RSA_KEY: &'static str = "rustcryp.to.rsa4096.key"; + + #[test] + fn vs_openssl_as_client_autoneg() { + vs_openssl_as_client(OpenSslGroupsList::default(), OpenSslCipherSuites::default()); + } + + #[test] + #[should_panic] // No ciphers enabled for max supported SSL/TLS version + fn vs_openssl_as_client_none() { + let cipher_suites = OpenSslCipherSuites { + TLS_AES_128_GCM_SHA256: false, + TLS_AES_256_GCM_SHA384: false, + TLS_CHACHA20_POLY1305_SHA256: false, + TLS_AES_128_CCM_SHA256: false, + TLS_AES_128_CCM_8_SHA256: false, + }; + vs_openssl_as_client(OpenSslGroupsList::default(), cipher_suites); + } + + #[test] + fn vs_openssl_as_client_gcm_sha256() { + let cipher_suites = OpenSslCipherSuites { + TLS_AES_128_GCM_SHA256: true, + TLS_AES_256_GCM_SHA384: false, + TLS_CHACHA20_POLY1305_SHA256: false, + TLS_AES_128_CCM_SHA256: false, + TLS_AES_128_CCM_8_SHA256: false, + }; + vs_openssl_as_client(OpenSslGroupsList::default(), cipher_suites); + } + + #[test] + fn vs_openssl_as_client_gcm_sha384() { + let cipher_suites = OpenSslCipherSuites { + TLS_AES_128_GCM_SHA256: false, + TLS_AES_256_GCM_SHA384: true, + TLS_CHACHA20_POLY1305_SHA256: false, + TLS_AES_128_CCM_SHA256: false, + TLS_AES_128_CCM_8_SHA256: false, + }; + vs_openssl_as_client(OpenSslGroupsList::default(), cipher_suites); + } + + #[test] + fn vs_openssl_as_client_poly1305_sha256() { + let cipher_suites = OpenSslCipherSuites { + TLS_AES_128_GCM_SHA256: false, + TLS_AES_256_GCM_SHA384: false, + TLS_CHACHA20_POLY1305_SHA256: true, + TLS_AES_128_CCM_SHA256: false, + TLS_AES_128_CCM_8_SHA256: false, + }; + vs_openssl_as_client(OpenSslGroupsList::default(), cipher_suites); + } + + #[test] + #[should_panic] // no_shared_cipher + fn vs_openssl_as_client_ccm_sha256() { + let cipher_suites = OpenSslCipherSuites { + TLS_AES_128_GCM_SHA256: false, + TLS_AES_256_GCM_SHA384: false, + TLS_CHACHA20_POLY1305_SHA256: false, + TLS_AES_128_CCM_SHA256: true, + TLS_AES_128_CCM_8_SHA256: false, + }; + vs_openssl_as_client(OpenSslGroupsList::default(), cipher_suites); + } + + #[test] + #[should_panic] // no_shared_cipher + fn vs_openssl_as_client_ccm8_sha256() { + let cipher_suites = OpenSslCipherSuites { + TLS_AES_128_GCM_SHA256: false, + TLS_AES_256_GCM_SHA384: false, + TLS_CHACHA20_POLY1305_SHA256: false, + TLS_AES_128_CCM_SHA256: false, + TLS_AES_128_CCM_8_SHA256: true, + }; + vs_openssl_as_client(OpenSslGroupsList::default(), cipher_suites); + } + + #[test] + #[should_panic] + fn vs_openssl_as_client_group_none() { + let group_list = OpenSslGroupsList::all_false(); + vs_openssl_as_client(group_list, OpenSslCipherSuites::default()); + } + #[test] + fn vs_openssl_as_client_group_p256() { + let mut group_list = OpenSslGroupsList::all_false(); + group_list.P256 = true; + vs_openssl_as_client(group_list, OpenSslCipherSuites::default()); + } + #[test] + fn vs_openssl_as_client_group_p384() { + let mut group_list = OpenSslGroupsList::all_false(); + group_list.P384 = true; + vs_openssl_as_client(group_list, OpenSslCipherSuites::default()); + } + #[test] + #[should_panic] // no support + fn vs_openssl_as_client_group_p521() { + let mut group_list = OpenSslGroupsList::all_false(); + group_list.P521 = true; + vs_openssl_as_client(group_list, OpenSslCipherSuites::default()); + } + #[test] + fn vs_openssl_as_client_group_x25519() { + let mut group_list = OpenSslGroupsList::all_false(); + group_list.X25519 = true; + vs_openssl_as_client(group_list, OpenSslCipherSuites::default()); + } + #[test] + #[should_panic] // no support + fn vs_openssl_as_client_group_x448() { + let mut group_list = OpenSslGroupsList::all_false(); + group_list.X448 = true; + vs_openssl_as_client(group_list, OpenSslCipherSuites::default()); + } + + fn vs_openssl_as_client(groups_list: OpenSslGroupsList, cipher_suites: OpenSslCipherSuites) { + let path_certs = Path::new("certs"); + + let (listener, server_addr) = net_util::new_localhost_tcplistener(); + + // Client rustls-rustcrypto thread + let client_thread = thread::spawn(move || { + let mut rustls_client = RustCryptoTlsClient::new(path_certs.join(CA_CERT), server_addr); + rustls_client.ping(); + assert_eq!(rustls_client.wait_pong(), "PONG\n"); + return; + }); + + // Canary Timeout thread + let timeout_thread = thread::spawn(move || { + thread::sleep(Duration::from_millis(1_000)); + panic!("timeout"); + }); + + // Server OpenSSL thread + let server_thread = thread::spawn(move || { + let mut openssl_server = OpenSslServer::from_listener(listener); + let mut tls_stream = openssl_server.accept_next( + groups_list, + cipher_suites, + path_certs.join(CA_CERT), + path_certs.join(CERT), + path_certs.join(RSA_KEY), + ); + + assert_eq!(tls_stream.wait_ping(), "PING\n"); + tls_stream.pong(); + tls_stream.shutdown(); + }); + + loop { + thread::sleep(Duration::from_millis(10)); + + if client_thread.is_finished() && server_thread.is_finished() { + break; + } + if timeout_thread.is_finished() { + panic!("TIMEOUT"); + } + } + + client_thread.join().expect("Client thread panic"); + server_thread.join().expect("Server thread panic"); + } +} diff --git a/validation/local_ping_pong_openssl/src/net_util.rs b/validation/local_ping_pong_openssl/src/net_util.rs new file mode 100644 index 0000000..c9785e4 --- /dev/null +++ b/validation/local_ping_pong_openssl/src/net_util.rs @@ -0,0 +1,8 @@ +use std::net::{SocketAddr, TcpListener}; + +/// Create a new TcpListener on localhost on random port +pub fn new_localhost_tcplistener() -> (TcpListener, SocketAddr) { + let listener = TcpListener::bind("127.0.0.1:0").unwrap(); + let server_addr = listener.local_addr().unwrap(); + (listener, server_addr) +} diff --git a/validation/local_ping_pong_openssl/src/openssl_util.rs b/validation/local_ping_pong_openssl/src/openssl_util.rs new file mode 100644 index 0000000..f08558b --- /dev/null +++ b/validation/local_ping_pong_openssl/src/openssl_util.rs @@ -0,0 +1,91 @@ +use std::io::Write; +use std::net::{TcpListener, TcpStream}; +use std::path::PathBuf; + +use openssl::ssl::{SslFiletype, SslMethod, SslStream}; + +mod cipher_suites; +mod groups_list; + +pub use cipher_suites::CipherSuites; +pub use groups_list::GroupsList; + +pub struct Server { + listener: TcpListener, +} + +pub struct TlsStream { + pub stream: SslStream, +} + +impl Server { + pub fn from_listener(listener: TcpListener) -> Self { + Self { listener } + } + pub fn accept_next( + &mut self, + groups_list: GroupsList, + cipher_suites: CipherSuites, + path_ca_cert: PathBuf, + path_cert: PathBuf, + path_key: PathBuf, + ) -> TlsStream { + let stream = match self.listener.incoming().next() { + Some(stream_try) => match stream_try { + Ok(stream) => stream, + Err(_) => panic!("Failed OpenSSL accept_next()"), + }, + None => panic!("No stream?"), + }; + + let mut ssl_context_build = + openssl::ssl::SslContext::builder(SslMethod::tls_server()).unwrap(); + ssl_context_build.set_verify(openssl::ssl::SslVerifyMode::NONE); + + ssl_context_build.set_ca_file(path_ca_cert).unwrap(); + ssl_context_build + .set_certificate_file(path_cert, SslFiletype::PEM) + .unwrap(); + + ssl_context_build + .set_private_key_file(path_key, SslFiletype::PEM) + .unwrap(); + + ssl_context_build + .set_groups_list(&groups_list.to_string()) + .unwrap(); + + ssl_context_build + .set_ciphersuites(&cipher_suites.to_string()) + .unwrap(); + // https://docs.rs/openssl/latest/openssl/ssl/struct.SslContextBuilder.html#method.set_cipher_list + // https://docs.rs/openssl/latest/openssl/ssl/struct.SslContextBuilder.html#method.set_ciphersuites + ssl_context_build.check_private_key().unwrap(); + let ctx = ssl_context_build.build(); + let ssl = openssl::ssl::Ssl::new(&ctx).unwrap(); + let mut ssl_stream = SslStream::new(ssl, stream).unwrap(); + ssl_stream.accept().unwrap(); + TlsStream { stream: ssl_stream } + } +} + +impl TlsStream { + pub fn wait_ping(&mut self) -> String { + let mut buf_in = vec![0; 1024]; + let siz = self.stream.ssl_read(&mut buf_in); + + let incoming = match siz { + Ok(i) => buf_in[0..i].to_vec(), + Err(_e) => panic!("Error reading?"), + }; + + String::from_utf8_lossy(&incoming).to_string() + } + pub fn pong(&mut self) { + let out = "PONG\n"; + self.stream.write_all(out.as_bytes()).unwrap(); + } + pub fn shutdown(&mut self) { + self.stream.shutdown().unwrap(); + } +} diff --git a/validation/local_ping_pong_openssl/src/openssl_util/cipher_suites.rs b/validation/local_ping_pong_openssl/src/openssl_util/cipher_suites.rs new file mode 100644 index 0000000..ff30521 --- /dev/null +++ b/validation/local_ping_pong_openssl/src/openssl_util/cipher_suites.rs @@ -0,0 +1,43 @@ +#[derive(Debug)] +#[allow(non_snake_case)] +pub struct CipherSuites { + pub TLS_AES_128_GCM_SHA256: bool, + pub TLS_AES_256_GCM_SHA384: bool, + pub TLS_CHACHA20_POLY1305_SHA256: bool, + pub TLS_AES_128_CCM_SHA256: bool, + pub TLS_AES_128_CCM_8_SHA256: bool, +} + +impl core::fmt::Display for CipherSuites { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> { + let mut vec_suites: Vec<&str> = vec![]; + if self.TLS_AES_128_GCM_SHA256 { + vec_suites.push("TLS_AES_128_GCM_SHA256"); + } + if self.TLS_AES_256_GCM_SHA384 { + vec_suites.push("TLS_AES_256_GCM_SHA384"); + } + if self.TLS_CHACHA20_POLY1305_SHA256 { + vec_suites.push("TLS_CHACHA20_POLY1305_SHA256"); + } + if self.TLS_AES_128_CCM_SHA256 { + vec_suites.push("TLS_AES_128_CCM_SHA256"); + } + if self.TLS_AES_128_CCM_8_SHA256 { + vec_suites.push("TLS_AES_128_CCM_8_SHA256"); + } + write!(f, "{}", vec_suites.join(":")) + } +} + +impl Default for CipherSuites { + fn default() -> Self { + CipherSuites { + TLS_AES_128_GCM_SHA256: true, + TLS_AES_256_GCM_SHA384: true, + TLS_CHACHA20_POLY1305_SHA256: true, + TLS_AES_128_CCM_SHA256: false, + TLS_AES_128_CCM_8_SHA256: false, + } + } +} diff --git a/validation/local_ping_pong_openssl/src/openssl_util/groups_list.rs b/validation/local_ping_pong_openssl/src/openssl_util/groups_list.rs new file mode 100644 index 0000000..ffe3c65 --- /dev/null +++ b/validation/local_ping_pong_openssl/src/openssl_util/groups_list.rs @@ -0,0 +1,108 @@ +//! Sets the context’s supported elliptic curve groups. +//! https://docs.rs/openssl/latest/openssl/ssl/struct.SslContextBuilder.html#method.set_groups_list +//! https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set1_groups_list.html + +#[derive(Debug)] +#[allow(non_snake_case)] +pub struct GroupsList { + pub P256: bool, + pub P384: bool, + pub P521: bool, + pub X25519: bool, + pub X448: bool, + pub brainpoolP256r1tls13: bool, + pub brainpoolP384r1tls13: bool, + pub brainpoolP512r1tls13: bool, + pub ffdhe2048: bool, + pub ffdhe3072: bool, + pub ffdhe4096: bool, + pub ffdhe6144: bool, + pub ffdhe8192: bool, +} + +impl GroupsList { + pub fn all_false() -> Self { + GroupsList { + P256: false, + P384: false, + P521: false, + X25519: false, + X448: false, + brainpoolP256r1tls13: false, + brainpoolP384r1tls13: false, + brainpoolP512r1tls13: false, + ffdhe2048: false, + ffdhe3072: false, + ffdhe4096: false, + ffdhe6144: false, + ffdhe8192: false, + } + } +} + +impl Default for GroupsList { + fn default() -> Self { + GroupsList { + P256: true, + P384: true, + P521: false, + X25519: true, + X448: false, + brainpoolP256r1tls13: false, + brainpoolP384r1tls13: false, + brainpoolP512r1tls13: false, + ffdhe2048: false, + ffdhe3072: false, + ffdhe4096: false, + ffdhe6144: false, + ffdhe8192: false, + } + } +} + +impl core::fmt::Display for GroupsList { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> { + let mut vec_groups: Vec<&str> = vec![]; + + if self.P256 { + vec_groups.push("P-256"); + } + if self.P384 { + vec_groups.push("P-384"); + } + if self.P521 { + vec_groups.push("P-521"); + } + if self.X25519 { + vec_groups.push("X25519"); + } + if self.X448 { + vec_groups.push("X448"); + } + if self.brainpoolP256r1tls13 { + vec_groups.push("brainpoolP256r1tls13"); + } + if self.brainpoolP384r1tls13 { + vec_groups.push("brainpoolP384r1tls13"); + } + if self.brainpoolP512r1tls13 { + vec_groups.push("brainpoolP512r1tls13"); + } + if self.ffdhe2048 { + vec_groups.push("ffdhe2048"); + } + if self.ffdhe3072 { + vec_groups.push("ffdhe3072"); + } + if self.ffdhe4096 { + vec_groups.push("ffdhe4096"); + } + if self.ffdhe6144 { + vec_groups.push("ffdhe6144"); + } + if self.ffdhe8192 { + vec_groups.push("ffdhe8192"); + } + write!(f, "{}", vec_groups.join(":")) + } +} diff --git a/validation/local_ping_pong_openssl/src/rustls_util.rs b/validation/local_ping_pong_openssl/src/rustls_util.rs new file mode 100644 index 0000000..919e2ec --- /dev/null +++ b/validation/local_ping_pong_openssl/src/rustls_util.rs @@ -0,0 +1,73 @@ +use std::fs::File; +use std::io::{Read, Write}; +use std::net::SocketAddr; +use std::net::TcpStream; +use std::path::PathBuf; +use std::sync::Arc; + +use rustls_rustcrypto::provider as rustcrypto_provider; + +use rustls::RootCertStore; +use rustls::StreamOwned as RustlsStreamOwned; +use rustls::{ClientConfig, ClientConnection}; + +use rustls::pki_types::CertificateDer; +use rustls::pki_types::ServerName; + +/// Read rustls compatible CertificateDer from ca_path +fn load_ca_der(ca_path: PathBuf) -> CertificateDer<'static> { + let mut ca_pkcs10_file = File::open(ca_path).unwrap(); + let mut ca_pkcs10_data: Vec = vec![]; + ca_pkcs10_file.read_to_end(&mut ca_pkcs10_data).unwrap(); + let (ca_type_label, ca_data) = pem_rfc7468::decode_vec(&ca_pkcs10_data).unwrap(); + assert_eq!(ca_type_label, "CERTIFICATE"); + ca_data.into() +} + +/// provide rustls roots with pinned CA cert +fn roots(ca_pinned: CertificateDer) -> RootCertStore { + let mut roots = rustls::RootCertStore::empty(); + roots.add(ca_pinned).unwrap(); + roots +} + +/// Create new ClientConfig +fn rustcrypto_client_config(root_store: RootCertStore) -> ClientConfig { + rustls::ClientConfig::builder_with_provider(Arc::new(rustcrypto_provider())) + .with_safe_default_protocol_versions() + .unwrap() + .with_root_certificates(root_store) + .with_no_client_auth() +} + +#[derive(Debug)] +pub struct Client { + pub tls: RustlsStreamOwned, +} + +impl Client { + pub fn new(ca_pinned: PathBuf, server_addr: SocketAddr) -> Self { + let ca = load_ca_der(ca_pinned); + let roots = roots(ca); + let config = rustcrypto_client_config(roots); + + let conn = rustls::ClientConnection::new( + Arc::new(config), + ServerName::try_from("localhost").unwrap(), + ) + .unwrap(); + + let sock = TcpStream::connect(server_addr).unwrap(); + let tls = rustls::StreamOwned::new(conn, sock); + + Self { tls } + } + pub fn ping(&mut self) { + self.tls.write_all(b"PING\n").unwrap() + } + pub fn wait_pong(&mut self) -> String { + let mut plaintext = Vec::new(); + self.tls.read_to_end(&mut plaintext).unwrap(); + String::from_utf8_lossy(&plaintext).to_string() + } +}