diff options
Diffstat (limited to 'examples/util_wolfssl.cc')
-rw-r--r-- | examples/util_wolfssl.cc | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/examples/util_wolfssl.cc b/examples/util_wolfssl.cc new file mode 100644 index 0000000..80eb096 --- /dev/null +++ b/examples/util_wolfssl.cc @@ -0,0 +1,130 @@ +/* + * ngtcp2 + * + * Copyright (c) 2020 ngtcp2 contributors + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#include "util.h" + +#include <cassert> +#include <iostream> +#include <array> + +#include <ngtcp2/ngtcp2_crypto.h> + +#include <wolfssl/options.h> +#include <wolfssl/ssl.h> +#include <wolfssl/openssl/pem.h> + +#include "template.h" + +namespace ngtcp2 { + +namespace util { + +int generate_secure_random(uint8_t *data, size_t datalen) { + if (wolfSSL_RAND_bytes(data, static_cast<int>(datalen)) != 1) { + return -1; + } + + return 0; +} + +int generate_secret(uint8_t *secret, size_t secretlen) { + std::array<uint8_t, 16> rand; + std::array<uint8_t, 32> md; + + assert(md.size() == secretlen); + + if (generate_secure_random(rand.data(), rand.size()) != 0) { + return -1; + } + + auto ctx = wolfSSL_EVP_MD_CTX_new(); + if (ctx == nullptr) { + return -1; + } + + unsigned int mdlen = md.size(); + if (!wolfSSL_EVP_DigestInit_ex(ctx, EVP_sha256(), nullptr) || + !wolfSSL_EVP_DigestUpdate(ctx, rand.data(), rand.size()) || + !wolfSSL_EVP_DigestFinal_ex(ctx, md.data(), &mdlen)) { + wolfSSL_EVP_MD_CTX_free(ctx); + return -1; + } + + std::copy_n(std::begin(md), secretlen, secret); + wolfSSL_EVP_MD_CTX_free(ctx); + return 0; +} + +std::optional<std::string> read_token(const std::string_view &filename) { + auto f = wolfSSL_BIO_new_file(filename.data(), "r"); + if (f == nullptr) { + std::cerr << "Could not open token file " << filename << std::endl; + return {}; + } + + char *name, *header; + unsigned char *data; + long datalen; + std::string token; + if (wolfSSL_PEM_read_bio(f, &name, &header, &data, &datalen) != 1) { + std::cerr << "Could not read token file " << filename << std::endl; + wolfSSL_BIO_free(f); + return {}; + } + wolfSSL_BIO_free(f); + + wolfSSL_OPENSSL_free(name); + wolfSSL_OPENSSL_free(header); + + auto res = std::string{data, data + datalen}; + + wolfSSL_OPENSSL_free(data); + + return res; +} + +int write_token(const std::string_view &filename, const uint8_t *token, + size_t tokenlen) { + auto f = wolfSSL_BIO_new_file(filename.data(), "w"); + if (f == nullptr) { + std::cerr << "Could not write token in " << filename << std::endl; + return -1; + } + + wolfSSL_PEM_write_bio(f, "QUIC TOKEN", "", token, tokenlen); + wolfSSL_BIO_free(f); + + return 0; +} + +const char *crypto_default_ciphers() { + return "TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_" + "SHA256:TLS_AES_128_CCM_SHA256"; +} + +const char *crypto_default_groups() { return "X25519:P-256:P-384:P-521"; } + +} // namespace util + +} // namespace ngtcp2 |